# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID daa8047710d053fc91049a14f3f569fb3a8fff04
# Parent dbf7032f1fc69df0fb7529ee80f2f0766f78653a
Enable migration of a domain to the local machine - some timing
issues needed to be resolved by executing certain code early/later
Restore the physical to machine array such that balloon-allocated
pages can be deallocated.
Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
diff -r dbf7032f1fc6 -r daa8047710d0
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Apr 20 17:16:27
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Apr 20 17:32:12
2006 +0100
@@ -49,6 +49,7 @@ typedef struct tpmif_st {
grant_handle_t shmem_handle;
grant_ref_t shmem_ref;
+ struct page *pagerange;
} tpmif_t;
void tpmif_disconnect_complete(tpmif_t * tpmif);
diff -r dbf7032f1fc6 -r daa8047710d0
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Thu Apr 20
17:16:27 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Thu Apr 20
17:32:12 2006 +0100
@@ -22,7 +22,6 @@ LIST_HEAD(tpmif_list);
static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
{
- struct page *page;
tpmif_t *tpmif;
tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
@@ -35,9 +34,10 @@ static tpmif_t *alloc_tpmif(domid_t domi
tpmif->tpm_instance = instance;
atomic_set(&tpmif->refcnt, 1);
- page = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
- BUG_ON(page == NULL);
- tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+ tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
+ BUG_ON(tpmif->pagerange == NULL);
+ tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(
+ page_to_pfn(tpmif->pagerange));
list_add(&tpmif->tpmif_list, &tpmif_list);
num_frontends++;
@@ -49,6 +49,7 @@ static void free_tpmif(tpmif_t * tpmif)
{
num_frontends--;
list_del(&tpmif->tpmif_list);
+ balloon_dealloc_empty_page_range(tpmif->pagerange, TPMIF_TX_RING_SIZE);
kmem_cache_free(tpmif_cachep, tpmif);
}
@@ -115,11 +116,11 @@ int tpmif_map(tpmif_t *tpmif, unsigned l
.cmd = EVTCHNOP_bind_interdomain,
.u.bind_interdomain.remote_dom = tpmif->domid,
.u.bind_interdomain.remote_port = evtchn,
- };
+ };
- if (tpmif->irq) {
- return 0;
- }
+ if (tpmif->irq) {
+ return 0;
+ }
if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
diff -r dbf7032f1fc6 -r daa8047710d0
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Thu Apr 20
17:16:27 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Thu Apr 20
17:32:12 2006 +0100
@@ -271,6 +271,7 @@ int _packet_write(struct packet *pak,
struct gnttab_map_grant_ref map_op;
struct gnttab_unmap_grant_ref unmap_op;
tpmif_tx_request_t *tx;
+ unsigned long pfn, mfn, mfn_orig;
tx = &tpmif->tx->ring[i].req;
@@ -293,9 +294,12 @@ int _packet_write(struct packet *pak,
DPRINTK(" Grant table operation failure !\n");
return 0;
}
- set_phys_to_machine(__pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT,
- FOREIGN_FRAME(map_op.
- dev_bus_addr >> PAGE_SHIFT));
+
+ pfn = __pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT;
+ mfn = FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
+ mfn_orig = phys_to_machine_mapping[pfn];
+
+ set_phys_to_machine(pfn, mfn);
tocopy = MIN(size - offset, PAGE_SIZE);
@@ -306,6 +310,8 @@ int _packet_write(struct packet *pak,
return -EFAULT;
}
tx->size = tocopy;
+
+ set_phys_to_machine(pfn, mfn_orig);
gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
GNTMAP_host_map, handle);
diff -r dbf7032f1fc6 -r daa8047710d0
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Apr 20 17:16:27
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Apr 20 17:32:12
2006 +0100
@@ -49,6 +49,8 @@ static int tpmback_remove(struct xenbus_
{
struct backend_info *be = dev->data;
+ if (!be) return 0;
+
if (be->backend_watch.node) {
unregister_xenbus_watch(&be->backend_watch);
kfree(be->backend_watch.node);
@@ -119,37 +121,9 @@ static void backend_changed(struct xenbu
return;
}
- if (be->is_instance_set != 0 && be->instance != instance) {
- printk(KERN_WARNING
- "tpmback: changing instance (from %ld to %ld) "
- "not allowed.\n",
- be->instance, instance);
- return;
- }
-
if (be->is_instance_set == 0) {
- be->tpmif = tpmif_find(dev->otherend_id,
- instance);
- if (IS_ERR(be->tpmif)) {
- err = PTR_ERR(be->tpmif);
- be->tpmif = NULL;
- xenbus_dev_fatal(dev,err,"creating block interface");
- return;
- }
be->instance = instance;
be->is_instance_set = 1;
-
- /*
- * There's an unfortunate problem:
- * Sometimes after a suspend/resume the
- * state switch to XenbusStateInitialised happens
- * *before* I get to this point here. Since then
- * the connect_ring() must have failed (be->tpmif is
- * still NULL), I just call it here again indirectly.
- */
- if (be->frontend_state == XenbusStateInitialised) {
- frontend_changed(dev, be->frontend_state);
- }
}
}
@@ -186,6 +160,7 @@ static void frontend_changed(struct xenb
*/
tpmif_vtpm_close(be->instance);
device_unregister(&be->dev->dev);
+ tpmback_remove(dev);
break;
case XenbusStateUnknown:
@@ -279,6 +254,18 @@ static int connect_ring(struct backend_i
dev->otherend);
return err;
}
+
+ if (!be->tpmif) {
+ be->tpmif = tpmif_find(dev->otherend_id,
+ be->instance);
+ if (IS_ERR(be->tpmif)) {
+ err = PTR_ERR(be->tpmif);
+ be->tpmif = NULL;
+ xenbus_dev_fatal(dev,err,"creating vtpm interface");
+ return err;
+ }
+ }
+
if (be->tpmif != NULL) {
err = tpmif_map(be->tpmif, ring_ref, evtchn);
if (err) {
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|