ia64/xen-unstable

changeset 14246:e74bfc744717

Merge with xenppc-unstable.hg
author kfraser@localhost.localdomain
date Mon Mar 05 11:14:15 2007 +0000 (2007-03-05)
parents 5a2b3a1b1f63 939d2b7d4a12
children f74b87177843
files linux-2.6-xen-sparse/mm/Kconfig
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S	Fri Dec 15 08:16:56 2006 -0500
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S	Mon Mar 05 11:14:15 2007 +0000
     1.3 @@ -12,8 +12,6 @@
     1.4  #include <xen/interface/xen.h>
     1.5  #include <xen/interface/elfnote.h>
     1.6  
     1.7 -#define _PAGE_PRESENT 0x1
     1.8 -
     1.9  /*
    1.10   * References to members of the new_cpu_data structure.
    1.11   */
     2.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Fri Dec 15 08:16:56 2006 -0500
     2.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Mon Mar 05 11:14:15 2007 +0000
     2.3 @@ -573,64 +573,67 @@ void make_pages_writable(void *va, unsig
     2.4  	}
     2.5  }
     2.6  
     2.7 -static inline int pgd_walk_set_prot(struct page *page, pgprot_t flags)
     2.8 +static inline void pgd_walk_set_prot(struct page *page, pgprot_t flags)
     2.9  {
    2.10  	unsigned long pfn = page_to_pfn(page);
    2.11 -
    2.12 -	if (PageHighMem(page))
    2.13 -		return pgprot_val(flags) & _PAGE_RW
    2.14 -		       ? test_and_clear_bit(PG_pinned, &page->flags)
    2.15 -		       : !test_and_set_bit(PG_pinned, &page->flags);
    2.16 +	int rc;
    2.17  
    2.18 -	BUG_ON(HYPERVISOR_update_va_mapping(
    2.19 -		(unsigned long)__va(pfn << PAGE_SHIFT),
    2.20 -		pfn_pte(pfn, flags), 0));
    2.21 -
    2.22 -	return 0;
    2.23 +	if (PageHighMem(page)) {
    2.24 +		if (pgprot_val(flags) & _PAGE_RW)
    2.25 +			clear_bit(PG_pinned, &page->flags);
    2.26 +		else
    2.27 +			set_bit(PG_pinned, &page->flags);
    2.28 +	} else {
    2.29 +		rc = HYPERVISOR_update_va_mapping(
    2.30 +			(unsigned long)__va(pfn << PAGE_SHIFT),
    2.31 +			pfn_pte(pfn, flags), 0);
    2.32 +		if (rc)
    2.33 +			BUG();
    2.34 +	}
    2.35  }
    2.36  
    2.37 -static int pgd_walk(pgd_t *pgd_base, pgprot_t flags)
    2.38 +static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
    2.39  {
    2.40  	pgd_t *pgd = pgd_base;
    2.41  	pud_t *pud;
    2.42  	pmd_t *pmd;
    2.43 -	int    g, u, m, flush;
    2.44 +	int    g, u, m, rc;
    2.45  
    2.46  	if (xen_feature(XENFEAT_auto_translated_physmap))
    2.47  		return 0;
    2.48  
    2.49 -	for (g = 0, flush = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
    2.50 +	for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
    2.51  		if (pgd_none(*pgd))
    2.52  			continue;
    2.53  		pud = pud_offset(pgd, 0);
    2.54  		if (PTRS_PER_PUD > 1) /* not folded */
    2.55 -			flush |= pgd_walk_set_prot(virt_to_page(pud),flags);
    2.56 +			pgd_walk_set_prot(virt_to_page(pud),flags);
    2.57  		for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
    2.58  			if (pud_none(*pud))
    2.59  				continue;
    2.60  			pmd = pmd_offset(pud, 0);
    2.61  			if (PTRS_PER_PMD > 1) /* not folded */
    2.62 -				flush |= pgd_walk_set_prot(virt_to_page(pmd),flags);
    2.63 +				pgd_walk_set_prot(virt_to_page(pmd),flags);
    2.64  			for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
    2.65  				if (pmd_none(*pmd))
    2.66  					continue;
    2.67 -				flush |= pgd_walk_set_prot(pmd_page(*pmd),flags);
    2.68 +				pgd_walk_set_prot(pmd_page(*pmd),flags);
    2.69  			}
    2.70  		}
    2.71  	}
    2.72  
    2.73 -	BUG_ON(HYPERVISOR_update_va_mapping(
    2.74 +	rc = HYPERVISOR_update_va_mapping(
    2.75  		(unsigned long)pgd_base,
    2.76  		pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
    2.77 -		UVMF_TLB_FLUSH));
    2.78 -
    2.79 -	return flush;
    2.80 +		UVMF_TLB_FLUSH);
    2.81 +	if (rc)
    2.82 +		BUG();
    2.83  }
    2.84  
    2.85  static void __pgd_pin(pgd_t *pgd)
    2.86  {
    2.87 -	if (pgd_walk(pgd, PAGE_KERNEL_RO))
    2.88 -		kmap_flush_unused();
    2.89 +	pgd_walk(pgd, PAGE_KERNEL_RO);
    2.90 +	kmap_flush_unused();
    2.91  	xen_pgd_pin(__pa(pgd));
    2.92  	set_bit(PG_pinned, &virt_to_page(pgd)->flags);
    2.93  }
    2.94 @@ -638,8 +641,7 @@ static void __pgd_pin(pgd_t *pgd)
    2.95  static void __pgd_unpin(pgd_t *pgd)
    2.96  {
    2.97  	xen_pgd_unpin(__pa(pgd));
    2.98 -	if (pgd_walk(pgd, PAGE_KERNEL))
    2.99 -		kmap_flush_unused();
   2.100 +	pgd_walk(pgd, PAGE_KERNEL);
   2.101  	clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
   2.102  }
   2.103  
     3.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Fri Dec 15 08:16:56 2006 -0500
     3.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Mon Mar 05 11:14:15 2007 +0000
     3.3 @@ -25,8 +25,6 @@
     3.4  
     3.5  #include <xen/interface/elfnote.h>
     3.6  
     3.7 -#define _PAGE_PRESENT 0x1
     3.8 -
     3.9  	.section .bootstrap.text, "ax", @progbits
    3.10  	.code64
    3.11  #define VIRT_ENTRY_OFFSET 0x0
     4.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Fri Dec 15 08:16:56 2006 -0500
     4.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Mon Mar 05 11:14:15 2007 +0000
     4.3 @@ -24,10 +24,13 @@ static inline void mm_walk_set_prot(void
     4.4  {
     4.5  	struct page *page = virt_to_page(pt);
     4.6  	unsigned long pfn = page_to_pfn(page);
     4.7 +	int rc;
     4.8  
     4.9 -	BUG_ON(HYPERVISOR_update_va_mapping(
    4.10 -		       (unsigned long)__va(pfn << PAGE_SHIFT),
    4.11 -		       pfn_pte(pfn, flags), 0));
    4.12 +	rc = HYPERVISOR_update_va_mapping(
    4.13 +		(unsigned long)__va(pfn << PAGE_SHIFT),
    4.14 +		pfn_pte(pfn, flags), 0);
    4.15 +	if (rc)
    4.16 +		BUG();
    4.17  }
    4.18  
    4.19  static void mm_walk(struct mm_struct *mm, pgprot_t flags)
     5.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Fri Dec 15 08:16:56 2006 -0500
     5.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Mon Mar 05 11:14:15 2007 +0000
     5.3 @@ -113,14 +113,13 @@ void __exit tpmif_exit(void);
     5.4  
     5.5  
     5.6  static inline int
     5.7 -tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
     5.8 +tx_buffer_copy(struct tx_buffer *txb, const u8 *src, int len,
     5.9                 int isuserbuffer)
    5.10  {
    5.11  	int copied = len;
    5.12  
    5.13 -	if (len > txb->size) {
    5.14 +	if (len > txb->size)
    5.15  		copied = txb->size;
    5.16 -	}
    5.17  	if (isuserbuffer) {
    5.18  		if (copy_from_user(txb->data, src, copied))
    5.19  			return -EFAULT;
    5.20 @@ -133,18 +132,20 @@ tx_buffer_copy(struct tx_buffer *txb, co
    5.21  
    5.22  static inline struct tx_buffer *tx_buffer_alloc(void)
    5.23  {
    5.24 -	struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
    5.25 -					GFP_KERNEL);
    5.26 +	struct tx_buffer *txb;
    5.27 +
    5.28 +	txb = kzalloc(sizeof(struct tx_buffer), GFP_KERNEL);
    5.29 +	if (!txb)
    5.30 +		return NULL;
    5.31  
    5.32 -	if (txb) {
    5.33 -		txb->len = 0;
    5.34 -		txb->size = PAGE_SIZE;
    5.35 -		txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
    5.36 -		if (txb->data == NULL) {
    5.37 -			kfree(txb);
    5.38 -			txb = NULL;
    5.39 -		}
    5.40 +	txb->len = 0;
    5.41 +	txb->size = PAGE_SIZE;
    5.42 +	txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
    5.43 +	if (txb->data == NULL) {
    5.44 +		kfree(txb);
    5.45 +		txb = NULL;
    5.46  	}
    5.47 +
    5.48  	return txb;
    5.49  }
    5.50  
    5.51 @@ -160,37 +161,41 @@ static inline void tx_buffer_free(struct
    5.52  /**************************************************************
    5.53   Utility function for the tpm_private structure
    5.54  **************************************************************/
    5.55 -static inline void tpm_private_init(struct tpm_private *tp)
    5.56 +static void tpm_private_init(struct tpm_private *tp)
    5.57  {
    5.58  	spin_lock_init(&tp->tx_lock);
    5.59  	init_waitqueue_head(&tp->wait_q);
    5.60  	atomic_set(&tp->refcnt, 1);
    5.61  }
    5.62  
    5.63 -static inline void tpm_private_put(void)
    5.64 +static void tpm_private_put(void)
    5.65  {
    5.66 -	if ( atomic_dec_and_test(&my_priv->refcnt)) {
    5.67 -		tpmif_free_tx_buffers(my_priv);
    5.68 -		kfree(my_priv);
    5.69 -		my_priv = NULL;
    5.70 -	}
    5.71 +	if (!atomic_dec_and_test(&my_priv->refcnt))
    5.72 +		return;
    5.73 +
    5.74 +	tpmif_free_tx_buffers(my_priv);
    5.75 +	kfree(my_priv);
    5.76 +	my_priv = NULL;
    5.77  }
    5.78  
    5.79  static struct tpm_private *tpm_private_get(void)
    5.80  {
    5.81  	int err;
    5.82 -	if (!my_priv) {
    5.83 -		my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
    5.84 -		if (my_priv) {
    5.85 -			tpm_private_init(my_priv);
    5.86 -			err = tpmif_allocate_tx_buffers(my_priv);
    5.87 -			if (err < 0) {
    5.88 -				tpm_private_put();
    5.89 -			}
    5.90 -		}
    5.91 -	} else {
    5.92 +
    5.93 +	if (my_priv) {
    5.94  		atomic_inc(&my_priv->refcnt);
    5.95 +		return my_priv;
    5.96  	}
    5.97 +
    5.98 +	my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
    5.99 +	if (!my_priv)
   5.100 +		return NULL;
   5.101 +
   5.102 +	tpm_private_init(my_priv);
   5.103 +	err = tpmif_allocate_tx_buffers(my_priv);
   5.104 +	if (err < 0)
   5.105 +		tpm_private_put();
   5.106 +
   5.107  	return my_priv;
   5.108  }
   5.109  
   5.110 @@ -379,10 +384,8 @@ static int tpmfront_probe(struct xenbus_
   5.111  		return -ENOMEM;
   5.112  
   5.113  	tp->chip = init_vtpm(&dev->dev, &tvd, tp);
   5.114 -
   5.115 -	if (IS_ERR(tp->chip)) {
   5.116 +	if (IS_ERR(tp->chip))
   5.117  		return PTR_ERR(tp->chip);
   5.118 -	}
   5.119  
   5.120  	err = xenbus_scanf(XBT_NIL, dev->nodename,
   5.121  	                   "handle", "%i", &handle);
   5.122 @@ -401,6 +404,7 @@ static int tpmfront_probe(struct xenbus_
   5.123  		tpm_private_put();
   5.124  		return err;
   5.125  	}
   5.126 +
   5.127  	return 0;
   5.128  }
   5.129  
   5.130 @@ -417,32 +421,36 @@ static int tpmfront_suspend(struct xenbu
   5.131  {
   5.132  	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
   5.133  	u32 ctr;
   5.134 -	/* lock, so no app can send */
   5.135 +
   5.136 +	/* Take the lock, preventing any application from sending. */
   5.137  	mutex_lock(&suspend_lock);
   5.138  	tp->is_suspended = 1;
   5.139  
   5.140 -	for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 300; ctr++) {
   5.141 +	for (ctr = 0; atomic_read(&tp->tx_busy); ctr++) {
   5.142  		if ((ctr % 10) == 0)
   5.143  			printk("TPM-FE [INFO]: Waiting for outstanding "
   5.144  			       "request.\n");
   5.145 -		/*
   5.146 -		 * Wait for a request to be responded to.
   5.147 -		 */
   5.148 +		/* Wait for a request to be responded to. */
   5.149  		interruptible_sleep_on_timeout(&tp->wait_q, 100);
   5.150  	}
   5.151 -	xenbus_switch_state(dev, XenbusStateClosing);
   5.152 -
   5.153 -	if (atomic_read(&tp->tx_busy)) {
   5.154 -		/*
   5.155 -		 * A temporary work-around.
   5.156 -		 */
   5.157 -		printk("TPM-FE [WARNING]: Resetting busy flag.");
   5.158 -		atomic_set(&tp->tx_busy, 0);
   5.159 -	}
   5.160  
   5.161  	return 0;
   5.162  }
   5.163  
   5.164 +static int tpmfront_suspend_finish(struct tpm_private *tp)
   5.165 +{
   5.166 +	tp->is_suspended = 0;
   5.167 +	/* Allow applications to send again. */
   5.168 +	mutex_unlock(&suspend_lock);
   5.169 +	return 0;
   5.170 +}
   5.171 +
   5.172 +static int tpmfront_suspend_cancel(struct xenbus_device *dev)
   5.173 +{
   5.174 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
   5.175 +	return tpmfront_suspend_finish(tp);
   5.176 +}
   5.177 +
   5.178  static int tpmfront_resume(struct xenbus_device *dev)
   5.179  {
   5.180  	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
   5.181 @@ -484,6 +492,7 @@ static struct xenbus_driver tpmfront = {
   5.182  	.resume = tpmfront_resume,
   5.183  	.otherend_changed = backend_changed,
   5.184  	.suspend = tpmfront_suspend,
   5.185 +	.suspend_cancel = tpmfront_suspend_cancel,
   5.186  };
   5.187  
   5.188  static void __init init_tpm_xenbus(void)
   5.189 @@ -514,9 +523,8 @@ static void tpmif_free_tx_buffers(struct
   5.190  {
   5.191  	unsigned int i;
   5.192  
   5.193 -	for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
   5.194 +	for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
   5.195  		tx_buffer_free(tp->tx_buffers[i]);
   5.196 -	}
   5.197  }
   5.198  
   5.199  static void tpmif_rx_action(unsigned long priv)
   5.200 @@ -536,9 +544,8 @@ static void tpmif_rx_action(unsigned lon
   5.201  	received = tx->size;
   5.202  
   5.203  	buffer = kmalloc(received, GFP_ATOMIC);
   5.204 -	if (NULL == buffer) {
   5.205 +	if (!buffer)
   5.206  		goto exit;
   5.207 -	}
   5.208  
   5.209  	for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
   5.210  		struct tx_buffer *txb = tp->tx_buffers[i];
   5.211 @@ -547,9 +554,8 @@ static void tpmif_rx_action(unsigned lon
   5.212  
   5.213  		tx = &tp->tx->ring[i].req;
   5.214  		tocopy = tx->size;
   5.215 -		if (tocopy > PAGE_SIZE) {
   5.216 +		if (tocopy > PAGE_SIZE)
   5.217  			tocopy = PAGE_SIZE;
   5.218 -		}
   5.219  
   5.220  		memcpy(&buffer[offset], txb->data, tocopy);
   5.221  
   5.222 @@ -607,12 +613,13 @@ static int tpm_xmit(struct tpm_private *
   5.223  		struct tx_buffer *txb = tp->tx_buffers[i];
   5.224  		int copied;
   5.225  
   5.226 -		if (NULL == txb) {
   5.227 +		if (!txb) {
   5.228  			DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
   5.229  				"Not transmitting anything!\n", i);
   5.230  			spin_unlock_irq(&tp->tx_lock);
   5.231  			return -EFAULT;
   5.232  		}
   5.233 +
   5.234  		copied = tx_buffer_copy(txb, &buf[offset], count,
   5.235  		                        isuserbuffer);
   5.236  		if (copied < 0) {
   5.237 @@ -624,25 +631,26 @@ static int tpm_xmit(struct tpm_private *
   5.238  		offset += copied;
   5.239  
   5.240  		tx = &tp->tx->ring[i].req;
   5.241 -
   5.242  		tx->addr = virt_to_machine(txb->data);
   5.243  		tx->size = txb->len;
   5.244  
   5.245 -		DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 0x%02x 0x%02x\n",
   5.246 +		DPRINTK("First 4 characters sent by TPM-FE are "
   5.247 +			"0x%02x 0x%02x 0x%02x 0x%02x\n",
   5.248  		        txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
   5.249  
   5.250 -		/* get the granttable reference for this page */
   5.251 +		/* Get the granttable reference for this page. */
   5.252  		tx->ref = gnttab_claim_grant_reference(&gref_head);
   5.253 -
   5.254 -		if (-ENOSPC == tx->ref) {
   5.255 +		if (tx->ref == -ENOSPC) {
   5.256  			spin_unlock_irq(&tp->tx_lock);
   5.257 -			DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
   5.258 +			DPRINTK("Grant table claim reference failed in "
   5.259 +				"func:%s line:%d file:%s\n",
   5.260 +				__FUNCTION__, __LINE__, __FILE__);
   5.261  			return -ENOSPC;
   5.262  		}
   5.263 -		gnttab_grant_foreign_access_ref( tx->ref,
   5.264 -		                                 tp->backend_id,
   5.265 -		                                 virt_to_mfn(txb->data),
   5.266 -		                                 0 /*RW*/);
   5.267 +		gnttab_grant_foreign_access_ref(tx->ref,
   5.268 +						tp->backend_id,
   5.269 +						virt_to_mfn(txb->data),
   5.270 +						0 /*RW*/);
   5.271  		wmb();
   5.272  	}
   5.273  
   5.274 @@ -660,15 +668,10 @@ static int tpm_xmit(struct tpm_private *
   5.275  
   5.276  static void tpmif_notify_upperlayer(struct tpm_private *tp)
   5.277  {
   5.278 -	/*
   5.279 -	 * Notify upper layer about the state of the connection
   5.280 -	 * to the BE.
   5.281 -	 */
   5.282 -	if (tp->is_connected) {
   5.283 -		vtpm_vd_status(tp->chip, TPM_VD_STATUS_CONNECTED);
   5.284 -	} else {
   5.285 -		vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED);
   5.286 -	}
   5.287 +	/* Notify upper layer about the state of the connection to the BE. */
   5.288 +	vtpm_vd_status(tp->chip, (tp->is_connected
   5.289 +				  ? TPM_VD_STATUS_CONNECTED
   5.290 +				  : TPM_VD_STATUS_DISCONNECTED));
   5.291  }
   5.292  
   5.293  
   5.294 @@ -679,20 +682,16 @@ static void tpmif_set_connected_state(st
   5.295  	 * should disconnect - assumption is that we will resume
   5.296  	 * The mutex keeps apps from sending.
   5.297  	 */
   5.298 -	if (is_connected == 0 && tp->is_suspended == 1) {
   5.299 +	if (is_connected == 0 && tp->is_suspended == 1)
   5.300  		return;
   5.301 -	}
   5.302  
   5.303  	/*
   5.304  	 * Unlock the mutex if we are connected again
   5.305  	 * after being suspended - now resuming.
   5.306  	 * This also removes the suspend state.
   5.307  	 */
   5.308 -	if (is_connected == 1 && tp->is_suspended == 1) {
   5.309 -		tp->is_suspended = 0;
   5.310 -		/* unlock, so apps can resume sending */
   5.311 -		mutex_unlock(&suspend_lock);
   5.312 -	}
   5.313 +	if (is_connected == 1 && tp->is_suspended == 1)
   5.314 +		tpmfront_suspend_finish(tp);
   5.315  
   5.316  	if (is_connected != tp->is_connected) {
   5.317  		tp->is_connected = is_connected;
   5.318 @@ -710,33 +709,24 @@ static void tpmif_set_connected_state(st
   5.319  
   5.320  static int __init tpmif_init(void)
   5.321  {
   5.322 -	long rc = 0;
   5.323  	struct tpm_private *tp;
   5.324  
   5.325  	if (is_initial_xendomain())
   5.326  		return -EPERM;
   5.327  
   5.328  	tp = tpm_private_get();
   5.329 -	if (!tp) {
   5.330 -		rc = -ENOMEM;
   5.331 -		goto failexit;
   5.332 -	}
   5.333 +	if (!tp)
   5.334 +		return -ENOMEM;
   5.335  
   5.336  	IPRINTK("Initialising the vTPM driver.\n");
   5.337 -	if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
   5.338 -	                                     &gref_head ) < 0) {
   5.339 -		rc = -EFAULT;
   5.340 -		goto gnttab_alloc_failed;
   5.341 +	if (gnttab_alloc_grant_references(TPMIF_TX_RING_SIZE,
   5.342 +					  &gref_head) < 0) {
   5.343 +		tpm_private_put();
   5.344 +		return -EFAULT;
   5.345  	}
   5.346  
   5.347  	init_tpm_xenbus();
   5.348  	return 0;
   5.349 -
   5.350 -gnttab_alloc_failed:
   5.351 -	tpm_private_put();
   5.352 -failexit:
   5.353 -
   5.354 -	return (int)rc;
   5.355  }
   5.356  
   5.357  
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Fri Dec 15 08:16:56 2006 -0500
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Mon Mar 05 11:14:15 2007 +0000
     6.3 @@ -59,23 +59,6 @@ EXPORT_SYMBOL(machine_restart);
     6.4  EXPORT_SYMBOL(machine_halt);
     6.5  EXPORT_SYMBOL(machine_power_off);
     6.6  
     6.7 -/* Ensure we run on the idle task page tables so that we will
     6.8 -   switch page tables before running user space. This is needed
     6.9 -   on architectures with separate kernel and user page tables
    6.10 -   because the user page table pointer is not saved/restored. */
    6.11 -static void switch_idle_mm(void)
    6.12 -{
    6.13 -	struct mm_struct *mm = current->active_mm;
    6.14 -
    6.15 -	if (mm == &init_mm)
    6.16 -		return;
    6.17 -
    6.18 -	atomic_inc(&init_mm.mm_count);
    6.19 -	switch_mm(mm, &init_mm, current);
    6.20 -	current->active_mm = &init_mm;
    6.21 -	mmdrop(mm);
    6.22 -}
    6.23 -
    6.24  static void pre_suspend(void)
    6.25  {
    6.26  	HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
    6.27 @@ -99,7 +82,9 @@ static void post_suspend(int suspend_can
    6.28  		xen_start_info->console.domU.mfn =
    6.29  			pfn_to_mfn(xen_start_info->console.domU.mfn);
    6.30  	} else {
    6.31 +#ifdef CONFIG_SMP
    6.32  		cpu_initialized_map = cpumask_of_cpu(0);
    6.33 +#endif
    6.34  	}
    6.35  	
    6.36  	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
    6.37 @@ -172,10 +157,25 @@ static int take_machine_down(void *p_fas
    6.38  
    6.39  	post_suspend(suspend_cancelled);
    6.40  	gnttab_resume();
    6.41 -	if (!suspend_cancelled)
    6.42 +	if (!suspend_cancelled) {
    6.43  		irq_resume();
    6.44 +#ifdef __x86_64__
    6.45 +		/*
    6.46 +		 * Older versions of Xen do not save/restore the user %cr3.
    6.47 +		 * We do it here just in case, but there's no need if we are
    6.48 +		 * in fast-suspend mode as that implies a new enough Xen.
    6.49 +		 */
    6.50 +		if (!fast_suspend) {
    6.51 +			struct mmuext_op op;
    6.52 +			op.cmd = MMUEXT_NEW_USER_BASEPTR;
    6.53 +			op.arg1.mfn = pfn_to_mfn(__pa(__user_pgd(
    6.54 +				current->active_mm->pgd)) >> PAGE_SHIFT);
    6.55 +			if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
    6.56 +				BUG();
    6.57 +		}
    6.58 +#endif
    6.59 +	}
    6.60  	time_resume();
    6.61 -	switch_idle_mm();
    6.62  	local_irq_enable();
    6.63  
    6.64  	if (fast_suspend && !suspend_cancelled) {
    6.65 @@ -210,6 +210,10 @@ int __xen_suspend(int fast_suspend)
    6.66  	}
    6.67  #endif
    6.68  
    6.69 +	/* If we are definitely UP then 'slow mode' is actually faster. */
    6.70 +	if (num_possible_cpus() == 1)
    6.71 +		fast_suspend = 0;
    6.72 +
    6.73  	if (fast_suspend) {
    6.74  		xenbus_suspend();
    6.75  		err = stop_machine_run(take_machine_down, &fast_suspend, 0);
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Fri Dec 15 08:16:56 2006 -0500
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Mon Mar 05 11:14:15 2007 +0000
     7.3 @@ -40,6 +40,9 @@
     7.4  
     7.5  /*#define NETBE_DEBUG_INTERRUPT*/
     7.6  
     7.7 +/* extra field used in struct page */
     7.8 +#define netif_page_index(pg) (*(long *)&(pg)->mapping)
     7.9 +
    7.10  struct netbk_rx_meta {
    7.11  	skb_frag_t frag;
    7.12  	int id;
    7.13 @@ -352,7 +355,7 @@ static u16 netbk_gop_frag(netif_t *netif
    7.14  		copy_gop->flags = GNTCOPY_dest_gref;
    7.15  		if (PageForeign(page)) {
    7.16  			struct pending_tx_info *src_pend =
    7.17 -				&pending_tx_info[page->index];
    7.18 +				&pending_tx_info[netif_page_index(page)];
    7.19  			copy_gop->source.domid = src_pend->netif->domid;
    7.20  			copy_gop->source.u.ref = src_pend->req.gref;
    7.21  			copy_gop->flags |= GNTCOPY_source_gref;
    7.22 @@ -1327,7 +1330,7 @@ static void netif_page_release(struct pa
    7.23  	/* Ready for next use. */
    7.24  	init_page_count(page);
    7.25  
    7.26 -	netif_idx_release(page->index);
    7.27 +	netif_idx_release(netif_page_index(page));
    7.28  }
    7.29  
    7.30  irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
    7.31 @@ -1457,7 +1460,7 @@ static int __init netback_init(void)
    7.32  	for (i = 0; i < MAX_PENDING_REQS; i++) {
    7.33  		page = mmap_pages[i];
    7.34  		SetPageForeign(page, netif_page_release);
    7.35 -		page->index = i;
    7.36 +		netif_page_index(page) = i;
    7.37  	}
    7.38  
    7.39  	pending_cons = 0;
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Fri Dec 15 08:16:56 2006 -0500
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Mon Mar 05 11:14:15 2007 +0000
     8.3 @@ -173,17 +173,22 @@ static ssize_t xenbus_dev_write(struct f
     8.4  	void *reply;
     8.5  	char *path, *token;
     8.6  	struct watch_adapter *watch, *tmp_watch;
     8.7 -	int err;
     8.8 +	int err, rc = len;
     8.9  
    8.10 -	if ((len + u->len) > sizeof(u->u.buffer))
    8.11 -		return -EINVAL;
    8.12 +	if ((len + u->len) > sizeof(u->u.buffer)) {
    8.13 +		rc = -EINVAL;
    8.14 +		goto out;
    8.15 +	}
    8.16  
    8.17 -	if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0)
    8.18 -		return -EFAULT;
    8.19 +	if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0) {
    8.20 +		rc = -EFAULT;
    8.21 +		goto out;
    8.22 +	}
    8.23  
    8.24  	u->len += len;
    8.25 -	if (u->len < (sizeof(u->u.msg) + u->u.msg.len))
    8.26 -		return len;
    8.27 +	if ((u->len < sizeof(u->u.msg)) ||
    8.28 +	    (u->len < (sizeof(u->u.msg) + u->u.msg.len)))
    8.29 +		return rc;
    8.30  
    8.31  	msg_type = u->u.msg.type;
    8.32  
    8.33 @@ -201,14 +206,17 @@ static ssize_t xenbus_dev_write(struct f
    8.34  	case XS_SET_PERMS:
    8.35  		if (msg_type == XS_TRANSACTION_START) {
    8.36  			trans = kmalloc(sizeof(*trans), GFP_KERNEL);
    8.37 -			if (!trans)
    8.38 -				return -ENOMEM;
    8.39 +			if (!trans) {
    8.40 +				rc = -ENOMEM;
    8.41 +				goto out;
    8.42 +			}
    8.43  		}
    8.44  
    8.45  		reply = xenbus_dev_request_and_reply(&u->u.msg);
    8.46  		if (IS_ERR(reply)) {
    8.47  			kfree(trans);
    8.48 -			return PTR_ERR(reply);
    8.49 +			rc = PTR_ERR(reply);
    8.50 +			goto out;
    8.51  		}
    8.52  
    8.53  		if (msg_type == XS_TRANSACTION_START) {
    8.54 @@ -231,8 +239,10 @@ static ssize_t xenbus_dev_write(struct f
    8.55  	case XS_UNWATCH:
    8.56  		path = u->u.buffer + sizeof(u->u.msg);
    8.57  		token = memchr(path, 0, u->u.msg.len);
    8.58 -		if (token == NULL)
    8.59 -			return -EILSEQ;
    8.60 +		if (token == NULL) {
    8.61 +			rc = -EILSEQ;
    8.62 +			goto out;
    8.63 +		}
    8.64  		token++;
    8.65  
    8.66  		if (msg_type == XS_WATCH) {
    8.67 @@ -251,7 +261,8 @@ static ssize_t xenbus_dev_write(struct f
    8.68  			err = register_xenbus_watch(&watch->watch);
    8.69  			if (err) {
    8.70  				free_watch_adapter(watch);
    8.71 -				return err;
    8.72 +				rc = err;
    8.73 +				goto out;
    8.74  			}
    8.75  			
    8.76  			list_add(&watch->list, &u->watches);
    8.77 @@ -265,7 +276,6 @@ static ssize_t xenbus_dev_write(struct f
    8.78                                                   &u->watches, list) {
    8.79  				if (!strcmp(watch->token, token) &&
    8.80  				    !strcmp(watch->watch.node, path))
    8.81 -					break;
    8.82  				{
    8.83  					unregister_xenbus_watch(&watch->watch);
    8.84  					list_del(&watch->list);
    8.85 @@ -278,11 +288,13 @@ static ssize_t xenbus_dev_write(struct f
    8.86  		break;
    8.87  
    8.88  	default:
    8.89 -		return -EINVAL;
    8.90 +		rc = -EINVAL;
    8.91 +		break;
    8.92  	}
    8.93  
    8.94 + out:
    8.95  	u->len = 0;
    8.96 -	return len;
    8.97 +	return rc;
    8.98  }
    8.99  
   8.100  static int xenbus_dev_open(struct inode *inode, struct file *filp)
     9.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Fri Dec 15 08:16:56 2006 -0500
     9.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Mon Mar 05 11:14:15 2007 +0000
     9.3 @@ -20,6 +20,14 @@
     9.4  #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
     9.5  
     9.6  #ifdef __KERNEL__
     9.7 +
     9.8 +/*
     9.9 + * Need to repeat this here in order to not include pgtable.h (which in turn
    9.10 + * depends on definitions made here), but to be able to use the symbolic
    9.11 + * below. The preprocessor will warn if the two definitions aren't identical.
    9.12 + */
    9.13 +#define _PAGE_PRESENT	0x001
    9.14 +
    9.15  #ifndef __ASSEMBLY__
    9.16  
    9.17  #include <linux/string.h>
    9.18 @@ -29,13 +37,6 @@
    9.19  #include <xen/interface/xen.h>
    9.20  #include <xen/features.h>
    9.21  
    9.22 -/*
    9.23 - * Need to repeat this here in order to not include pgtable.h (which in turn
    9.24 - * depends on definitions made here), but to be able to use the symbolic
    9.25 - * below. The preprocessor will warn if the two definitions aren't identical.
    9.26 - */
    9.27 -#define _PAGE_PRESENT	0x001
    9.28 -
    9.29  #define arch_free_page(_page,_order)		\
    9.30  ({	int foreign = PageForeign(_page);	\
    9.31  	if (foreign)				\
    10.1 --- a/linux-2.6-xen-sparse/include/linux/page-flags.h	Fri Dec 15 08:16:56 2006 -0500
    10.2 +++ b/linux-2.6-xen-sparse/include/linux/page-flags.h	Mon Mar 05 11:14:15 2007 +0000
    10.3 @@ -252,14 +252,14 @@
    10.4  #define PageForeign(page)	test_bit(PG_foreign, &(page)->flags)
    10.5  #define SetPageForeign(page, dtor) do {		\
    10.6  	set_bit(PG_foreign, &(page)->flags);	\
    10.7 -	(page)->mapping = (void *)dtor;		\
    10.8 +	(page)->index = (long)(dtor);		\
    10.9  } while (0)
   10.10  #define ClearPageForeign(page) do {		\
   10.11  	clear_bit(PG_foreign, &(page)->flags);	\
   10.12 -	(page)->mapping = NULL;			\
   10.13 +	(page)->index = 0;			\
   10.14  } while (0)
   10.15  #define PageForeignDestructor(page)		\
   10.16 -	( (void (*) (struct page *)) (page)->mapping )(page)
   10.17 +	( (void (*) (struct page *)) (page)->index )(page)
   10.18  
   10.19  struct page;	/* forward declaration */
   10.20  
    11.1 --- a/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h	Fri Dec 15 08:16:56 2006 -0500
    11.2 +++ b/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h	Mon Mar 05 11:14:15 2007 +0000
    11.3 @@ -4,7 +4,7 @@
    11.4  #include <linux/kernel.h>
    11.5  #include <linux/cpumask.h>
    11.6  
    11.7 -#if defined(CONFIG_X86)
    11.8 +#if defined(CONFIG_X86) && defined(CONFIG_SMP)
    11.9  extern cpumask_t cpu_initialized_map;
   11.10  #define cpu_set_initialized(cpu) cpu_set(cpu, cpu_initialized_map)
   11.11  #else
    12.1 --- a/linux-2.6-xen-sparse/mm/Kconfig	Fri Dec 15 08:16:56 2006 -0500
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,157 +0,0 @@
    12.4 -config SELECT_MEMORY_MODEL
    12.5 -	def_bool y
    12.6 -	depends on EXPERIMENTAL || ARCH_SELECT_MEMORY_MODEL
    12.7 -
    12.8 -choice
    12.9 -	prompt "Memory model"
   12.10 -	depends on SELECT_MEMORY_MODEL
   12.11 -	default DISCONTIGMEM_MANUAL if ARCH_DISCONTIGMEM_DEFAULT
   12.12 -	default SPARSEMEM_MANUAL if ARCH_SPARSEMEM_DEFAULT
   12.13 -	default FLATMEM_MANUAL
   12.14 -
   12.15 -config FLATMEM_MANUAL
   12.16 -	bool "Flat Memory"
   12.17 -	depends on !(ARCH_DISCONTIGMEM_ENABLE || ARCH_SPARSEMEM_ENABLE) || ARCH_FLATMEM_ENABLE
   12.18 -	help
   12.19 -	  This option allows you to change some of the ways that
   12.20 -	  Linux manages its memory internally.  Most users will
   12.21 -	  only have one option here: FLATMEM.  This is normal
   12.22 -	  and a correct option.
   12.23 -
   12.24 -	  Some users of more advanced features like NUMA and
   12.25 -	  memory hotplug may have different options here.
   12.26 -	  DISCONTIGMEM is an more mature, better tested system,
   12.27 -	  but is incompatible with memory hotplug and may suffer
   12.28 -	  decreased performance over SPARSEMEM.  If unsure between
   12.29 -	  "Sparse Memory" and "Discontiguous Memory", choose
   12.30 -	  "Discontiguous Memory".
   12.31 -
   12.32 -	  If unsure, choose this option (Flat Memory) over any other.
   12.33 -
   12.34 -config DISCONTIGMEM_MANUAL
   12.35 -	bool "Discontiguous Memory"
   12.36 -	depends on ARCH_DISCONTIGMEM_ENABLE
   12.37 -	help
   12.38 -	  This option provides enhanced support for discontiguous
   12.39 -	  memory systems, over FLATMEM.  These systems have holes
   12.40 -	  in their physical address spaces, and this option provides
   12.41 -	  more efficient handling of these holes.  However, the vast
   12.42 -	  majority of hardware has quite flat address spaces, and
   12.43 -	  can have degraded performance from extra overhead that
   12.44 -	  this option imposes.
   12.45 -
   12.46 -	  Many NUMA configurations will have this as the only option.
   12.47 -
   12.48 -	  If unsure, choose "Flat Memory" over this option.
   12.49 -
   12.50 -config SPARSEMEM_MANUAL
   12.51 -	bool "Sparse Memory"
   12.52 -	depends on ARCH_SPARSEMEM_ENABLE
   12.53 -	help
   12.54 -	  This will be the only option for some systems, including
   12.55 -	  memory hotplug systems.  This is normal.
   12.56 -
   12.57 -	  For many other systems, this will be an alternative to
   12.58 -	  "Discontiguous Memory".  This option provides some potential
   12.59 -	  performance benefits, along with decreased code complexity,
   12.60 -	  but it is newer, and more experimental.
   12.61 -
   12.62 -	  If unsure, choose "Discontiguous Memory" or "Flat Memory"
   12.63 -	  over this option.
   12.64 -
   12.65 -endchoice
   12.66 -
   12.67 -config DISCONTIGMEM
   12.68 -	def_bool y
   12.69 -	depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL
   12.70 -
   12.71 -config SPARSEMEM
   12.72 -	def_bool y
   12.73 -	depends on SPARSEMEM_MANUAL
   12.74 -
   12.75 -config FLATMEM
   12.76 -	def_bool y
   12.77 -	depends on (!DISCONTIGMEM && !SPARSEMEM) || FLATMEM_MANUAL
   12.78 -
   12.79 -config FLAT_NODE_MEM_MAP
   12.80 -	def_bool y
   12.81 -	depends on !SPARSEMEM
   12.82 -
   12.83 -#
   12.84 -# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's
   12.85 -# to represent different areas of memory.  This variable allows
   12.86 -# those dependencies to exist individually.
   12.87 -#
   12.88 -config NEED_MULTIPLE_NODES
   12.89 -	def_bool y
   12.90 -	depends on DISCONTIGMEM || NUMA
   12.91 -
   12.92 -config HAVE_MEMORY_PRESENT
   12.93 -	def_bool y
   12.94 -	depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM
   12.95 -
   12.96 -#
   12.97 -# SPARSEMEM_EXTREME (which is the default) does some bootmem
   12.98 -# allocations when memory_present() is called.  If this can not
   12.99 -# be done on your architecture, select this option.  However,
  12.100 -# statically allocating the mem_section[] array can potentially
  12.101 -# consume vast quantities of .bss, so be careful.
  12.102 -#
  12.103 -# This option will also potentially produce smaller runtime code
  12.104 -# with gcc 3.4 and later.
  12.105 -#
  12.106 -config SPARSEMEM_STATIC
  12.107 -	def_bool n
  12.108 -
  12.109 -#
  12.110 -# Architectecture platforms which require a two level mem_section in SPARSEMEM
  12.111 -# must select this option. This is usually for architecture platforms with
  12.112 -# an extremely sparse physical address space.
  12.113 -#
  12.114 -config SPARSEMEM_EXTREME
  12.115 -	def_bool y
  12.116 -	depends on SPARSEMEM && !SPARSEMEM_STATIC
  12.117 -
  12.118 -# eventually, we can have this option just 'select SPARSEMEM'
  12.119 -config MEMORY_HOTPLUG
  12.120 -	bool "Allow for memory hot-add"
  12.121 -	depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG
  12.122 -	depends on (IA64 || X86 || PPC64)
  12.123 -
  12.124 -comment "Memory hotplug is currently incompatible with Software Suspend"
  12.125 -	depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
  12.126 -
  12.127 -# Heavily threaded applications may benefit from splitting the mm-wide
  12.128 -# page_table_lock, so that faults on different parts of the user address
  12.129 -# space can be handled with less contention: split it at this NR_CPUS.
  12.130 -# Default to 4 for wider testing, though 8 might be more appropriate.
  12.131 -# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
  12.132 -# PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes.
  12.133 -# XEN on x86 architecture uses the mapping field on pagetable pages to store a
  12.134 -# pointer to the destructor. This conflicts with pte_lock_deinit().
  12.135 -#
  12.136 -config SPLIT_PTLOCK_CPUS
  12.137 -	int
  12.138 -	default "4096" if ARM && !CPU_CACHE_VIPT
  12.139 -	default "4096" if PARISC && !PA20
  12.140 -	default "4096" if X86_XEN || X86_64_XEN
  12.141 -	default "4"
  12.142 -
  12.143 -#
  12.144 -# support for page migration
  12.145 -#
  12.146 -config MIGRATION
  12.147 -	bool "Page migration"
  12.148 -	def_bool y
  12.149 -	depends on NUMA
  12.150 -	help
  12.151 -	  Allows the migration of the physical location of pages of processes
  12.152 -	  while the virtual addresses are not changed. This is useful for
  12.153 -	  example on NUMA systems to put pages nearer to the processors accessing
  12.154 -	  the page.
  12.155 -
  12.156 -config RESOURCES_64BIT
  12.157 -	bool "64 bit Memory and IO resources (EXPERIMENTAL)" if (!64BIT && EXPERIMENTAL)
  12.158 -	default 64BIT
  12.159 -	help
  12.160 -	  This option allows memory and IO resources to be 64 bit.
    13.1 --- a/tools/libxc/xc_dom_core.c	Fri Dec 15 08:16:56 2006 -0500
    13.2 +++ b/tools/libxc/xc_dom_core.c	Mon Mar 05 11:14:15 2007 +0000
    13.3 @@ -721,9 +721,6 @@ int xc_dom_build_image(struct xc_dom_ima
    13.4      }
    13.5      page_size = XC_DOM_PAGE_SIZE(dom);
    13.6  
    13.7 -    /* 4MB align virtual base address */
    13.8 -    dom->parms.virt_base &= ~(((uint64_t)1<<22)-1);
    13.9 -
   13.10      /* load kernel */
   13.11      if ( xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel",
   13.12                                dom->kernel_seg.vstart,
    14.1 --- a/tools/libxc/xc_linux_restore.c	Fri Dec 15 08:16:56 2006 -0500
    14.2 +++ b/tools/libxc/xc_linux_restore.c	Mon Mar 05 11:14:15 2007 +0000
    14.3 @@ -19,7 +19,7 @@ static unsigned long max_mfn;
    14.4  /* virtual starting address of the hypervisor */
    14.5  static unsigned long hvirt_start;
    14.6  
    14.7 -/* #levels of page tables used by the currrent guest */
    14.8 +/* #levels of page tables used by the current guest */
    14.9  static unsigned int pt_levels;
   14.10  
   14.11  /* total number of pages used by the current guest */
   14.12 @@ -857,6 +857,28 @@ int xc_linux_restore(int xc_handle, int 
   14.13  
   14.14          ctxt.ctrlreg[3] = xen_pfn_to_cr3(p2m[pfn]);
   14.15  
   14.16 +        /* Guest pagetable (x86/64) stored in otherwise-unused CR1. */
   14.17 +        if ( (pt_levels == 4) && ctxt.ctrlreg[1] )
   14.18 +        {
   14.19 +            pfn = xen_cr3_to_pfn(ctxt.ctrlreg[1]);
   14.20 +
   14.21 +            if (pfn >= max_pfn) {
   14.22 +                ERROR("User PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
   14.23 +                      pfn, max_pfn, pfn_type[pfn]);
   14.24 +                goto out;
   14.25 +            }
   14.26 +
   14.27 +            if ( (pfn_type[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) !=
   14.28 +                 ((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) {
   14.29 +                ERROR("User PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
   14.30 +                      pfn, max_pfn, pfn_type[pfn],
   14.31 +                      (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
   14.32 +                goto out;
   14.33 +            }
   14.34 +
   14.35 +            ctxt.ctrlreg[1] = xen_pfn_to_cr3(p2m[pfn]);
   14.36 +        }
   14.37 +
   14.38          domctl.cmd = XEN_DOMCTL_setvcpucontext;
   14.39          domctl.domain = (domid_t)dom;
   14.40          domctl.u.vcpucontext.vcpu = i;
    15.1 --- a/tools/libxc/xc_linux_save.c	Fri Dec 15 08:16:56 2006 -0500
    15.2 +++ b/tools/libxc/xc_linux_save.c	Mon Mar 05 11:14:15 2007 +0000
    15.3 @@ -34,7 +34,7 @@ static unsigned long max_mfn;
    15.4  /* virtual starting address of the hypervisor */
    15.5  static unsigned long hvirt_start;
    15.6  
    15.7 -/* #levels of page tables used by the currrent guest */
    15.8 +/* #levels of page tables used by the current guest */
    15.9  static unsigned int pt_levels;
   15.10  
   15.11  /* total number of pages used by the current guest */
   15.12 @@ -491,7 +491,7 @@ static int canonicalize_pagetable(unsign
   15.13      ** reserved hypervisor mappings. This depends on the current
   15.14      ** page table type as well as the number of paging levels.
   15.15      */
   15.16 -    xen_start = xen_end = pte_last = PAGE_SIZE / ((pt_levels == 2)? 4 : 8);
   15.17 +    xen_start = xen_end = pte_last = PAGE_SIZE / ((pt_levels == 2) ? 4 : 8);
   15.18  
   15.19      if (pt_levels == 2 && type == XEN_DOMCTL_PFINFO_L2TAB)
   15.20          xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT);
   15.21 @@ -1279,6 +1279,18 @@ int xc_linux_save(int xc_handle, int io_
   15.22          ctxt.ctrlreg[3] = 
   15.23              xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3])));
   15.24  
   15.25 +        /* Guest pagetable (x86/64) stored in otherwise-unused CR1. */
   15.26 +        if ( (pt_levels == 4) && ctxt.ctrlreg[1] )
   15.27 +        {
   15.28 +            if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn(ctxt.ctrlreg[1])) ) {
   15.29 +                ERROR("PT base is not in range of pseudophys map");
   15.30 +                goto out;
   15.31 +            }
   15.32 +            /* Least-significant bit means 'valid PFN'. */
   15.33 +            ctxt.ctrlreg[1] = 1 |
   15.34 +                xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[1])));
   15.35 +        }
   15.36 +
   15.37          if (!write_exact(io_fd, &ctxt, sizeof(ctxt))) {
   15.38              ERROR("Error when writing to state file (1) (errno %d)", errno);
   15.39              goto out;
    16.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Dec 15 08:16:56 2006 -0500
    16.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Mar 05 11:14:15 2007 +0000
    16.3 @@ -1503,7 +1503,7 @@ class XendDomainInfo:
    16.4              self.info['start_time'] = time.time()
    16.5  
    16.6              self._stateSet(DOM_STATE_RUNNING)
    16.7 -        except RuntimeError, exn:
    16.8 +        except (RuntimeError, VmError), exn:
    16.9              log.exception("XendDomainInfo.initDomain: exception occurred")
   16.10              self.image.cleanupBootloading()
   16.11              raise VmError(str(exn))
    17.1 --- a/tools/python/xen/xend/XendNode.py	Fri Dec 15 08:16:56 2006 -0500
    17.2 +++ b/tools/python/xen/xend/XendNode.py	Mon Mar 05 11:14:15 2007 +0000
    17.3 @@ -97,6 +97,10 @@ class XendNode:
    17.4          for u in self.cpus.keys():
    17.5              log.error(self.cpus[u])
    17.6              number = self.cpus[u]['number']
    17.7 +            # We can run off the end of the cpuinfo list if domain0 does not
    17.8 +            # have #vcpus == #pcpus. In that case we just replicate pcpu0 info.
    17.9 +            if not cpuinfo.has_key(number):
   17.10 +                number = 0
   17.11              log.error(number)
   17.12              log.error(cpuinfo)
   17.13              self.cpus[u].update(
    18.1 --- a/tools/xenfb/xenfb.c	Fri Dec 15 08:16:56 2006 -0500
    18.2 +++ b/tools/xenfb/xenfb.c	Mon Mar 05 11:14:15 2007 +0000
    18.3 @@ -245,11 +245,10 @@ static int xenfb_wait_for_state(struct x
    18.4  	unsigned state, dummy;
    18.5  	char **vec;
    18.6  
    18.7 +	awaited |= 1 << XenbusStateUnknown;
    18.8 +
    18.9  	for (;;) {
   18.10  		state = xenfb_read_state(xsh, dir);
   18.11 -		if (state < 0)
   18.12 -			return -1;
   18.13 -
   18.14  		if ((1 << state) & awaited)
   18.15  			return state;
   18.16  
    19.1 --- a/xen/Rules.mk	Fri Dec 15 08:16:56 2006 -0500
    19.2 +++ b/xen/Rules.mk	Mon Mar 05 11:14:15 2007 +0000
    19.3 @@ -41,8 +41,8 @@ HDRS += $(wildcard $(BASEDIR)/include/as
    19.4  include $(BASEDIR)/arch/$(TARGET_ARCH)/Rules.mk
    19.5  
    19.6  # Do not depend on auto-generated header files.
    19.7 -HDRS := $(subst $(BASEDIR)/include/asm-$(TARGET_ARCH)/asm-offsets.h,,$(HDRS))
    19.8 -HDRS := $(subst $(BASEDIR)/include/xen/compile.h,,$(HDRS))
    19.9 +AHDRS := $(filter-out %/include/xen/compile.h,$(HDRS))
   19.10 +HDRS  := $(filter-out %/asm-offsets.h,$(AHDRS))
   19.11  
   19.12  # Note that link order matters!
   19.13  ALL_OBJS-y               += $(BASEDIR)/common/built_in.o
   19.14 @@ -110,12 +110,12 @@ clean:: $(addprefix _clean_, $(subdir-al
   19.15  %.o: %.c $(HDRS) Makefile
   19.16  	$(CC) $(CFLAGS) -c $< -o $@
   19.17  
   19.18 -%.o: %.S $(HDRS) Makefile
   19.19 +%.o: %.S $(AHDRS) Makefile
   19.20  	$(CC) $(AFLAGS) -c $< -o $@
   19.21  
   19.22  %.i: %.c $(HDRS) Makefile
   19.23  	$(CPP) $(CFLAGS) $< -o $@
   19.24  
   19.25  # -std=gnu{89,99} gets confused by # as an end-of-line comment marker
   19.26 -%.s: %.S $(HDRS) Makefile
   19.27 +%.s: %.S $(AHDRS) Makefile
   19.28  	$(CPP) $(AFLAGS) $< -o $@
    20.1 --- a/xen/arch/x86/domain.c	Fri Dec 15 08:16:56 2006 -0500
    20.2 +++ b/xen/arch/x86/domain.c	Mon Mar 05 11:14:15 2007 +0000
    20.3 @@ -641,6 +641,31 @@ int arch_set_info_guest(
    20.4              }
    20.5  
    20.6              v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
    20.7 +
    20.8 +#ifdef __x86_64__
    20.9 +            if ( c.nat->ctrlreg[1] )
   20.10 +            {
   20.11 +                cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1]));
   20.12 +
   20.13 +                if ( !mfn_valid(cr3_pfn) ||
   20.14 +                     (paging_mode_refcounts(d)
   20.15 +                      ? !get_page(mfn_to_page(cr3_pfn), d)
   20.16 +                      : !get_page_and_type(mfn_to_page(cr3_pfn), d,
   20.17 +                                           PGT_base_page_table)) )
   20.18 +                {
   20.19 +                    cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
   20.20 +                    v->arch.guest_table = pagetable_null();
   20.21 +                    if ( paging_mode_refcounts(d) )
   20.22 +                        put_page(mfn_to_page(cr3_pfn));
   20.23 +                    else
   20.24 +                        put_page_and_type(mfn_to_page(cr3_pfn));
   20.25 +                    destroy_gdt(v);
   20.26 +                    return -EINVAL;
   20.27 +                }
   20.28 +
   20.29 +                v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
   20.30 +            }
   20.31 +#endif
   20.32          }
   20.33  #ifdef CONFIG_COMPAT
   20.34          else
    21.1 --- a/xen/arch/x86/domain_build.c	Fri Dec 15 08:16:56 2006 -0500
    21.2 +++ b/xen/arch/x86/domain_build.c	Mon Mar 05 11:14:15 2007 +0000
    21.3 @@ -374,9 +374,6 @@ int construct_dom0(struct domain *d,
    21.4      if ( parms.f_required[0] /* Huh? -- kraxel */ )
    21.5              panic("Domain 0 requires an unsupported hypervisor feature.\n");
    21.6  
    21.7 -    /* Align load address to 4MB boundary. */
    21.8 -    v_start = parms.virt_base & ~((1UL<<22)-1);
    21.9 -
   21.10      /*
   21.11       * Why do we need this? The number of page-table frames depends on the 
   21.12       * size of the bootstrap address space. But the size of the address space 
   21.13 @@ -384,6 +381,7 @@ int construct_dom0(struct domain *d,
   21.14       * read-only). We have a pair of simultaneous equations in two unknowns, 
   21.15       * which we solve by exhaustive search.
   21.16       */
   21.17 +    v_start          = parms.virt_base;
   21.18      vkern_start      = parms.virt_kstart;
   21.19      vkern_end        = parms.virt_kend;
   21.20      vinitrd_start    = round_pgup(vkern_end);
    22.1 --- a/xen/arch/x86/domctl.c	Fri Dec 15 08:16:56 2006 -0500
    22.2 +++ b/xen/arch/x86/domctl.c	Mon Mar 05 11:14:15 2007 +0000
    22.3 @@ -470,8 +470,15 @@ void arch_get_info_guest(struct vcpu *v,
    22.4          c(user_regs.eflags |= v->arch.iopl << 12);
    22.5  
    22.6          if ( !IS_COMPAT(v->domain) )
    22.7 +        {
    22.8              c.nat->ctrlreg[3] = xen_pfn_to_cr3(
    22.9                  pagetable_get_pfn(v->arch.guest_table));
   22.10 +#ifdef __x86_64__
   22.11 +            if ( !pagetable_is_null(v->arch.guest_table_user) )
   22.12 +                c.nat->ctrlreg[1] = xen_pfn_to_cr3(
   22.13 +                    pagetable_get_pfn(v->arch.guest_table_user));
   22.14 +#endif
   22.15 +        }
   22.16  #ifdef CONFIG_COMPAT
   22.17          else
   22.18          {
    23.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Dec 15 08:16:56 2006 -0500
    23.2 +++ b/xen/arch/x86/mm/shadow/common.c	Mon Mar 05 11:14:15 2007 +0000
    23.3 @@ -2912,7 +2912,16 @@ void sh_mark_dirty(struct domain *d, mfn
    23.4       * can be called from __hvm_copy during emulation).
    23.5       * If the lock isn't held, take it for the duration of the call. */
    23.6      do_locking = !shadow_locked_by_me(d);
    23.7 -    if ( do_locking ) shadow_lock(d);
    23.8 +    if ( do_locking ) 
    23.9 +    { 
   23.10 +        shadow_lock(d);
   23.11 +        /* Check the mode again with the lock held */ 
   23.12 +        if ( unlikely(!shadow_mode_log_dirty(d)) )
   23.13 +        {
   23.14 +            shadow_unlock(d);
   23.15 +            return;
   23.16 +        }
   23.17 +    }
   23.18  
   23.19      ASSERT(d->arch.paging.shadow.dirty_bitmap != NULL);
   23.20  
    24.1 --- a/xen/drivers/acpi/numa.c	Fri Dec 15 08:16:56 2006 -0500
    24.2 +++ b/xen/drivers/acpi/numa.c	Mon Mar 05 11:14:15 2007 +0000
    24.3 @@ -22,10 +22,6 @@
    24.4   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    24.5   *
    24.6   */
    24.7 -#if 0
    24.8 -#include <linux/module.h>
    24.9 -#include <linux/kernel.h>
   24.10 -#endif
   24.11  #include <xen/config.h>
   24.12  #include <xen/init.h>
   24.13  #include <xen/types.h>
   24.14 @@ -34,7 +30,6 @@
   24.15  #include <xen/numa.h>
   24.16  #include <acpi/acpi_bus.h>
   24.17  #include <acpi/acmacros.h>
   24.18 -#include <asm/page.h> /* __va() */
   24.19  
   24.20  #define ACPI_NUMA	0x80000000
   24.21  #define _COMPONENT	ACPI_NUMA
   24.22 @@ -106,7 +101,7 @@ static int __init acpi_parse_slit(unsign
   24.23  	if (!phys_addr || !size)
   24.24  		return -EINVAL;
   24.25  
   24.26 -	slit = (struct acpi_table_slit *)__va(phys_addr);
   24.27 +	slit = (struct acpi_table_slit *)__acpi_map_table(phys_addr, size);
   24.28  
   24.29  	/* downcast just for %llu vs %lu for i386/ia64  */
   24.30  	localities = (u32) slit->localities;
   24.31 @@ -159,7 +154,7 @@ static int __init acpi_parse_srat(unsign
   24.32  	if (!phys_addr || !size)
   24.33  		return -EINVAL;
   24.34  
   24.35 -	srat = (struct acpi_table_srat *)__va(phys_addr);
   24.36 +	srat = (struct acpi_table_srat *)__acpi_map_table(phys_addr, size);
   24.37  
   24.38  	return 0;
   24.39  }
    25.1 --- a/xen/include/acm/acm_hooks.h	Fri Dec 15 08:16:56 2006 -0500
    25.2 +++ b/xen/include/acm/acm_hooks.h	Mon Mar 05 11:14:15 2007 +0000
    25.3 @@ -247,12 +247,12 @@ static inline int acm_pre_domctl(struct 
    25.4              if (*ssid == NULL) {
    25.5                  printk("%s: Warning. Destroying domain without ssid pointer.\n", 
    25.6                         __func__);
    25.7 -                domain_rcu_lock(d);
    25.8 +                rcu_unlock_domain(d);
    25.9                  return -EACCES;
   25.10              }
   25.11              d->ssid = NULL; /* make sure it's not used any more */
   25.12               /* no policy-specific hook */
   25.13 -            domain_rcu_lock(d);
   25.14 +            rcu_unlock_domain(d);
   25.15              ret = 0;
   25.16          }
   25.17          break;
    26.1 --- a/xen/include/public/arch-x86/xen.h	Fri Dec 15 08:16:56 2006 -0500
    26.2 +++ b/xen/include/public/arch-x86/xen.h	Mon Mar 05 11:14:15 2007 +0000
    26.3 @@ -132,6 +132,7 @@ struct vcpu_guest_context {
    26.4      unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
    26.5      unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
    26.6      unsigned long kernel_ss, kernel_sp;     /* Virtual TSS (only SS1/SP1)   */
    26.7 +    /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */
    26.8      unsigned long ctrlreg[8];               /* CR0-CR7 (control registers)  */
    26.9      unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
   26.10  #ifdef __i386__
    27.1 --- a/xen/include/public/xen.h	Fri Dec 15 08:16:56 2006 -0500
    27.2 +++ b/xen/include/public/xen.h	Mon Mar 05 11:14:15 2007 +0000
    27.3 @@ -473,26 +473,24 @@ typedef struct shared_info shared_info_t
    27.4  #endif
    27.5  
    27.6  /*
    27.7 - * Start-of-day memory layout for the initial domain (DOM0):
    27.8 + * Start-of-day memory layout:
    27.9   *  1. The domain is started within contiguous virtual-memory region.
   27.10 - *  2. The contiguous region begins and ends on an aligned 4MB boundary.
   27.11 - *  3. The region start corresponds to the load address of the OS image.
   27.12 - *     If the load address is not 4MB aligned then the address is rounded down.
   27.13 - *  4. This the order of bootstrap elements in the initial virtual region:
   27.14 + *  2. The contiguous region ends on an aligned 4MB boundary.
   27.15 + *  3. This the order of bootstrap elements in the initial virtual region:
   27.16   *      a. relocated kernel image
   27.17   *      b. initial ram disk              [mod_start, mod_len]
   27.18   *      c. list of allocated page frames [mfn_list, nr_pages]
   27.19   *      d. start_info_t structure        [register ESI (x86)]
   27.20   *      e. bootstrap page tables         [pt_base, CR3 (x86)]
   27.21   *      f. bootstrap stack               [register ESP (x86)]
   27.22 - *  5. Bootstrap elements are packed together, but each is 4kB-aligned.
   27.23 - *  6. The initial ram disk may be omitted.
   27.24 - *  7. The list of page frames forms a contiguous 'pseudo-physical' memory
   27.25 + *  4. Bootstrap elements are packed together, but each is 4kB-aligned.
   27.26 + *  5. The initial ram disk may be omitted.
   27.27 + *  6. The list of page frames forms a contiguous 'pseudo-physical' memory
   27.28   *     layout for the domain. In particular, the bootstrap virtual-memory
   27.29   *     region is a 1:1 mapping to the first section of the pseudo-physical map.
   27.30 - *  8. All bootstrap elements are mapped read-writable for the guest OS. The
   27.31 + *  7. All bootstrap elements are mapped read-writable for the guest OS. The
   27.32   *     only exception is the bootstrap page table, which is mapped read-only.
   27.33 - *  9. There is guaranteed to be at least 512kB padding after the final
   27.34 + *  8. There is guaranteed to be at least 512kB padding after the final
   27.35   *     bootstrap element. If necessary, the bootstrap virtual region is
   27.36   *     extended by an extra 4MB to ensure this.
   27.37   */