[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] merge



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 5e5ae834095691ec677fcaaf11e9b16fcaeb76ed
# Parent  4e1031ce3bc203badf97c75fa124178e485ca028
# Parent  081b326162bcabd1c1245e16c14c8427f33b1b5e
merge

diff -r 4e1031ce3bc2 -r 5e5ae8340956 .hgignore
--- a/.hgignore Mon Sep 26 17:15:55 2005
+++ b/.hgignore Wed Sep 28 20:06:49 2005
@@ -158,6 +158,7 @@
 ^tools/xenstore/xs_dom0_test$
 ^tools/xenstore/xs_random$
 ^tools/xenstore/xs_stress$
+^tools/xenstore/xs_tdb_dump$
 ^tools/xenstore/xs_test$
 ^tools/xenstore/xs_watch_stress$
 ^tools/xentrace/xenctx$
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Mon Sep 
26 17:15:55 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Wed Sep 
28 20:06:49 2005
@@ -2684,7 +2684,7 @@
 #
 # File systems
 #
-CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
@@ -2913,7 +2913,7 @@
 # CONFIG_KEYS_DEBUG_PROC_KEYS is not set
 CONFIG_SECURITY=y
 # CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=m
+CONFIG_SECURITY_CAPABILITIES=y
 CONFIG_SECURITY_ROOTPLUG=m
 CONFIG_SECURITY_SECLVL=m
 CONFIG_SECURITY_SELINUX=y
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Mon Sep 26 
17:15:55 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Wed Sep 28 
20:06:49 2005
@@ -112,6 +112,10 @@
 
 #ifdef CONFIG_HOTPLUG_CPU
 #include <asm/nmi.h>
+#ifdef CONFIG_SMP
+extern void smp_suspend(void);
+extern void smp_resume(void);
+#endif
 /* We don't actually take CPU down, just spin without interrupts. */
 static inline void play_dead(void)
 {
@@ -120,6 +124,13 @@
                HYPERVISOR_yield();
 
        __flush_tlb_all();
+   /* 
+    * Restore IPI/IRQ mappings before marking online to prevent 
+    * race between pending interrupts and restoration of handler. 
+    */
+#ifdef CONFIG_SMP
+       smp_resume();
+#endif
        cpu_set(smp_processor_id(), cpu_online_map);
 }
 #else
@@ -135,10 +146,6 @@
  * low exit latency (ie sit in a loop waiting for
  * somebody to say that they'd like to reschedule)
  */
-#ifdef CONFIG_SMP
-extern void smp_suspend(void);
-extern void smp_resume(void);
-#endif
 void cpu_idle (void)
 {
        int cpu = _smp_processor_id();
@@ -166,9 +173,6 @@
                                HYPERVISOR_vcpu_down(cpu);
 #endif
                                play_dead();
-#ifdef CONFIG_SMP
-                               smp_resume();
-#endif
                                local_irq_enable();
                        }
 
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c     Mon Sep 26 17:15:55 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c     Wed Sep 28 20:06:49 2005
@@ -209,7 +209,10 @@
 {
        unsigned long *p, page;
 
-        page = __pa(per_cpu(cur_pgd, smp_processor_id()));
+       preempt_disable();
+       page = __pa(per_cpu(cur_pgd, smp_processor_id()));
+       preempt_enable();
+
        p  = (unsigned long *)__va(page);
        p += (address >> 30) * 2;
        printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
@@ -237,7 +240,12 @@
 {
        unsigned long page;
 
+       preempt_disable();
        page = ((unsigned long *) per_cpu(cur_pgd, smp_processor_id()))
+           [address >> 22];
+       preempt_enable();
+
+       page = ((unsigned long *) per_cpu(cur_pgd, get_cpu()))
            [address >> 22];
        printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page,
               machine_to_phys(page));
@@ -567,7 +575,9 @@
                pmd_t *pmd, *pmd_k;
                pte_t *pte_k;
 
+               preempt_disable();
                pgd = index + per_cpu(cur_pgd, smp_processor_id());
+               preempt_enable();
                pgd_k = init_mm.pgd + index;
 
                if (!pgd_present(*pgd_k))
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Mon Sep 26 17:15:55 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Wed Sep 28 20:06:49 2005
@@ -1,13 +1,10 @@
 /******************************************************************************
  * gnttab.c
  * 
- * Two sets of functionality:
- * 1. Granting foreign access to our memory reservation.
- * 2. Accessing others' memory reservations via grant references.
- * (i.e., mechanisms for both sender and recipient of grant references)
+ * Granting foreign access to our memory reservation.
  * 
  * Copyright (c) 2005, Christopher Clark
- * Copyright (c) 2004, K A Fraser
+ * Copyright (c) 2004-2005, K A Fraser
  */
 
 #include <linux/config.h>
@@ -23,15 +20,15 @@
 #include <asm/synch_bitops.h>
 
 #if 1
-#define ASSERT(_p) \
-    if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
-    #_p , __LINE__, __FILE__); *(int*)0=0; }
+#define ASSERT(_p)                                                           \
+       if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
+       #_p , __LINE__, __FILE__); *(int*)0=0; }
 #else
 #define ASSERT(_p) ((void)0)
 #endif
 
-#define WPRINTK(fmt, args...) \
-    printk(KERN_WARNING "xen_grant: " fmt, ##args)
+#define WPRINTK(fmt, args...)                          \
+       printk(KERN_WARNING "xen_grant: " fmt, ##args)
 
 
 EXPORT_SYMBOL(gnttab_grant_foreign_access);
@@ -49,11 +46,14 @@
 EXPORT_SYMBOL(gnttab_grant_foreign_access_ref);
 EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref);
 
+/* External tools reserve first few grant table entries. */
+#define NR_RESERVED_ENTRIES 8
+
 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
 #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
 
 static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
-static int gnttab_free_count = NR_GRANT_ENTRIES;
+static int gnttab_free_count;
 static grant_ref_t gnttab_free_head;
 static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED;
 
@@ -64,22 +64,22 @@
 static int
 get_free_entries(int count)
 {
-    unsigned long flags;
-    int ref;
-    grant_ref_t head;
-    spin_lock_irqsave(&gnttab_list_lock, flags);
-    if (gnttab_free_count < count) {
+       unsigned long flags;
+       int ref;
+       grant_ref_t head;
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+       if (gnttab_free_count < count) {
+               spin_unlock_irqrestore(&gnttab_list_lock, flags);
+               return -1;
+       }
+       ref = head = gnttab_free_head;
+       gnttab_free_count -= count;
+       while (count-- > 1)
+               head = gnttab_list[head];
+       gnttab_free_head = gnttab_list[head];
+       gnttab_list[head] = GNTTAB_LIST_END;
        spin_unlock_irqrestore(&gnttab_list_lock, flags);
-       return -1;
-    }
-    ref = head = gnttab_free_head;
-    gnttab_free_count -= count;
-    while (count-- > 1)
-       head = gnttab_list[head];
-    gnttab_free_head = gnttab_list[head];
-    gnttab_list[head] = GNTTAB_LIST_END;
-    spin_unlock_irqrestore(&gnttab_list_lock, flags);
-    return ref;
+       return ref;
 }
 
 #define get_free_entry() get_free_entries(1)
@@ -87,38 +87,41 @@
 static void
 do_free_callbacks(void)
 {
-    struct gnttab_free_callback *callback = gnttab_free_callback_list, *next;
-    gnttab_free_callback_list = NULL;
-    while (callback) {
-       next = callback->next;
-       if (gnttab_free_count >= callback->count) {
-           callback->next = NULL;
-           callback->fn(callback->arg);
-       } else {
-           callback->next = gnttab_free_callback_list;
-           gnttab_free_callback_list = callback;
-       }
-       callback = next;
-    }
+       struct gnttab_free_callback *callback, *next;
+
+       callback = gnttab_free_callback_list;
+       gnttab_free_callback_list = NULL;
+
+       while (callback != NULL) {
+               next = callback->next;
+               if (gnttab_free_count >= callback->count) {
+                       callback->next = NULL;
+                       callback->fn(callback->arg);
+               } else {
+                       callback->next = gnttab_free_callback_list;
+                       gnttab_free_callback_list = callback;
+               }
+               callback = next;
+       }
 }
 
 static inline void
 check_free_callbacks(void)
 {
-    if (unlikely(gnttab_free_callback_list))
-       do_free_callbacks();
+       if (unlikely(gnttab_free_callback_list))
+               do_free_callbacks();
 }
 
 static void
 put_free_entry(grant_ref_t ref)
 {
-    unsigned long flags;
-    spin_lock_irqsave(&gnttab_list_lock, flags);
-    gnttab_list[ref] = gnttab_free_head;
-    gnttab_free_head = ref;
-    gnttab_free_count++;
-    check_free_callbacks();
-    spin_unlock_irqrestore(&gnttab_list_lock, flags);
+       unsigned long flags;
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+       gnttab_list[ref] = gnttab_free_head;
+       gnttab_free_head = ref;
+       gnttab_free_count++;
+       check_free_callbacks();
+       spin_unlock_irqrestore(&gnttab_list_lock, flags);
 }
 
 /*
@@ -128,187 +131,189 @@
 int
 gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
 {
-    int ref;
+       int ref;
     
-    if ( unlikely((ref = get_free_entry()) == -1) )
-        return -ENOSPC;
-
-    shared[ref].frame = frame;
-    shared[ref].domid = domid;
-    wmb();
-    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
-
-    return ref;
+       if (unlikely((ref = get_free_entry()) == -1))
+               return -ENOSPC;
+
+       shared[ref].frame = frame;
+       shared[ref].domid = domid;
+       wmb();
+       shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
+
+       return ref;
 }
 
 void
 gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
                                unsigned long frame, int readonly)
 {
-    shared[ref].frame = frame;
-    shared[ref].domid = domid;
-    wmb();
-    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
+       shared[ref].frame = frame;
+       shared[ref].domid = domid;
+       wmb();
+       shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
 }
 
 
 int
 gnttab_query_foreign_access(grant_ref_t ref)
 {
-    u16 nflags;
-
-    nflags = shared[ref].flags;
-
-    return ( nflags & (GTF_reading|GTF_writing) );
+       u16 nflags;
+
+       nflags = shared[ref].flags;
+
+       return (nflags & (GTF_reading|GTF_writing));
 }
 
 void
 gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
 {
-    u16 flags, nflags;
-
-    nflags = shared[ref].flags;
-    do {
-        if ( (flags = nflags) & (GTF_reading|GTF_writing) )
-            printk(KERN_ALERT "WARNING: g.e. still in use!\n");
-    }
-    while ( (nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != flags );
+       u16 flags, nflags;
+
+       nflags = shared[ref].flags;
+       do {
+               if ( (flags = nflags) & (GTF_reading|GTF_writing) )
+                       printk(KERN_ALERT "WARNING: g.e. still in use!\n");
+       }
+       while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
+              flags);
 }
 
 void
 gnttab_end_foreign_access(grant_ref_t ref, int readonly)
 {
-    gnttab_end_foreign_access_ref(ref, readonly);
-    put_free_entry(ref);
+       gnttab_end_foreign_access_ref(ref, readonly);
+       put_free_entry(ref);
 }
 
 int
 gnttab_grant_foreign_transfer(domid_t domid)
 {
-    int ref;
-
-    if ( unlikely((ref = get_free_entry()) == -1) )
-        return -ENOSPC;
-
-    shared[ref].frame = 0;
-    shared[ref].domid = domid;
-    wmb();
-    shared[ref].flags = GTF_accept_transfer;
-
-    return ref;
+       int ref;
+
+       if (unlikely((ref = get_free_entry()) == -1))
+               return -ENOSPC;
+
+       shared[ref].frame = 0;
+       shared[ref].domid = domid;
+       wmb();
+       shared[ref].flags = GTF_accept_transfer;
+
+       return ref;
 }
 
 void
 gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid)
 {
-    shared[ref].frame = 0;
-    shared[ref].domid = domid;
-    wmb();
-    shared[ref].flags = GTF_accept_transfer;
+       shared[ref].frame = 0;
+       shared[ref].domid = domid;
+       wmb();
+       shared[ref].flags = GTF_accept_transfer;
 }
 
 unsigned long
 gnttab_end_foreign_transfer_ref(grant_ref_t ref)
 {
-    unsigned long frame = 0;
-    u16           flags;
-
-    flags = shared[ref].flags;
-
-    /*
-     * If a transfer is committed then wait for the frame address to appear.
-     * Otherwise invalidate the grant entry against future use.
-     */
-    if ( likely(flags != GTF_accept_transfer) ||
-         (synch_cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) )
-        while ( unlikely((frame = shared[ref].frame) == 0) )
-            cpu_relax();
-
-    return frame;
+       unsigned long frame = 0;
+       u16           flags;
+
+       flags = shared[ref].flags;
+
+       /*
+        * If a transfer is committed then wait for the frame address to
+        * appear. Otherwise invalidate the grant entry against future use.
+        */
+       if (likely(flags != GTF_accept_transfer) ||
+           (synch_cmpxchg(&shared[ref].flags, flags, 0) !=
+            GTF_accept_transfer))
+               while (unlikely((frame = shared[ref].frame) == 0))
+                       cpu_relax();
+
+       return frame;
 }
 
 unsigned long
 gnttab_end_foreign_transfer(grant_ref_t ref)
 {
-    unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
-    put_free_entry(ref);
-    return frame;
+       unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
+       put_free_entry(ref);
+       return frame;
 }
 
 void
 gnttab_free_grant_reference(grant_ref_t ref)
 {
 
-    put_free_entry(ref);
+       put_free_entry(ref);
 }
 
 void
 gnttab_free_grant_references(grant_ref_t head)
 {
-    grant_ref_t ref;
-    unsigned long flags;
-    int count = 1;
-    if (head == GNTTAB_LIST_END)
-       return;
-    spin_lock_irqsave(&gnttab_list_lock, flags);
-    ref = head;
-    while (gnttab_list[ref] != GNTTAB_LIST_END) {
-       ref = gnttab_list[ref];
-       count++;
-    }
-    gnttab_list[ref] = gnttab_free_head;
-    gnttab_free_head = head;
-    gnttab_free_count += count;
-    check_free_callbacks();
-    spin_unlock_irqrestore(&gnttab_list_lock, flags);
+       grant_ref_t ref;
+       unsigned long flags;
+       int count = 1;
+       if (head == GNTTAB_LIST_END)
+               return;
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+       ref = head;
+       while (gnttab_list[ref] != GNTTAB_LIST_END) {
+               ref = gnttab_list[ref];
+               count++;
+       }
+       gnttab_list[ref] = gnttab_free_head;
+       gnttab_free_head = head;
+       gnttab_free_count += count;
+       check_free_callbacks();
+       spin_unlock_irqrestore(&gnttab_list_lock, flags);
 }
 
 int
 gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
 {
-    int h = get_free_entries(count);
-
-    if (h == -1)
-       return -ENOSPC;
-
-    *head = h;
-
-    return 0;
+       int h = get_free_entries(count);
+
+       if (h == -1)
+               return -ENOSPC;
+
+       *head = h;
+
+       return 0;
 }
 
 int
 gnttab_claim_grant_reference(grant_ref_t *private_head)
 {
-    grant_ref_t g = *private_head;
-    if (unlikely(g == GNTTAB_LIST_END))
-        return -ENOSPC;
-    *private_head = gnttab_list[g];
-    return g;
+       grant_ref_t g = *private_head;
+       if (unlikely(g == GNTTAB_LIST_END))
+               return -ENOSPC;
+       *private_head = gnttab_list[g];
+       return g;
 }
 
 void
 gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t  release)
 {
-    gnttab_list[release] = *private_head;
-    *private_head = release;
+       gnttab_list[release] = *private_head;
+       *private_head = release;
 }
 
 void
 gnttab_request_free_callback(struct gnttab_free_callback *callback,
                             void (*fn)(void *), void *arg, u16 count)
 {
-    unsigned long flags;
-    spin_lock_irqsave(&gnttab_list_lock, flags);
-    if (callback->next)
-       goto out;
-    callback->fn = fn;
-    callback->arg = arg;
-    callback->count = count;
-    callback->next = gnttab_free_callback_list;
-    gnttab_free_callback_list = callback;
-    check_free_callbacks();
+       unsigned long flags;
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+       if (callback->next)
+               goto out;
+       callback->fn = fn;
+       callback->arg = arg;
+       callback->count = count;
+       callback->next = gnttab_free_callback_list;
+       gnttab_free_callback_list = callback;
+       check_free_callbacks();
  out:
-    spin_unlock_irqrestore(&gnttab_list_lock, flags);
+       spin_unlock_irqrestore(&gnttab_list_lock, flags);
 }
 
 /*
@@ -323,79 +328,83 @@
 grant_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
            unsigned long data)
 {
-    int                     ret;
-    privcmd_hypercall_t     hypercall;
-
-    /* XXX Need safety checks here if using for anything other
-     *     than debugging */
-    return -ENOSYS;
-
-    if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
-        return -ENOSYS;
-
-    if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
-        return -EFAULT;
-
-    if ( hypercall.op != __HYPERVISOR_grant_table_op )
-        return -ENOSYS;
-
-    /* hypercall-invoking asm taken from privcmd.c */
-    __asm__ __volatile__ (
-        "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
-        "movl  4(%%eax),%%ebx ;"
-        "movl  8(%%eax),%%ecx ;"
-        "movl 12(%%eax),%%edx ;"
-        "movl 16(%%eax),%%esi ;"
-        "movl 20(%%eax),%%edi ;"
-        "movl   (%%eax),%%eax ;"
-        TRAP_INSTR "; "
-        "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
-        : "=a" (ret) : "0" (&hypercall) : "memory" );
-
-    return ret;
+       int                     ret;
+       privcmd_hypercall_t     hypercall;
+
+       /*
+        * XXX Need safety checks here if using for anything other
+        *     than debugging.
+        */
+       return -ENOSYS;
+
+       if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
+               return -ENOSYS;
+
+       if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
+               return -EFAULT;
+
+       if ( hypercall.op != __HYPERVISOR_grant_table_op )
+               return -ENOSYS;
+
+       /* hypercall-invoking asm taken from privcmd.c */
+       __asm__ __volatile__ (
+               "pushl %%ebx; pushl %%ecx; pushl %%edx; "
+               "pushl %%esi; pushl %%edi; "
+               "movl  4(%%eax),%%ebx ;"
+               "movl  8(%%eax),%%ecx ;"
+               "movl 12(%%eax),%%edx ;"
+               "movl 16(%%eax),%%esi ;"
+               "movl 20(%%eax),%%edi ;"
+               "movl   (%%eax),%%eax ;"
+               TRAP_INSTR "; "
+               "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
+               : "=a" (ret) : "0" (&hypercall) : "memory" );
+
+       return ret;
 }
 
 static struct file_operations grant_file_ops = {
-    ioctl:  grant_ioctl,
+       ioctl:  grant_ioctl,
 };
 
 static int
 grant_read(char *page, char **start, off_t off, int count, int *eof,
           void *data)
 {
-    int             len;
-    unsigned int    i;
-    grant_entry_t  *gt;
-
-    gt = (grant_entry_t *)shared;
-    len = 0;
-
-    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
-        /* TODO: safety catch here until this can handle >PAGE_SIZE output */
-        if (len > (PAGE_SIZE - 200))
-        {
-            len += sprintf( page + len, "Truncated.\n");
-            break;
-        }
-
-        if ( gt[i].flags )
-            len += sprintf( page + len,
-                    "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame 
(0x%x)\n", 
-                    i,
-                    gt[i].flags,
-                    gt[i].domid,
-                    gt[i].frame );
-
-    *eof = 1;
-    return len;
+       int             len;
+       unsigned int    i;
+       grant_entry_t  *gt;
+
+       gt = (grant_entry_t *)shared;
+       len = 0;
+
+       for (i = 0; i < NR_GRANT_ENTRIES; i++) {
+               if (len > (PAGE_SIZE - 200)) {
+                       len += sprintf( page + len, "Truncated.\n");
+                       break;
+               }
+       }
+
+       if (gt[i].flags) {
+               len += sprintf(page + len,
+                              "Grant: ref (0x%x) flags (0x%hx) "
+                              "dom (0x%hx) frame (0x%x)\n", 
+                              i,
+                              gt[i].flags,
+                              gt[i].domid,
+                              gt[i].frame );
+       }
+
+       *eof = 1;
+       return len;
 }
 
 static int
 grant_write(struct file *file, const char __user *buffer, unsigned long count,
            void *data)
 {
-    /* TODO: implement this */
-    return -ENOSYS;
+       /* TODO: implement this */
+       return -ENOSYS;
 }
 
 #endif /* CONFIG_PROC_FS */
@@ -403,70 +412,81 @@
 int
 gnttab_resume(void)
 {
-    gnttab_setup_table_t setup;
-    unsigned long        frames[NR_GRANT_FRAMES];
-    int                  i;
-
-    setup.dom        = DOMID_SELF;
-    setup.nr_frames  = NR_GRANT_FRAMES;
-    setup.frame_list = frames;
-
-    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0);
-    BUG_ON(setup.status != 0);
-
-    for ( i = 0; i < NR_GRANT_FRAMES; i++ )
-        set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
-
-    return 0;
+       gnttab_setup_table_t setup;
+       unsigned long        frames[NR_GRANT_FRAMES];
+       int                  i;
+
+       setup.dom        = DOMID_SELF;
+       setup.nr_frames  = NR_GRANT_FRAMES;
+       setup.frame_list = frames;
+
+       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
+       BUG_ON(setup.status != 0);
+
+       for (i = 0; i < NR_GRANT_FRAMES; i++)
+               set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
+
+       return 0;
 }
 
 int
 gnttab_suspend(void)
 {
-    int i;
-
-    for ( i = 0; i < NR_GRANT_FRAMES; i++ )
-       clear_fixmap(FIX_GNTTAB_END - i);
-
-    return 0;
+       int i;
+
+       for (i = 0; i < NR_GRANT_FRAMES; i++)
+               clear_fixmap(FIX_GNTTAB_END - i);
+
+       return 0;
 }
 
 static int __init
 gnttab_init(void)
 {
-    int i;
-
-    if (xen_init() < 0)
-        return -ENODEV;
-
-    BUG_ON(gnttab_resume());
-
-    shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
-
-    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
-        gnttab_list[i] = i + 1;
-    
+       int i;
+
+       if (xen_init() < 0)
+               return -ENODEV;
+
+       BUG_ON(gnttab_resume());
+
+       shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
+
+       for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
+               gnttab_list[i] = i + 1;
+       gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
+       gnttab_free_head  = NR_RESERVED_ENTRIES;
+
 #ifdef CONFIG_PROC_FS
-    /*
-     *  /proc/xen/grant : used by libxc to access grant tables
-     */
-    if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL )
-    {
-        WPRINTK("Unable to create grant xen proc entry\n");
-        return -1;
-    }
-
-    grant_file_ops.read   = grant_pde->proc_fops->read;
-    grant_file_ops.write  = grant_pde->proc_fops->write;
-
-    grant_pde->proc_fops  = &grant_file_ops;
-
-    grant_pde->read_proc  = &grant_read;
-    grant_pde->write_proc = &grant_write;
+       /*
+        *  /proc/xen/grant : used by libxc to access grant tables
+        */
+       if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
+               WPRINTK("Unable to create grant xen proc entry\n");
+               return -1;
+       }
+
+       grant_file_ops.read   = grant_pde->proc_fops->read;
+       grant_file_ops.write  = grant_pde->proc_fops->write;
+
+       grant_pde->proc_fops  = &grant_file_ops;
+
+       grant_pde->read_proc  = &grant_read;
+       grant_pde->write_proc = &grant_write;
 #endif
 
-    printk("Grant table initialized\n");
-    return 0;
+       printk("Grant table initialized\n");
+       return 0;
 }
 
 __initcall(gnttab_init);
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c   Mon Sep 26 17:15:55 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c   Wed Sep 28 20:06:49 2005
@@ -149,7 +149,9 @@
        pmd_t *pmd;
        pte_t *pte;
 
+       preempt_disable();
        pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
+       preempt_enable();
        pgd += pgd_index(address);
 
        printk("PGD %lx ", pgd_val(*pgd));
@@ -252,7 +254,9 @@
 
        /* On Xen the line below does not always work. Needs investigating! */
        /*pgd = pgd_offset(current->mm ?: &init_mm, address);*/
+       preempt_disable();
        pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
+       preempt_enable();
        pgd += pgd_index(address);
 
        pgd_ref = pgd_offset_k(address);
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Mon Sep 26 17:15:55 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Sep 28 20:06:49 2005
@@ -80,6 +80,15 @@
                return;
        }
 
+       /* Map the shared frame, irq etc. */
+       err = blkif_map(be->blkif, ring_ref, evtchn);
+       if (err) {
+               xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
+                                ring_ref, evtchn);
+               return;
+       }
+       /* XXX From here on should 'blkif_unmap' on error. */
+
 again:
        /* Supply the information about the device the frontend needs */
        err = xenbus_transaction_start();
@@ -109,14 +118,6 @@
        if (err) {
                xenbus_dev_error(be->dev, err, "writing %s/sector-size",
                                 be->dev->nodename);
-               goto abort;
-       }
-
-       /* Map the shared frame, irq etc. */
-       err = blkif_map(be->blkif, ring_ref, evtchn);
-       if (err) {
-               xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
-                                ring_ref, evtchn);
                goto abort;
        }
 
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Mon Sep 26 
17:15:55 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Wed Sep 28 
20:06:49 2005
@@ -57,10 +57,7 @@
 
 #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
     (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
-#define GRANTREF_INVALID (1<<15)
-#define GRANT_INVALID_REF      (0xFFFF)
-
-static int recovery = 0; /* Recovery in progress: protected by blkif_io_lock */
+#define GRANT_INVALID_REF      0
 
 static void kick_pending_request_queues(struct blkfront_info *info);
 
@@ -82,18 +79,6 @@
        info->shadow[id].req.id  = info->shadow_free;
        info->shadow[id].request = 0;
        info->shadow_free = id;
-}
-
-static inline void pickle_request(struct blk_shadow *s, blkif_request_t *r)
-{
-
-       s->req = *r;
-}
-
-static inline void unpickle_request(blkif_request_t *r, struct blk_shadow *s)
-{
-
-       *r = s->req;
 }
 
 static inline void flush_requests(struct blkfront_info *info)
@@ -235,7 +220,7 @@
                                rq_data_dir(req) );
 
                        info->shadow[id].frame[ring_req->nr_segments] =
-                               buffer_mfn;
+                               mfn_to_pfn(buffer_mfn);
 
                        ring_req->frame_and_sects[ring_req->nr_segments] =
                                blkif_fas_from_gref(ref, fsect, lsect);
@@ -247,7 +232,7 @@
        info->ring.req_prod_pvt++;
 
        /* Keep a private copy so we can reissue requests when recovering. */
-       pickle_request(&info->shadow[id], ring_req);
+       info->shadow[id].req = *ring_req;
 
        gnttab_free_grant_references(gref_head);
 
@@ -312,7 +297,7 @@
 
        spin_lock_irqsave(&blkif_io_lock, flags);
 
-       if (unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery)) {
+       if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
                spin_unlock_irqrestore(&blkif_io_lock, flags);
                return IRQ_HANDLED;
        }
@@ -401,36 +386,30 @@
                if (copy[i].request == 0)
                        continue;
 
-               /* Grab a request slot and unpickle shadow state into it. */
+               /* Grab a request slot and copy shadow state into it. */
                req = RING_GET_REQUEST(
                        &info->ring, info->ring.req_prod_pvt);
-               unpickle_request(req, &copy[i]);
+               *req = copy[i].req;
 
                /* We get a new request id, and must reset the shadow state. */
                req->id = GET_ID_FROM_FREELIST(info);
                memcpy(&info->shadow[req->id], &copy[i], sizeof(copy[i]));
 
                /* Rewrite any grant references invalidated by susp/resume. */
-               for (j = 0; j < req->nr_segments; j++) {
-                       if ( req->frame_and_sects[j] & GRANTREF_INVALID )
-                               gnttab_grant_foreign_access_ref(
-                                       blkif_gref_from_fas(
-                                               req->frame_and_sects[j]),
-                                       info->backend_id,
-                                       info->shadow[req->id].frame[j],
-                                       rq_data_dir(
-                                               (struct request *)
-                                               info->shadow[req->id].request));
-                       req->frame_and_sects[j] &= ~GRANTREF_INVALID;
-               }
+               for (j = 0; j < req->nr_segments; j++)
+                       gnttab_grant_foreign_access_ref(
+                               blkif_gref_from_fas(req->frame_and_sects[j]),
+                               info->backend_id,
+                               pfn_to_mfn(info->shadow[req->id].frame[j]),
+                               rq_data_dir(
+                                       (struct request *)
+                                       info->shadow[req->id].request));
                info->shadow[req->id].req = *req;
 
                info->ring.req_prod_pvt++;
        }
 
        kfree(copy);
-
-       recovery = 0;
 
        /* info->ring->req_prod will be set when we flush_requests().*/
        wmb();
@@ -438,7 +417,7 @@
        /* Kicks things back into life. */
        flush_requests(info);
 
-       /* Now safe to left other people use the interface. */
+       /* Now safe to let other people use the interface. */
        info->connected = BLKIF_STATE_CONNECTED;
 }
 
@@ -591,17 +570,6 @@
                goto abort_transaction;
        }
 
-       info->backend = backend;
-       backend = NULL;
-
-       info->watch.node = info->backend;
-       info->watch.callback = watch_for_status;
-       err = register_xenbus_watch(&info->watch);
-       if (err) {
-               message = "registering watch on backend";
-               goto abort_transaction;
-       }
-
        err = xenbus_transaction_end(0);
        if (err) {
                if (err == -EAGAIN)
@@ -610,10 +578,17 @@
                goto destroy_blkring;
        }
 
- out:
-       if (backend)
-               kfree(backend);
-       return err;
+       info->watch.node = backend;
+       info->watch.callback = watch_for_status;
+       err = register_xenbus_watch(&info->watch);
+       if (err) {
+               message = "registering watch on backend";
+               goto destroy_blkring;
+       }
+
+       info->backend = backend;
+
+       return 0;
 
  abort_transaction:
        xenbus_transaction_end(1);
@@ -621,7 +596,10 @@
        xenbus_dev_error(dev, err, "%s", message);
  destroy_blkring:
        blkif_free(info);
-       goto out;
+ out:
+       if (backend)
+               kfree(backend);
+       return err;
 }
 
 /* Setup supplies the backend dir, virtual device.
@@ -702,7 +680,6 @@
        kfree(info->backend);
        info->backend = NULL;
 
-       recovery = 1;
        blkif_free(info);
 
        return 0;
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Mon Sep 26 17:15:55 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Sep 28 20:06:49 2005
@@ -21,8 +21,6 @@
 #include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/gnttab.h>
 #include <asm-xen/driver_util.h>
-
-#define GRANT_INVALID_REF (0xFFFF)
 
 #if 0
 #define ASSERT(_p) \
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon Sep 26 
17:15:55 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Sep 28 
20:06:49 2005
@@ -434,7 +434,6 @@
                gop->host_addr    = MMAP_VADDR(pending_idx);
                gop->dev_bus_addr = 0;
                gop->handle       = grant_tx_ref[pending_idx];
-               grant_tx_ref[pending_idx] = GRANT_INVALID_REF;
                gop++;
        }
        BUG_ON(HYPERVISOR_grant_table_op(
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Mon Sep 26 
17:15:55 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Sep 28 
20:06:49 2005
@@ -1,7 +1,7 @@
 /******************************************************************************
  * Virtual network driver for conversing with remote driver backends.
  * 
- * Copyright (c) 2002-2004, K A Fraser
+ * Copyright (c) 2002-2005, K A Fraser
  * 
  * This file may be distributed separately from the Linux kernel, or
  * incorporated into other software packages, subject to the following license:
@@ -57,7 +57,7 @@
 #include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/gnttab.h>
 
-#define GRANT_INVALID_REF      (0xFFFF)
+#define GRANT_INVALID_REF      0
 
 #ifndef __GFP_NOWARN
 #define __GFP_NOWARN 0
@@ -700,6 +700,7 @@
        struct net_private *np;
        int i, requeue_idx;
        netif_tx_request_t *tx;
+       struct sk_buff *skb;
 
        np = netdev_priv(dev);
        spin_lock_irq(&np->tx_lock);
@@ -711,7 +712,8 @@
        np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
        np->rx->event = np->tx->event = 1;
 
-       /* Step 2: Rebuild the RX and TX ring contents.
+       /*
+        * Step 2: Rebuild the RX and TX ring contents.
         * NB. We could just free the queued TX packets now but we hope
         * that sending them out might do some good.  We have to rebuild
         * the RX ring because some of our pages are currently flipped out
@@ -722,49 +724,52 @@
         * them.
         */
 
-       /* Rebuild the TX buffer freelist and the TX ring itself.
+       /*
+        * Rebuild the TX buffer freelist and the TX ring itself.
         * NB. This reorders packets.  We could keep more private state
         * to avoid this but maybe it doesn't matter so much given the
         * interface has been down.
         */
        for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) {
-               if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) {
-                       struct sk_buff *skb = np->tx_skbs[i];
-
-                       tx = &np->tx->ring[requeue_idx++].req;
-
-                       tx->id   = i;
-                       gnttab_grant_foreign_access_ref(
-                               np->grant_tx_ref[i], np->backend_id, 
-                               virt_to_mfn(np->tx_skbs[i]->data),
-                               GNTMAP_readonly); 
-                       tx->gref = np->grant_tx_ref[i];
-                       tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
-                       tx->size = skb->len;
-
-                       np->stats.tx_bytes += skb->len;
-                       np->stats.tx_packets++;
-               }
+               if ((unsigned long)np->tx_skbs[i] < __PAGE_OFFSET)
+                       continue;
+
+               skb = np->tx_skbs[i];
+
+               tx = &np->tx->ring[requeue_idx++].req;
+
+               tx->id = i;
+               gnttab_grant_foreign_access_ref(
+                       np->grant_tx_ref[i], np->backend_id, 
+                       virt_to_mfn(np->tx_skbs[i]->data),
+                       GNTMAP_readonly); 
+               tx->gref = np->grant_tx_ref[i];
+               tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
+               tx->size = skb->len;
+               tx->csum_blank = (skb->ip_summed == CHECKSUM_HW);
+
+               np->stats.tx_bytes += skb->len;
+               np->stats.tx_packets++;
        }
        wmb();
        np->tx->req_prod = requeue_idx;
 
        /* Rebuild the RX buffer freelist and the RX ring itself. */
        for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) { 
-               if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) {
-                       gnttab_grant_foreign_transfer_ref(
-                               np->grant_rx_ref[i], np->backend_id);
-                       np->rx->ring[requeue_idx].req.gref =
-                               np->grant_rx_ref[i];
-                       np->rx->ring[requeue_idx].req.id = i;
-                       requeue_idx++; 
-               }
-       }
-
+               if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
+                       continue;
+               gnttab_grant_foreign_transfer_ref(
+                       np->grant_rx_ref[i], np->backend_id);
+               np->rx->ring[requeue_idx].req.gref =
+                       np->grant_rx_ref[i];
+               np->rx->ring[requeue_idx].req.id = i;
+               requeue_idx++; 
+       }
        wmb();                
        np->rx->req_prod = requeue_idx;
 
-       /* Step 3: All public and private state should now be sane.  Get
+       /*
+        * Step 3: All public and private state should now be sane.  Get
         * ready to start sending and receiving packets and give the driver
         * domain a kick because we've probably just requeued some
         * packets.
@@ -798,7 +803,8 @@
 #endif
 }
 
-/* Move the vif into connected state.
+/*
+ * Move the vif into connected state.
  * Sets the mac and event channel from the message.
  * Binds the irq to the event channel.
  */
@@ -1053,8 +1059,7 @@
        info->evtchn = 0;
 }
 
-/* Stop network device and free tx/rx queues and irq.
- */
+/* Stop network device and free tx/rx queues and irq. */
 static void shutdown_device(struct net_private *np)
 {
        /* Stop old i/f to prevent errors whilst we rebuild the state. */
@@ -1148,17 +1153,6 @@
                goto abort_transaction;
        }
 
-       info->backend = backend;
-       backend = NULL;
-
-       info->watch.node = info->backend;
-       info->watch.callback = watch_for_status;
-       err = register_xenbus_watch(&info->watch);
-       if (err) {
-               message = "registering watch on backend";
-               goto abort_transaction;
-       }
-
        err = xenbus_transaction_end(0);
        if (err) {
                if (err == -EAGAIN)
@@ -1167,12 +1161,19 @@
                goto destroy_ring;
        }
 
+       info->watch.node = backend;
+       info->watch.callback = watch_for_status;
+       err = register_xenbus_watch(&info->watch);
+       if (err) {
+               message = "registering watch on backend";
+               goto destroy_ring;
+       }
+
+       info->backend = backend;
+
        netif_state = NETIF_STATE_CONNECTED;
 
- out:
-       if (backend)
-               kfree(backend);
-       return err;
+       return 0;
 
  abort_transaction:
        xenbus_transaction_end(1);
@@ -1180,13 +1181,17 @@
        xenbus_dev_error(dev, err, "%s", message);
  destroy_ring:
        shutdown_device(info);
-       goto out;
-}
-
-/* Setup supplies the backend dir, virtual device.
-
-   We place an event channel and shared frame entries.
-   We watch backend to wait if it's ok. */
+ out:
+       if (backend)
+               kfree(backend);
+       return err;
+}
+
+/*
+ * Setup supplies the backend dir, virtual device.
+ * We place an event channel and shared frame entries.
+ * We watch backend to wait if it's ok.
+ */
 static int netfront_probe(struct xenbus_device *dev,
                          const struct xenbus_device_id *id)
 {
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Mon Sep 26 17:15:55 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Wed Sep 28 20:06:49 2005
@@ -88,6 +88,26 @@
                return;
        }
 
+       err = tpmif_map(be->tpmif, ringref, evtchn);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "mapping shared-frame %lu port %u",
+                                ringref, evtchn);
+               return;
+       }
+
+       err = tpmif_vtpm_open(be->tpmif,
+                             be->frontend_id,
+                             be->instance);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "queueing vtpm open packet");
+               /*
+                * Should close down this device and notify FE
+                * about closure.
+                */
+               return;
+       }
 
        /*
         * Tell the front-end that we are ready to go -
@@ -104,27 +124,6 @@
                            "ready", "%lu", ready);
        if (err) {
                xenbus_dev_error(be->dev, err, "writing 'ready'");
-               goto abort;
-       }
-
-       err = tpmif_map(be->tpmif, ringref, evtchn);
-       if (err) {
-               xenbus_dev_error(be->dev, err,
-                                "mapping shared-frame %lu port %u",
-                                ringref, evtchn);
-               goto abort;
-       }
-
-       err = tpmif_vtpm_open(be->tpmif,
-                             be->frontend_id,
-                             be->instance);
-       if (err) {
-               xenbus_dev_error(be->dev, err,
-                                "queueing vtpm open packet");
-               /*
-                * Should close down this device and notify FE
-                * about closure.
-                */
                goto abort;
        }
 
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Mon Sep 26 
17:15:55 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Wed Sep 28 
20:06:49 2005
@@ -352,17 +352,6 @@
                goto abort_transaction;
        }
 
-       info->backend = backend;
-       backend = NULL;
-
-       info->watch.node = info->backend;
-       info->watch.callback = watch_for_status;
-       err = register_xenbus_watch(&info->watch);
-       if (err) {
-               message = "registering watch on backend";
-               goto abort_transaction;
-       }
-
        err = xenbus_transaction_end(0);
        if (err == -EAGAIN)
                goto again;
@@ -371,10 +360,17 @@
                goto destroy_tpmring;
        }
 
-out:
-       if (backend)
-               kfree(backend);
-       return err;
+       info->watch.node = backend;
+       info->watch.callback = watch_for_status;
+       err = register_xenbus_watch(&info->watch);
+       if (err) {
+               message = "registering watch on backend";
+               goto destroy_tpmring;
+       }
+
+       info->backend = backend;
+
+       return 0;
 
 abort_transaction:
        xenbus_transaction_end(1);
@@ -382,7 +378,10 @@
        xenbus_dev_error(dev, err, "%s", message);
 destroy_tpmring:
        destroy_tpmring(info, &my_private);
-       goto out;
+out:
+       if (backend)
+               kfree(backend);
+       return err;
 }
 
 
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Mon Sep 26 17:15:55 2005
+++ b/tools/console/daemon/io.c Wed Sep 28 20:06:49 2005
@@ -399,7 +399,7 @@
 
        while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) {
                dom = lookup_domain(dominfo.domid);
-               if (dominfo.dying || dominfo.crashed || dominfo.shutdown) {
+               if (dominfo.dying) {
                        if (dom)
                                shutdown_domain(dom);
                } else {
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/gen.c
--- a/tools/firmware/vmxassist/gen.c    Mon Sep 26 17:15:55 2005
+++ b/tools/firmware/vmxassist/gen.c    Wed Sep 28 20:06:49 2005
@@ -23,7 +23,7 @@
 #include <vm86.h>
 
 int
-main()
+main(void)
 {
        printf("/* MACHINE GENERATED; DO NOT EDIT */\n");
        printf("#define VMX_ASSIST_CTX_GS_SEL   0x%x\n",
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/head.S
--- a/tools/firmware/vmxassist/head.S   Mon Sep 26 17:15:55 2005
+++ b/tools/firmware/vmxassist/head.S   Wed Sep 28 20:06:49 2005
@@ -110,6 +110,10 @@
 _start:
        cli
 
+       /* save register parameters to C land */
+       movl    %edx, booting_cpu
+       movl    %ebx, booting_vector
+
        /* clear bss */
        cld
        xorb    %al, %al
@@ -128,7 +132,6 @@
        /* go ... */
        call    main
        jmp     halt
-
 
 /*
  * Something bad happened, print invoking %eip and loop forever
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c  Mon Sep 26 17:15:55 2005
+++ b/tools/firmware/vmxassist/setup.c  Wed Sep 28 20:06:49 2005
@@ -29,6 +29,9 @@
 
 #define        min(a, b)       ((a) > (b) ? (b) : (a))
 
+/* Which CPU are we booting, and what is the initial CS segment? */
+int booting_cpu, booting_vector;
+
 unsigned long long gdt[] __attribute__ ((aligned(32))) = {
        0x0000000000000000ULL,          /* 0x00: reserved */
        0x0000890000000000ULL,          /* 0x08: 32-bit TSS */
@@ -201,12 +204,17 @@
                initialize_real_mode = 0;
                regs->eflags |= EFLAGS_VM | 0x02;
                regs->ves = regs->vds = regs->vfs = regs->vgs = 0xF000;
-               regs->cs = 0xF000; /* ROM BIOS POST entry point */
-#ifdef TEST
-               regs->eip = 0xFFE0;
+               if (booting_cpu == 0) {
+                       regs->cs = 0xF000; /* ROM BIOS POST entry point */
+#ifdef TEST
+                       regs->eip = 0xFFE0;
 #else
-               regs->eip = 0xFFF0;
-#endif
+                       regs->eip = 0xFFF0;
+#endif
+               } else {
+                       regs->cs = booting_vector << 8; /* AP entry point */
+                       regs->eip = 0;
+               }
                regs->uesp = 0;
                regs->uss = 0;
                printf("Starting emulated 16-bit real-mode: ip=%04x:%04x\n",
@@ -215,8 +223,8 @@
                mode = VM86_REAL; /* becomes previous mode */
                set_mode(regs, VM86_REAL);
 
-                /* this should get us into 16-bit mode */
-                return;
+               /* this should get us into 16-bit mode */
+               return;
        } else {
                /* go from protected to real mode */
                regs->eflags |= EFLAGS_VM;
@@ -334,7 +342,12 @@
 {
        unsigned long cr0;
 
-       printf("Start BIOS ...\n");
+       if (booting_cpu == 0)
+               printf("Start BIOS ...\n");
+       else
+               printf("Start AP %d from %08x ...\n",
+                      booting_cpu, booting_vector << 12);
+
        initialize_real_mode = 1;
        cr0 = get_cr0();
 #ifndef TEST
@@ -345,20 +358,28 @@
 }
 
 int
-main()
-{
-       banner();
+main(void)
+{
+       if (booting_cpu == 0)
+               banner();
+
 #ifdef TEST
        setup_paging();
 #endif
+
        setup_gdt();
        setup_idt();
+
 #ifndef        TEST
-       set_cr4(get_cr4() | CR4_VME); 
-#endif
+       set_cr4(get_cr4() | CR4_VME);
+#endif
+
        setup_ctx();
-       setup_pic();
+
+       if (booting_cpu == 0)
+               setup_pic();
+
        start_bios();
+
        return 0;
 }
-
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Mon Sep 26 17:15:55 2005
+++ b/tools/firmware/vmxassist/vm86.c   Wed Sep 28 20:06:49 2005
@@ -752,6 +752,9 @@
                                        goto invalid;
                                }
                                break;
+                       case 0x09: /* wbinvd */
+                               asm volatile ( "wbinvd" );
+                               return OPC_EMULATED;
                        case 0x20: /* mov Rd, Cd (1h) */
                        case 0x22:
                                if (!movcr(regs, prefix, opc))
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/vmxloader.c
--- a/tools/firmware/vmxassist/vmxloader.c      Mon Sep 26 17:15:55 2005
+++ b/tools/firmware/vmxassist/vmxloader.c      Wed Sep 28 20:06:49 2005
@@ -132,11 +132,12 @@
                 memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
        }
 #endif
-                       
+
        puts("Loading VMXAssist ...\n");
        memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
+
        puts("Go ...\n");
-       ((void (*)())TEXTADDR)();
+       asm volatile ( "jmp *%%eax" : : "a" (TEXTADDR), "d" (0) );
+
        return 0;
 }
-
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Mon Sep 26 17:15:55 2005
+++ b/tools/ioemu/vl.c  Wed Sep 28 20:06:49 2005
@@ -2385,7 +2385,8 @@
 setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long  
*mem_page_array, unsigned long *page_table_array, unsigned long v_start, 
unsigned long v_end)
 {
     l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
-    l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
+    l2_pgentry_t *vl2tab[4] = {NULL, NULL, NULL, NULL};
+    l2_pgentry_t *vl2e=NULL, *vl2_table = NULL;
     unsigned long l1tab;
     unsigned long ppt_alloc = 0;
     unsigned long count;
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/web/SrvBase.py
--- a/tools/python/xen/web/SrvBase.py   Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/web/SrvBase.py   Wed Sep 28 20:06:49 2005
@@ -81,7 +81,14 @@
             req.write("Operation not implemented: " + op)
             return ''
         else:
-            return op_method(op, req)
+            try:
+                return op_method(op, req)
+            except Exception, exn:
+                log.exception("Request %s failed.", op)
+                if req.useSxp():
+                    return ['xend.err', "Exception: " + str(exn)]
+                else:
+                    return "<p>%s</p>" % str(exn)
 
     def print_path(self, req):
         """Print the path with hyperlinks.
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/web/http.py
--- a/tools/python/xen/web/http.py      Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/web/http.py      Wed Sep 28 20:06:49 2005
@@ -22,6 +22,7 @@
 from  mimetools import Message
 from cStringIO import StringIO
 import math
+import socket
 import time
 import cgi
 
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/PrettyPrint.py
--- a/tools/python/xen/xend/PrettyPrint.py      Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/PrettyPrint.py      Wed Sep 28 20:06:49 2005
@@ -39,9 +39,9 @@
         print '***PrettyItem>output>', self
         pass
 
-    def prettyprint(self, _, width):
+    def prettyprint(self, _):
         print '***PrettyItem>prettyprint>', self
-        return width
+        return self.width
 
 class PrettyString(PrettyItem):
 
@@ -52,7 +52,7 @@
     def output(self, out):
         out.write(self.value)
 
-    def prettyprint(self, line, _):
+    def prettyprint(self, line):
         line.output(self)
 
     def show(self, out):
@@ -63,7 +63,7 @@
     def output(self, out):
         out.write(' ' * self.width)
 
-    def prettyprint(self, line, _):
+    def prettyprint(self, line):
         line.output(self)
 
     def show(self, out):
@@ -80,7 +80,7 @@
     def output(self, out):
         out.write(' ' * self.width)
 
-    def prettyprint(self, line, _):
+    def prettyprint(self, line):
         if line.breaks(self.space):
             self.active = 1
             line.newline(self.indent)
@@ -97,7 +97,7 @@
         block.newline()
         block.addtoline(self)
 
-    def prettyprint(self, line, _):
+    def prettyprint(self, line):
         line.newline(0)
         line.output(self)
 
@@ -127,7 +127,7 @@
             lastbreak.space = (width - lastwidth)
         self.width = width
  
-    def prettyprint(self, line, _):
+    def prettyprint(self, line):
         for x in self.content:
             x.prettyprint(line)
 
@@ -168,7 +168,7 @@
     def addtoline(self, x):
         self.lines[-1].write(x)
 
-    def prettyprint(self, line, _):
+    def prettyprint(self, line):
         self.indent = line.used
         line.block = self
         if not line.fits(self.width):
@@ -252,7 +252,7 @@
         self.block = self.block.parent
 
     def prettyprint(self, out=sys.stdout):
-        self.top.prettyprint(Line(out, self.width), self.width)
+        self.top.prettyprint(Line(out, self.width))
 
 class SXPPrettyPrinter(PrettyPrinter):
     """An SXP prettyprinter.
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Wed Sep 28 20:06:49 2005
@@ -10,8 +10,12 @@
 import sxp
 from string import join
 from struct import pack, unpack, calcsize
+
 from xen.util.xpopen import xPopen3
+
 import xen.lowlevel.xc
+
+import XendDomainInfo
 from xen.xend.xenstore.xsutil import IntroduceDomain
 
 from XendError import XendError
@@ -74,7 +78,7 @@
                 if l.rstrip() == "suspend":
                     log.info("suspending %d" % dominfo.domid)
                     xd.domain_shutdown(dominfo.domid, reason='suspend')
-                    dominfo.state_wait("suspended")
+                    dominfo.state_wait(XendDomainInfo.STATE_VM_SUSPENDED)
                     log.info("suspend %d done" % dominfo.domid)
                     child.tochild.write("done\n")
                     child.tochild.flush()
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/XendClient.py       Wed Sep 28 20:06:49 2005
@@ -302,12 +302,6 @@
                              {'op'      : 'devices',
                               'type'    : type })
 
-    def xend_domain_device(self, id, type, idx):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device',
-                              'type'    : type,
-                              'idx'     : idx })
-    
     def xend_domain_device_create(self, id, config):
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'device_create',
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/XendDomain.py       Wed Sep 28 20:06:49 2005
@@ -28,16 +28,11 @@
 from xen.xend import sxp
 from xen.xend import XendRoot
 from xen.xend import XendCheckpoint
-from xen.xend.XendDomainInfo import XendDomainInfo, shutdown_reason
+from xen.xend.XendDomainInfo import XendDomainInfo
 from xen.xend import EventServer
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
-from xen.xend import scheduler
 from xen.xend.server import relocate
-from xen.xend.uuid import getUuid
-from xen.xend.xenstore import XenNode, DBMap
-from xen.xend.xenstore.xstransact import xstransact
-from xen.xend.xenstore.xsutil import GetDomainPath
 
 
 xc = xen.lowlevel.xc.new()
@@ -47,14 +42,7 @@
 
 __all__ = [ "XendDomain" ]
 
-SHUTDOWN_TIMEOUT = 30
-PRIV_DOMAIN      =  0
-
-def is_dead(dom):
-    return dom['crashed'] or dom['shutdown'] or (
-        dom['dying'] and not(dom['running'] or dom['paused'] or
-                             dom['blocked']))
-
+PRIV_DOMAIN = 0
 
 class XendDomainDict(dict):
     def get_by_name(self, name):
@@ -77,11 +65,8 @@
         # So we stuff the XendDomain instance (self) into xroot's components.
         xroot.add_component("xen.xend.XendDomain", self)
         self.domains = XendDomainDict()
-        self.domroot = "/domain"
-        self.vmroot = "/domain"
-        self.dbmap = DBMap(db=XenNode(self.vmroot))
         self.watchReleaseDomain()
-        self.initial_refresh()
+        self.refresh()
         self.dom0_setup()
 
     def list(self):
@@ -110,9 +95,7 @@
         return map(lambda x: x.getName(), doms)
 
     def onReleaseDomain(self):
-        self.reap()
         self.refresh()
-        self.domain_restarts()
 
     def watchReleaseDomain(self):
         from xen.xend.xenstore.xswatch import xswatch
@@ -141,43 +124,22 @@
             dominfo = dominfo[0]
         return dominfo
 
-    def initial_refresh(self):
-        """Refresh initial domain info from db.
-        """
-        doms = self.xen_domains()
-        self.dbmap.readDB()             # XXX only needed for "xend"
-        for dom in doms.values():
-            domid = dom['dom']
-            dompath = GetDomainPath(domid)
-            if not dompath:
-                continue
-            vmpath = xstransact.Read(dompath, "vm")
-            if not vmpath:
-                continue
-            uuid = xstransact.Read(vmpath, "uuid")
-            if not uuid:
-                continue
-            log.info("recreating domain %d, uuid %s" % (domid, uuid))
-            dompath = "/".join(dompath.split("/")[0:-1])
-            try:
-                dominfo = XendDomainInfo.recreate(uuid, dompath, domid, dom)
-            except Exception, ex:
-                log.exception("Error recreating domain info: id=%d", domid)
-                continue
-            self._add_domain(dominfo)
-        self.reap()
-        self.refresh()
-        self.domain_restarts()
+
+    def recreate_domain(self, xeninfo):
+        """Refresh initial domain info from db."""
+
+        dominfo = XendDomainInfo.recreate(xeninfo)
+        self._add_domain(dominfo)
+        return dominfo
+
 
     def dom0_setup(self):
         dom0 = self.domain_lookup(PRIV_DOMAIN)
         if not dom0:
-            dom0 = self.dom0_unknown()
-        dom0.dom0_init_store()    
+            dom0 = self.recreate_domain(self.xen_domain(PRIV_DOMAIN))
+        dom0.dom0_init_store()
         dom0.dom0_enforce_vcpus()
 
-    def close(self):
-        pass
 
     def _add_domain(self, info, notify=True):
         """Add a domain entry to the tables.
@@ -193,70 +155,45 @@
             eserver.inject('xend.domain.create', [info.getName(),
                                                   info.getDomid()])
 
-    def _delete_domain(self, id, notify=True):
+    def _delete_domain(self, domid, notify=True):
         """Remove a domain from the tables.
 
         @param id:     domain id
         @param notify: send a domain died event if true
         """
-        info = self.domains.get(id)
+        info = self.domains.get(domid)
         if info:
-            del self.domains[id]
+            del self.domains[domid]
             info.cleanup()
             info.delete()
             if notify:
                 eserver.inject('xend.domain.died', [info.getName(),
                                                     info.getDomid()])
-        # XXX this should not be needed
-        for domdb in self.dbmap.values():
-            if not domdb.has_key("xend"):
-                continue
-            db = domdb.addChild("xend")
-            try:
-                domid = int(domdb["domid"].getData())
-            except:
-                domid = None
-            if (domid is None) or (domid == id):
-                domdb.delete()
-
-    def reap(self):
-        """Look for domains that have crashed or stopped.
-        Tidy them up.
-        """
-        doms = self.xen_domains()
-        for d in doms.values():
-            if not is_dead(d):
-                continue
-            domid = d['dom']
-            dominfo = self.domains.get(domid)
-            if not dominfo or dominfo.is_terminated():
-                continue
-            log.debug('domain died name=%s domid=%d', dominfo.getName(), domid)
-            if d['crashed'] and xroot.get_enable_dump():
-                self.domain_dumpcore(domid)
-            if d['shutdown']:
-                reason = shutdown_reason(d['shutdown_reason'])
-                log.debug('shutdown name=%s id=%d reason=%s',
-                          dominfo.getName(), domid, reason)
-                if reason == 'suspend':
-                    dominfo.state_set("suspended")
-                    continue
-                if reason in ['poweroff', 'reboot']:
-                    self.domain_restart_schedule(domid, reason)
-            dominfo.destroy()
+
 
     def refresh(self):
         """Refresh domain list from Xen.
         """
         doms = self.xen_domains()
-        # Remove entries for domains that no longer exist.
-        # Update entries for existing domains.
         for d in self.domains.values():
             info = doms.get(d.getDomid())
             if info:
                 d.update(info)
-            elif not d.restart_pending():
+            else:
                 self._delete_domain(d.getDomid())
+        for d in doms:
+            if d not in self.domains:
+                try:
+                    self.recreate_domain(doms[d])
+                except:
+                    log.exception(
+                        "Failed to recreate information for domain %d.  "
+                        "Destroying it in the hope of recovery.", d)
+                    try:
+                        xc.domain_destroy(dom = d)
+                    except:
+                        log.exception('Destruction of %d failed.', d)
+
 
     def update_domain(self, id):
         """Update information for a single domain.
@@ -277,32 +214,8 @@
         @param config: configuration
         @return: domain
         """
-        dominfo = XendDomainInfo.create(self.dbmap.getPath(), config)
+        dominfo = XendDomainInfo.create(config)
         self._add_domain(dominfo)
-        return dominfo
-
-    def domain_restart(self, dominfo):
-        """Restart a domain.
-
-        @param dominfo: domain object
-        """
-        log.info("Restarting domain: name=%s id=%s", dominfo.getName(),
-                 dominfo.getDomid())
-        eserver.inject("xend.domain.restart",
-                       [dominfo.getName(), dominfo.getDomid(), "begin"])
-        try:
-            dominfo.restart()
-            log.info('Restarted domain name=%s id=%s', dominfo.getName(),
-                     dominfo.getDomid())
-            eserver.inject("xend.domain.restart",
-                           [dominfo.getName(), dominfo.getDomid(),
-                            "success"])
-            self.domain_unpause(dominfo.getDomid())
-        except Exception, ex:
-            log.exception("Exception restarting domain: name=%s id=%s",
-                          dominfo.getName(), dominfo.getDomid())
-            eserver.inject("xend.domain.restart",
-                           [dominfo.getName(), dominfo.getDomid(), "fail"])
         return dominfo
 
     def domain_configure(self, config):
@@ -318,13 +231,12 @@
         nested = sxp.child_value(config, 'config')
         if nested:
             config = nested
-        return XendDomainInfo.restore(self.dbmap.getPath(), config)
-
-    def domain_restore(self, src, progress=False):
+        return XendDomainInfo.restore(config)
+
+    def domain_restore(self, src):
         """Restore a domain from file.
 
         @param src:      source file
-        @param progress: output progress if true
         """
 
         try:
@@ -345,33 +257,7 @@
         self.update_domain(id)
         return self.domains.get(id)
 
-    def dom0_unknown(self):
-        dom0 = PRIV_DOMAIN
-        uuid = None
-        info = self.xen_domain(dom0)
-        dompath = GetDomainPath(dom0)
-        if dompath:
-            vmpath = xstransact.Read(dompath, "vm")
-            if vmpath:
-                uuid = xstransact.Read(vmpath, "uuid")
-            if not uuid:
-                uuid = dompath.split("/")[-1]
-            dompath = "/".join(dompath.split("/")[0:-1])
-        if not uuid:
-            uuid = getUuid()
-            dompath = self.domroot
-        log.info("Creating entry for unknown xend domain: id=%d uuid=%s",
-                 dom0, uuid)
-        try:
-            dominfo = XendDomainInfo.recreate(uuid, dompath, dom0, info)
-            self._add_domain(dominfo)
-            return dominfo
-        except Exception, exn:
-            log.exception(exn)
-            raise XendError("Error recreating xend domain info: id=%d: %s" %
-                            (dom0, str(exn)))
-
-        
+
     def domain_lookup(self, id):
         return self.domains.get(id)
 
@@ -410,8 +296,9 @@
             return xc.domain_pause(dom=dominfo.getDomid())
         except Exception, ex:
             raise XendError(str(ex))
-    
-    def domain_shutdown(self, id, reason='poweroff'):
+
+
+    def domain_shutdown(self, domid, reason='poweroff'):
         """Shutdown domain (nicely).
          - poweroff: restart according to exit code and restart mode
          - reboot:   restart on exit
@@ -422,89 +309,13 @@
         @param id:     domain id
         @param reason: shutdown type: poweroff, reboot, suspend, halt
         """
-        dominfo = self.domain_lookup(id)
-        self.domain_restart_schedule(dominfo.getDomid(), reason, force=True)
-        eserver.inject('xend.domain.shutdown', [dominfo.getName(),
-                                                dominfo.getDomid(), reason])
-        if reason == 'halt':
-            reason = 'poweroff'
-        val = dominfo.shutdown(reason)
-        if not reason in ['suspend']:
-            self.domain_shutdowns()
-        return val
-
-
-    def domain_sysrq(self, id, key):
+        self.callInfo(domid, XendDomainInfo.shutdown, reason)
+
+
+    def domain_sysrq(self, domid, key):
         """Send a SysRq to the specified domain."""
-        return self.callInfo(id, XendDomainInfo.send_sysrq, key)
-
-
-    def domain_shutdowns(self):
-        """Process pending domain shutdowns.
-        Destroys domains whose shutdowns have timed out.
-        """
-        timeout = SHUTDOWN_TIMEOUT + 1
-        for dominfo in self.domains.values():
-            if not dominfo.shutdown_pending:
-                # domain doesn't need shutdown
-                continue
-            id = dominfo.getDomid()
-            left = dominfo.shutdown_time_left(SHUTDOWN_TIMEOUT)
-            if left <= 0:
-                # Shutdown expired - destroy domain.
-                try:
-                    log.info("Domain shutdown timeout expired: name=%s id=%s",
-                             dominfo.getName(), id)
-                    self.domain_destroy(id, reason=
-                                        dominfo.shutdown_pending['reason'])
-                except Exception:
-                    pass
-            else:
-                # Shutdown still pending.
-                timeout = min(timeout, left)
-        if timeout <= SHUTDOWN_TIMEOUT:
-            # Pending shutdowns remain - reschedule.
-            scheduler.later(timeout, self.domain_shutdowns)
-
-    def domain_restart_schedule(self, id, reason, force=False):
-        """Schedule a restart for a domain if it needs one.
-
-        @param id:     domain id
-        @param reason: shutdown reason
-        """
-        log.debug('domain_restart_schedule> %d %s %d', id, reason, force)
-        dominfo = self.domain_lookup(id)
-        if not dominfo:
-            return
-        restart = (force and reason == 'reboot') or 
dominfo.restart_needed(reason)
-        if restart:
-            log.info('Scheduling restart for domain: name=%s id=%s',
-                     dominfo.getName(), dominfo.getDomid())
-            eserver.inject("xend.domain.restart",
-                           [dominfo.getName(), dominfo.getDomid(),
-                            "schedule"])
-            dominfo.restarting()
-        else:
-            log.info('Cancelling restart for domain: name=%s id=%s',
-                     dominfo.getName(), dominfo.getDomid())
-            eserver.inject("xend.domain.restart",
-                           [dominfo.getName(), dominfo.getDomid(), "cancel"])
-            dominfo.restart_cancel()
-
-    def domain_restarts(self):
-        """Execute any scheduled domain restarts for domains that have gone.
-        """
-        doms = self.xen_domains()
-        for dominfo in self.domains.values():
-            if not dominfo.restart_pending():
-                continue
-            info = doms.get(dominfo.getDomid())
-            if info:
-                # Don't execute restart for domains still running.
-                continue
-            # Remove it from the restarts.
-            log.info('restarting: %s' % dominfo.getName())
-            self.domain_restart(dominfo)
+        return self.callInfo(domid, XendDomainInfo.send_sysrq, key)
+
 
     def domain_destroy(self, domid, reason='halt'):
         """Terminate domain immediately.
@@ -517,7 +328,6 @@
         if domid == PRIV_DOMAIN:
             raise XendError("Cannot destroy privileged domain %i" % domid)
         
-        self.domain_restart_schedule(domid, reason, force=True)
         dominfo = self.domain_lookup(domid)
         if dominfo:
             val = dominfo.destroy()
@@ -554,12 +364,11 @@
         
         return None
 
-    def domain_save(self, id, dst, progress=False):
+    def domain_save(self, id, dst):
         """Start saving a domain to file.
 
         @param id:       domain id
         @param dst:      destination file
-        @param progress: output progress if true
         """
 
         try:
@@ -659,14 +468,6 @@
     def domain_devtype_ls(self, domid, devtype):
         """Get list of device sxprs for the specified domain."""
         return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
-
-
-    def domain_devtype_get(self, domid, devtype, devid):
-        """Get a device from a domain.
-        
-        @return: device object (or None)
-        """
-        return self.callInfo(domid, XendDomainInfo.getDevice, devtype, devid)
 
 
     def domain_vif_limit_set(self, id, vif, credit, period):
@@ -730,10 +531,16 @@
     ## private:
 
     def callInfo(self, domid, fn, *args, **kwargs):
-        self.refresh()
-        dominfo = self.domains.get(domid)
-        if dominfo:
-            return fn(dominfo, *args, **kwargs)
+        try:
+            self.refresh()
+            dominfo = self.domains.get(domid)
+            if dominfo:
+                return fn(dominfo, *args, **kwargs)
+        except XendError:
+            raise
+        except Exception, exn:
+            log.exception("")
+            raise XendError(str(exn))
 
 
 def instance():
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Sep 28 20:06:49 2005
@@ -35,7 +35,9 @@
 from xen.xend.server.channel import EventChannel
 
 from xen.xend import image
+from xen.xend import scheduler
 from xen.xend import sxp
+from xen.xend import XendRoot
 from xen.xend.XendBootloader import bootloader
 from xen.xend.XendLogging import log
 from xen.xend.XendError import XendError, VmError
@@ -43,7 +45,7 @@
 
 from xen.xend.uuid import getUuid
 from xen.xend.xenstore.xstransact import xstransact
-from xen.xend.xenstore.xsutil import IntroduceDomain
+from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
 
 """Shutdown code for poweroff."""
 DOMAIN_POWEROFF = 0
@@ -75,9 +77,6 @@
     RESTART_NEVER,
     ]
 
-STATE_RESTART_PENDING = 'pending'
-STATE_RESTART_BOOTING = 'booting'
-
 STATE_VM_OK         = "ok"
 STATE_VM_TERMINATED = "terminated"
 STATE_VM_SUSPENDED  = "suspended"
@@ -92,7 +91,29 @@
 SIF_TPM_BE_DOMAIN = (1<<7)
 
 
+SHUTDOWN_TIMEOUT = 30
+
+
+DOMROOT = '/domain'
+VMROOT  = '/domain'
+
+
 xc = xen.lowlevel.xc.new()
+xroot = XendRoot.instance()
+
+
+## Configuration entries that we expect to round-trip -- be read from the
+# config file or xc, written to save-files (i.e. through sxpr), and reused as
+# config on restart or restore, all without munging.  Some configuration
+# entries are munged for backwards compatibility reasons, or because they
+# don't come out of xc in the same form as they are specified in the config
+# file, so those are handled separately.
+ROUNDTRIPPING_CONFIG_ENTRIES = [
+        ('name',         str),
+        ('ssidref',      int),
+        ('cpu_weight',   float),
+        ('bootloader',   str)
+    ]
 
 
 def domain_exists(name):
@@ -133,47 +154,64 @@
     MINIMUM_RESTART_TIME = 20
 
 
-    def create(cls, dompath, config):
+    def create(cls, config):
         """Create a VM from a configuration.
 
-        @param dompath:   The path to all domain information
         @param config    configuration
         @raise: VmError for invalid configuration
         """
 
-        log.debug("XendDomainInfo.create(%s, ...)", dompath)
+        log.debug("XendDomainInfo.create(...)")
         
-        vm = cls(getUuid(), dompath, cls.parseConfig(config))
+        vm = cls(getUuid(), cls.parseConfig(config))
         vm.construct()
+        vm.refreshShutdown()
         return vm
 
     create = classmethod(create)
 
 
-    def recreate(cls, uuid, dompath, domid, info):
-        """Create the VM object for an existing domain.
-
-        @param dompath:   The path to all domain information
-        @param info:      domain info from xc
-        """
-
-        log.debug("XendDomainInfo.recreate(%s, %s, %s, %s)", uuid, dompath,
-                  domid, info)
-
-        return cls(uuid, dompath, info, domid, True)
+    def recreate(cls, xeninfo):
+        """Create the VM object for an existing domain."""
+
+        log.debug("XendDomainInfo.recreate(%s)", xeninfo)
+
+        domid = xeninfo['dom']
+        try:
+            dompath = GetDomainPath(domid)
+            if not dompath:
+                raise XendError(
+                    'No domain path in store for existing domain %d' % domid)
+            vmpath = xstransact.Read(dompath, "vm")
+            if not vmpath:
+                raise XendError(
+                    'No vm path in store for existing domain %d' % domid)
+            uuid = xstransact.Read(vmpath, "uuid")
+            if not uuid:
+                raise XendError(
+                    'No vm/uuid path in store for existing domain %d' % domid)
+
+        except Exception, exn:
+            log.warn(str(exn))
+            uuid = getUuid()
+
+        log.info("Recreating domain %d, uuid %s", domid, uuid)
+
+        vm = cls(uuid, xeninfo, domid, True)
+        vm.refreshShutdown(xeninfo)
+        return vm
 
     recreate = classmethod(recreate)
 
 
-    def restore(cls, dompath, config, uuid = None):
+    def restore(cls, config, uuid = None):
         """Create a domain and a VM object to do a restore.
 
-        @param dompath:   The path to all domain information
         @param config:    domain configuration
         @param uuid:      uuid to use
         """
         
-        log.debug("XendDomainInfo.restore(%s, %s, %s)", dompath, config, uuid)
+        log.debug("XendDomainInfo.restore(%s, %s)", config, uuid)
 
         if not uuid:
             uuid = getUuid()
@@ -183,14 +221,12 @@
         except TypeError, exn:
             raise VmError('Invalid ssidref in config: %s' % exn)
 
-        log.debug('restoring with ssidref = %d' % ssidref)
-
-        vm = cls(uuid, dompath, cls.parseConfig(config),
+        vm = cls(uuid, cls.parseConfig(config),
                  xc.domain_create(ssidref = ssidref))
-        vm.clear_shutdown()
         vm.create_channel()
         vm.configure()
         vm.exportToDB()
+        vm.refreshShutdown()
         return vm
 
     restore = classmethod(restore)
@@ -214,33 +250,28 @@
         log.debug("parseConfig: config is %s" % str(config))
 
         result = {}
-        imagecfg = "()"
-
-        result['name']         = get_cfg('name')
-        result['ssidref']      = get_cfg('ssidref',    int)
+
+        for e in ROUNDTRIPPING_CONFIG_ENTRIES:
+            result[e[0]] = get_cfg(e[0], e[1])
+
         result['memory']       = get_cfg('memory',     int)
         result['mem_kb']       = get_cfg('mem_kb',     int)
         result['maxmem']       = get_cfg('maxmem',     int)
         result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
         result['cpu']          = get_cfg('cpu',        int)
-        result['cpu_weight']   = get_cfg('cpu_weight', float)
-        result['bootloader']   = get_cfg('bootloader')
         result['restart_mode'] = get_cfg('restart')
+        result['image']        = get_cfg('image')
 
         try:
-            imagecfg = get_cfg('image')
-
-            if imagecfg:
-                result['image'] = imagecfg
-                result['vcpus'] = int(sxp.child_value(imagecfg, 'vcpus',
-                                                      1))
+            if result['image']:
+                result['vcpus'] = int(sxp.child_value(result['image'],
+                                                      'vcpus', 1))
             else:
                 result['vcpus'] = 1
         except TypeError, exn:
             raise VmError(
                 'Invalid configuration setting: vcpus = %s: %s' %
-                (sxp.child_value(imagecfg, 'vcpus', 1),
-                 str(exn)))
+                (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
 
         result['backend'] = []
         for c in sxp.children(config, 'backend'):
@@ -258,12 +289,12 @@
     parseConfig = classmethod(parseConfig)
 
     
-    def __init__(self, uuid, parentpath, info, domid = None, augment = False):
+    def __init__(self, uuid, info, domid = None, augment = False):
 
         self.uuid = uuid
         self.info = info
 
-        self.path = parentpath + "/" + uuid
+        self.path = DOMROOT + "/" + uuid
 
         if domid:
             self.domid = domid
@@ -283,26 +314,26 @@
         self.store_mfn = None
         self.console_channel = None
         self.console_mfn = None
-        
-        #todo: state: running, suspended
+
         self.state = STATE_VM_OK
         self.state_updated = threading.Condition()
-        self.shutdown_pending = None
-
-        self.restart_state = None
-        self.restart_time = None
-        self.restart_count = 0
-        
+
         self.writeVm("uuid", self.uuid)
         self.storeDom("vm", self.path)
 
 
     def augmentInfo(self):
+        """Augment self.info, as given to us through {@link #recreate}, with
+        values taken from the store.  This recovers those values known to xend
+        but not to the hypervisor.
+        """
         def useIfNeeded(name, val):
             if not self.infoIsSet(name) and val is not None:
                 self.info[name] = val
 
         params = (("name", str),
+                  ("restart-mode", str),
+                  ("image",        str),
                   ("start-time", float))
 
         from_store = self.gatherVm(*params)
@@ -322,12 +353,17 @@
             defaultInfo('name',         lambda: "Domain-%d" % self.domid)
             defaultInfo('ssidref',      lambda: 0)
             defaultInfo('restart_mode', lambda: RESTART_ONREBOOT)
+            defaultInfo('cpu',          lambda: None)
             defaultInfo('cpu_weight',   lambda: 1.0)
             defaultInfo('bootloader',   lambda: None)
             defaultInfo('backend',      lambda: [])
             defaultInfo('device',       lambda: [])
+            defaultInfo('image',        lambda: None)
 
             self.check_name(self.info['name'])
+
+            if isinstance(self.info['image'], str):
+                self.info['image'] = sxp.from_string(self.info['image'])
 
             # Internally, we keep only maxmem_KiB, and not maxmem or maxmem_kb
             # (which come from outside, and are in MiB and KiB respectively).
@@ -451,17 +487,16 @@
             'domid':              str(self.domid),
             'uuid':               self.uuid,
 
-            'restart_time':       str(self.restart_time),
-
-            'xend/state':         self.state,
-            'xend/restart_count': str(self.restart_count),
             'xend/restart_mode':  str(self.info['restart_mode']),
 
             'memory/target':      str(self.info['memory_KiB'])
             }
 
         for (k, v) in self.info.items():
-            to_store[k] = str(v)
+            if v:
+                to_store[k] = str(v)
+
+        to_store['image'] = sxp.to_string(self.info['image'])
 
         log.debug("Storing %s" % str(to_store))
 
@@ -511,6 +546,88 @@
     def getBackendFlags(self):
         return reduce(lambda x, y: x | backendFlags[y],
                       self.info['backend'], 0)
+
+
+    def refreshShutdown(self, xeninfo = None):
+        if xeninfo is None:
+            xeninfo = dom_get(self.domid)
+            if xeninfo is None:
+                # The domain no longer exists.  This will occur if we have
+                # scheduled a timer to check for shutdown timeouts and the
+                # shutdown succeeded.
+                return
+
+        if xeninfo['dying']:
+            # Dying means that a domain has been destroyed, but has not yet
+            # been cleaned up by Xen.  This could persist indefinitely if,
+            # for example, another domain has some of its pages mapped.
+            # We might like to diagnose this problem in the future, but for
+            # now all we can sensibly do is ignore it.
+            pass
+
+        elif xeninfo['crashed']:
+            log.warn('Domain has crashed: name=%s id=%d.',
+                     self.info['name'], self.domid)
+
+            if xroot.get_enable_dump():
+                self.dumpCore()
+
+            self.maybeRestart('crashed')
+
+        elif xeninfo['shutdown']:
+            reason = shutdown_reason(xeninfo['shutdown_reason'])
+
+            log.info('Domain has shutdown: name=%s id=%d reason=%s.',
+                     self.info['name'], self.domid, reason)
+
+            self.clearRestart()
+
+            if reason == 'suspend':
+                self.state_set(STATE_VM_SUSPENDED)
+                # Don't destroy the domain.  XendCheckpoint will do this once
+                # it has finished.
+            elif reason in ['poweroff', 'reboot']:
+                self.maybeRestart(reason)
+            else:
+                self.destroy()
+
+        else:
+            # Domain is alive.  If we are shutting it down, then check
+            # the timeout on that, and destroy it if necessary.
+
+            sst = self.readVm('xend/shutdown_start_time')
+            if sst:
+                sst = float(sst)
+                timeout = SHUTDOWN_TIMEOUT - time.time() + sst
+                if timeout < 0:
+                    log.info(
+                        "Domain shutdown timeout expired: name=%s id=%s",
+                        self.info['name'], self.domid)
+                    self.destroy()
+                else:
+                    log.debug(
+                        "Scheduling refreshShutdown on domain %d in %ds.",
+                        self.domid, timeout)
+                    scheduler.later(timeout, self.refreshShutdown)
+
+
+    def shutdown(self, reason):
+        if not reason in shutdown_reasons.values():
+            raise XendError('invalid reason:' + reason)
+        self.storeVm("control/shutdown", reason)
+        if not reason == 'suspend':
+            self.storeVm('xend/shutdown_start_time', time.time())
+
+
+    def clearRestart(self):
+        self.removeVm("xend/shutdown_start_time")
+
+
+    def maybeRestart(self, reason):
+        if self.restart_needed(reason):
+            self.restart()
+        else:
+            self.destroy()
 
 
     def dumpCore(self):
@@ -526,18 +643,32 @@
                       self.domid, self.info['name'], str(exn))
 
 
+    def closeChannel(self, channel, entry):
+        """Close the given channel, if set, and remove the given entry in the
+        store.  Nothrow guarantee."""
+        
+        try:
+            try:
+                if channel:
+                    channel.close()
+            finally:
+                self.removeDom(entry)
+        except Exception, exn:
+            log.exception(exn)
+        
+
     def closeStoreChannel(self):
         """Close the store channel, if any.  Nothrow guarantee."""
-        
-        try:
-            if self.store_channel:
-                try:
-                    self.store_channel.close()
-                    self.removeDom("store/port")
-                finally:
-                    self.store_channel = None
-        except Exception, exn:
-            log.exception(exn)
+
+        self.closeChannel(self.store_channel, "store/port")
+        self.store_channel = None
+
+
+    def closeConsoleChannel(self):
+        """Close the console channel, if any.  Nothrow guarantee."""
+
+        self.closeChannel(self.console_channel, "console/port")
+        self.console_channel = None
 
 
     def setConsoleRef(self, ref):
@@ -566,10 +697,13 @@
             
         self.info.update(info)
         self.validateInfo()
+        self.refreshShutdown(info)
 
         log.debug("XendDomainInfo.update done on domain %d: %s", self.domid,
                   self.info)
 
+
+    ## private:
 
     def state_set(self, state):
         self.state_updated.acquire()
@@ -577,13 +711,16 @@
             self.state = state
             self.state_updated.notifyAll()
         self.state_updated.release()
-        self.exportToDB()
+
+
+    ## public:
 
     def state_wait(self, state):
         self.state_updated.acquire()
         while self.state != state:
             self.state_updated.wait()
         self.state_updated.release()
+
 
     def __str__(self):
         s = "<domain"
@@ -597,6 +734,25 @@
     __repr__ = __str__
 
 
+    def createDevice(self, deviceClass, devconfig):
+        return self.getDeviceController(deviceClass).createDevice(devconfig)
+
+
+    def configureDevice(self, deviceClass, devid, devconfig):
+        return self.getDeviceController(deviceClass).configureDevice(
+            devid, devconfig)
+
+
+    def destroyDevice(self, deviceClass, devid):
+        return self.getDeviceController(deviceClass).destroyDevice(devid)
+
+
+    def getDeviceSxprs(self, deviceClass):
+        return self.getDeviceController(deviceClass).sxprs()
+
+
+    ## private:
+
     def getDeviceController(self, name):
         if name not in controllerClasses:
             raise XendError("unknown device type: " + str(name))
@@ -604,62 +760,53 @@
         return controllerClasses[name](self)
 
 
-    def createDevice(self, deviceClass, devconfig):
-        return self.getDeviceController(deviceClass).createDevice(devconfig)
-
-
-    def configureDevice(self, deviceClass, devid, devconfig):
-        return self.getDeviceController(deviceClass).configureDevice(
-            devid, devconfig)
-
-
-    def destroyDevice(self, deviceClass, devid):
-        return self.getDeviceController(deviceClass).destroyDevice(devid)
-
+    ## public:
 
     def sxpr(self):
         sxpr = ['domain',
-                ['domid', self.domid],
-                ['name', self.info['name']],
-                ['memory', self.info['memory_KiB'] / 1024],
-                ['ssidref', self.info['ssidref']]]
-        if self.uuid:
-            sxpr.append(['uuid', self.uuid])
-        if self.info:
-            sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024])
-
-            if self.infoIsSet('device'):
-                for (_, c) in self.info['device']:
-                    sxpr.append(['device', c])
-
-            def stateChar(name):
-                if name in self.info:
-                    if self.info[name]:
-                        return name[0]
-                    else:
-                        return '-'
+                ['domid',   self.domid],
+                ['uuid',    self.uuid],
+                ['memory',  self.info['memory_KiB'] / 1024]]
+
+        for e in ROUNDTRIPPING_CONFIG_ENTRIES:
+            if self.infoIsSet(e[0]):
+                sxpr.append([e[0], self.info[e[0]]])
+        
+        sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024])
+
+        if self.infoIsSet('image'):
+            sxpr.append(['image', self.info['image']])
+
+        if self.infoIsSet('device'):
+            for (_, c) in self.info['device']:
+                sxpr.append(['device', c])
+
+        def stateChar(name):
+            if name in self.info:
+                if self.info[name]:
+                    return name[0]
                 else:
-                    return '?'
-
-            state = reduce(
-                lambda x, y: x + y,
-                map(stateChar,
-                    ['running', 'blocked', 'paused', 'shutdown', 'crashed']))
-
-            sxpr.append(['state', state])
-            if self.infoIsSet('shutdown'):
-                reason = shutdown_reason(self.info['shutdown_reason'])
-                sxpr.append(['shutdown_reason', reason])
-            if self.infoIsSet('cpu_time'):
-                sxpr.append(['cpu_time', self.info['cpu_time']/1e9])    
-            sxpr.append(['vcpus', self.info['vcpus']])
-            sxpr.append(['cpumap', self.info['cpumap']])
-            if self.infoIsSet('vcpu_to_cpu'):
-                sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
-                # build a string, using '|' to separate items, show only up
-                # to number of vcpus in domain, and trim the trailing '|'
-                sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|',
-                            
self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]])
+                    return '-'
+            else:
+                return '?'
+
+        state = reduce(
+            lambda x, y: x + y,
+            map(stateChar,
+                ['running', 'blocked', 'paused', 'shutdown', 'crashed',
+                 'dying']))
+
+        sxpr.append(['state', state])
+        if self.infoIsSet('shutdown'):
+            reason = shutdown_reason(self.info['shutdown_reason'])
+            sxpr.append(['shutdown_reason', reason])
+        if self.infoIsSet('cpu_time'):
+            sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
+        sxpr.append(['vcpus', self.info['vcpus']])
+        sxpr.append(['cpumap', self.info['cpumap']])
+        if self.infoIsSet('vcpu_to_cpu'):
+            sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
+            sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()])
             
         if self.infoIsSet('start_time'):
             up_time =  time.time() - self.info['start_time']
@@ -674,13 +821,16 @@
             sxpr.append(['console_channel', self.console_channel.sxpr()])
         if self.console_mfn:
             sxpr.append(['console_mfn', self.console_mfn])
-        if self.restart_count:
-            sxpr.append(['restart_count', self.restart_count])
-        if self.restart_state:
-            sxpr.append(['restart_state', self.restart_state])
-        if self.restart_time:
-            sxpr.append(['restart_time', str(self.restart_time)])
+
         return sxpr
+
+
+    ## private:
+
+    def prettyVCpuMap(self):
+        return '|'.join(map(str,
+                            self.info['vcpu_to_cpu'][0:self.info['vcpus']]))
+
 
     def check_name(self, name):
         """Check if a vm name is valid. Valid names contain alphabetic 
characters,
@@ -719,11 +869,19 @@
         @param config: configuration
         @raise: VmError on error
         """
-        # todo - add support for scheduling params?
+
+        log.debug('XendDomainInfo.construct: %s %s',
+                  str(self.domid),
+                  str(self.info['ssidref']))
+
+        self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'])
+
+        if self.domid <= 0:
+            raise VmError('Creating domain failed: name=%s' %
+                          self.info['name'])
+
         try:
             self.initDomain()
-
-            # Create domain devices.
             self.construct_image()
             self.configure()
             self.exportToDB()
@@ -737,30 +895,23 @@
 
 
     def initDomain(self):
-        log.debug('XendDomainInfo.initDomain: %s %s %s %s)',
+        log.debug('XendDomainInfo.initDomain: %s %s %s',
                   str(self.domid),
                   str(self.info['memory_KiB']),
-                  str(self.info['ssidref']),
                   str(self.info['cpu_weight']))
 
-        self.domid = xc.domain_create(dom = self.domid or 0,
-                                      ssidref = self.info['ssidref'])
-
-        if 'image' not in self.info:
+        if not self.infoIsSet('image'):
             raise VmError('Missing image in configuration')
 
         self.image = image.create(self,
                                   self.info['image'],
                                   self.info['device'])
 
-        if self.domid <= 0:
-            raise VmError('Creating domain failed: name=%s' %
-                          self.info['name'])
-
         if self.info['bootloader']:
             self.image.handleBootloading()
 
         xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
+        # XXX Merge with configure_maxmem?
         m = self.image.getDomainMemory(self.info['memory_KiB'])
         xc.domain_setmaxmem(self.domid, m)
         xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
@@ -794,6 +945,8 @@
         self.configure_vcpus(self.info['vcpus'])
 
 
+    ## public:
+
     def delete(self):
         """Delete the vm's db.
         """
@@ -803,48 +956,46 @@
             log.warning("error in domain db delete: %s", ex)
 
 
-    def destroy_domain(self):
-        """Destroy the vm's domain.
-        The domain will not finally go away unless all vm
-        devices have been released.
-        """
-        if self.domid is None:
-            return
-        try:
-            xc.domain_destroy(dom=self.domid)
-        except Exception, err:
-            log.exception("Domain destroy failed: %s", self.info['name'])
-
     def cleanup(self):
-        """Cleanup vm resources: release devices.
-        """
-        self.state = STATE_VM_TERMINATED
+        """Cleanup vm resources: release devices.  Nothrow guarantee."""
+
+        self.state_set(STATE_VM_TERMINATED)
         self.release_devices()
         self.closeStoreChannel()
-        if self.console_channel:
-            # notify processes using this console?
-            try:
-                self.console_channel.close()
-                self.console_channel = None
-            except:
-                pass
+        self.closeConsoleChannel()
+
         if self.image:
             try:
                 self.image.destroy()
-                self.image = None
             except:
-                pass
+                log.exception(
+                    "XendDomainInfo.cleanup: image.destroy() failed.")
+            self.image = None
+
 
     def destroy(self):
-        """Cleanup vm and destroy domain.
-        """
-
-        log.debug("XendDomainInfo.destroy")
-
-        self.destroy_domain()
+        """Cleanup vm and destroy domain.  Nothrow guarantee."""
+
+        log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
+
         self.cleanup()
-        self.exportToDB()
-        return 0
+
+        try:
+            self.removeVm()
+        except Exception:
+            log.exception("Removing VM path failed.")
+
+        try:
+            self.removeDom()
+        except Exception:
+            log.exception("Removing domain path failed.")
+
+        try:
+            if self.domid is not None:
+                xc.domain_destroy(dom=self.domid)
+        except Exception:
+            log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
+
 
     def is_terminated(self):
         """Check if a domain has been terminated.
@@ -852,8 +1003,7 @@
         return self.state == STATE_VM_TERMINATED
 
     def release_devices(self):
-        """Release all vm devices.
-        """
+        """Release all vm devices.  Nothrow guarantee."""
 
         while True:
             t = xstransact("%s/device" % self.path)
@@ -865,8 +1015,8 @@
                         # Log and swallow any exceptions in removal --
                         # there's nothing more we can do.
                         log.exception(
-                           "Device release failed: %s; %s; %s; %s" %
-                            (self.info['name'], n, d, str(ex)))
+                           "Device release failed: %s; %s; %s",
+                           self.info['name'], n, d)
             if t.commit():
                 break
 
@@ -902,8 +1052,7 @@
 
         @raise: VmError for invalid devices
         """
-        if not self.rebooting():
-            self.create_configured_devices()
+        self.create_configured_devices()
         if self.image:
             self.image.createDeviceModel()
 
@@ -942,23 +1091,6 @@
             return reason == 'reboot'
         return False
 
-    def restart_cancel(self):
-        """Cancel a vm restart.
-        """
-        self.restart_state = None
-
-    def restarting(self):
-        """Put the vm into restart mode.
-        """
-        self.restart_state = STATE_RESTART_PENDING
-
-    def restart_pending(self):
-        """Test if the vm has a pending restart.
-        """
-        return self.restart_state == STATE_RESTART_PENDING
-
-    def rebooting(self):
-        return self.restart_state == STATE_RESTART_BOOTING
 
     def restart_check(self):
         """Check if domain restart is OK.
@@ -976,23 +1108,37 @@
         self.restart_time = tnow
         self.restart_count += 1
 
+
     def restart(self):
-        """Restart the domain after it has exited.
-        Reuses the domain id
-
-        """
+        """Restart the domain after it has exited. """
+
+        #            self.restart_check()
+        self.cleanup()
+
+        config = self.sxpr()
+
+        if self.readVm('xend/restart_in_progress'):
+            log.error('Xend failed during restart of domain %d.  '
+                      'Refusing to restart to avoid loops.',
+                      self.domid)
+            self.destroy()
+            return
+
+        self.writeVm('xend/restart_in_progress', 'True')
+
         try:
-            self.clear_shutdown()
-            self.state = STATE_VM_OK
-            self.shutdown_pending = None
-            self.restart_check()
-            self.exportToDB()
-            self.restart_state = STATE_RESTART_BOOTING
-            self.configure_bootloader()
-            self.construct()
-            self.exportToDB()
+            self.destroy()
+            try:
+                xd = get_component('xen.xend.XendDomain')
+                xd.domain_unpause(xd.domain_create(config).getDomid())
+            except Exception, exn:
+                log.exception('Failed to restart domain %d.', self.domid)
         finally:
-            self.restart_state = None
+            self.removeVm('xend/restart_in_progress')
+            
+        # self.configure_bootloader()
+        #        self.exportToDB()
+
 
     def configure_bootloader(self):
         if not self.info['bootloader']:
@@ -1006,7 +1152,8 @@
         if dev:
             disk = sxp.child_value(dev, "uname")
             fn = blkdev_uname_to_file(disk)
-            blcfg = bootloader(self.info['bootloader'], fn, 1, 
self.info['vcpus'])
+            blcfg = bootloader(self.info['bootloader'], fn, 1,
+                               self.info['vcpus'])
         if blcfg is None:
             msg = "Had a bootloader specified, but can't find disk"
             log.error(msg)
@@ -1023,7 +1170,9 @@
 
 
     def configure_maxmem(self):
-        xc.domain_setmaxmem(self.domid, maxmem_kb = self.info['maxmem_KiB'])
+        if self.image:
+            m = self.image.getDomainMemory(self.info['memory_KiB'])
+            xc.domain_setmaxmem(self.domid, maxmem_kb = m)
 
 
     def vcpu_hotplug(self, vcpu, state):
@@ -1038,23 +1187,8 @@
             availability = "online"
         self.storeVm("cpu/%d/availability" % vcpu, availability)
 
-    def shutdown(self, reason):
-        if not reason in shutdown_reasons.values():
-            raise XendError('invalid reason:' + reason)
-        self.storeVm("control/shutdown", reason)
-        if not reason in ['suspend']:
-            self.shutdown_pending = {'start':time.time(), 'reason':reason}
-
-    def clear_shutdown(self):
-        self.removeVm("control/shutdown")
-
     def send_sysrq(self, key=0):
         self.storeVm("control/sysrq", '%c' % key)
-
-    def shutdown_time_left(self, timeout):
-        if not self.shutdown_pending:
-            return 0
-        return timeout - (time.time() - self.shutdown_pending['start'])
 
     def dom0_init_store(self):
         if not self.store_channel:
@@ -1078,8 +1212,6 @@
     def dom0_enforce_vcpus(self):
         dom = 0
         # get max number of vcpus to use for dom0 from config
-        from xen.xend import XendRoot
-        xroot = XendRoot.instance()
         target = int(xroot.get_dom0_vcpus())
         log.debug("number of vcpus to use is %d" % (target))
    
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/server/DevController.py     Wed Sep 28 20:06:49 2005
@@ -81,6 +81,13 @@
         xstransact.Remove(backpath)
 
 
+    def sxprs(self):
+        """@return an s-expression describing all the devices of this
+        controller's device-class.
+        """
+        return xstransact.ListRecursive(self.frontendRoot())
+
+
     def sxpr(self, devid):
         """@return an s-expression describing the specified device.
         """
@@ -126,8 +133,8 @@
         compulsory to use it; subclasses may prefer to allocate IDs based upon
         the device configuration instead.
         """
+        path = self.frontendMiscPath()
         while True:
-            path = self.frontendMiscPath()
             t = xstransact(path)
             try:
                 result = t.read("nextDeviceID")
@@ -196,8 +203,11 @@
 
 
     def frontendPath(self, devid):
-        return "%s/device/%s/%d" % (self.vm.getPath(), self.deviceClass,
-                                    devid)
+        return "%s/%d" % (self.frontendRoot(), devid)
+
+
+    def frontendRoot(self):
+        return "%s/device/%s" % (self.vm.getPath(), self.deviceClass)
 
 
     def frontendMiscPath(self):
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/server/SrvDaemon.py Wed Sep 28 20:06:49 2005
@@ -9,25 +9,23 @@
 import sys
 import threading
 import linecache
-import socket
 import pwd
 import re
-import StringIO
 import traceback
-import time
-import glob
-
-from xen.xend import sxp
-from xen.xend import PrettyPrint
-from xen.xend import EventServer; eserver = EventServer.instance()
-from xen.xend.XendError import XendError
+
+from xen.xend import EventServer
 from xen.xend.server import SrvServer
 from xen.xend.XendLogging import log
-from xen.xend import XendRoot; xroot = XendRoot.instance()
+from xen.xend import XendRoot
 
 import event
 import relocate
 from params import *
+
+
+eserver = EventServer.instance()
+xroot = XendRoot.instance()
+
 
 class Daemon:
     """The xend daemon.
@@ -233,7 +231,7 @@
             except:
                 pass
 
-    def print_trace(self, str):
+    def print_trace(self, string):
         for i in range(self.traceindent):
             ch = " "
             if (i % 5):
@@ -241,7 +239,7 @@
             else:
                 ch = '|'
             self.tracefile.write(ch)
-        self.tracefile.write(str)
+        self.tracefile.write(string)
             
     def trace(self, frame, event, arg):
         if not self.traceon:
@@ -289,7 +287,7 @@
         try:
             os.setuid(pwd.getpwnam(XEND_USER)[2])
             return 0
-        except KeyError, error:
+        except KeyError:
             print >>sys.stderr, "Error: no such user '%s'" % XEND_USER
             return 1
 
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvDmesg.py
--- a/tools/python/xen/xend/server/SrvDmesg.py  Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/server/SrvDmesg.py  Wed Sep 28 20:06:49 2005
@@ -13,14 +13,14 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
 #============================================================================
 
-import os
 
-from xen.xend import sxp
 from xen.xend import XendDmesg
 
 from xen.web.SrvDir import SrvDir
+
 
 class SrvDmesg(SrvDir):
     """Xen Dmesg output.
@@ -47,6 +47,6 @@
     def info(self):
         return self.xd.info()
 
-    def op_clear(self, op, req):
+    def op_clear(self, _1, _2):
         self.xd.clear()
         return 0
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/server/SrvDomain.py Wed Sep 28 20:06:49 2005
@@ -150,17 +150,6 @@
         val = fn(req.args, {'dom': self.dom.domid})
         return val
 
-    def op_device(self, op, req):
-        fn = FormFn(self.xd.domain_devtype_get,
-                    [['dom',    'int'],
-                     ['type',   'str'],
-                     ['idx',    'int']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        if val:
-            return val.sxpr()
-        else:
-            raise XendError("invalid device")
-
     def op_device_create(self, op, req):
         fn = FormFn(self.xd.domain_device_create,
                     [['dom',    'int'],
@@ -172,7 +161,7 @@
         fn = FormFn(self.xd.domain_device_refresh,
                     [['dom',  'int'],
                      ['type', 'str'],
-                     ['idx',  'str']])
+                     ['idx',  'int']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
 
@@ -180,7 +169,7 @@
         fn = FormFn(self.xd.domain_device_destroy,
                     [['dom',  'int'],
                      ['type', 'str'],
-                     ['idx',  'str']])
+                     ['idx',  'int']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
                 
@@ -188,7 +177,7 @@
         fn = FormFn(self.xd.domain_device_configure,
                     [['dom',    'int'],
                      ['config', 'sxpr'],
-                     ['idx',    'str']])
+                     ['idx',    'int']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
 
@@ -230,10 +219,6 @@
             self.print_path(req)
             #self.ls()
             req.write('<p>%s</p>' % self.dom)
-            if self.dom.config:
-                req.write("<code><pre>")
-                PrettyPrint.prettyprint(self.dom.config, out=req)
-                req.write("</pre></code>")
             self.form(req)
             req.write('</body></html>')
         return ''
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
tools/python/xen/xend/server/SrvDomainDir.py
--- a/tools/python/xen/xend/server/SrvDomainDir.py      Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/server/SrvDomainDir.py      Wed Sep 28 20:06:49 2005
@@ -38,19 +38,17 @@
         self.xd = XendDomain.instance()
 
     def domain(self, x):
-        val = None
         dom = self.xd.domain_lookup_by_name(x)
         if not dom:
             raise XendError('No such domain ' + str(x))
-        val = SrvDomain(dom)
-        return val
+        return SrvDomain(dom)
 
     def get(self, x):
         v = SrvDir.get(self, x)
         if v is not None:
             return v
-        v = self.domain(x)
-        return v
+        else:
+            return self.domain(x)
 
     def op_create(self, op, req):
         """Create a domain.
@@ -152,11 +150,11 @@
             domains = self.xd.list_sorted()
             req.write('<ul>')
             for d in domains:
-                req.write('<li><a href="%s%s"> Domain %s</a>'
-                          % (url, d.getName(), d.getName()))
-                req.write('id=%s' % d.getDomain())
-                req.write('memory=%d'% d.getMemoryTarget())
-                req.write('ssidref=%d'% d.getSsidref())
+                req.write(
+                    '<li><a href="%s%s">Domain %s</a>: id = %s, memory = %d, '
+                    'ssidref = %d.'
+                    % (url, d.getName(), d.getName(), d.getDomid(),
+                       d.getMemoryTarget(), d.getSsidref()))
                 req.write('</li>')
             req.write('</ul>')
 
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvNode.py
--- a/tools/python/xen/xend/server/SrvNode.py   Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/server/SrvNode.py   Wed Sep 28 20:06:49 2005
@@ -62,7 +62,7 @@
             for d in self.info():
                 req.write('<li> %10s: %s' % (d[0], str(d[1])))
             req.write('<li><a href="%sdmesg">Xen dmesg output</a>' % url)
-            req.write('<li><a href="%slog>Xend log</a>' % url)
+            req.write('<li><a href="%slog">Xend log</a>' % url)
             req.write('</ul>')
             req.write('</body></html>')
             
diff -r 4e1031ce3bc2 -r 5e5ae8340956 
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py      Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py      Wed Sep 28 20:06:49 2005
@@ -1,4 +1,5 @@
 # Copyright (C) 2005 Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
+# Copyright (C) 2005 XenSource Ltd
 
 # This file is subject to the terms and conditions of the GNU General
 # Public License.  See the file "COPYING" in the main directory of
@@ -8,6 +9,7 @@
 import threading
 from xen.lowlevel import xs
 from xen.xend.xenstore.xsutil import xshandle
+
 
 class xstransact:
 
@@ -40,8 +42,15 @@
                                '%s, while reading %s' % (ex.args[1], path))
 
     def read(self, *args):
-        if len(args) == 0:
-            raise TypeError
+        """If no arguments are given, return the value at this transaction's
+        path.  If one argument is given, treat that argument as a subpath to
+        this transaction's path, and return the value at that path.
+        Otherwise, treat each argument as a subpath to this transaction's
+        path, and return a list composed of the values at each of those
+        instead.
+        """
+        if len(args) == 0:
+            return xshandle().read(self.path)
         if len(args) == 1:
             return self._read(args[0])
         ret = []
@@ -105,12 +114,49 @@
         return []
 
     def list(self, *args):
-        if len(args) == 0:
-            raise TypeError
+        """If no arguments are given, list this transaction's path, returning
+        the entries therein, or the empty list if no entries are found.
+        Otherwise, treat each argument as a subpath to this transaction's
+        path, and return the cumulative listing of each of those instead.
+        """
+        if len(args) == 0:
+            ret = xshandle().ls(self.path)
+            if ret is None:
+                return []
+            else:
+                return ret
+        else:
+            ret = []
+            for key in args:
+                ret.extend(self._list(key))
+            return ret
+
+
+    def list_recursive_(self, subdir, keys):
         ret = []
-        for key in args:
-            ret.extend(self._list(key))
+        for key in keys:
+            new_subdir = subdir + "/" + key
+            l = xshandle().ls(new_subdir)
+            if l:
+                ret.append([key, self.list_recursive_(new_subdir, l)])
+            else:
+                ret.append([key, xshandle().read(new_subdir)])
         return ret
+
+
+    def list_recursive(self, *args):
+        """If no arguments are given, list this transaction's path, returning
+        the entries therein, or the empty list if no entries are found.
+        Otherwise, treat each argument as a subpath to this transaction's
+        path, and return the cumulative listing of each of those instead.
+        """
+        if len(args) == 0:
+            args = self.list()
+            if args is None or len(args) == 0:
+                return []
+
+        return self.list_recursive_(self.path, args)
+
 
     def gather(self, *args):
         if len(args) and type(args[0]) != tuple:
@@ -163,6 +209,13 @@
 
 
     def Read(cls, path, *args):
+        """If only one argument is given (path), return the value stored at
+        that path.  If two arguments are given, treat the second argument as a
+        subpath within the first, and return the value at the composed path.
+        Otherwise, treat each argument after the first as a subpath to the
+        given path, and return a list composed of the values at each of those
+        instead.  This operation is performed inside a transaction.
+        """
         while True:
             t = cls(path)
             try:
@@ -206,6 +259,12 @@
     Remove = classmethod(Remove)
 
     def List(cls, path, *args):
+        """If only one argument is given (path), list its contents, returning
+        the entries therein, or the empty list if no entries are found.
+        Otherwise, treat each further argument as a subpath to the given path,
+        and return the cumulative listing of each of those instead.  This
+        operation is performed inside a transaction.
+        """
         while True:
             t = cls(path)
             try:
@@ -218,6 +277,25 @@
 
     List = classmethod(List)
 
+    def ListRecursive(cls, path, *args):
+        """If only one argument is given (path), list its contents
+        recursively, returning the entries therein, or the empty list if no
+        entries are found.  Otherwise, treat each further argument as a
+        subpath to the given path, and return the cumulative listing of each
+        of those instead.  This operation is performed inside a transaction.
+        """
+        while True:
+            t = cls(path)
+            try:
+                v = t.list_recursive(*args)
+                if t.commit():
+                    return v
+            except:
+                t.abort()
+                raise
+
+    ListRecursive = classmethod(ListRecursive)
+
     def Gather(cls, path, *args):
         while True:
             t = cls(path)
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Mon Sep 26 17:15:55 2005
+++ b/tools/python/xen/xm/main.py       Wed Sep 28 20:06:49 2005
@@ -175,6 +175,10 @@
 
     dom = args[0] # TODO: should check if this exists
     savefile = os.path.abspath(args[1])
+
+    if not os.access(os.path.dirname(savefile), os.W_OK):
+        err("xm save: Unable to create file %s" % savefile)
+        sys.exit(1)
     
     from xen.xend.XendClient import server
     server.xend_domain_save(dom, savefile)
@@ -183,6 +187,10 @@
     arg_check(args,1,"restore")
 
     savefile = os.path.abspath(args[0])
+
+    if not os.access(savefile, os.R_OK):
+        err("xm restore: Unable to read file %s" % savefile)
+        sys.exit(1)
 
     from xen.xend.XendClient import server
     info = server.xend_domain_restore(savefile)
diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Mon Sep 26 17:15:55 2005
+++ b/tools/xenstore/xenstored_domain.c Wed Sep 28 20:06:49 2005
@@ -63,6 +63,8 @@
        /* The connection associated with this. */
        struct connection *conn;
 
+       /* Have we noticed that this domain is shutdown? */
+       int shutdown;
 };
 
 static LIST_HEAD(domains);
@@ -222,19 +224,25 @@
 {
        xc_dominfo_t dominfo;
        struct domain *domain, *tmp;
-       int released = 0;
+       int notify = 0;
 
        list_for_each_entry_safe(domain, tmp, &domains, list) {
                if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
                                      &dominfo) == 1 &&
-                   dominfo.domid == domain->domid &&
-                   !dominfo.dying && !dominfo.crashed && !dominfo.shutdown)
-                       continue;
+                   dominfo.domid == domain->domid) {
+                       if ((dominfo.crashed || dominfo.shutdown)
+                           && !domain->shutdown) {
+                               domain->shutdown = 1;
+                               notify = 1;
+                       }
+                       if (!dominfo.dying)
+                               continue;
+               }
                talloc_free(domain->conn);
-               released++;
-       }
-
-       if (released)
+               notify = 1;
+       }
+
+       if (notify)
                fire_watches(NULL, "@releaseDomain", false);
 }
 
@@ -272,6 +280,7 @@
        struct domain *domain;
        domain = talloc(context, struct domain);
        domain->port = 0;
+       domain->shutdown = 0;
        domain->domid = domid;
        domain->path = talloc_strdup(domain, path);
        domain->page = xc_map_foreign_range(*xc_handle, domain->domid,
diff -r 4e1031ce3bc2 -r 5e5ae8340956 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Mon Sep 26 17:15:55 2005
+++ b/xen/arch/x86/shadow32.c   Wed Sep 28 20:06:49 2005
@@ -755,9 +755,13 @@
 
     /*
      * Then free monitor_table.
+     * Note: for VMX guest, only BSP need do this free.
      */
-    mfn = pagetable_get_pfn(v->arch.monitor_table);
-    free_domheap_page(&frame_table[mfn]);
+    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
+        mfn = pagetable_get_pfn(v->arch.monitor_table);
+        unmap_domain_page(v->arch.monitor_vtable);
+        free_domheap_page(&frame_table[mfn]);
+    }
 
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
diff -r 4e1031ce3bc2 -r 5e5ae8340956 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Mon Sep 26 17:15:55 2005
+++ b/xen/arch/x86/shadow_public.c      Wed Sep 28 20:06:49 2005
@@ -256,14 +256,15 @@
 {
     unsigned long mfn;
 
-//    ASSERT( pagetable_val(v->arch.monitor_table) );
     /*
      * free monitor_table.
+     * Note: for VMX guest, only BSP need do this free.
      */
-    //mfn = (pagetable_val(v->arch.monitor_table)) >> PAGE_SHIFT;
-    mfn = pagetable_get_pfn(v->arch.monitor_table);
-    unmap_domain_page(v->arch.monitor_vtable);
-    free_domheap_page(&frame_table[mfn]);
+    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
+        mfn = pagetable_get_pfn(v->arch.monitor_table);
+        unmap_domain_page(v->arch.monitor_vtable);
+        free_domheap_page(&frame_table[mfn]);
+    }
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
 }
@@ -358,9 +359,13 @@
 
     /*
      * Then free monitor_table.
+     * Note: for VMX guest, only BSP need do this free.
      */
-    mfn = pagetable_get_pfn(v->arch.monitor_table);
-    free_domheap_page(&frame_table[mfn]);
+    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
+        mfn = pagetable_get_pfn(v->arch.monitor_table);
+        unmap_domain_page(v->arch.monitor_vtable);
+        free_domheap_page(&frame_table[mfn]);
+    }
 
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
diff -r 4e1031ce3bc2 -r 5e5ae8340956 xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c       Mon Sep 26 17:15:55 2005
+++ b/xen/arch/x86/vmx_platform.c       Wed Sep 28 20:06:49 2005
@@ -667,6 +667,7 @@
     mpcip->instr = inst->instr;
     mpcip->operand[0] = inst->operand[0]; /* source */
     mpcip->operand[1] = inst->operand[1]; /* destination */
+    mpcip->immediate = inst->immediate;
 
     if (inst->operand[0] & REGISTER) { /* dest is memory */
         index = operand_index(inst->operand[0]);
@@ -833,12 +834,16 @@
         mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mpcip, regs);
         break;
 
-    case INSTR_CMP:
-        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
-        break;
-
+    case INSTR_CMP:        /* Pass through */
     case INSTR_TEST:
-        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
+        mpcip->flags = mmio_inst.flags;
+        mpcip->instr = mmio_inst.instr;
+        mpcip->operand[0] = mmio_inst.operand[0]; /* source */
+        mpcip->operand[1] = mmio_inst.operand[1]; /* destination */
+        mpcip->immediate = mmio_inst.immediate;
+
+        /* send the request and wait for the value */
+        send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, mmio_inst.op_size, 0, 
IOREQ_READ, 0);
         break;
 
     default:

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.