ia64/xen-unstable

changeset 9796:daa8047710d0

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>
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 20 17:32:12 2006 +0100 (2006-04-20)
parents dbf7032f1fc6
children 7bc251b4c2b5
files linux-2.6-xen-sparse/drivers/xen/tpmback/common.h linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Thu Apr 20 17:16:27 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Thu Apr 20 17:32:12 2006 +0100
     1.3 @@ -49,6 +49,7 @@ typedef struct tpmif_st {
     1.4  
     1.5  	grant_handle_t shmem_handle;
     1.6  	grant_ref_t shmem_ref;
     1.7 +	struct page *pagerange;
     1.8  } tpmif_t;
     1.9  
    1.10  void tpmif_disconnect_complete(tpmif_t * tpmif);
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Thu Apr 20 17:16:27 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Thu Apr 20 17:32:12 2006 +0100
     2.3 @@ -22,7 +22,6 @@ LIST_HEAD(tpmif_list);
     2.4  
     2.5  static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
     2.6  {
     2.7 -	struct page *page;
     2.8  	tpmif_t *tpmif;
     2.9  
    2.10  	tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
    2.11 @@ -35,9 +34,10 @@ static tpmif_t *alloc_tpmif(domid_t domi
    2.12  	tpmif->tpm_instance = instance;
    2.13  	atomic_set(&tpmif->refcnt, 1);
    2.14  
    2.15 -	page = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
    2.16 -	BUG_ON(page == NULL);
    2.17 -	tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
    2.18 +	tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
    2.19 +	BUG_ON(tpmif->pagerange == NULL);
    2.20 +	tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(
    2.21 +	                                    page_to_pfn(tpmif->pagerange));
    2.22  
    2.23  	list_add(&tpmif->tpmif_list, &tpmif_list);
    2.24  	num_frontends++;
    2.25 @@ -49,6 +49,7 @@ static void free_tpmif(tpmif_t * tpmif)
    2.26  {
    2.27  	num_frontends--;
    2.28  	list_del(&tpmif->tpmif_list);
    2.29 +	balloon_dealloc_empty_page_range(tpmif->pagerange, TPMIF_TX_RING_SIZE);
    2.30  	kmem_cache_free(tpmif_cachep, tpmif);
    2.31  }
    2.32  
    2.33 @@ -115,11 +116,11 @@ int tpmif_map(tpmif_t *tpmif, unsigned l
    2.34  		.cmd = EVTCHNOP_bind_interdomain,
    2.35  		.u.bind_interdomain.remote_dom = tpmif->domid,
    2.36  		.u.bind_interdomain.remote_port = evtchn,
    2.37 -        };
    2.38 +	};
    2.39  
    2.40 -        if (tpmif->irq) {
    2.41 -                return 0;
    2.42 -        }
    2.43 +	if (tpmif->irq) {
    2.44 +		return 0;
    2.45 +	}
    2.46  
    2.47  	if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
    2.48  		return -ENOMEM;
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Thu Apr 20 17:16:27 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Thu Apr 20 17:32:12 2006 +0100
     3.3 @@ -271,6 +271,7 @@ int _packet_write(struct packet *pak,
     3.4  		struct gnttab_map_grant_ref map_op;
     3.5  		struct gnttab_unmap_grant_ref unmap_op;
     3.6  		tpmif_tx_request_t *tx;
     3.7 +		unsigned long pfn, mfn, mfn_orig;
     3.8  
     3.9  		tx = &tpmif->tx->ring[i].req;
    3.10  
    3.11 @@ -293,9 +294,12 @@ int _packet_write(struct packet *pak,
    3.12  			DPRINTK(" Grant table operation failure !\n");
    3.13  			return 0;
    3.14  		}
    3.15 -		set_phys_to_machine(__pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT,
    3.16 -				    FOREIGN_FRAME(map_op.
    3.17 -						  dev_bus_addr >> PAGE_SHIFT));
    3.18 +
    3.19 +		pfn = __pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT;
    3.20 +		mfn = FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
    3.21 +		mfn_orig = phys_to_machine_mapping[pfn];
    3.22 +
    3.23 +		set_phys_to_machine(pfn, mfn);
    3.24  
    3.25  		tocopy = MIN(size - offset, PAGE_SIZE);
    3.26  
    3.27 @@ -307,6 +311,8 @@ int _packet_write(struct packet *pak,
    3.28  		}
    3.29  		tx->size = tocopy;
    3.30  
    3.31 +		set_phys_to_machine(pfn, mfn_orig);
    3.32 +
    3.33  		gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
    3.34  				    GNTMAP_host_map, handle);
    3.35  
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Thu Apr 20 17:16:27 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Thu Apr 20 17:32:12 2006 +0100
     4.3 @@ -49,6 +49,8 @@ static int tpmback_remove(struct xenbus_
     4.4  {
     4.5  	struct backend_info *be = dev->data;
     4.6  
     4.7 +	if (!be) return 0;
     4.8 +
     4.9  	if (be->backend_watch.node) {
    4.10  		unregister_xenbus_watch(&be->backend_watch);
    4.11  		kfree(be->backend_watch.node);
    4.12 @@ -119,37 +121,9 @@ static void backend_changed(struct xenbu
    4.13  		return;
    4.14  	}
    4.15  
    4.16 -	if (be->is_instance_set != 0 && be->instance != instance) {
    4.17 -		printk(KERN_WARNING
    4.18 -		       "tpmback: changing instance (from %ld to %ld) "
    4.19 -		       "not allowed.\n",
    4.20 -		       be->instance, instance);
    4.21 -		return;
    4.22 -	}
    4.23 -
    4.24  	if (be->is_instance_set == 0) {
    4.25 -		be->tpmif = tpmif_find(dev->otherend_id,
    4.26 -		                       instance);
    4.27 -		if (IS_ERR(be->tpmif)) {
    4.28 -			err = PTR_ERR(be->tpmif);
    4.29 -			be->tpmif = NULL;
    4.30 -			xenbus_dev_fatal(dev,err,"creating block interface");
    4.31 -			return;
    4.32 -		}
    4.33  		be->instance = instance;
    4.34  		be->is_instance_set = 1;
    4.35 -
    4.36 -		/*
    4.37 -		 * There's an unfortunate problem:
    4.38 -		 * Sometimes after a suspend/resume the
    4.39 -		 * state switch to XenbusStateInitialised happens
    4.40 -		 * *before* I get to this point here. Since then
    4.41 -		 * the connect_ring() must have failed (be->tpmif is
    4.42 -		 * still NULL), I just call it here again indirectly.
    4.43 -		 */
    4.44 -		if (be->frontend_state == XenbusStateInitialised) {
    4.45 -			frontend_changed(dev, be->frontend_state);
    4.46 -		}
    4.47  	}
    4.48  }
    4.49  
    4.50 @@ -186,6 +160,7 @@ static void frontend_changed(struct xenb
    4.51  		 */
    4.52  		tpmif_vtpm_close(be->instance);
    4.53  		device_unregister(&be->dev->dev);
    4.54 +		tpmback_remove(dev);
    4.55  		break;
    4.56  
    4.57  	case XenbusStateUnknown:
    4.58 @@ -279,6 +254,18 @@ static int connect_ring(struct backend_i
    4.59  				 dev->otherend);
    4.60  		return err;
    4.61  	}
    4.62 +
    4.63 +	if (!be->tpmif) {
    4.64 +		be->tpmif = tpmif_find(dev->otherend_id,
    4.65 +		                       be->instance);
    4.66 +		if (IS_ERR(be->tpmif)) {
    4.67 +			err = PTR_ERR(be->tpmif);
    4.68 +			be->tpmif = NULL;
    4.69 +			xenbus_dev_fatal(dev,err,"creating vtpm interface");
    4.70 +			return err;
    4.71 +		}
    4.72 +	}
    4.73 +
    4.74  	if (be->tpmif != NULL) {
    4.75  		err = tpmif_map(be->tpmif, ring_ref, evtchn);
    4.76  		if (err) {