WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Merge with xenppc-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Merge with xenppc-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 07 Mar 2007 11:30:40 -0800
Delivery-date: Wed, 07 Mar 2007 11:31:57 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1173093255 0
# Node ID e74bfc74471778ad6515cef1674bd529b6814ff0
# Parent  5a2b3a1b1f632475c8abdce25132e9d3ea767f7f
# Parent  939d2b7d4a12acea391c75324d189fa8858ffc9c
Merge with xenppc-unstable.hg
---
 linux-2.6-xen-sparse/mm/Kconfig                           |  157 -----------
 linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S          |    2 
 linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c           |   58 ++--
 linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S        |    2 
 linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c        |   11 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c           |  192 ++++++--------
 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    |   42 +--
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c        |    9 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      |   52 ++-
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h |   15 -
 linux-2.6-xen-sparse/include/linux/page-flags.h           |    6 
 linux-2.6-xen-sparse/include/xen/cpu_hotplug.h            |    2 
 tools/libxc/xc_dom_core.c                                 |    3 
 tools/libxc/xc_linux_restore.c                            |   24 +
 tools/libxc/xc_linux_save.c                               |   16 +
 tools/python/xen/xend/XendDomainInfo.py                   |    2 
 tools/python/xen/xend/XendNode.py                         |    4 
 tools/xenfb/xenfb.c                                       |    5 
 xen/Rules.mk                                              |    8 
 xen/arch/x86/domain.c                                     |   25 +
 xen/arch/x86/domain_build.c                               |    4 
 xen/arch/x86/domctl.c                                     |    7 
 xen/arch/x86/mm/shadow/common.c                           |   11 
 xen/drivers/acpi/numa.c                                   |    9 
 xen/include/acm/acm_hooks.h                               |    4 
 xen/include/public/arch-x86/xen.h                         |    1 
 xen/include/public/xen.h                                  |   18 -
 27 files changed, 305 insertions(+), 384 deletions(-)

diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Fri Dec 15 08:16:56 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Mon Mar 05 11:14:15 
2007 +0000
@@ -11,8 +11,6 @@
 #include <asm/asm-offsets.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/elfnote.h>
-
-#define _PAGE_PRESENT 0x1
 
 /*
  * References to members of the new_cpu_data structure.
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Fri Dec 15 08:16:56 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Mon Mar 05 11:14:15 
2007 +0000
@@ -573,64 +573,67 @@ void make_pages_writable(void *va, unsig
        }
 }
 
-static inline int pgd_walk_set_prot(struct page *page, pgprot_t flags)
+static inline void pgd_walk_set_prot(struct page *page, pgprot_t flags)
 {
        unsigned long pfn = page_to_pfn(page);
-
-       if (PageHighMem(page))
-               return pgprot_val(flags) & _PAGE_RW
-                      ? test_and_clear_bit(PG_pinned, &page->flags)
-                      : !test_and_set_bit(PG_pinned, &page->flags);
-
-       BUG_ON(HYPERVISOR_update_va_mapping(
-               (unsigned long)__va(pfn << PAGE_SHIFT),
-               pfn_pte(pfn, flags), 0));
-
-       return 0;
-}
-
-static int pgd_walk(pgd_t *pgd_base, pgprot_t flags)
+       int rc;
+
+       if (PageHighMem(page)) {
+               if (pgprot_val(flags) & _PAGE_RW)
+                       clear_bit(PG_pinned, &page->flags);
+               else
+                       set_bit(PG_pinned, &page->flags);
+       } else {
+               rc = HYPERVISOR_update_va_mapping(
+                       (unsigned long)__va(pfn << PAGE_SHIFT),
+                       pfn_pte(pfn, flags), 0);
+               if (rc)
+                       BUG();
+       }
+}
+
+static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
 {
        pgd_t *pgd = pgd_base;
        pud_t *pud;
        pmd_t *pmd;
-       int    g, u, m, flush;
+       int    g, u, m, rc;
 
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return 0;
 
-       for (g = 0, flush = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
+       for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
                if (pgd_none(*pgd))
                        continue;
                pud = pud_offset(pgd, 0);
                if (PTRS_PER_PUD > 1) /* not folded */
-                       flush |= pgd_walk_set_prot(virt_to_page(pud),flags);
+                       pgd_walk_set_prot(virt_to_page(pud),flags);
                for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
                        if (pud_none(*pud))
                                continue;
                        pmd = pmd_offset(pud, 0);
                        if (PTRS_PER_PMD > 1) /* not folded */
-                               flush |= 
pgd_walk_set_prot(virt_to_page(pmd),flags);
+                               pgd_walk_set_prot(virt_to_page(pmd),flags);
                        for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
                                if (pmd_none(*pmd))
                                        continue;
-                               flush |= 
pgd_walk_set_prot(pmd_page(*pmd),flags);
+                               pgd_walk_set_prot(pmd_page(*pmd),flags);
                        }
                }
        }
 
-       BUG_ON(HYPERVISOR_update_va_mapping(
+       rc = HYPERVISOR_update_va_mapping(
                (unsigned long)pgd_base,
                pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
-               UVMF_TLB_FLUSH));
-
-       return flush;
+               UVMF_TLB_FLUSH);
+       if (rc)
+               BUG();
 }
 
 static void __pgd_pin(pgd_t *pgd)
 {
-       if (pgd_walk(pgd, PAGE_KERNEL_RO))
-               kmap_flush_unused();
+       pgd_walk(pgd, PAGE_KERNEL_RO);
+       kmap_flush_unused();
        xen_pgd_pin(__pa(pgd));
        set_bit(PG_pinned, &virt_to_page(pgd)->flags);
 }
@@ -638,8 +641,7 @@ static void __pgd_unpin(pgd_t *pgd)
 static void __pgd_unpin(pgd_t *pgd)
 {
        xen_pgd_unpin(__pa(pgd));
-       if (pgd_walk(pgd, PAGE_KERNEL))
-               kmap_flush_unused();
+       pgd_walk(pgd, PAGE_KERNEL);
        clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
 }
 
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S        Fri Dec 15 
08:16:56 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S        Mon Mar 05 
11:14:15 2007 +0000
@@ -24,8 +24,6 @@
 #include <asm/cache.h>
 
 #include <xen/interface/elfnote.h>
-
-#define _PAGE_PRESENT 0x1
 
        .section .bootstrap.text, "ax", @progbits
        .code64
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c        Fri Dec 15 
08:16:56 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c        Mon Mar 05 
11:14:15 2007 +0000
@@ -24,10 +24,13 @@ static inline void mm_walk_set_prot(void
 {
        struct page *page = virt_to_page(pt);
        unsigned long pfn = page_to_pfn(page);
-
-       BUG_ON(HYPERVISOR_update_va_mapping(
-                      (unsigned long)__va(pfn << PAGE_SHIFT),
-                      pfn_pte(pfn, flags), 0));
+       int rc;
+
+       rc = HYPERVISOR_update_va_mapping(
+               (unsigned long)__va(pfn << PAGE_SHIFT),
+               pfn_pte(pfn, flags), 0);
+       if (rc)
+               BUG();
 }
 
 static void mm_walk(struct mm_struct *mm, pgprot_t flags)
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Fri Dec 15 08:16:56 
2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Mon Mar 05 11:14:15 
2007 +0000
@@ -113,14 +113,13 @@ void __exit tpmif_exit(void);
 
 
 static inline int
-tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
+tx_buffer_copy(struct tx_buffer *txb, const u8 *src, int len,
                int isuserbuffer)
 {
        int copied = len;
 
-       if (len > txb->size) {
+       if (len > txb->size)
                copied = txb->size;
-       }
        if (isuserbuffer) {
                if (copy_from_user(txb->data, src, copied))
                        return -EFAULT;
@@ -133,18 +132,20 @@ tx_buffer_copy(struct tx_buffer *txb, co
 
 static inline struct tx_buffer *tx_buffer_alloc(void)
 {
-       struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
-                                       GFP_KERNEL);
-
-       if (txb) {
-               txb->len = 0;
-               txb->size = PAGE_SIZE;
-               txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
-               if (txb->data == NULL) {
-                       kfree(txb);
-                       txb = NULL;
-               }
-       }
+       struct tx_buffer *txb;
+
+       txb = kzalloc(sizeof(struct tx_buffer), GFP_KERNEL);
+       if (!txb)
+               return NULL;
+
+       txb->len = 0;
+       txb->size = PAGE_SIZE;
+       txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
+       if (txb->data == NULL) {
+               kfree(txb);
+               txb = NULL;
+       }
+
        return txb;
 }
 
@@ -160,37 +161,41 @@ static inline void tx_buffer_free(struct
 /**************************************************************
  Utility function for the tpm_private structure
 **************************************************************/
-static inline void tpm_private_init(struct tpm_private *tp)
+static void tpm_private_init(struct tpm_private *tp)
 {
        spin_lock_init(&tp->tx_lock);
        init_waitqueue_head(&tp->wait_q);
        atomic_set(&tp->refcnt, 1);
 }
 
-static inline void tpm_private_put(void)
-{
-       if ( atomic_dec_and_test(&my_priv->refcnt)) {
-               tpmif_free_tx_buffers(my_priv);
-               kfree(my_priv);
-               my_priv = NULL;
-       }
+static void tpm_private_put(void)
+{
+       if (!atomic_dec_and_test(&my_priv->refcnt))
+               return;
+
+       tpmif_free_tx_buffers(my_priv);
+       kfree(my_priv);
+       my_priv = NULL;
 }
 
 static struct tpm_private *tpm_private_get(void)
 {
        int err;
-       if (!my_priv) {
-               my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
-               if (my_priv) {
-                       tpm_private_init(my_priv);
-                       err = tpmif_allocate_tx_buffers(my_priv);
-                       if (err < 0) {
-                               tpm_private_put();
-                       }
-               }
-       } else {
+
+       if (my_priv) {
                atomic_inc(&my_priv->refcnt);
-       }
+               return my_priv;
+       }
+
+       my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
+       if (!my_priv)
+               return NULL;
+
+       tpm_private_init(my_priv);
+       err = tpmif_allocate_tx_buffers(my_priv);
+       if (err < 0)
+               tpm_private_put();
+
        return my_priv;
 }
 
@@ -379,10 +384,8 @@ static int tpmfront_probe(struct xenbus_
                return -ENOMEM;
 
        tp->chip = init_vtpm(&dev->dev, &tvd, tp);
-
-       if (IS_ERR(tp->chip)) {
+       if (IS_ERR(tp->chip))
                return PTR_ERR(tp->chip);
-       }
 
        err = xenbus_scanf(XBT_NIL, dev->nodename,
                           "handle", "%i", &handle);
@@ -401,6 +404,7 @@ static int tpmfront_probe(struct xenbus_
                tpm_private_put();
                return err;
        }
+
        return 0;
 }
 
@@ -417,30 +421,34 @@ static int tpmfront_suspend(struct xenbu
 {
        struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        u32 ctr;
-       /* lock, so no app can send */
+
+       /* Take the lock, preventing any application from sending. */
        mutex_lock(&suspend_lock);
        tp->is_suspended = 1;
 
-       for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 300; ctr++) {
+       for (ctr = 0; atomic_read(&tp->tx_busy); ctr++) {
                if ((ctr % 10) == 0)
                        printk("TPM-FE [INFO]: Waiting for outstanding "
                               "request.\n");
-               /*
-                * Wait for a request to be responded to.
-                */
+               /* Wait for a request to be responded to. */
                interruptible_sleep_on_timeout(&tp->wait_q, 100);
        }
-       xenbus_switch_state(dev, XenbusStateClosing);
-
-       if (atomic_read(&tp->tx_busy)) {
-               /*
-                * A temporary work-around.
-                */
-               printk("TPM-FE [WARNING]: Resetting busy flag.");
-               atomic_set(&tp->tx_busy, 0);
-       }
-
-       return 0;
+
+       return 0;
+}
+
+static int tpmfront_suspend_finish(struct tpm_private *tp)
+{
+       tp->is_suspended = 0;
+       /* Allow applications to send again. */
+       mutex_unlock(&suspend_lock);
+       return 0;
+}
+
+static int tpmfront_suspend_cancel(struct xenbus_device *dev)
+{
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
+       return tpmfront_suspend_finish(tp);
 }
 
 static int tpmfront_resume(struct xenbus_device *dev)
@@ -484,6 +492,7 @@ static struct xenbus_driver tpmfront = {
        .resume = tpmfront_resume,
        .otherend_changed = backend_changed,
        .suspend = tpmfront_suspend,
+       .suspend_cancel = tpmfront_suspend_cancel,
 };
 
 static void __init init_tpm_xenbus(void)
@@ -514,9 +523,8 @@ static void tpmif_free_tx_buffers(struct
 {
        unsigned int i;
 
-       for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
+       for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
                tx_buffer_free(tp->tx_buffers[i]);
-       }
 }
 
 static void tpmif_rx_action(unsigned long priv)
@@ -536,9 +544,8 @@ static void tpmif_rx_action(unsigned lon
        received = tx->size;
 
        buffer = kmalloc(received, GFP_ATOMIC);
-       if (NULL == buffer) {
+       if (!buffer)
                goto exit;
-       }
 
        for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
                struct tx_buffer *txb = tp->tx_buffers[i];
@@ -547,9 +554,8 @@ static void tpmif_rx_action(unsigned lon
 
                tx = &tp->tx->ring[i].req;
                tocopy = tx->size;
-               if (tocopy > PAGE_SIZE) {
+               if (tocopy > PAGE_SIZE)
                        tocopy = PAGE_SIZE;
-               }
 
                memcpy(&buffer[offset], txb->data, tocopy);
 
@@ -607,12 +613,13 @@ static int tpm_xmit(struct tpm_private *
                struct tx_buffer *txb = tp->tx_buffers[i];
                int copied;
 
-               if (NULL == txb) {
+               if (!txb) {
                        DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
                                "Not transmitting anything!\n", i);
                        spin_unlock_irq(&tp->tx_lock);
                        return -EFAULT;
                }
+
                copied = tx_buffer_copy(txb, &buf[offset], count,
                                        isuserbuffer);
                if (copied < 0) {
@@ -624,25 +631,26 @@ static int tpm_xmit(struct tpm_private *
                offset += copied;
 
                tx = &tp->tx->ring[i].req;
-
                tx->addr = virt_to_machine(txb->data);
                tx->size = txb->len;
 
-               DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 
0x%02x 0x%02x\n",
+               DPRINTK("First 4 characters sent by TPM-FE are "
+                       "0x%02x 0x%02x 0x%02x 0x%02x\n",
                        txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
 
-               /* get the granttable reference for this page */
+               /* Get the granttable reference for this page. */
                tx->ref = gnttab_claim_grant_reference(&gref_head);
-
-               if (-ENOSPC == tx->ref) {
+               if (tx->ref == -ENOSPC) {
                        spin_unlock_irq(&tp->tx_lock);
-                       DPRINTK(" Grant table claim reference failed in func:%s 
line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
+                       DPRINTK("Grant table claim reference failed in "
+                               "func:%s line:%d file:%s\n",
+                               __FUNCTION__, __LINE__, __FILE__);
                        return -ENOSPC;
                }
-               gnttab_grant_foreign_access_ref( tx->ref,
-                                                tp->backend_id,
-                                                virt_to_mfn(txb->data),
-                                                0 /*RW*/);
+               gnttab_grant_foreign_access_ref(tx->ref,
+                                               tp->backend_id,
+                                               virt_to_mfn(txb->data),
+                                               0 /*RW*/);
                wmb();
        }
 
@@ -660,15 +668,10 @@ static int tpm_xmit(struct tpm_private *
 
 static void tpmif_notify_upperlayer(struct tpm_private *tp)
 {
-       /*
-        * Notify upper layer about the state of the connection
-        * to the BE.
-        */
-       if (tp->is_connected) {
-               vtpm_vd_status(tp->chip, TPM_VD_STATUS_CONNECTED);
-       } else {
-               vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED);
-       }
+       /* Notify upper layer about the state of the connection to the BE. */
+       vtpm_vd_status(tp->chip, (tp->is_connected
+                                 ? TPM_VD_STATUS_CONNECTED
+                                 : TPM_VD_STATUS_DISCONNECTED));
 }
 
 
@@ -679,20 +682,16 @@ static void tpmif_set_connected_state(st
         * should disconnect - assumption is that we will resume
         * The mutex keeps apps from sending.
         */
-       if (is_connected == 0 && tp->is_suspended == 1) {
+       if (is_connected == 0 && tp->is_suspended == 1)
                return;
-       }
 
        /*
         * Unlock the mutex if we are connected again
         * after being suspended - now resuming.
         * This also removes the suspend state.
         */
-       if (is_connected == 1 && tp->is_suspended == 1) {
-               tp->is_suspended = 0;
-               /* unlock, so apps can resume sending */
-               mutex_unlock(&suspend_lock);
-       }
+       if (is_connected == 1 && tp->is_suspended == 1)
+               tpmfront_suspend_finish(tp);
 
        if (is_connected != tp->is_connected) {
                tp->is_connected = is_connected;
@@ -710,33 +709,24 @@ static void tpmif_set_connected_state(st
 
 static int __init tpmif_init(void)
 {
-       long rc = 0;
        struct tpm_private *tp;
 
        if (is_initial_xendomain())
                return -EPERM;
 
        tp = tpm_private_get();
-       if (!tp) {
-               rc = -ENOMEM;
-               goto failexit;
-       }
+       if (!tp)
+               return -ENOMEM;
 
        IPRINTK("Initialising the vTPM driver.\n");
-       if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
-                                            &gref_head ) < 0) {
-               rc = -EFAULT;
-               goto gnttab_alloc_failed;
+       if (gnttab_alloc_grant_references(TPMIF_TX_RING_SIZE,
+                                         &gref_head) < 0) {
+               tpm_private_put();
+               return -EFAULT;
        }
 
        init_tpm_xenbus();
        return 0;
-
-gnttab_alloc_failed:
-       tpm_private_put();
-failexit:
-
-       return (int)rc;
 }
 
 
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Fri Dec 15 
08:16:56 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Mon Mar 05 
11:14:15 2007 +0000
@@ -59,23 +59,6 @@ EXPORT_SYMBOL(machine_halt);
 EXPORT_SYMBOL(machine_halt);
 EXPORT_SYMBOL(machine_power_off);
 
-/* Ensure we run on the idle task page tables so that we will
-   switch page tables before running user space. This is needed
-   on architectures with separate kernel and user page tables
-   because the user page table pointer is not saved/restored. */
-static void switch_idle_mm(void)
-{
-       struct mm_struct *mm = current->active_mm;
-
-       if (mm == &init_mm)
-               return;
-
-       atomic_inc(&init_mm.mm_count);
-       switch_mm(mm, &init_mm, current);
-       current->active_mm = &init_mm;
-       mmdrop(mm);
-}
-
 static void pre_suspend(void)
 {
        HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
@@ -99,7 +82,9 @@ static void post_suspend(int suspend_can
                xen_start_info->console.domU.mfn =
                        pfn_to_mfn(xen_start_info->console.domU.mfn);
        } else {
+#ifdef CONFIG_SMP
                cpu_initialized_map = cpumask_of_cpu(0);
+#endif
        }
        
        set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
@@ -172,10 +157,25 @@ static int take_machine_down(void *p_fas
 
        post_suspend(suspend_cancelled);
        gnttab_resume();
-       if (!suspend_cancelled)
+       if (!suspend_cancelled) {
                irq_resume();
+#ifdef __x86_64__
+               /*
+                * Older versions of Xen do not save/restore the user %cr3.
+                * We do it here just in case, but there's no need if we are
+                * in fast-suspend mode as that implies a new enough Xen.
+                */
+               if (!fast_suspend) {
+                       struct mmuext_op op;
+                       op.cmd = MMUEXT_NEW_USER_BASEPTR;
+                       op.arg1.mfn = pfn_to_mfn(__pa(__user_pgd(
+                               current->active_mm->pgd)) >> PAGE_SHIFT);
+                       if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
+                               BUG();
+               }
+#endif
+       }
        time_resume();
-       switch_idle_mm();
        local_irq_enable();
 
        if (fast_suspend && !suspend_cancelled) {
@@ -210,6 +210,10 @@ int __xen_suspend(int fast_suspend)
        }
 #endif
 
+       /* If we are definitely UP then 'slow mode' is actually faster. */
+       if (num_possible_cpus() == 1)
+               fast_suspend = 0;
+
        if (fast_suspend) {
                xenbus_suspend();
                err = stop_machine_run(take_machine_down, &fast_suspend, 0);
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Dec 15 
08:16:56 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon Mar 05 
11:14:15 2007 +0000
@@ -40,6 +40,9 @@
 
 /*#define NETBE_DEBUG_INTERRUPT*/
 
+/* extra field used in struct page */
+#define netif_page_index(pg) (*(long *)&(pg)->mapping)
+
 struct netbk_rx_meta {
        skb_frag_t frag;
        int id;
@@ -352,7 +355,7 @@ static u16 netbk_gop_frag(netif_t *netif
                copy_gop->flags = GNTCOPY_dest_gref;
                if (PageForeign(page)) {
                        struct pending_tx_info *src_pend =
-                               &pending_tx_info[page->index];
+                               &pending_tx_info[netif_page_index(page)];
                        copy_gop->source.domid = src_pend->netif->domid;
                        copy_gop->source.u.ref = src_pend->req.gref;
                        copy_gop->flags |= GNTCOPY_source_gref;
@@ -1327,7 +1330,7 @@ static void netif_page_release(struct pa
        /* Ready for next use. */
        init_page_count(page);
 
-       netif_idx_release(page->index);
+       netif_idx_release(netif_page_index(page));
 }
 
 irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
@@ -1457,7 +1460,7 @@ static int __init netback_init(void)
        for (i = 0; i < MAX_PENDING_REQS; i++) {
                page = mmap_pages[i];
                SetPageForeign(page, netif_page_release);
-               page->index = i;
+               netif_page_index(page) = i;
        }
 
        pending_cons = 0;
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Fri Dec 15 
08:16:56 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Mon Mar 05 
11:14:15 2007 +0000
@@ -173,17 +173,22 @@ static ssize_t xenbus_dev_write(struct f
        void *reply;
        char *path, *token;
        struct watch_adapter *watch, *tmp_watch;
-       int err;
-
-       if ((len + u->len) > sizeof(u->u.buffer))
-               return -EINVAL;
-
-       if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0)
-               return -EFAULT;
+       int err, rc = len;
+
+       if ((len + u->len) > sizeof(u->u.buffer)) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0) {
+               rc = -EFAULT;
+               goto out;
+       }
 
        u->len += len;
-       if (u->len < (sizeof(u->u.msg) + u->u.msg.len))
-               return len;
+       if ((u->len < sizeof(u->u.msg)) ||
+           (u->len < (sizeof(u->u.msg) + u->u.msg.len)))
+               return rc;
 
        msg_type = u->u.msg.type;
 
@@ -201,14 +206,17 @@ static ssize_t xenbus_dev_write(struct f
        case XS_SET_PERMS:
                if (msg_type == XS_TRANSACTION_START) {
                        trans = kmalloc(sizeof(*trans), GFP_KERNEL);
-                       if (!trans)
-                               return -ENOMEM;
+                       if (!trans) {
+                               rc = -ENOMEM;
+                               goto out;
+                       }
                }
 
                reply = xenbus_dev_request_and_reply(&u->u.msg);
                if (IS_ERR(reply)) {
                        kfree(trans);
-                       return PTR_ERR(reply);
+                       rc = PTR_ERR(reply);
+                       goto out;
                }
 
                if (msg_type == XS_TRANSACTION_START) {
@@ -231,8 +239,10 @@ static ssize_t xenbus_dev_write(struct f
        case XS_UNWATCH:
                path = u->u.buffer + sizeof(u->u.msg);
                token = memchr(path, 0, u->u.msg.len);
-               if (token == NULL)
-                       return -EILSEQ;
+               if (token == NULL) {
+                       rc = -EILSEQ;
+                       goto out;
+               }
                token++;
 
                if (msg_type == XS_WATCH) {
@@ -251,7 +261,8 @@ static ssize_t xenbus_dev_write(struct f
                        err = register_xenbus_watch(&watch->watch);
                        if (err) {
                                free_watch_adapter(watch);
-                               return err;
+                               rc = err;
+                               goto out;
                        }
                        
                        list_add(&watch->list, &u->watches);
@@ -265,7 +276,6 @@ static ssize_t xenbus_dev_write(struct f
                                                  &u->watches, list) {
                                if (!strcmp(watch->token, token) &&
                                    !strcmp(watch->watch.node, path))
-                                       break;
                                {
                                        unregister_xenbus_watch(&watch->watch);
                                        list_del(&watch->list);
@@ -278,11 +288,13 @@ static ssize_t xenbus_dev_write(struct f
                break;
 
        default:
-               return -EINVAL;
-       }
-
+               rc = -EINVAL;
+               break;
+       }
+
+ out:
        u->len = 0;
-       return len;
+       return rc;
 }
 
 static int xenbus_dev_open(struct inode *inode, struct file *filp)
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Fri Dec 15 
08:16:56 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon Mar 05 
11:14:15 2007 +0000
@@ -20,6 +20,14 @@
 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
 
 #ifdef __KERNEL__
+
+/*
+ * Need to repeat this here in order to not include pgtable.h (which in turn
+ * depends on definitions made here), but to be able to use the symbolic
+ * below. The preprocessor will warn if the two definitions aren't identical.
+ */
+#define _PAGE_PRESENT  0x001
+
 #ifndef __ASSEMBLY__
 
 #include <linux/string.h>
@@ -28,13 +36,6 @@
 #include <asm/bug.h>
 #include <xen/interface/xen.h>
 #include <xen/features.h>
-
-/*
- * Need to repeat this here in order to not include pgtable.h (which in turn
- * depends on definitions made here), but to be able to use the symbolic
- * below. The preprocessor will warn if the two definitions aren't identical.
- */
-#define _PAGE_PRESENT  0x001
 
 #define arch_free_page(_page,_order)           \
 ({     int foreign = PageForeign(_page);       \
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/include/linux/page-flags.h
--- a/linux-2.6-xen-sparse/include/linux/page-flags.h   Fri Dec 15 08:16:56 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/linux/page-flags.h   Mon Mar 05 11:14:15 
2007 +0000
@@ -252,14 +252,14 @@
 #define PageForeign(page)      test_bit(PG_foreign, &(page)->flags)
 #define SetPageForeign(page, dtor) do {                \
        set_bit(PG_foreign, &(page)->flags);    \
-       (page)->mapping = (void *)dtor;         \
+       (page)->index = (long)(dtor);           \
 } while (0)
 #define ClearPageForeign(page) do {            \
        clear_bit(PG_foreign, &(page)->flags);  \
-       (page)->mapping = NULL;                 \
+       (page)->index = 0;                      \
 } while (0)
 #define PageForeignDestructor(page)            \
-       ( (void (*) (struct page *)) (page)->mapping )(page)
+       ( (void (*) (struct page *)) (page)->index )(page)
 
 struct page;   /* forward declaration */
 
diff -r 5a2b3a1b1f63 -r e74bfc744717 
linux-2.6-xen-sparse/include/xen/cpu_hotplug.h
--- a/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h    Fri Dec 15 08:16:56 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h    Mon Mar 05 11:14:15 
2007 +0000
@@ -4,7 +4,7 @@
 #include <linux/kernel.h>
 #include <linux/cpumask.h>
 
-#if defined(CONFIG_X86)
+#if defined(CONFIG_X86) && defined(CONFIG_SMP)
 extern cpumask_t cpu_initialized_map;
 #define cpu_set_initialized(cpu) cpu_set(cpu, cpu_initialized_map)
 #else
diff -r 5a2b3a1b1f63 -r e74bfc744717 linux-2.6-xen-sparse/mm/Kconfig
--- a/linux-2.6-xen-sparse/mm/Kconfig   Fri Dec 15 08:16:56 2006 -0500
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-config SELECT_MEMORY_MODEL
-       def_bool y
-       depends on EXPERIMENTAL || ARCH_SELECT_MEMORY_MODEL
-
-choice
-       prompt "Memory model"
-       depends on SELECT_MEMORY_MODEL
-       default DISCONTIGMEM_MANUAL if ARCH_DISCONTIGMEM_DEFAULT
-       default SPARSEMEM_MANUAL if ARCH_SPARSEMEM_DEFAULT
-       default FLATMEM_MANUAL
-
-config FLATMEM_MANUAL
-       bool "Flat Memory"
-       depends on !(ARCH_DISCONTIGMEM_ENABLE || ARCH_SPARSEMEM_ENABLE) || 
ARCH_FLATMEM_ENABLE
-       help
-         This option allows you to change some of the ways that
-         Linux manages its memory internally.  Most users will
-         only have one option here: FLATMEM.  This is normal
-         and a correct option.
-
-         Some users of more advanced features like NUMA and
-         memory hotplug may have different options here.
-         DISCONTIGMEM is an more mature, better tested system,
-         but is incompatible with memory hotplug and may suffer
-         decreased performance over SPARSEMEM.  If unsure between
-         "Sparse Memory" and "Discontiguous Memory", choose
-         "Discontiguous Memory".
-
-         If unsure, choose this option (Flat Memory) over any other.
-
-config DISCONTIGMEM_MANUAL
-       bool "Discontiguous Memory"
-       depends on ARCH_DISCONTIGMEM_ENABLE
-       help
-         This option provides enhanced support for discontiguous
-         memory systems, over FLATMEM.  These systems have holes
-         in their physical address spaces, and this option provides
-         more efficient handling of these holes.  However, the vast
-         majority of hardware has quite flat address spaces, and
-         can have degraded performance from extra overhead that
-         this option imposes.
-
-         Many NUMA configurations will have this as the only option.
-
-         If unsure, choose "Flat Memory" over this option.
-
-config SPARSEMEM_MANUAL
-       bool "Sparse Memory"
-       depends on ARCH_SPARSEMEM_ENABLE
-       help
-         This will be the only option for some systems, including
-         memory hotplug systems.  This is normal.
-
-         For many other systems, this will be an alternative to
-         "Discontiguous Memory".  This option provides some potential
-         performance benefits, along with decreased code complexity,
-         but it is newer, and more experimental.
-
-         If unsure, choose "Discontiguous Memory" or "Flat Memory"
-         over this option.
-
-endchoice
-
-config DISCONTIGMEM
-       def_bool y
-       depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || 
DISCONTIGMEM_MANUAL
-
-config SPARSEMEM
-       def_bool y
-       depends on SPARSEMEM_MANUAL
-
-config FLATMEM
-       def_bool y
-       depends on (!DISCONTIGMEM && !SPARSEMEM) || FLATMEM_MANUAL
-
-config FLAT_NODE_MEM_MAP
-       def_bool y
-       depends on !SPARSEMEM
-
-#
-# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's
-# to represent different areas of memory.  This variable allows
-# those dependencies to exist individually.
-#
-config NEED_MULTIPLE_NODES
-       def_bool y
-       depends on DISCONTIGMEM || NUMA
-
-config HAVE_MEMORY_PRESENT
-       def_bool y
-       depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM
-
-#
-# SPARSEMEM_EXTREME (which is the default) does some bootmem
-# allocations when memory_present() is called.  If this can not
-# be done on your architecture, select this option.  However,
-# statically allocating the mem_section[] array can potentially
-# consume vast quantities of .bss, so be careful.
-#
-# This option will also potentially produce smaller runtime code
-# with gcc 3.4 and later.
-#
-config SPARSEMEM_STATIC
-       def_bool n
-
-#
-# Architectecture platforms which require a two level mem_section in SPARSEMEM
-# must select this option. This is usually for architecture platforms with
-# an extremely sparse physical address space.
-#
-config SPARSEMEM_EXTREME
-       def_bool y
-       depends on SPARSEMEM && !SPARSEMEM_STATIC
-
-# eventually, we can have this option just 'select SPARSEMEM'
-config MEMORY_HOTPLUG
-       bool "Allow for memory hot-add"
-       depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && 
ARCH_ENABLE_MEMORY_HOTPLUG
-       depends on (IA64 || X86 || PPC64)
-
-comment "Memory hotplug is currently incompatible with Software Suspend"
-       depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
-
-# Heavily threaded applications may benefit from splitting the mm-wide
-# page_table_lock, so that faults on different parts of the user address
-# space can be handled with less contention: split it at this NR_CPUS.
-# Default to 4 for wider testing, though 8 might be more appropriate.
-# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
-# PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes.
-# XEN on x86 architecture uses the mapping field on pagetable pages to store a
-# pointer to the destructor. This conflicts with pte_lock_deinit().
-#
-config SPLIT_PTLOCK_CPUS
-       int
-       default "4096" if ARM && !CPU_CACHE_VIPT
-       default "4096" if PARISC && !PA20
-       default "4096" if X86_XEN || X86_64_XEN
-       default "4"
-
-#
-# support for page migration
-#
-config MIGRATION
-       bool "Page migration"
-       def_bool y
-       depends on NUMA
-       help
-         Allows the migration of the physical location of pages of processes
-         while the virtual addresses are not changed. This is useful for
-         example on NUMA systems to put pages nearer to the processors 
accessing
-         the page.
-
-config RESOURCES_64BIT
-       bool "64 bit Memory and IO resources (EXPERIMENTAL)" if (!64BIT && 
EXPERIMENTAL)
-       default 64BIT
-       help
-         This option allows memory and IO resources to be 64 bit.
diff -r 5a2b3a1b1f63 -r e74bfc744717 tools/libxc/xc_dom_core.c
--- a/tools/libxc/xc_dom_core.c Fri Dec 15 08:16:56 2006 -0500
+++ b/tools/libxc/xc_dom_core.c Mon Mar 05 11:14:15 2007 +0000
@@ -721,9 +721,6 @@ int xc_dom_build_image(struct xc_dom_ima
     }
     page_size = XC_DOM_PAGE_SIZE(dom);
 
-    /* 4MB align virtual base address */
-    dom->parms.virt_base &= ~(((uint64_t)1<<22)-1);
-
     /* load kernel */
     if ( xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel",
                               dom->kernel_seg.vstart,
diff -r 5a2b3a1b1f63 -r e74bfc744717 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Fri Dec 15 08:16:56 2006 -0500
+++ b/tools/libxc/xc_linux_restore.c    Mon Mar 05 11:14:15 2007 +0000
@@ -19,7 +19,7 @@ static unsigned long max_mfn;
 /* virtual starting address of the hypervisor */
 static unsigned long hvirt_start;
 
-/* #levels of page tables used by the currrent guest */
+/* #levels of page tables used by the current guest */
 static unsigned int pt_levels;
 
 /* total number of pages used by the current guest */
@@ -857,6 +857,28 @@ int xc_linux_restore(int xc_handle, int 
 
         ctxt.ctrlreg[3] = xen_pfn_to_cr3(p2m[pfn]);
 
+        /* Guest pagetable (x86/64) stored in otherwise-unused CR1. */
+        if ( (pt_levels == 4) && ctxt.ctrlreg[1] )
+        {
+            pfn = xen_cr3_to_pfn(ctxt.ctrlreg[1]);
+
+            if (pfn >= max_pfn) {
+                ERROR("User PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
+                      pfn, max_pfn, pfn_type[pfn]);
+                goto out;
+            }
+
+            if ( (pfn_type[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) !=
+                 ((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) {
+                ERROR("User PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
+                      pfn, max_pfn, pfn_type[pfn],
+                      (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
+                goto out;
+            }
+
+            ctxt.ctrlreg[1] = xen_pfn_to_cr3(p2m[pfn]);
+        }
+
         domctl.cmd = XEN_DOMCTL_setvcpucontext;
         domctl.domain = (domid_t)dom;
         domctl.u.vcpucontext.vcpu = i;
diff -r 5a2b3a1b1f63 -r e74bfc744717 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Fri Dec 15 08:16:56 2006 -0500
+++ b/tools/libxc/xc_linux_save.c       Mon Mar 05 11:14:15 2007 +0000
@@ -34,7 +34,7 @@ static unsigned long max_mfn;
 /* virtual starting address of the hypervisor */
 static unsigned long hvirt_start;
 
-/* #levels of page tables used by the currrent guest */
+/* #levels of page tables used by the current guest */
 static unsigned int pt_levels;
 
 /* total number of pages used by the current guest */
@@ -491,7 +491,7 @@ static int canonicalize_pagetable(unsign
     ** reserved hypervisor mappings. This depends on the current
     ** page table type as well as the number of paging levels.
     */
-    xen_start = xen_end = pte_last = PAGE_SIZE / ((pt_levels == 2)? 4 : 8);
+    xen_start = xen_end = pte_last = PAGE_SIZE / ((pt_levels == 2) ? 4 : 8);
 
     if (pt_levels == 2 && type == XEN_DOMCTL_PFINFO_L2TAB)
         xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT);
@@ -1279,6 +1279,18 @@ int xc_linux_save(int xc_handle, int io_
         ctxt.ctrlreg[3] = 
             xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3])));
 
+        /* Guest pagetable (x86/64) stored in otherwise-unused CR1. */
+        if ( (pt_levels == 4) && ctxt.ctrlreg[1] )
+        {
+            if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn(ctxt.ctrlreg[1])) ) {
+                ERROR("PT base is not in range of pseudophys map");
+                goto out;
+            }
+            /* Least-significant bit means 'valid PFN'. */
+            ctxt.ctrlreg[1] = 1 |
+                xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[1])));
+        }
+
         if (!write_exact(io_fd, &ctxt, sizeof(ctxt))) {
             ERROR("Error when writing to state file (1) (errno %d)", errno);
             goto out;
diff -r 5a2b3a1b1f63 -r e74bfc744717 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Dec 15 08:16:56 2006 -0500
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Mar 05 11:14:15 2007 +0000
@@ -1503,7 +1503,7 @@ class XendDomainInfo:
             self.info['start_time'] = time.time()
 
             self._stateSet(DOM_STATE_RUNNING)
-        except RuntimeError, exn:
+        except (RuntimeError, VmError), exn:
             log.exception("XendDomainInfo.initDomain: exception occurred")
             self.image.cleanupBootloading()
             raise VmError(str(exn))
diff -r 5a2b3a1b1f63 -r e74bfc744717 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Fri Dec 15 08:16:56 2006 -0500
+++ b/tools/python/xen/xend/XendNode.py Mon Mar 05 11:14:15 2007 +0000
@@ -97,6 +97,10 @@ class XendNode:
         for u in self.cpus.keys():
             log.error(self.cpus[u])
             number = self.cpus[u]['number']
+            # We can run off the end of the cpuinfo list if domain0 does not
+            # have #vcpus == #pcpus. In that case we just replicate pcpu0 info.
+            if not cpuinfo.has_key(number):
+                number = 0
             log.error(number)
             log.error(cpuinfo)
             self.cpus[u].update(
diff -r 5a2b3a1b1f63 -r e74bfc744717 tools/xenfb/xenfb.c
--- a/tools/xenfb/xenfb.c       Fri Dec 15 08:16:56 2006 -0500
+++ b/tools/xenfb/xenfb.c       Mon Mar 05 11:14:15 2007 +0000
@@ -245,11 +245,10 @@ static int xenfb_wait_for_state(struct x
        unsigned state, dummy;
        char **vec;
 
+       awaited |= 1 << XenbusStateUnknown;
+
        for (;;) {
                state = xenfb_read_state(xsh, dir);
-               if (state < 0)
-                       return -1;
-
                if ((1 << state) & awaited)
                        return state;
 
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/Rules.mk
--- a/xen/Rules.mk      Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/Rules.mk      Mon Mar 05 11:14:15 2007 +0000
@@ -41,8 +41,8 @@ include $(BASEDIR)/arch/$(TARGET_ARCH)/R
 include $(BASEDIR)/arch/$(TARGET_ARCH)/Rules.mk
 
 # Do not depend on auto-generated header files.
-HDRS := $(subst $(BASEDIR)/include/asm-$(TARGET_ARCH)/asm-offsets.h,,$(HDRS))
-HDRS := $(subst $(BASEDIR)/include/xen/compile.h,,$(HDRS))
+AHDRS := $(filter-out %/include/xen/compile.h,$(HDRS))
+HDRS  := $(filter-out %/asm-offsets.h,$(AHDRS))
 
 # Note that link order matters!
 ALL_OBJS-y               += $(BASEDIR)/common/built_in.o
@@ -110,12 +110,12 @@ _clean_%/: FORCE
 %.o: %.c $(HDRS) Makefile
        $(CC) $(CFLAGS) -c $< -o $@
 
-%.o: %.S $(HDRS) Makefile
+%.o: %.S $(AHDRS) Makefile
        $(CC) $(AFLAGS) -c $< -o $@
 
 %.i: %.c $(HDRS) Makefile
        $(CPP) $(CFLAGS) $< -o $@
 
 # -std=gnu{89,99} gets confused by # as an end-of-line comment marker
-%.s: %.S $(HDRS) Makefile
+%.s: %.S $(AHDRS) Makefile
        $(CPP) $(AFLAGS) $< -o $@
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/arch/x86/domain.c     Mon Mar 05 11:14:15 2007 +0000
@@ -641,6 +641,31 @@ int arch_set_info_guest(
             }
 
             v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
+
+#ifdef __x86_64__
+            if ( c.nat->ctrlreg[1] )
+            {
+                cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1]));
+
+                if ( !mfn_valid(cr3_pfn) ||
+                     (paging_mode_refcounts(d)
+                      ? !get_page(mfn_to_page(cr3_pfn), d)
+                      : !get_page_and_type(mfn_to_page(cr3_pfn), d,
+                                           PGT_base_page_table)) )
+                {
+                    cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
+                    v->arch.guest_table = pagetable_null();
+                    if ( paging_mode_refcounts(d) )
+                        put_page(mfn_to_page(cr3_pfn));
+                    else
+                        put_page_and_type(mfn_to_page(cr3_pfn));
+                    destroy_gdt(v);
+                    return -EINVAL;
+                }
+
+                v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
+            }
+#endif
         }
 #ifdef CONFIG_COMPAT
         else
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/arch/x86/domain_build.c       Mon Mar 05 11:14:15 2007 +0000
@@ -374,9 +374,6 @@ int construct_dom0(struct domain *d,
     if ( parms.f_required[0] /* Huh? -- kraxel */ )
             panic("Domain 0 requires an unsupported hypervisor feature.\n");
 
-    /* Align load address to 4MB boundary. */
-    v_start = parms.virt_base & ~((1UL<<22)-1);
-
     /*
      * Why do we need this? The number of page-table frames depends on the 
      * size of the bootstrap address space. But the size of the address space 
@@ -384,6 +381,7 @@ int construct_dom0(struct domain *d,
      * read-only). We have a pair of simultaneous equations in two unknowns, 
      * which we solve by exhaustive search.
      */
+    v_start          = parms.virt_base;
     vkern_start      = parms.virt_kstart;
     vkern_end        = parms.virt_kend;
     vinitrd_start    = round_pgup(vkern_end);
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/arch/x86/domctl.c     Mon Mar 05 11:14:15 2007 +0000
@@ -470,8 +470,15 @@ void arch_get_info_guest(struct vcpu *v,
         c(user_regs.eflags |= v->arch.iopl << 12);
 
         if ( !IS_COMPAT(v->domain) )
+        {
             c.nat->ctrlreg[3] = xen_pfn_to_cr3(
                 pagetable_get_pfn(v->arch.guest_table));
+#ifdef __x86_64__
+            if ( !pagetable_is_null(v->arch.guest_table_user) )
+                c.nat->ctrlreg[1] = xen_pfn_to_cr3(
+                    pagetable_get_pfn(v->arch.guest_table_user));
+#endif
+        }
 #ifdef CONFIG_COMPAT
         else
         {
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/arch/x86/mm/shadow/common.c   Mon Mar 05 11:14:15 2007 +0000
@@ -2912,7 +2912,16 @@ void sh_mark_dirty(struct domain *d, mfn
      * can be called from __hvm_copy during emulation).
      * If the lock isn't held, take it for the duration of the call. */
     do_locking = !shadow_locked_by_me(d);
-    if ( do_locking ) shadow_lock(d);
+    if ( do_locking ) 
+    { 
+        shadow_lock(d);
+        /* Check the mode again with the lock held */ 
+        if ( unlikely(!shadow_mode_log_dirty(d)) )
+        {
+            shadow_unlock(d);
+            return;
+        }
+    }
 
     ASSERT(d->arch.paging.shadow.dirty_bitmap != NULL);
 
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/drivers/acpi/numa.c
--- a/xen/drivers/acpi/numa.c   Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/drivers/acpi/numa.c   Mon Mar 05 11:14:15 2007 +0000
@@ -22,10 +22,6 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  */
-#if 0
-#include <linux/module.h>
-#include <linux/kernel.h>
-#endif
 #include <xen/config.h>
 #include <xen/init.h>
 #include <xen/types.h>
@@ -34,7 +30,6 @@
 #include <xen/numa.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acmacros.h>
-#include <asm/page.h> /* __va() */
 
 #define ACPI_NUMA      0x80000000
 #define _COMPONENT     ACPI_NUMA
@@ -106,7 +101,7 @@ static int __init acpi_parse_slit(unsign
        if (!phys_addr || !size)
                return -EINVAL;
 
-       slit = (struct acpi_table_slit *)__va(phys_addr);
+       slit = (struct acpi_table_slit *)__acpi_map_table(phys_addr, size);
 
        /* downcast just for %llu vs %lu for i386/ia64  */
        localities = (u32) slit->localities;
@@ -159,7 +154,7 @@ static int __init acpi_parse_srat(unsign
        if (!phys_addr || !size)
                return -EINVAL;
 
-       srat = (struct acpi_table_srat *)__va(phys_addr);
+       srat = (struct acpi_table_srat *)__acpi_map_table(phys_addr, size);
 
        return 0;
 }
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/include/acm/acm_hooks.h
--- a/xen/include/acm/acm_hooks.h       Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/include/acm/acm_hooks.h       Mon Mar 05 11:14:15 2007 +0000
@@ -247,12 +247,12 @@ static inline int acm_pre_domctl(struct 
             if (*ssid == NULL) {
                 printk("%s: Warning. Destroying domain without ssid 
pointer.\n", 
                        __func__);
-                domain_rcu_lock(d);
+                rcu_unlock_domain(d);
                 return -EACCES;
             }
             d->ssid = NULL; /* make sure it's not used any more */
              /* no policy-specific hook */
-            domain_rcu_lock(d);
+            rcu_unlock_domain(d);
             ret = 0;
         }
         break;
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/include/public/arch-x86/xen.h
--- a/xen/include/public/arch-x86/xen.h Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/include/public/arch-x86/xen.h Mon Mar 05 11:14:15 2007 +0000
@@ -132,6 +132,7 @@ struct vcpu_guest_context {
     unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
     unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
     unsigned long kernel_ss, kernel_sp;     /* Virtual TSS (only SS1/SP1)   */
+    /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */
     unsigned long ctrlreg[8];               /* CR0-CR7 (control registers)  */
     unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
 #ifdef __i386__
diff -r 5a2b3a1b1f63 -r e74bfc744717 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Fri Dec 15 08:16:56 2006 -0500
+++ b/xen/include/public/xen.h  Mon Mar 05 11:14:15 2007 +0000
@@ -473,26 +473,24 @@ typedef struct shared_info shared_info_t
 #endif
 
 /*
- * Start-of-day memory layout for the initial domain (DOM0):
+ * Start-of-day memory layout:
  *  1. The domain is started within contiguous virtual-memory region.
- *  2. The contiguous region begins and ends on an aligned 4MB boundary.
- *  3. The region start corresponds to the load address of the OS image.
- *     If the load address is not 4MB aligned then the address is rounded down.
- *  4. This the order of bootstrap elements in the initial virtual region:
+ *  2. The contiguous region ends on an aligned 4MB boundary.
+ *  3. This the order of bootstrap elements in the initial virtual region:
  *      a. relocated kernel image
  *      b. initial ram disk              [mod_start, mod_len]
  *      c. list of allocated page frames [mfn_list, nr_pages]
  *      d. start_info_t structure        [register ESI (x86)]
  *      e. bootstrap page tables         [pt_base, CR3 (x86)]
  *      f. bootstrap stack               [register ESP (x86)]
- *  5. Bootstrap elements are packed together, but each is 4kB-aligned.
- *  6. The initial ram disk may be omitted.
- *  7. The list of page frames forms a contiguous 'pseudo-physical' memory
+ *  4. Bootstrap elements are packed together, but each is 4kB-aligned.
+ *  5. The initial ram disk may be omitted.
+ *  6. The list of page frames forms a contiguous 'pseudo-physical' memory
  *     layout for the domain. In particular, the bootstrap virtual-memory
  *     region is a 1:1 mapping to the first section of the pseudo-physical map.
- *  8. All bootstrap elements are mapped read-writable for the guest OS. The
+ *  7. All bootstrap elements are mapped read-writable for the guest OS. The
  *     only exception is the bootstrap page table, which is mapped read-only.
- *  9. There is guaranteed to be at least 512kB padding after the final
+ *  8. There is guaranteed to be at least 512kB padding after the final
  *     bootstrap element. If necessary, the bootstrap virtual region is
  *     extended by an extra 4MB to ensure this.
  */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>