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@us.ibm.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2006-04-20 17:32:12 +01:00
1 parent d4184d7e40
commit cfc4a77198
4 files changed
+34 -39

No files matched your search

@@ -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);
@@ -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 domid, long int instance)
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 long shared_page, unsigned int evtchn)
.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;
@@ -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);
@@ -307,6 +311,8 @@ int _packet_write(struct packet *pak,
}
tx->size = tocopy;
set_phys_to_machine(pfn, mfn_orig);
gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
GNTMAP_host_map, handle);
@@ -49,6 +49,8 @@ static int tpmback_remove(struct xenbus_device *dev)
{
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 xenbus_watch *watch,
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 xenbus_device *dev,
*/
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_info *be)
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) {
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.