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

[Xen-changelog] Merge xen-unstable into xen-ia64-unstable



# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID 61b3b357d827ce0d803b7fee2e72e65cfe2aec41
# Parent  93e27f7ca8a83da233a90ae11c75745c86ec639a
# Parent  d88e98fd4f7a6d007b3f905a1f3c36c53fd7427a
Merge xen-unstable into xen-ia64-unstable

diff -r 93e27f7ca8a8 -r 61b3b357d827 .hgignore
--- a/.hgignore Thu Sep 29 22:22:02 2005
+++ b/.hgignore Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
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        Thu Sep 
29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Thu Sep 
29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Thu Sep 29 
23:28:44 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,14 @@
                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
+       local_irq_enable(); /* XXX Needed for smp_resume(). Clean me up. */
+       smp_resume();
+#endif
        cpu_set(smp_processor_id(), cpu_online_map);
 }
 #else
@@ -135,10 +147,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 +174,6 @@
                                HYPERVISOR_vcpu_down(cpu);
 #endif
                                play_dead();
-#ifdef CONFIG_SMP
-                               smp_resume();
-#endif
                                local_irq_enable();
                        }
 
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c   Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c   Thu Sep 29 23:28:44 2005
@@ -131,21 +131,9 @@
 
 static inline void __send_IPI_one(unsigned int cpu, int vector)
 {
-       unsigned int evtchn;
-
-       evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
-       // printk("send_IPI_mask_bitmask cpu %d vector %d evtchn %d\n", cpu, 
vector, evtchn);
-       if (evtchn) {
-#if 0
-               shared_info_t *s = HYPERVISOR_shared_info;
-               while (synch_test_bit(evtchn, &s->evtchn_pending[0]) ||
-                      synch_test_bit(evtchn, &s->evtchn_mask[0]))
-                       ;
-#endif
-               notify_via_evtchn(evtchn);
-       } else
-               printk("send_IPI to unbound port %d/%d",
-                      cpu, vector);
+       int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
+       BUG_ON(evtchn < 0);
+       notify_remote_via_evtchn(evtchn);
 }
 
 void __send_IPI_shortcut(unsigned int shortcut, int vector)
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Thu Sep 29 
23:28:44 2005
@@ -446,27 +446,6 @@
 
 static int cpucount;
 
-
-static irqreturn_t ldebug_interrupt(
-       int irq, void *dev_id, struct pt_regs *regs)
-{
-       return IRQ_HANDLED;
-}
-
-static DEFINE_PER_CPU(int, ldebug_irq);
-static char ldebug_name[NR_CPUS][15];
-
-void ldebug_setup(void)
-{
-       int cpu = smp_processor_id();
-
-       per_cpu(ldebug_irq, cpu) = bind_virq_to_irq(VIRQ_DEBUG);
-       sprintf(ldebug_name[cpu], "ldebug%d", cpu);
-       BUG_ON(request_irq(per_cpu(ldebug_irq, cpu), ldebug_interrupt,
-                          SA_INTERRUPT, ldebug_name[cpu], NULL));
-}
-
-
 extern void local_setup_timer(void);
 
 /*
@@ -484,7 +463,6 @@
        while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
                rep_nop();
        local_setup_timer();
-       ldebug_setup();
        smp_intr_init();
        local_irq_enable();
        /*
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Thu Sep 29 23:28:44 2005
@@ -186,8 +186,8 @@
                "mov  %4,%%eax ; "
                "mov  %%edx,%4 ; "
                "mul  %5       ; "
+               "xor  %5,%5    ; "
                "add  %4,%%eax ; "
-               "xor  %5,%5    ; "
                "adc  %5,%%edx ; "
                : "=A" (product), "=r" (tmp1), "=r" (tmp2)
                : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
@@ -836,13 +836,6 @@
        cpu_clear(smp_processor_id(), nohz_cpu_mask);
 }
 
-void time_suspend(void)
-{
-       /* nothing */
-       teardown_irq(per_cpu(timer_irq, 0), &irq_timer);
-       unbind_virq_from_irq(VIRQ_TIMER);
-}
-
 /* No locking required. We are only CPU running, and interrupts are off. */
 void time_resume(void)
 {
@@ -854,9 +847,6 @@
        per_cpu(processed_system_time, 0) = processed_system_time;
 
        update_wallclock();
-
-       per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER);
-       (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
 }
 
 #ifdef CONFIG_SMP
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c     Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c     Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/kernel/devmem.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/devmem.c     Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/devmem.c     Thu Sep 29 23:28:44 2005
@@ -144,3 +144,13 @@
        .mmap           = mmap_mem,
        .open           = open_mem,
 };
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Thu Sep 29 23:28:44 2005
@@ -3,7 +3,7 @@
  * 
  * Communication via Xen event channels.
  * 
- * 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:
@@ -73,27 +73,33 @@
 static u8  cpu_evtchn[NR_EVENT_CHANNELS];
 static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32];
 
-#define active_evtchns(cpu,sh,idx)              \
-    ((sh)->evtchn_pending[idx] &                \
-     cpu_evtchn_mask[cpu][idx] &                \
-     ~(sh)->evtchn_mask[idx])
-
-void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
-{
-    clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
-    set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
-    cpu_evtchn[chn] = cpu;
+#define active_evtchns(cpu,sh,idx)             \
+       ((sh)->evtchn_pending[idx] &            \
+        cpu_evtchn_mask[cpu][idx] &            \
+        ~(sh)->evtchn_mask[idx])
+
+static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
+{
+       clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
+       set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
+       cpu_evtchn[chn] = cpu;
+}
+
+static void init_evtchn_cpu_bindings(void)
+{
+       /* By default all event channels notify CPU#0. */
+       memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
+       memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
 }
 
 #else
 
-#define active_evtchns(cpu,sh,idx)              \
-    ((sh)->evtchn_pending[idx] &                \
-     ~(sh)->evtchn_mask[idx])
-
-void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
-{
-}
+#define active_evtchns(cpu,sh,idx)             \
+       ((sh)->evtchn_pending[idx] &            \
+        ~(sh)->evtchn_mask[idx])
+#define bind_evtchn_to_cpu(chn,cpu)    ((void)0)
+#define init_evtchn_cpu_bindings()     ((void)0)
+
 #endif
 
 /* Upcall to generic IRQ layer. */
@@ -108,9 +114,9 @@
 #elif defined (__x86_64__)
 #define IRQ_REG orig_rax
 #endif
-#define do_IRQ(irq, regs) do {                  \
-    (regs)->IRQ_REG = (irq);                    \
-    do_IRQ((regs));                             \
+#define do_IRQ(irq, regs) do {                 \
+       (regs)->IRQ_REG = (irq);                \
+       do_IRQ((regs));                         \
 } while (0)
 #endif
 
@@ -123,249 +129,241 @@
  */
 void force_evtchn_callback(void)
 {
-    (void)HYPERVISOR_xen_version(0, NULL);
+       (void)HYPERVISOR_xen_version(0, NULL);
 }
 EXPORT_SYMBOL(force_evtchn_callback);
 
 /* NB. Interrupts are disabled on entry. */
 asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
 {
-    u32     l1, l2;
-    unsigned int   l1i, l2i, port;
-    int            irq, cpu = smp_processor_id();
-    shared_info_t *s = HYPERVISOR_shared_info;
-    vcpu_info_t   *vcpu_info = &s->vcpu_data[cpu];
-
-    vcpu_info->evtchn_upcall_pending = 0;
-
-    /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
-    l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
-    while ( l1 != 0 )
-    {
-        l1i = __ffs(l1);
-        l1 &= ~(1 << l1i);
+       u32     l1, l2;
+       unsigned int   l1i, l2i, port;
+       int            irq, cpu = smp_processor_id();
+       shared_info_t *s = HYPERVISOR_shared_info;
+       vcpu_info_t   *vcpu_info = &s->vcpu_data[cpu];
+
+       vcpu_info->evtchn_upcall_pending = 0;
+
+       /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
+       l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
+       while (l1 != 0) {
+               l1i = __ffs(l1);
+               l1 &= ~(1 << l1i);
         
-        while ( (l2 = active_evtchns(cpu, s, l1i)) != 0 )
-        {
-            l2i = __ffs(l2);
-            l2 &= ~(1 << l2i);
+               while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
+                       l2i = __ffs(l2);
+                       l2 &= ~(1 << l2i);
             
-            port = (l1i << 5) + l2i;
-            if ( (irq = evtchn_to_irq[port]) != -1 ) {
-                do_IRQ(irq, regs);
-           } else
-                evtchn_device_upcall(port);
-        }
-    }
+                       port = (l1i << 5) + l2i;
+                       if ((irq = evtchn_to_irq[port]) != -1)
+                               do_IRQ(irq, regs);
+                       else
+                               evtchn_device_upcall(port);
+               }
+       }
 }
 EXPORT_SYMBOL(evtchn_do_upcall);
 
 static int find_unbound_irq(void)
 {
-    int irq;
-
-    for ( irq = 0; irq < NR_IRQS; irq++ )
-        if ( irq_bindcount[irq] == 0 )
-            break;
-
-    if ( irq == NR_IRQS )
-        panic("No available IRQ to bind to: increase NR_IRQS!\n");
-
-    return irq;
+       int irq;
+
+       for (irq = 0; irq < NR_IRQS; irq++)
+               if (irq_bindcount[irq] == 0)
+                       break;
+
+       if (irq == NR_IRQS)
+               panic("No available IRQ to bind to: increase NR_IRQS!\n");
+
+       return irq;
 }
 
 int bind_virq_to_irq(int virq)
 {
-    evtchn_op_t op;
-    int evtchn, irq;
-    int cpu = smp_processor_id();
-
-    spin_lock(&irq_mapping_update_lock);
-
-    if ( (irq = per_cpu(virq_to_irq, cpu)[virq]) == -1 )
-    {
-        op.cmd              = EVTCHNOP_bind_virq;
-        op.u.bind_virq.virq = virq;
-        if ( HYPERVISOR_event_channel_op(&op) != 0 )
-            panic("Failed to bind virtual IRQ %d\n", virq);
-        evtchn = op.u.bind_virq.port;
-
-        irq = find_unbound_irq();
-        evtchn_to_irq[evtchn] = irq;
-        irq_to_evtchn[irq]    = evtchn;
-
-        per_cpu(virq_to_irq, cpu)[virq] = irq;
-
-        bind_evtchn_to_cpu(evtchn, cpu);
-    }
-
-    irq_bindcount[irq]++;
-
-    spin_unlock(&irq_mapping_update_lock);
+       evtchn_op_t op;
+       int evtchn, irq;
+       int cpu = smp_processor_id();
+
+       spin_lock(&irq_mapping_update_lock);
+
+       if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
+               op.cmd              = EVTCHNOP_bind_virq;
+               op.u.bind_virq.virq = virq;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+               evtchn = op.u.bind_virq.port;
+
+               irq = find_unbound_irq();
+               evtchn_to_irq[evtchn] = irq;
+               irq_to_evtchn[irq]    = evtchn;
+
+               per_cpu(virq_to_irq, cpu)[virq] = irq;
+
+               bind_evtchn_to_cpu(evtchn, cpu);
+       }
+
+       irq_bindcount[irq]++;
+
+       spin_unlock(&irq_mapping_update_lock);
     
-    return irq;
+       return irq;
 }
 EXPORT_SYMBOL(bind_virq_to_irq);
 
 void unbind_virq_from_irq(int virq)
 {
-    evtchn_op_t op;
-    int cpu    = smp_processor_id();
-    int irq    = per_cpu(virq_to_irq, cpu)[virq];
-    int evtchn = irq_to_evtchn[irq];
-
-    spin_lock(&irq_mapping_update_lock);
-
-    if ( --irq_bindcount[irq] == 0 )
-    {
-        op.cmd          = EVTCHNOP_close;
-        op.u.close.dom  = DOMID_SELF;
-        op.u.close.port = evtchn;
-        if ( HYPERVISOR_event_channel_op(&op) != 0 )
-            panic("Failed to unbind virtual IRQ %d\n", virq);
-
-        /*
-         * This is a slight hack. Interdomain ports can be allocated directly 
-         * by userspace, and at that point they get bound by Xen to vcpu 0. We 
-         * therefore need to make sure that if we get an event on an event 
-         * channel we don't know about vcpu 0 handles it. Binding channels to 
-         * vcpu 0 when closing them achieves this.
-         */
-        bind_evtchn_to_cpu(evtchn, 0);
-        evtchn_to_irq[evtchn] = -1;
-        irq_to_evtchn[irq]    = -1;
-        per_cpu(virq_to_irq, cpu)[virq]     = -1;
-    }
-
-    spin_unlock(&irq_mapping_update_lock);
+       evtchn_op_t op;
+       int cpu    = smp_processor_id();
+       int irq    = per_cpu(virq_to_irq, cpu)[virq];
+       int evtchn = irq_to_evtchn[irq];
+
+       spin_lock(&irq_mapping_update_lock);
+
+       if (--irq_bindcount[irq] == 0) {
+               op.cmd          = EVTCHNOP_close;
+               op.u.close.dom  = DOMID_SELF;
+               op.u.close.port = evtchn;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
+               /*
+                * This is a slight hack. Interdomain ports can be allocated 
+                * directly by userspace, and at that point they get bound by 
+                * Xen to vcpu 0. We therefore need to make sure that if we get
+                * an event on an event channel we don't know about vcpu 0 
+                * handles it. Binding channels to vcpu 0 when closing them
+                * achieves this.
+                */
+               bind_evtchn_to_cpu(evtchn, 0);
+               evtchn_to_irq[evtchn] = -1;
+               irq_to_evtchn[irq]    = -1;
+               per_cpu(virq_to_irq, cpu)[virq] = -1;
+       }
+
+       spin_unlock(&irq_mapping_update_lock);
 }
 EXPORT_SYMBOL(unbind_virq_from_irq);
 
 int bind_ipi_to_irq(int ipi)
 {
-    evtchn_op_t op;
-    int evtchn, irq;
-    int cpu = smp_processor_id();
-
-    spin_lock(&irq_mapping_update_lock);
-
-    if ( (evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0 )
-    {
-        op.cmd = EVTCHNOP_bind_ipi;
-        if ( HYPERVISOR_event_channel_op(&op) != 0 )
-            panic("Failed to bind virtual IPI %d on cpu %d\n", ipi, cpu);
-        evtchn = op.u.bind_ipi.port;
-
-        irq = find_unbound_irq();
-        evtchn_to_irq[evtchn] = irq;
-        irq_to_evtchn[irq]    = evtchn;
-
-        per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
-
-        bind_evtchn_to_cpu(evtchn, cpu);
-    } 
-    else
-    {
-        irq = evtchn_to_irq[evtchn];
-    }
-
-    irq_bindcount[irq]++;
-
-    spin_unlock(&irq_mapping_update_lock);
-
-    return irq;
+       evtchn_op_t op;
+       int evtchn, irq;
+       int cpu = smp_processor_id();
+
+       spin_lock(&irq_mapping_update_lock);
+
+       if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) {
+               op.cmd = EVTCHNOP_bind_ipi;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+               evtchn = op.u.bind_ipi.port;
+
+               irq = find_unbound_irq();
+               evtchn_to_irq[evtchn] = irq;
+               irq_to_evtchn[irq]    = evtchn;
+
+               per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
+
+               bind_evtchn_to_cpu(evtchn, cpu);
+       } else {
+               irq = evtchn_to_irq[evtchn];
+       }
+
+       irq_bindcount[irq]++;
+
+       spin_unlock(&irq_mapping_update_lock);
+
+       return irq;
 }
 EXPORT_SYMBOL(bind_ipi_to_irq);
 
 void unbind_ipi_from_irq(int ipi)
 {
-    evtchn_op_t op;
-    int cpu    = smp_processor_id();
-    int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
-    int irq    = evtchn_to_irq[evtchn];
-
-    spin_lock(&irq_mapping_update_lock);
-
-    if ( --irq_bindcount[irq] == 0 )
-    {
-        op.cmd          = EVTCHNOP_close;
-        op.u.close.dom  = DOMID_SELF;
-        op.u.close.port = evtchn;
-        if ( HYPERVISOR_event_channel_op(&op) != 0 )
-            panic("Failed to unbind virtual IPI %d on cpu %d\n", ipi, cpu);
-
-        /* See comments in unbind_virq_from_irq */
-        bind_evtchn_to_cpu(evtchn, 0);
-        evtchn_to_irq[evtchn] = -1;
-        irq_to_evtchn[irq]    = -1;
-        per_cpu(ipi_to_evtchn, cpu)[ipi] = 0;
-    }
-
-    spin_unlock(&irq_mapping_update_lock);
+       evtchn_op_t op;
+       int cpu    = smp_processor_id();
+       int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
+       int irq    = evtchn_to_irq[evtchn];
+
+       spin_lock(&irq_mapping_update_lock);
+
+       if (--irq_bindcount[irq] == 0) {
+               op.cmd          = EVTCHNOP_close;
+               op.u.close.dom  = DOMID_SELF;
+               op.u.close.port = evtchn;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
+               /* See comments in unbind_virq_from_irq */
+               bind_evtchn_to_cpu(evtchn, 0);
+               evtchn_to_irq[evtchn] = -1;
+               irq_to_evtchn[irq]    = -1;
+               per_cpu(ipi_to_evtchn, cpu)[ipi] = -1;
+       }
+
+       spin_unlock(&irq_mapping_update_lock);
 }
 EXPORT_SYMBOL(unbind_ipi_from_irq);
 
 int bind_evtchn_to_irq(unsigned int evtchn)
 {
-    int irq;
-
-    spin_lock(&irq_mapping_update_lock);
-
-    if ( (irq = evtchn_to_irq[evtchn]) == -1 )
-    {
-        irq = find_unbound_irq();
-        evtchn_to_irq[evtchn] = irq;
-        irq_to_evtchn[irq]    = evtchn;
-    }
-
-    irq_bindcount[irq]++;
-
-    spin_unlock(&irq_mapping_update_lock);
+       int irq;
+
+       spin_lock(&irq_mapping_update_lock);
+
+       if ((irq = evtchn_to_irq[evtchn]) == -1) {
+               irq = find_unbound_irq();
+               evtchn_to_irq[evtchn] = irq;
+               irq_to_evtchn[irq]    = evtchn;
+       }
+
+       irq_bindcount[irq]++;
+
+       spin_unlock(&irq_mapping_update_lock);
     
-    return irq;
+       return irq;
 }
 EXPORT_SYMBOL(bind_evtchn_to_irq);
 
-void unbind_evtchn_from_irq(unsigned int evtchn)
-{
-    int irq = evtchn_to_irq[evtchn];
-
-    spin_lock(&irq_mapping_update_lock);
-
-    if ( --irq_bindcount[irq] == 0 )
-    {
-        evtchn_to_irq[evtchn] = -1;
-        irq_to_evtchn[irq]    = -1;
-    }
-
-    spin_unlock(&irq_mapping_update_lock);
+void unbind_evtchn_from_irq(unsigned int irq)
+{
+       evtchn_op_t op;
+       int evtchn = irq_to_evtchn[irq];
+
+       spin_lock(&irq_mapping_update_lock);
+
+       if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
+               op.cmd          = EVTCHNOP_close;
+               op.u.close.dom  = DOMID_SELF;
+               op.u.close.port = evtchn;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
+               evtchn_to_irq[evtchn] = -1;
+               irq_to_evtchn[irq]    = -1;
+       }
+
+       spin_unlock(&irq_mapping_update_lock);
 }
 EXPORT_SYMBOL(unbind_evtchn_from_irq);
 
 int bind_evtchn_to_irqhandler(
-    unsigned int evtchn,
-    irqreturn_t (*handler)(int, void *, struct pt_regs *),
-    unsigned long irqflags,
-    const char *devname,
-    void *dev_id)
-{
-    unsigned int irq;
-    int retval;
-
-    irq = bind_evtchn_to_irq(evtchn);
-    retval = request_irq(irq, handler, irqflags, devname, dev_id);
-    if ( retval != 0 )
-        unbind_evtchn_from_irq(evtchn);
-
-    return retval;
+       unsigned int evtchn,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id)
+{
+       unsigned int irq;
+       int retval;
+
+       irq = bind_evtchn_to_irq(evtchn);
+       retval = request_irq(irq, handler, irqflags, devname, dev_id);
+       if (retval != 0)
+               unbind_evtchn_from_irq(irq);
+
+       return irq;
 }
 EXPORT_SYMBOL(bind_evtchn_to_irqhandler);
 
-void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
-{
-    unsigned int irq = evtchn_to_irq[evtchn];
-    free_irq(irq, dev_id);
-    unbind_evtchn_from_irq(evtchn);
+void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id)
+{
+       free_irq(irq, dev_id);
+       unbind_evtchn_from_irq(irq);
 }
 EXPORT_SYMBOL(unbind_evtchn_from_irqhandler);
 
@@ -378,50 +376,50 @@
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
 static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
 {
-    evtchn_op_t op;
-    int evtchn;
-
-    spin_lock(&irq_mapping_update_lock);
-    evtchn = irq_to_evtchn[irq];
-    if (!VALID_EVTCHN(evtchn)) {
-        spin_unlock(&irq_mapping_update_lock);
-        return;
-    }
-
-    /* Tell Xen to send future instances of this interrupt to other vcpu. */
-    op.cmd = EVTCHNOP_bind_vcpu;
-    op.u.bind_vcpu.port = evtchn;
-    op.u.bind_vcpu.vcpu = tcpu;
-
-    /*
-     * If this fails, it usually just indicates that we're dealing with a virq 
-     * or IPI channel, which don't actually need to be rebound. Ignore it, 
-     * but don't do the xenlinux-level rebind in that case.
-     */
-    if (HYPERVISOR_event_channel_op(&op) >= 0)
-        bind_evtchn_to_cpu(evtchn, tcpu);
-
-    spin_unlock(&irq_mapping_update_lock);
-
-    /*
-     * Now send the new target processor a NOP IPI. When this returns, it 
-     * will check for any pending interrupts, and so service any that got 
-     * delivered to the wrong processor by mistake.
-     * 
-     * XXX: The only time this is called with interrupts disabled is from the 
-     * hotplug/hotunplug path. In that case, all cpus are stopped with 
-     * interrupts disabled, and the missed interrupts will be picked up when 
-     * they start again. This is kind of a hack.
-     */
-    if (!irqs_disabled())
-        smp_call_function(do_nothing_function, NULL, 0, 0);
+       evtchn_op_t op;
+       int evtchn;
+
+       spin_lock(&irq_mapping_update_lock);
+       evtchn = irq_to_evtchn[irq];
+       if (!VALID_EVTCHN(evtchn)) {
+               spin_unlock(&irq_mapping_update_lock);
+               return;
+       }
+
+       /* Send future instances of this interrupt to other vcpu. */
+       op.cmd = EVTCHNOP_bind_vcpu;
+       op.u.bind_vcpu.port = evtchn;
+       op.u.bind_vcpu.vcpu = tcpu;
+
+       /*
+        * If this fails, it usually just indicates that we're dealing with a 
+        * virq or IPI channel, which don't actually need to be rebound. Ignore
+        * it, but don't do the xenlinux-level rebind in that case.
+        */
+       if (HYPERVISOR_event_channel_op(&op) >= 0)
+               bind_evtchn_to_cpu(evtchn, tcpu);
+
+       spin_unlock(&irq_mapping_update_lock);
+
+       /*
+        * Now send the new target processor a NOP IPI. When this returns, it
+        * will check for any pending interrupts, and so service any that got 
+        * delivered to the wrong processor by mistake.
+        * 
+        * XXX: The only time this is called with interrupts disabled is from
+        * the hotplug/hotunplug path. In that case, all cpus are stopped with 
+        * interrupts disabled, and the missed interrupts will be picked up
+        * when they start again. This is kind of a hack.
+        */
+       if (!irqs_disabled())
+               smp_call_function(do_nothing_function, NULL, 0, 0);
 }
 
 
 static void set_affinity_irq(unsigned irq, cpumask_t dest)
 {
-    unsigned tcpu = first_cpu(dest);
-    rebind_irq_to_cpu(irq, tcpu);
+       unsigned tcpu = first_cpu(dest);
+       rebind_irq_to_cpu(irq, tcpu);
 }
 
 /*
@@ -430,83 +428,84 @@
 
 static unsigned int startup_dynirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-
-    if ( !VALID_EVTCHN(evtchn) )
-        return 0;
-    unmask_evtchn(evtchn);
-    return 0;
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn))
+               unmask_evtchn(evtchn);
+       return 0;
 }
 
 static void shutdown_dynirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-
-    if ( !VALID_EVTCHN(evtchn) )
-        return;
-    mask_evtchn(evtchn);
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn))
+               mask_evtchn(evtchn);
 }
 
 static void enable_dynirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-
-    unmask_evtchn(evtchn);
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn))
+               unmask_evtchn(evtchn);
 }
 
 static void disable_dynirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-
-    mask_evtchn(evtchn);
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn))
+               mask_evtchn(evtchn);
 }
 
 static void ack_dynirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-
-    mask_evtchn(evtchn);
-    clear_evtchn(evtchn);
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn)) {
+               mask_evtchn(evtchn);
+               clear_evtchn(evtchn);
+       }
 }
 
 static void end_dynirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-
-    if ( !(irq_desc[irq].status & IRQ_DISABLED) )
-        unmask_evtchn(evtchn);
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED))
+               unmask_evtchn(evtchn);
 }
 
 static struct hw_interrupt_type dynirq_type = {
-    "Dynamic-irq",
-    startup_dynirq,
-    shutdown_dynirq,
-    enable_dynirq,
-    disable_dynirq,
-    ack_dynirq,
-    end_dynirq,
-    set_affinity_irq
+       "Dynamic-irq",
+       startup_dynirq,
+       shutdown_dynirq,
+       enable_dynirq,
+       disable_dynirq,
+       ack_dynirq,
+       end_dynirq,
+       set_affinity_irq
 };
 
 static inline void pirq_unmask_notify(int pirq)
 {
-    physdev_op_t op;
-    if ( unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0])) )
-    {
-        op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
-        (void)HYPERVISOR_physdev_op(&op);
-    }
+       physdev_op_t op;
+       if (unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0]))) {
+               op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
+               (void)HYPERVISOR_physdev_op(&op);
+       }
 }
 
 static inline void pirq_query_unmask(int pirq)
 {
-    physdev_op_t op;
-    op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
-    op.u.irq_status_query.irq = pirq;
-    (void)HYPERVISOR_physdev_op(&op);
-    clear_bit(pirq, &pirq_needs_unmask_notify[0]);
-    if ( op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY )
-        set_bit(pirq, &pirq_needs_unmask_notify[0]);
+       physdev_op_t op;
+       op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
+       op.u.irq_status_query.irq = pirq;
+       (void)HYPERVISOR_physdev_op(&op);
+       clear_bit(pirq, &pirq_needs_unmask_notify[0]);
+       if (op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY)
+               set_bit(pirq, &pirq_needs_unmask_notify[0]);
 }
 
 /*
@@ -517,218 +516,252 @@
 
 static unsigned int startup_pirq(unsigned int irq)
 {
-    evtchn_op_t op;
-    int evtchn;
-
-    op.cmd               = EVTCHNOP_bind_pirq;
-    op.u.bind_pirq.pirq  = irq;
-    /* NB. We are happy to share unless we are probing. */
-    op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
-    if ( HYPERVISOR_event_channel_op(&op) != 0 )
-    {
-        if ( !probing_irq(irq) ) /* Some failures are expected when probing. */
-            printk(KERN_INFO "Failed to obtain physical IRQ %d\n", irq);
-        return 0;
-    }
-    evtchn = op.u.bind_pirq.port;
-
-    pirq_query_unmask(irq_to_pirq(irq));
-
-    bind_evtchn_to_cpu(evtchn, 0);
-    evtchn_to_irq[evtchn] = irq;
-    irq_to_evtchn[irq]    = evtchn;
-
-    unmask_evtchn(evtchn);
-    pirq_unmask_notify(irq_to_pirq(irq));
-
-    return 0;
+       evtchn_op_t op;
+       int evtchn;
+
+       op.cmd               = EVTCHNOP_bind_pirq;
+       op.u.bind_pirq.pirq  = irq;
+       /* NB. We are happy to share unless we are probing. */
+       op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
+       if (HYPERVISOR_event_channel_op(&op) != 0) {
+               if ( !probing_irq(irq) )
+                       printk(KERN_INFO "Failed to obtain physical "
+                              "IRQ %d\n", irq);
+               return 0;
+       }
+       evtchn = op.u.bind_pirq.port;
+
+       pirq_query_unmask(irq_to_pirq(irq));
+
+       bind_evtchn_to_cpu(evtchn, 0);
+       evtchn_to_irq[evtchn] = irq;
+       irq_to_evtchn[irq]    = evtchn;
+
+       unmask_evtchn(evtchn);
+       pirq_unmask_notify(irq_to_pirq(irq));
+
+       return 0;
 }
 
 static void shutdown_pirq(unsigned int irq)
 {
-    evtchn_op_t op;
-    int evtchn = irq_to_evtchn[irq];
-
-    if ( !VALID_EVTCHN(evtchn) )
-        return;
-
-    mask_evtchn(evtchn);
-
-    op.cmd          = EVTCHNOP_close;
-    op.u.close.dom  = DOMID_SELF;
-    op.u.close.port = evtchn;
-    if ( HYPERVISOR_event_channel_op(&op) != 0 )
-        panic("Failed to unbind physical IRQ %d\n", irq);
-
-    bind_evtchn_to_cpu(evtchn, 0);
-    evtchn_to_irq[evtchn] = -1;
-    irq_to_evtchn[irq]    = -1;
+       evtchn_op_t op;
+       int evtchn = irq_to_evtchn[irq];
+
+       if (!VALID_EVTCHN(evtchn))
+               return;
+
+       mask_evtchn(evtchn);
+
+       op.cmd          = EVTCHNOP_close;
+       op.u.close.dom  = DOMID_SELF;
+       op.u.close.port = evtchn;
+       BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
+       bind_evtchn_to_cpu(evtchn, 0);
+       evtchn_to_irq[evtchn] = -1;
+       irq_to_evtchn[irq]    = -1;
 }
 
 static void enable_pirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-    if ( !VALID_EVTCHN(evtchn) )
-        return;
-    unmask_evtchn(evtchn);
-    pirq_unmask_notify(irq_to_pirq(irq));
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn)) {
+               unmask_evtchn(evtchn);
+               pirq_unmask_notify(irq_to_pirq(irq));
+       }
 }
 
 static void disable_pirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-    if ( !VALID_EVTCHN(evtchn) )
-        return;
-    mask_evtchn(evtchn);
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn))
+               mask_evtchn(evtchn);
 }
 
 static void ack_pirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-    if ( !VALID_EVTCHN(evtchn) )
-        return;
-    mask_evtchn(evtchn);
-    clear_evtchn(evtchn);
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn)) {
+               mask_evtchn(evtchn);
+               clear_evtchn(evtchn);
+       }
 }
 
 static void end_pirq(unsigned int irq)
 {
-    int evtchn = irq_to_evtchn[irq];
-    if ( !VALID_EVTCHN(evtchn) )
-        return;
-    if ( !(irq_desc[irq].status & IRQ_DISABLED) )
-    {
-        unmask_evtchn(evtchn);
-        pirq_unmask_notify(irq_to_pirq(irq));
-    }
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
+               unmask_evtchn(evtchn);
+               pirq_unmask_notify(irq_to_pirq(irq));
+       }
 }
 
 static struct hw_interrupt_type pirq_type = {
-    "Phys-irq",
-    startup_pirq,
-    shutdown_pirq,
-    enable_pirq,
-    disable_pirq,
-    ack_pirq,
-    end_pirq,
-    set_affinity_irq
+       "Phys-irq",
+       startup_pirq,
+       shutdown_pirq,
+       enable_pirq,
+       disable_pirq,
+       ack_pirq,
+       end_pirq,
+       set_affinity_irq
 };
 
 void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
 {
-    int evtchn = irq_to_evtchn[i];
-    shared_info_t *s = HYPERVISOR_shared_info;
-    if ( !VALID_EVTCHN(evtchn) )
-        return;
-    BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0]));
-    synch_set_bit(evtchn, &s->evtchn_pending[0]);
-}
-
-void irq_suspend(void)
-{
-    int pirq, virq, irq, evtchn;
-    int cpu = smp_processor_id(); /* XXX */
-
-    /* Unbind VIRQs from event channels. */
-    for ( virq = 0; virq < NR_VIRQS; virq++ )
-    {
-        if ( (irq = per_cpu(virq_to_irq, cpu)[virq]) == -1 )
-            continue;
-        evtchn = irq_to_evtchn[irq];
-
-        /* Mark the event channel as unused in our table. */
-        evtchn_to_irq[evtchn] = -1;
-        irq_to_evtchn[irq]    = -1;
-    }
-
-    /* Check that no PIRQs are still bound. */
-    for ( pirq = 0; pirq < NR_PIRQS; pirq++ )
-        if ( (evtchn = irq_to_evtchn[pirq_to_irq(pirq)]) != -1 )
-            panic("Suspend attempted while PIRQ %d bound to evtchn %d.\n",
-                  pirq, evtchn);
+       int evtchn = irq_to_evtchn[i];
+       shared_info_t *s = HYPERVISOR_shared_info;
+       if (!VALID_EVTCHN(evtchn))
+               return;
+       BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0]));
+       synch_set_bit(evtchn, &s->evtchn_pending[0]);
+}
+
+void notify_remote_via_irq(int irq)
+{
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn))
+               notify_remote_via_evtchn(evtchn);
 }
 
 void irq_resume(void)
 {
-    evtchn_op_t op;
-    int         virq, irq, evtchn;
-    int cpu = smp_processor_id(); /* XXX */
-
-    for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
-        mask_evtchn(evtchn); /* New event-channel space is not 'live' yet. */
-
-    for ( virq = 0; virq < NR_VIRQS; virq++ )
-    {
-        if ( (irq = per_cpu(virq_to_irq, cpu)[virq]) == -1 )
-            continue;
-
-        /* Get a new binding from Xen. */
-        op.cmd              = EVTCHNOP_bind_virq;
-        op.u.bind_virq.virq = virq;
-        if ( HYPERVISOR_event_channel_op(&op) != 0 )
-            panic("Failed to bind virtual IRQ %d\n", virq);
-        evtchn = op.u.bind_virq.port;
+       evtchn_op_t op;
+       int         cpu, pirq, virq, ipi, irq, evtchn;
+
+       init_evtchn_cpu_bindings();
+
+       /* New event-channel space is not 'live' yet. */
+       for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
+               mask_evtchn(evtchn);
+
+       /* Check that no PIRQs are still bound. */
+       for (pirq = 0; pirq < NR_PIRQS; pirq++)
+               BUG_ON(irq_to_evtchn[pirq_to_irq(pirq)] != -1);
+
+       /* Secondary CPUs must have no VIRQ or IPI bindings. */
+       for (cpu = 1; cpu < NR_CPUS; cpu++) {
+               for (virq = 0; virq < NR_VIRQS; virq++)
+                       BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1);
+               for (ipi = 0; ipi < NR_IPIS; ipi++)
+                       BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
+       }
+
+       /* No IRQ -> event-channel mappings. */
+       for (irq = 0; irq < NR_IRQS; irq++)
+               irq_to_evtchn[irq] = -1;
+
+       /* Primary CPU: rebind VIRQs automatically. */
+       for (virq = 0; virq < NR_VIRQS; virq++) {
+               if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
+                       continue;
+
+               /* Get a new binding from Xen. */
+               op.cmd              = EVTCHNOP_bind_virq;
+               op.u.bind_virq.virq = virq;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+               evtchn = op.u.bind_virq.port;
         
-        /* Record the new mapping. */
-        bind_evtchn_to_cpu(evtchn, 0);
-        evtchn_to_irq[evtchn] = irq;
-        irq_to_evtchn[irq]    = evtchn;
-
-        /* Ready for use. */
-        unmask_evtchn(evtchn);
-    }
+               /* Record the new mapping. */
+               evtchn_to_irq[evtchn] = irq;
+               irq_to_evtchn[irq]    = evtchn;
+
+               /* Ready for use. */
+               unmask_evtchn(evtchn);
+       }
+
+       /* Primary CPU: rebind IPIs automatically. */
+       for (ipi = 0; ipi < NR_IPIS; ipi++) {
+               if ((evtchn = per_cpu(ipi_to_evtchn, 0)[ipi]) == -1)
+                       continue;
+
+               irq = evtchn_to_irq[evtchn];
+               evtchn_to_irq[evtchn] = -1;
+
+               /* Get a new binding from Xen. */
+               op.cmd = EVTCHNOP_bind_ipi;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+               evtchn = op.u.bind_ipi.port;
+        
+               /* Record the new mapping. */
+               evtchn_to_irq[evtchn] = irq;
+               irq_to_evtchn[irq]    = evtchn;
+
+               /* Ready for use. */
+               unmask_evtchn(evtchn);
+       }
+
+       /* Remove defunct event-channel -> IRQ mappings. */
+       for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
+               if ((evtchn_to_irq[evtchn] != -1) &&
+                   (irq_to_evtchn[evtchn_to_irq[evtchn]] == -1))
+                       evtchn_to_irq[evtchn] = -1;
+       }
 }
 
 void __init init_IRQ(void)
 {
-    int i;
-    int cpu;
-
-    irq_ctx_init(0);
-
-    spin_lock_init(&irq_mapping_update_lock);
-
-#ifdef CONFIG_SMP
-    /* By default all event channels notify CPU#0. */
-    memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
-#endif
-
-    for ( cpu = 0; cpu < NR_CPUS; cpu++ ) {
-        /* No VIRQ -> IRQ mappings. */
-        for ( i = 0; i < NR_VIRQS; i++ )
-            per_cpu(virq_to_irq, cpu)[i] = -1;
-    }
-
-    /* No event-channel -> IRQ mappings. */
-    for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
-    {
-        evtchn_to_irq[i] = -1;
-        mask_evtchn(i); /* No event channels are 'live' right now. */
-    }
-
-    /* No IRQ -> event-channel mappings. */
-    for ( i = 0; i < NR_IRQS; i++ )
-        irq_to_evtchn[i] = -1;
-
-    for ( i = 0; i < NR_DYNIRQS; i++ )
-    {
-        /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
-        irq_bindcount[dynirq_to_irq(i)] = 0;
-
-        irq_desc[dynirq_to_irq(i)].status  = IRQ_DISABLED;
-        irq_desc[dynirq_to_irq(i)].action  = 0;
-        irq_desc[dynirq_to_irq(i)].depth   = 1;
-        irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
-    }
-
-    for ( i = 0; i < NR_PIRQS; i++ )
-    {
-        /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
-        irq_bindcount[pirq_to_irq(i)] = 1;
-
-        irq_desc[pirq_to_irq(i)].status  = IRQ_DISABLED;
-        irq_desc[pirq_to_irq(i)].action  = 0;
-        irq_desc[pirq_to_irq(i)].depth   = 1;
-        irq_desc[pirq_to_irq(i)].handler = &pirq_type;
-    }
-}
+       int i;
+       int cpu;
+
+       irq_ctx_init(0);
+
+       spin_lock_init(&irq_mapping_update_lock);
+
+       init_evtchn_cpu_bindings();
+
+       /* No VIRQ or IPI bindings. */
+       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+               for (i = 0; i < NR_VIRQS; i++)
+                       per_cpu(virq_to_irq, cpu)[i] = -1;
+               for (i = 0; i < NR_IPIS; i++)
+                       per_cpu(ipi_to_evtchn, cpu)[i] = -1;
+       }
+
+       /* No event-channel -> IRQ mappings. */
+       for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+               evtchn_to_irq[i] = -1;
+               mask_evtchn(i); /* No event channels are 'live' right now. */
+       }
+
+       /* No IRQ -> event-channel mappings. */
+       for (i = 0; i < NR_IRQS; i++)
+               irq_to_evtchn[i] = -1;
+
+       /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
+       for (i = 0; i < NR_DYNIRQS; i++) {
+               irq_bindcount[dynirq_to_irq(i)] = 0;
+
+               irq_desc[dynirq_to_irq(i)].status  = IRQ_DISABLED;
+               irq_desc[dynirq_to_irq(i)].action  = 0;
+               irq_desc[dynirq_to_irq(i)].depth   = 1;
+               irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
+       }
+
+       /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
+       for (i = 0; i < NR_PIRQS; i++)
+       {
+               irq_bindcount[pirq_to_irq(i)] = 1;
+
+               irq_desc[pirq_to_irq(i)].status  = IRQ_DISABLED;
+               irq_desc[pirq_to_irq(i)].action  = 0;
+               irq_desc[pirq_to_irq(i)].depth   = 1;
+               irq_desc[pirq_to_irq(i)].handler = &pirq_type;
+       }
+}
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/kernel/fixup.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/fixup.c      Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/fixup.c      Thu Sep 29 23:28:44 2005
@@ -37,51 +37,57 @@
 
 #define DP(_f, _args...) printk(KERN_ALERT "  " _f "\n" , ## _args )
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define __LINKAGE fastcall
-#else
-#define __LINKAGE asmlinkage
-#endif
+fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
+{
+       static unsigned long printed = 0;
+       char info[100];
+       int i;
 
-__LINKAGE void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
-{
-    static unsigned long printed = 0;
-    char info[100];
-    int i;
+       if (test_and_set_bit(0, &printed))
+               return;
 
-    if ( !test_and_set_bit(0, &printed) )
-    {
-        HYPERVISOR_vm_assist(VMASST_CMD_disable,
-                            VMASST_TYPE_4gb_segments_notify);
+       HYPERVISOR_vm_assist(
+               VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
 
-        sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
+       sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
 
-        DP("");
-        DP("***************************************************************");
-        DP("***************************************************************");
-        DP("** WARNING: Currently emulating unsupported memory accesses  **");
-        DP("**          in /lib/tls libraries. The emulation is very     **");
-        DP("**          slow. To ensure full performance you should      **");
-        DP("**          execute the following as root:                   **");
-        DP("**          mv /lib/tls /lib/tls.disabled                    **");
-        DP("** Offending process: %-38.38s **", info);
-        DP("***************************************************************");
-        DP("***************************************************************");
-        DP("");
 
-        for ( i = 5; i > 0; i-- )
-        {
-            printk("Pausing... %d", i);
-            mdelay(1000);
-            printk("\b\b\b\b\b\b\b\b\b\b\b\b");
-        }
-        printk("Continuing...\n\n");
-    }
+       DP("");
+       DP("***************************************************************");
+       DP("***************************************************************");
+       DP("** WARNING: Currently emulating unsupported memory accesses  **");
+       DP("**          in /lib/tls libraries. The emulation is very     **");
+       DP("**          slow. To ensure full performance you should      **");
+       DP("**          execute the following as root:                   **");
+       DP("**          mv /lib/tls /lib/tls.disabled                    **");
+       DP("** Offending process: %-38.38s **", info);
+       DP("***************************************************************");
+       DP("***************************************************************");
+       DP("");
+
+       for (i = 5; i > 0; i--) {
+               printk("Pausing... %d", i);
+               mdelay(1000);
+               printk("\b\b\b\b\b\b\b\b\b\b\b\b");
+       }
+
+       printk("Continuing...\n\n");
 }
 
 static int __init fixup_init(void)
 {
-    HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
-    return 0;
+       HYPERVISOR_vm_assist(
+               VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
+       return 0;
 }
 __initcall(fixup_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 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Thu Sep 29 23:28:44 2005
@@ -12,7 +12,6 @@
 #include <asm-xen/evtchn.h>
 #include <asm/hypervisor.h>
 #include <asm-xen/xen-public/dom0_ops.h>
-#include <asm-xen/queues.h>
 #include <asm-xen/xenbus.h>
 #include <linux/cpu.h>
 #include <linux/kthread.h>
@@ -43,12 +42,10 @@
        HYPERVISOR_shutdown();
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 int reboot_thru_bios = 0;      /* for dmi_scan.c */
 EXPORT_SYMBOL(machine_restart);
 EXPORT_SYMBOL(machine_halt);
 EXPORT_SYMBOL(machine_power_off);
-#endif
 
 
 /******************************************************************************
@@ -66,227 +63,194 @@
 
 static int __do_suspend(void *ignore)
 {
-    int i, j, k, fpp;
-
-#ifdef CONFIG_XEN_USB_FRONTEND
-    extern void usbif_resume();
-#else
-#define usbif_resume() do{}while(0)
-#endif
-
-    extern int gnttab_suspend(void);
-    extern int gnttab_resume(void);
-
-    extern void time_suspend(void);
-    extern void time_resume(void);
-    extern unsigned long max_pfn;
-    extern unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[];
+       int i, j, k, fpp;
+
+       extern int gnttab_suspend(void);
+       extern int gnttab_resume(void);
+
+       extern void time_resume(void);
+       extern unsigned long max_pfn;
+       extern unsigned long *pfn_to_mfn_frame_list_list;
+       extern unsigned long *pfn_to_mfn_frame_list[];
 
 #ifdef CONFIG_SMP
-    extern void smp_suspend(void);
-    extern void smp_resume(void);
-
-    static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
-    cpumask_t prev_online_cpus, prev_present_cpus;
-
-    void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
-    int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
-#endif
-
-    extern void xencons_suspend(void);
-    extern void xencons_resume(void);
-
-    int err = 0;
-
-    BUG_ON(smp_processor_id() != 0);
-    BUG_ON(in_interrupt());
+       static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
+       cpumask_t prev_online_cpus, prev_present_cpus;
+
+       void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
+       int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
+#endif
+
+       extern void xencons_resume(void);
+
+       int err = 0;
+
+       BUG_ON(smp_processor_id() != 0);
+       BUG_ON(in_interrupt());
 
 #if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
-    if (num_online_cpus() > 1) {
-       printk(KERN_WARNING 
-               "Can't suspend SMP guests without CONFIG_HOTPLUG_CPU\n");
-       return -EOPNOTSUPP;
-    }
-#endif
-
-    preempt_disable();
+       if (num_online_cpus() > 1) {
+               printk(KERN_WARNING "Can't suspend SMP guests "
+                      "without CONFIG_HOTPLUG_CPU\n");
+               return -EOPNOTSUPP;
+       }
+#endif
+
+       xenbus_suspend();
+
+       preempt_disable();
 #ifdef CONFIG_SMP
-    /* Take all of the other cpus offline.  We need to be careful not
-       to get preempted between the final test for num_online_cpus()
-       == 1 and disabling interrupts, since otherwise userspace could
-       bring another cpu online, and then we'd be stuffed.  At the
-       same time, cpu_down can reschedule, so we need to enable
-       preemption while doing that.  This kind of sucks, but should be
-       correct. */
-    /* (We don't need to worry about other cpus bringing stuff up,
-       since by the time num_online_cpus() == 1, there aren't any
-       other cpus) */
-    cpus_clear(prev_online_cpus);
-    while (num_online_cpus() > 1) {
+       /* Take all of the other cpus offline.  We need to be careful not
+          to get preempted between the final test for num_online_cpus()
+          == 1 and disabling interrupts, since otherwise userspace could
+          bring another cpu online, and then we'd be stuffed.  At the
+          same time, cpu_down can reschedule, so we need to enable
+          preemption while doing that.  This kind of sucks, but should be
+          correct. */
+       /* (We don't need to worry about other cpus bringing stuff up,
+          since by the time num_online_cpus() == 1, there aren't any
+          other cpus) */
+       cpus_clear(prev_online_cpus);
+       while (num_online_cpus() > 1) {
+               preempt_enable();
+               for_each_online_cpu(i) {
+                       if (i == 0)
+                               continue;
+                       err = cpu_down(i);
+                       if (err != 0) {
+                               printk(KERN_CRIT "Failed to take all CPUs "
+                                      "down: %d.\n", err);
+                               goto out_reenable_cpus;
+                       }
+                       cpu_set(i, prev_online_cpus);
+               }
+               preempt_disable();
+       }
+#endif
+
+       __cli();
+
        preempt_enable();
-       for_each_online_cpu(i) {
-           if (i == 0)
-               continue;
-           err = cpu_down(i);
-           if (err != 0) {
-               printk(KERN_CRIT "Failed to take all CPUs down: %d.\n", err);
-               goto out_reenable_cpus;
-           }
-           cpu_set(i, prev_online_cpus);
-       }
-       preempt_disable();
-    }
-#endif
-
-    __cli();
-
-    preempt_enable();
 
 #ifdef CONFIG_SMP
-    cpus_clear(prev_present_cpus);
-    for_each_present_cpu(i) {
-       if (i == 0)
-           continue;
-       save_vcpu_context(i, &suspended_cpu_records[i]);
-       cpu_set(i, prev_present_cpus);
-    }
-#endif
+       cpus_clear(prev_present_cpus);
+       for_each_present_cpu(i) {
+               if (i == 0)
+                       continue;
+               save_vcpu_context(i, &suspended_cpu_records[i]);
+               cpu_set(i, prev_present_cpus);
+       }
+#endif
+
+       gnttab_suspend();
 
 #ifdef __i386__
-    mm_pin_all();
-    kmem_cache_shrink(pgd_cache);
-#endif
-
-    time_suspend();
-
-#ifdef CONFIG_SMP
-    smp_suspend();
-#endif
-
-    xenbus_suspend();
-
-    xencons_suspend();
-
-    irq_suspend();
-
-    gnttab_suspend();
-
-    HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
-    clear_fixmap(FIX_SHARED_INFO);
-
-    xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
-    xen_start_info->console_mfn = mfn_to_pfn(xen_start_info->console_mfn);
-
-    /* We'll stop somewhere inside this hypercall.  When it returns,
-       we'll start resuming after the restore. */
-    HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
-
-    shutting_down = SHUTDOWN_INVALID; 
-
-    set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-
-    HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-
-    memset(empty_zero_page, 0, PAGE_SIZE);
+       mm_pin_all();
+       kmem_cache_shrink(pgd_cache);
+#endif
+
+       HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
+       clear_fixmap(FIX_SHARED_INFO);
+
+       xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
+       xen_start_info->console_mfn = mfn_to_pfn(xen_start_info->console_mfn);
+
+       /* We'll stop somewhere inside this hypercall.  When it returns,
+          we'll start resuming after the restore. */
+       HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
+
+       shutting_down = SHUTDOWN_INVALID; 
+
+       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+
+       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+
+       memset(empty_zero_page, 0, PAGE_SIZE);
             
-    HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
+       HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
                virt_to_mfn(pfn_to_mfn_frame_list_list);
   
-    fpp = PAGE_SIZE/sizeof(unsigned long);
-    for ( i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++ )
-    {
-       if ( (j % fpp) == 0 )
-       {
-           k++;
-           pfn_to_mfn_frame_list_list[k] = 
-                   virt_to_mfn(pfn_to_mfn_frame_list[k]);
-           j=0;
-       }
-       pfn_to_mfn_frame_list[k][j] = 
-               virt_to_mfn(&phys_to_machine_mapping[i]);
-    }
-    HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-
-    gnttab_resume();
-
-    irq_resume();
-
-    xencons_resume();
-
-    xenbus_resume();
+       fpp = PAGE_SIZE/sizeof(unsigned long);
+       for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
+               if ((j % fpp) == 0) {
+                       k++;
+                       pfn_to_mfn_frame_list_list[k] = 
+                               virt_to_mfn(pfn_to_mfn_frame_list[k]);
+                       j = 0;
+               }
+               pfn_to_mfn_frame_list[k][j] = 
+                       virt_to_mfn(&phys_to_machine_mapping[i]);
+       }
+       HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
+
+       gnttab_resume();
+
+       irq_resume();
+
+       time_resume();
 
 #ifdef CONFIG_SMP
-    smp_resume();
-#endif
-
-    time_resume();
-
-    usbif_resume();
-
-#ifdef CONFIG_SMP
-    for_each_cpu_mask(i, prev_present_cpus)
-       restore_vcpu_context(i, &suspended_cpu_records[i]);
-#endif
-
-    __sti();
+       for_each_cpu_mask(i, prev_present_cpus)
+               restore_vcpu_context(i, &suspended_cpu_records[i]);
+#endif
+
+       __sti();
+
+       xencons_resume();
+
+       xenbus_resume();
 
 #ifdef CONFIG_SMP
  out_reenable_cpus:
-    for_each_cpu_mask(i, prev_online_cpus) {
-       j = cpu_up(i);
-       if (j != 0) {
-           printk(KERN_CRIT "Failed to bring cpu %d back up (%d).\n",
-                  i, j);
-           err = j;
-       }
-    }
-#endif
-
-    return err;
+       for_each_cpu_mask(i, prev_online_cpus) {
+               j = cpu_up(i);
+               if (j != 0) {
+                       printk(KERN_CRIT "Failed to bring cpu "
+                              "%d back up (%d).\n",
+                              i, j);
+                       err = j;
+               }
+       }
+#endif
+
+       return err;
 }
 
 static int shutdown_process(void *__unused)
 {
-    static char *envp[] = { "HOME=/", "TERM=linux", 
-                            "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
-    static char *restart_argv[]  = { "/sbin/reboot", NULL };
-    static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
-
-    extern asmlinkage long sys_reboot(int magic1, int magic2,
-                                      unsigned int cmd, void *arg);
-
-    daemonize(
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        "shutdown"
-#endif
-        );
-
-    switch ( shutting_down )
-    {
-    case SHUTDOWN_POWEROFF:
-        if ( execve("/sbin/poweroff", poweroff_argv, envp) < 0 )
-        {
-            sys_reboot(LINUX_REBOOT_MAGIC1,
-                       LINUX_REBOOT_MAGIC2,
-                       LINUX_REBOOT_CMD_POWER_OFF,
-                       NULL);
-        }
-        break;
-
-    case SHUTDOWN_REBOOT:
-        if ( execve("/sbin/reboot", restart_argv, envp) < 0 )
-        {
-            sys_reboot(LINUX_REBOOT_MAGIC1,
-                       LINUX_REBOOT_MAGIC2,
-                       LINUX_REBOOT_CMD_RESTART,
-                       NULL);
-        }
-        break;
-    }
-
-    shutting_down = SHUTDOWN_INVALID; /* could try again */
-
-    return 0;
+       static char *envp[] = { "HOME=/", "TERM=linux", 
+                               "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+       static char *restart_argv[]  = { "/sbin/reboot", NULL };
+       static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
+
+       extern asmlinkage long sys_reboot(int magic1, int magic2,
+                                         unsigned int cmd, void *arg);
+
+       daemonize("shutdown");
+
+       switch (shutting_down) {
+       case SHUTDOWN_POWEROFF:
+               if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) {
+                       sys_reboot(LINUX_REBOOT_MAGIC1,
+                                  LINUX_REBOOT_MAGIC2,
+                                  LINUX_REBOOT_CMD_POWER_OFF,
+                                  NULL);
+               }
+               break;
+
+       case SHUTDOWN_REBOOT:
+               if (execve("/sbin/reboot", restart_argv, envp) < 0) {
+                       sys_reboot(LINUX_REBOOT_MAGIC1,
+                                  LINUX_REBOOT_MAGIC2,
+                                  LINUX_REBOOT_CMD_RESTART,
+                                  NULL);
+               }
+               break;
+       }
+
+       shutting_down = SHUTDOWN_INVALID; /* could try again */
+
+       return 0;
 }
 
 static struct task_struct *kthread_create_on_cpu(int (*f)(void *arg),
@@ -294,113 +258,109 @@
                                                 const char *name,
                                                 int cpu)
 {
-    struct task_struct *p;
-    p = kthread_create(f, arg, name);
-    kthread_bind(p, cpu);
-    wake_up_process(p);
-    return p;
+       struct task_struct *p;
+       p = kthread_create(f, arg, name);
+       kthread_bind(p, cpu);
+       wake_up_process(p);
+       return p;
 }
 
 static void __shutdown_handler(void *unused)
 {
-    int err;
-
-    if ( shutting_down != SHUTDOWN_SUSPEND )
-    {
-        err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES);
-        if ( err < 0 )
-            printk(KERN_ALERT "Error creating shutdown process!\n");
-    }
-    else
-    {
-       kthread_create_on_cpu(__do_suspend, NULL, "suspender", 0);
-    }
+       int err;
+
+       if (shutting_down != SHUTDOWN_SUSPEND) {
+               err = kernel_thread(shutdown_process, NULL,
+                                   CLONE_FS | CLONE_FILES);
+               if ( err < 0 )
+                       printk(KERN_ALERT "Error creating shutdown "
+                              "process!\n");
+       } else {
+               kthread_create_on_cpu(__do_suspend, NULL, "suspender", 0);
+       }
 }
 
 static void shutdown_handler(struct xenbus_watch *watch, const char *node)
 {
-    static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
-    char *str;
-    int err;
+       static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
+       char *str;
+       int err;
 
  again:
-    err = xenbus_transaction_start();
-    if (err)
-       return;
-    str = (char *)xenbus_read("control", "shutdown", NULL);
-    /* Ignore read errors and empty reads. */
-    if (XENBUS_IS_ERR_READ(str)) {
-       xenbus_transaction_end(1);
-       return;
-    }
-
-    xenbus_write("control", "shutdown", "");
-
-    err = xenbus_transaction_end(0);
-    if (err == -EAGAIN) {
+       err = xenbus_transaction_start();
+       if (err)
+               return;
+       str = (char *)xenbus_read("control", "shutdown", NULL);
+       /* Ignore read errors and empty reads. */
+       if (XENBUS_IS_ERR_READ(str)) {
+               xenbus_transaction_end(1);
+               return;
+       }
+
+       xenbus_write("control", "shutdown", "");
+
+       err = xenbus_transaction_end(0);
+       if (err == -EAGAIN) {
+               kfree(str);
+               goto again;
+       }
+
+       if (strcmp(str, "poweroff") == 0)
+               shutting_down = SHUTDOWN_POWEROFF;
+       else if (strcmp(str, "reboot") == 0)
+               shutting_down = SHUTDOWN_REBOOT;
+       else if (strcmp(str, "suspend") == 0)
+               shutting_down = SHUTDOWN_SUSPEND;
+       else {
+               printk("Ignoring shutdown request: %s\n", str);
+               shutting_down = SHUTDOWN_INVALID;
+       }
+
        kfree(str);
-       goto again;
-    }
-
-    if (strcmp(str, "poweroff") == 0)
-        shutting_down = SHUTDOWN_POWEROFF;
-    else if (strcmp(str, "reboot") == 0)
-        shutting_down = SHUTDOWN_REBOOT;
-    else if (strcmp(str, "suspend") == 0)
-        shutting_down = SHUTDOWN_SUSPEND;
-    else {
-        printk("Ignoring shutdown request: %s\n", str);
-        shutting_down = SHUTDOWN_INVALID;
-    }
-
-    kfree(str);
-
-    if (shutting_down != SHUTDOWN_INVALID)
-        schedule_work(&shutdown_work);
+
+       if (shutting_down != SHUTDOWN_INVALID)
+               schedule_work(&shutdown_work);
 }
 
 #ifdef CONFIG_MAGIC_SYSRQ
 static void sysrq_handler(struct xenbus_watch *watch, const char *node)
 {
-    char sysrq_key = '\0';
-    int err;
+       char sysrq_key = '\0';
+       int err;
 
  again:
-    err = xenbus_transaction_start();
-    if (err)
-       return;
-    if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
-        printk(KERN_ERR "Unable to read sysrq code in control/sysrq\n");
-       xenbus_transaction_end(1);
-       return;
-    }
-
-    if (sysrq_key != '\0')
-       xenbus_printf("control", "sysrq", "%c", '\0');
-
-    err = xenbus_transaction_end(0);
-    if (err == -EAGAIN)
-       goto again;
-
-    if (sysrq_key != '\0') {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        handle_sysrq(sysrq_key, NULL, NULL);
-#else
-        handle_sysrq(sysrq_key, NULL, NULL, NULL);
-#endif
-    }
+       err = xenbus_transaction_start();
+       if (err)
+               return;
+       if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
+               printk(KERN_ERR "Unable to read sysrq code in "
+                      "control/sysrq\n");
+               xenbus_transaction_end(1);
+               return;
+       }
+
+       if (sysrq_key != '\0')
+               xenbus_printf("control", "sysrq", "%c", '\0');
+
+       err = xenbus_transaction_end(0);
+       if (err == -EAGAIN)
+               goto again;
+
+       if (sysrq_key != '\0') {
+               handle_sysrq(sysrq_key, NULL, NULL);
+       }
 }
 #endif
 
 static struct xenbus_watch shutdown_watch = {
-    .node = "control/shutdown",
-    .callback = shutdown_handler
+       .node = "control/shutdown",
+       .callback = shutdown_handler
 };
 
 #ifdef CONFIG_MAGIC_SYSRQ
 static struct xenbus_watch sysrq_watch = {
-    .node ="control/sysrq",
-    .callback = sysrq_handler
+       .node ="control/sysrq",
+       .callback = sysrq_handler
 };
 #endif
 
@@ -413,39 +373,50 @@
                                   unsigned long event,
                                   void *data)
 {
-    int err1 = 0;
+       int err1 = 0;
 #ifdef CONFIG_MAGIC_SYSRQ
-    int err2 = 0;
-#endif
-
-    BUG_ON(down_trylock(&xenbus_lock) == 0);
-
-    err1 = register_xenbus_watch(&shutdown_watch);
+       int err2 = 0;
+#endif
+
+       BUG_ON(down_trylock(&xenbus_lock) == 0);
+
+       err1 = register_xenbus_watch(&shutdown_watch);
 #ifdef CONFIG_MAGIC_SYSRQ
-    err2 = register_xenbus_watch(&sysrq_watch);
-#endif
-
-    if (err1) {
-        printk(KERN_ERR "Failed to set shutdown watcher\n");
-    }
+       err2 = register_xenbus_watch(&sysrq_watch);
+#endif
+
+       if (err1) {
+               printk(KERN_ERR "Failed to set shutdown watcher\n");
+       }
     
 #ifdef CONFIG_MAGIC_SYSRQ
-    if (err2) {
-        printk(KERN_ERR "Failed to set sysrq watcher\n");
-    }
-#endif
-
-    return NOTIFY_DONE;
+       if (err2) {
+               printk(KERN_ERR "Failed to set sysrq watcher\n");
+       }
+#endif
+
+       return NOTIFY_DONE;
 }
 
 static int __init setup_shutdown_event(void)
 {
     
-    xenstore_notifier.notifier_call = setup_shutdown_watcher;
-
-    register_xenstore_notifier(&xenstore_notifier);
+       xenstore_notifier.notifier_call = setup_shutdown_watcher;
+
+       register_xenstore_notifier(&xenstore_notifier);
     
-    return 0;
+       return 0;
 }
 
 subsys_initcall(setup_shutdown_event);
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
+#
diff -r 93e27f7ca8a8 -r 61b3b357d827 linux-2.6-xen-sparse/arch/xen/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/smp.c        Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/smp.c        Thu Sep 29 23:28:44 2005
@@ -11,6 +11,15 @@
 int setup_profiling_timer(unsigned int multiplier)
 {
        printk("setup_profiling_timer\n");
-
        return 0;
 }
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c   Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c   Thu Sep 29 23:28:44 2005
@@ -6,13 +6,23 @@
 
 struct proc_dir_entry *create_xen_proc_entry(const char *name, mode_t mode)
 {
-    if ( xen_base == NULL )
-        if ( (xen_base = proc_mkdir("xen", &proc_root)) == NULL )
-            panic("Couldn't create /proc/xen");
-    return create_proc_entry(name, mode, xen_base);
+       if ( xen_base == NULL )
+               if ( (xen_base = proc_mkdir("xen", &proc_root)) == NULL )
+                       panic("Couldn't create /proc/xen");
+       return create_proc_entry(name, mode, xen_base);
 }
 
 void remove_xen_proc_entry(const char *name)
 {
-    remove_proc_entry(name, xen_base);
+       remove_proc_entry(name, xen_base);
 }
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S       Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S       Thu Sep 29 
23:28:44 2005
@@ -536,7 +536,7 @@
        CFI_ENDPROC
        .endm
 
-#ifdef CONFIG_SMP      
+#if 0
 ENTRY(reschedule_interrupt)
        apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
 
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Thu Sep 29 
23:28:44 2005
@@ -31,14 +31,9 @@
 
 static inline void __send_IPI_one(unsigned int cpu, int vector)
 {
-       unsigned int evtchn;
-       Dprintk("%s\n", __FUNCTION__);
-
-       evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
-       if (evtchn)
-               notify_via_evtchn(evtchn);
-       else
-               printk("send_IPI to unbound port %d/%d", cpu, vector);
+       int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
+       BUG_ON(evtchn < 0);
+       notify_remote_via_evtchn(evtchn);
 }
 
 void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int 
dest)
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Thu Sep 29 
23:28:44 2005
@@ -771,11 +771,14 @@
                                virt_to_mfn(&phys_to_machine_mapping[i]);
                }
                HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-               
-               
-
-
-
+       }
+
+       if ( ! (xen_start_info->flags & SIF_INITDOMAIN))
+       {
+               acpi_disabled = 1;
+#ifdef  CONFIG_ACPI_BOOT
+               acpi_ht = 0;
+#endif
        }
 #endif
 
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Thu Sep 29 
23:28:44 2005
@@ -445,25 +445,6 @@
 }
 
 #ifdef CONFIG_XEN
-static irqreturn_t ldebug_interrupt(
-       int irq, void *dev_id, struct pt_regs *regs)
-{
-       return IRQ_HANDLED;
-}
-
-static DEFINE_PER_CPU(int, ldebug_irq);
-static char ldebug_name[NR_CPUS][15];
-
-void ldebug_setup(void)
-{
-       int cpu = smp_processor_id();
-
-       per_cpu(ldebug_irq, cpu) = bind_virq_to_irq(VIRQ_DEBUG);
-       sprintf(ldebug_name[cpu], "ldebug%d", cpu);
-       BUG_ON(request_irq(per_cpu(ldebug_irq, cpu), ldebug_interrupt,
-                          SA_INTERRUPT, ldebug_name[cpu], NULL));
-}
-
 extern void local_setup_timer(void);
 #endif
 
@@ -498,7 +479,6 @@
        enable_APIC_timer();
 #else
        local_setup_timer();
-       ldebug_setup();
        smp_intr_init();
        local_irq_enable();
 #endif
diff -r 93e27f7ca8a8 -r 61b3b357d827 
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   Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c   Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Thu Sep 29 
23:28:44 2005
@@ -481,7 +481,7 @@
        spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
 
        /* Kick the relevant domain. */
-       notify_via_evtchn(blkif->evtchn);
+       notify_remote_via_irq(blkif->irq);
 }
 
 void blkif_deschedule(blkif_t *blkif)
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Sep 29 23:28:44 2005
@@ -44,7 +44,7 @@
        unsigned int      handle;
        /* Physical parameters of the comms window. */
        unsigned int      evtchn;
-       unsigned int      remote_evtchn;
+       unsigned int      irq;
        /* Comms information. */
        blkif_back_ring_t blk_ring;
        struct vm_struct *blk_ring_area;
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Thu Sep 29 
23:28:44 2005
@@ -71,8 +71,6 @@
        evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
        int err;
 
-       BUG_ON(blkif->remote_evtchn);
-
        if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
                return -ENOMEM;
 
@@ -94,13 +92,12 @@
        }
 
        blkif->evtchn = op.u.bind_interdomain.port1;
-       blkif->remote_evtchn = evtchn;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
        SHARED_RING_INIT(sring);
        BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
-       bind_evtchn_to_irqhandler(
+       blkif->irq = bind_evtchn_to_irqhandler(
                blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
        blkif->status = CONNECTED;
 
@@ -109,20 +106,12 @@
 
 static void free_blkif(void *arg)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        blkif_t *blkif = (blkif_t *)arg;
 
-       op.u.close.port = blkif->evtchn;
-       op.u.close.dom = DOMID_SELF;
-       HYPERVISOR_event_channel_op(&op);
-       op.u.close.port = blkif->remote_evtchn;
-       op.u.close.dom = blkif->domid;
-       HYPERVISOR_event_channel_op(&op);
+       if (blkif->irq)
+               unbind_evtchn_from_irqhandler(blkif->irq, blkif);
 
        vbd_free(&blkif->vbd);
-
-       if (blkif->evtchn)
-               unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
 
        if (blkif->blk_ring.sring) {
                unmap_frontend_page(blkif);
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Thu Sep 29 
23:28:44 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);
 
@@ -84,22 +81,10 @@
        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)
 {
        RING_PUSH_REQUESTS(&info->ring);
-       notify_via_evtchn(info->evtchn);
+       notify_remote_via_irq(info->irq);
 }
 
 static void kick_pending_request_queues(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;
        }
@@ -372,8 +357,9 @@
        if (info->ring_ref != GRANT_INVALID_REF)
                gnttab_end_foreign_access(info->ring_ref, 0);
        info->ring_ref = GRANT_INVALID_REF;
-       unbind_evtchn_from_irqhandler(info->evtchn, info); 
-       info->evtchn = 0;
+       if (info->irq)
+               unbind_evtchn_from_irqhandler(info->irq, info); 
+       info->evtchn = info->irq = 0;
 }
 
 static void blkif_recover(struct blkfront_info *info)
@@ -401,36 +387,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 +418,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;
 }
 
@@ -450,10 +430,12 @@
 
        err = bind_evtchn_to_irqhandler(
                info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
-       if (err != 0) {
+       if (err <= 0) {
                WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
                return;
        }
+
+       info->irq = err;
 }
 
 
@@ -487,8 +469,8 @@
                return;
        }
 
+       info->connected = BLKIF_STATE_CONNECTED;
        xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
-       info->connected = BLKIF_STATE_CONNECTED;
 
        blkif_state = BLKIF_STATE_CONNECTED;
 
@@ -591,17 +573,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 +581,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 +599,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,9 +683,6 @@
        kfree(info->backend);
        info->backend = NULL;
 
-       recovery = 1;
-       blkif_free(info);
-
        return 0;
 }
 
@@ -713,11 +691,12 @@
        struct blkfront_info *info = dev->data;
        int err;
 
-       /* FIXME: Check geometry hasn't changed here... */
+       blkif_free(info);
+
        err = talk_to_backend(dev, info);
-       if (!err) {
+       if (!err)
                blkif_recover(info);
-       }
+
        return err;
 }
 
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Sep 29 23:28:44 2005
@@ -123,7 +123,7 @@
        int backend_id;
        int ring_ref;
        blkif_front_ring_t ring;
-       unsigned int evtchn;
+       unsigned int evtchn, irq;
        struct xlbd_major_info *mi;
        request_queue_t *rq;
        struct work_struct work;
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Thu Sep 29 23:28:44 2005
@@ -842,7 +842,7 @@
        spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
 
        /* Kick the relevant domain. */
-       notify_via_evtchn(blkif->evtchn);
+       notify_remote_via_irq(blkif->irq);
 }
 
 static struct miscdevice blktap_miscdev = {
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h  Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h  Thu Sep 29 23:28:44 2005
@@ -46,7 +46,7 @@
        unsigned int      handle;
        /* Physical parameters of the comms window. */
        unsigned int      evtchn;
-       unsigned int      remote_evtchn;
+       unsigned int      irq;
        /* Comms information. */
        blkif_back_ring_t blk_ring;
        struct vm_struct *blk_ring_area;
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Thu Sep 29 
23:28:44 2005
@@ -71,8 +71,6 @@
        evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
        int err;
 
-       BUG_ON(blkif->remote_evtchn);
-
        if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
 
@@ -93,35 +91,26 @@
                return err;
        }
 
-
        blkif->evtchn = op.u.bind_interdomain.port1;
-       blkif->remote_evtchn = evtchn;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
        SHARED_RING_INIT(sring);
        BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
-       bind_evtchn_to_irqhandler(
+       blkif->irq = bind_evtchn_to_irqhandler(
                blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
-       blkif->status        = CONNECTED;
+
+       blkif->status = CONNECTED;
 
        return 0;
 }
 
 static void free_blkif(void *arg)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        blkif_t *blkif = (blkif_t *)arg;
 
-       op.u.close.port = blkif->evtchn;
-       op.u.close.dom = DOMID_SELF;
-       HYPERVISOR_event_channel_op(&op);
-       op.u.close.port = blkif->remote_evtchn;
-       op.u.close.dom = blkif->domid;
-       HYPERVISOR_event_channel_op(&op);
-
-       if (blkif->evtchn)
-               unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
+       if (blkif->irq)
+               unbind_evtchn_from_irqhandler(blkif->irq, blkif);
 
        if (blkif->blk_ring.sring) {
                unmap_frontend_page(blkif);
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Thu Sep 29 
23:28:44 2005
@@ -21,7 +21,6 @@
 #include <linux/err.h>
 #include "xencons_ring.h"
 
-
 struct ring_head
 {
        u32 cons;
@@ -29,6 +28,7 @@
        char buf[0];
 } __attribute__((packed));
 
+static int xencons_irq;
 
 #define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head))
 #define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE)
@@ -46,7 +46,8 @@
 
 
 /* don't block -  write as much as possible and return */
-static int __xencons_ring_send(struct ring_head *ring, const char *data, 
unsigned len)
+static int __xencons_ring_send(
+       struct ring_head *ring, const char *data, unsigned len)
 {
        int copied = 0;
 
@@ -63,13 +64,9 @@
 
 int xencons_ring_send(const char *data, unsigned len)
 {
-       struct ring_head *out = outring();
-       int sent = 0;
-       
-       sent = __xencons_ring_send(out, data, len);
-       notify_via_evtchn(xen_start_info->console_evtchn);
+       int sent = __xencons_ring_send(outring(), data, len);
+       notify_remote_via_irq(xencons_irq);
        return sent;
-
 }      
 
 
@@ -97,32 +94,28 @@
 {
        int err;
 
+       if (xencons_irq)
+               unbind_evtchn_from_irqhandler(xencons_irq, inring());
+       xencons_irq = 0;
+
        if (!xen_start_info->console_evtchn)
                return 0;
 
-       err = bind_evtchn_to_irqhandler(xen_start_info->console_evtchn,
-                                       handle_input, 0, "xencons", inring());
-       if (err) {
+       err = bind_evtchn_to_irqhandler(
+               xen_start_info->console_evtchn,
+               handle_input, 0, "xencons", inring());
+       if (err <= 0) {
                xprintk("XEN console request irq failed %i\n", err);
                return err;
        }
 
+       xencons_irq = err;
+
        return 0;
-}
-
-void xencons_suspend(void)
-{
-
-       if (!xen_start_info->console_evtchn)
-               return;
-
-       unbind_evtchn_from_irqhandler(xen_start_info->console_evtchn,
-                                     inring());
 }
 
 void xencons_resume(void)
 {
-
        (void)xencons_ring_init();
 }
 
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Sep 29 23:28:44 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) \
@@ -52,7 +50,7 @@
        u16              rx_shmem_handle;
        grant_ref_t      rx_shmem_ref; 
        unsigned int     evtchn;
-       unsigned int     remote_evtchn;
+       unsigned int     irq;
 
        /* The shared rings and indexes. */
        netif_tx_interface_t *tx;
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Thu Sep 29 
23:28:44 2005
@@ -15,18 +15,17 @@
        spin_lock_bh(&dev->xmit_lock);
        netif->active = 1;
        spin_unlock_bh(&dev->xmit_lock);
-       (void)bind_evtchn_to_irqhandler(
-               netif->evtchn, netif_be_int, 0, dev->name, netif);
+       enable_irq(netif->irq);
        netif_schedule_work(netif);
 }
 
 static void __netif_down(netif_t *netif)
 {
        struct net_device *dev = netif->dev;
+       disable_irq(netif->irq);
        spin_lock_bh(&dev->xmit_lock);
        netif->active = 0;
        spin_unlock_bh(&dev->xmit_lock);
-       unbind_evtchn_from_irqhandler(netif->evtchn, netif);
        netif_deschedule_work(netif);
 }
 
@@ -203,7 +202,10 @@
        }
 
        netif->evtchn = op.u.bind_interdomain.port1;
-       netif->remote_evtchn = evtchn;
+
+       netif->irq = bind_evtchn_to_irqhandler(
+               netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
+       disable_irq(netif->irq);
 
        netif->tx = (netif_tx_interface_t *)netif->comms_area->addr;
        netif->rx = (netif_rx_interface_t *)
@@ -224,21 +226,15 @@
 
 static void free_netif_callback(void *arg)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        netif_t *netif = (netif_t *)arg;
 
        /*
-        * These can't be done in netif_disconnect() because at that point
+        * This can't be done in netif_disconnect() because at that point
         * there may be outstanding requests in the network stack whose
         * asynchronous responses must still be notified to the remote driver.
         */
-
-       op.u.close.port = netif->evtchn;
-       op.u.close.dom = DOMID_SELF;
-       HYPERVISOR_event_channel_op(&op);
-       op.u.close.port = netif->remote_evtchn;
-       op.u.close.dom = netif->domid;
-       HYPERVISOR_event_channel_op(&op);
+       if (netif->irq)
+               unbind_evtchn_from_irqhandler(netif->irq, netif);
 
        unregister_netdev(netif->dev);
 
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Thu Sep 29 
23:28:44 2005
@@ -42,7 +42,7 @@
 static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
 
 static gnttab_transfer_t grant_rx_op[MAX_PENDING_REQS];
-static unsigned char rx_notify[NR_EVENT_CHANNELS];
+static unsigned char rx_notify[NR_IRQS];
 
 /* Don't currently gate addition of an interface to the tx scheduling list. */
 #define tx_work_exists(_if) (1)
@@ -209,7 +209,7 @@
 {
        netif_t *netif = NULL; 
        s8 status;
-       u16 size, id, evtchn;
+       u16 size, id, irq;
        multicall_entry_t *mcl;
        mmu_update_t *mmu;
        gnttab_transfer_t *gop;
@@ -320,16 +320,16 @@
                                gop->status, netif->domid);
                        /* XXX SMH: should free 'old_mfn' here */
                        status = NETIF_RSP_ERROR; 
-               } 
-               evtchn = netif->evtchn;
+               }
+               irq = netif->irq;
                id = netif->rx->ring[
                        MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
                if (make_rx_response(netif, id, status,
                                     (unsigned long)skb->data & ~PAGE_MASK,
                                     size, skb->proto_csum_valid) &&
-                   (rx_notify[evtchn] == 0)) {
-                       rx_notify[evtchn] = 1;
-                       notify_list[notify_nr++] = evtchn;
+                   (rx_notify[irq] == 0)) {
+                       rx_notify[irq] = 1;
+                       notify_list[notify_nr++] = irq;
                }
 
                netif_put(netif);
@@ -339,9 +339,9 @@
        }
 
        while (notify_nr != 0) {
-               evtchn = notify_list[--notify_nr];
-               rx_notify[evtchn] = 0;
-               notify_via_evtchn(evtchn);
+               irq = notify_list[--notify_nr];
+               rx_notify[irq] = 0;
+               notify_remote_via_irq(irq);
        }
 
        /* More work to do? */
@@ -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(
@@ -718,7 +717,7 @@
 
        mb(); /* Update producer before checking event threshold. */
        if (i == netif->tx->event)
-               notify_via_evtchn(netif->evtchn);
+               notify_remote_via_irq(netif->irq);
 }
 
 static int make_rx_response(netif_t *netif, 
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Thu Sep 29 
23:28:44 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
@@ -127,7 +127,7 @@
        spinlock_t   rx_lock;
 
        unsigned int handle;
-       unsigned int evtchn;
+       unsigned int evtchn, irq;
 
        /* What is the status of our connection to the remote backend? */
 #define BEST_CLOSED       0
@@ -457,7 +457,7 @@
        /* Only notify Xen if we really have to. */
        mb();
        if (np->tx->TX_TEST_IDX == i)
-               notify_via_evtchn(np->evtchn);
+               notify_remote_via_irq(np->irq);
 
        return 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,56 +724,59 @@
         * 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.
         */
        np->backend_state = BEST_CONNECTED;
        wmb();
-       notify_via_evtchn(np->evtchn);  
+       notify_remote_via_irq(np->irq);
        network_tx_buf_gc(dev);
 
        if (np->user_state == UST_OPEN)
@@ -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.
  */
@@ -809,7 +815,7 @@
        memcpy(dev->dev_addr, np->mac, ETH_ALEN);
        np->evtchn = evtchn;
        network_connect(dev);
-       (void)bind_evtchn_to_irqhandler(
+       np->irq = bind_evtchn_to_irqhandler(
                np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
        (void)send_fake_arp(dev);
        show_device(np);
@@ -1049,12 +1055,12 @@
                gnttab_end_foreign_access(info->rx_ring_ref, 0);
        info->rx_ring_ref = GRANT_INVALID_REF;
 
-       unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
-       info->evtchn = 0;
-}
-
-/* Stop network device and free tx/rx queues and irq.
- */
+       if (info->irq)
+               unbind_evtchn_from_irqhandler(info->irq, info->netdev);
+       info->evtchn = info->irq = 0;
+}
+
+/* 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 +1154,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 +1162,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 +1182,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)
 {
@@ -1241,24 +1247,17 @@
 static int netfront_suspend(struct xenbus_device *dev)
 {
        struct netfront_info *info = dev->data;
-
        unregister_xenbus_watch(&info->watch);
        kfree(info->backend);
        info->backend = NULL;
-
+       return 0;
+}
+
+static int netfront_resume(struct xenbus_device *dev)
+{
+       struct netfront_info *info = dev->data;
        netif_free(info);
-
-       return 0;
-}
-
-static int netfront_resume(struct xenbus_device *dev)
-{
-       struct net_private *np = dev->data;
-       int err;
-
-       err = talk_to_backend(dev, np);
-
-       return err;
+       return talk_to_backend(dev, info);
 }
 
 static struct xenbus_driver netfront = {
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep 29 23:28:44 2005
@@ -35,7 +35,7 @@
 
        /* Physical parameters of the comms window. */
        unsigned int evtchn;
-       unsigned int remote_evtchn;
+       unsigned int irq;
 
        /* The shared rings and indexes. */
        tpmif_tx_interface_t *tx;
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Thu Sep 29 
23:28:44 2005
@@ -120,8 +120,6 @@
        evtchn_op_t op = {.cmd = EVTCHNOP_bind_interdomain };
        int err;
 
-       BUG_ON(tpmif->remote_evtchn);
-
        if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
 
@@ -143,12 +141,11 @@
        }
 
        tpmif->evtchn = op.u.bind_interdomain.port1;
-       tpmif->remote_evtchn = evtchn;
 
        tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
 
-       bind_evtchn_to_irqhandler(tpmif->evtchn,
-                                 tpmif_be_int, 0, "tpmif-backend", tpmif);
+       tpmif->irq = bind_evtchn_to_irqhandler(
+               tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
        tpmif->status = CONNECTED;
        tpmif->shmem_ref = shared_page;
        tpmif->active = 1;
@@ -159,18 +156,10 @@
 static void
 __tpmif_disconnect_complete(void *arg)
 {
-       evtchn_op_t op = {.cmd = EVTCHNOP_close };
        tpmif_t *tpmif = (tpmif_t *) arg;
 
-       op.u.close.port = tpmif->evtchn;
-       op.u.close.dom = DOMID_SELF;
-       HYPERVISOR_event_channel_op(&op);
-       op.u.close.port = tpmif->remote_evtchn;
-       op.u.close.dom = tpmif->domid;
-       HYPERVISOR_event_channel_op(&op);
-
-       if (tpmif->evtchn)
-               unbind_evtchn_from_irqhandler(tpmif->evtchn, tpmif);
+       if (tpmif->irq)
+               unbind_evtchn_from_irqhandler(tpmif->irq, tpmif);
 
        if (tpmif->tx) {
                unmap_frontend_page(tpmif);
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Thu Sep 29 
23:28:44 2005
@@ -308,7 +308,7 @@
        rc = offset;
        DPRINTK("Notifying frontend via event channel %d\n",
                tpmif->evtchn);
-       notify_via_evtchn(tpmif->evtchn);
+       notify_remote_via_irq(tpmif->irq);
 
        return rc;
 }
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Thu Sep 29 
23:28:44 2005
@@ -292,8 +292,10 @@
                free_page((unsigned long)tp->tx);
                tp->tx = NULL;
        }
-       unbind_evtchn_from_irqhandler(tp->evtchn, NULL);
-       tp->evtchn = 0;
+
+       if (tpm->irq)
+               unbind_evtchn_from_irqhandler(tp->irq, NULL);
+       tp->evtchn = tpm->irq = 0;
 }
 
 
@@ -352,17 +354,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 +362,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 +380,10 @@
        xenbus_dev_error(dev, err, "%s", message);
 destroy_tpmring:
        destroy_tpmring(info, &my_private);
-       goto out;
+out:
+       if (backend)
+               kfree(backend);
+       return err;
 }
 
 
@@ -502,10 +503,12 @@
        err = bind_evtchn_to_irqhandler(
                tp->evtchn,
                tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
-       if ( err != 0 ) {
+       if ( err <= 0 ) {
                WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
                return;
        }
+
+       tp->irq = err;
 }
 
 static struct xenbus_device_id tpmfront_ids[] = {
@@ -679,7 +682,7 @@
        DPRINTK("Notifying backend via event channel %d\n",
                tp->evtchn);
 
-       notify_via_evtchn(tp->evtchn);
+       notify_remote_via_irq(tp->irq);
 
        spin_unlock_irq(&tp->tx_lock);
        return offset;
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Thu Sep 29 
23:28:44 2005
@@ -5,7 +5,7 @@
 struct tpm_private
 {
        tpmif_tx_interface_t *tx;
-       unsigned int evtchn;
+       unsigned int evtchn, irq;
        int connected;
 
        spinlock_t tx_lock;
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Thu Sep 29 
23:28:44 2005
@@ -43,6 +43,8 @@
        u8 flags;
        char buf[0];
 } __attribute__((packed));
+
+static int xenbus_irq;
 
 DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
 
@@ -145,7 +147,7 @@
                data += avail;
                len -= avail;
                update_output_chunk(out, avail);
-               notify_via_evtchn(xen_start_info->store_evtchn);
+               notify_remote_via_irq(xenbus_irq);
        } while (len != 0);
 
        return 0;
@@ -190,7 +192,7 @@
                pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
                /* If it was full, tell them we've taken some. */
                if (was_full)
-                       notify_via_evtchn(xen_start_info->store_evtchn);
+                       notify_remote_via_irq(xenbus_irq);
        }
 
        /* If we left something, wake watch thread to deal with it. */
@@ -205,31 +207,27 @@
 {
        int err;
 
+       if (xenbus_irq)
+               unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
+       xenbus_irq = 0;
+
        if (!xen_start_info->store_evtchn)
                return 0;
 
        err = bind_evtchn_to_irqhandler(
                xen_start_info->store_evtchn, wake_waiting,
                0, "xenbus", &xb_waitq);
-       if (err) {
+       if (err <= 0) {
                printk(KERN_ERR "XENBUS request irq failed %i\n", err);
-               unbind_evtchn_from_irq(xen_start_info->store_evtchn);
                return err;
        }
 
+       xenbus_irq = err;
+
        /* FIXME zero out page -- domain builder should probably do this*/
        memset(mfn_to_virt(xen_start_info->store_mfn), 0, PAGE_SIZE);
 
        return 0;
-}
-
-void xb_suspend_comms(void)
-{
-
-       if (!xen_start_info->store_evtchn)
-               return;
-
-       unbind_evtchn_from_irqhandler(xen_start_info->store_evtchn, &xb_waitq);
 }
 
 /*
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h    Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h    Thu Sep 29 
23:28:44 2005
@@ -30,7 +30,6 @@
 
 int xs_init(void);
 int xb_init_comms(void);
-void xb_suspend_comms(void);
 
 /* Low level routines. */
 int xb_write(const void *data, unsigned len);
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Thu Sep 29 
23:28:44 2005
@@ -607,7 +607,6 @@
        down(&xenbus_lock);
        bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
        bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
-       xb_suspend_comms();
 }
 
 void xenbus_resume(void)
@@ -651,7 +650,6 @@
        int err = 0;
 
        /* Initialize xenstore comms unless already done. */
-       printk("store_evtchn = %i\n", xen_start_info->store_evtchn);
        err = xs_init();
        if (err) {
                printk("XENBUS: Error initializing xenstore comms:"
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h      
Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h      
Thu Sep 29 23:28:44 2005
@@ -80,11 +80,9 @@
  * the usable vector space is 0x20-0xff (224 vectors)
  */
 
-#define NR_IPIS 8
-
-#define RESCHEDULE_VECTOR      1
-#define INVALIDATE_TLB_VECTOR  2
-#define CALL_FUNCTION_VECTOR   3
+#define RESCHEDULE_VECTOR      0
+#define CALL_FUNCTION_VECTOR   1
+#define NR_IPIS                        2
 
 /*
  * The maximum number of vectors supported by i386 processors
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h    
Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h    
Thu Sep 29 23:28:44 2005
@@ -78,11 +78,9 @@
  * the usable vector space is 0x20-0xff (224 vectors)
  */
 
-#define NR_IPIS 8
-
-#define RESCHEDULE_VECTOR      1
-#define INVALIDATE_TLB_VECTOR  2
-#define CALL_FUNCTION_VECTOR   3
+#define RESCHEDULE_VECTOR      0
+#define CALL_FUNCTION_VECTOR   1
+#define NR_IPIS                        2
 
 /*
  * The maximum number of vectors supported by i386 processors
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/balloon.h
--- a/linux-2.6-xen-sparse/include/asm-xen/balloon.h    Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/balloon.h    Thu Sep 29 23:28:44 2005
@@ -58,3 +58,13 @@
 #define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags)
 
 #endif /* __ASM_BALLOON_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/driver_util.h
--- a/linux-2.6-xen-sparse/include/asm-xen/driver_util.h        Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/driver_util.h        Thu Sep 29 
23:28:44 2005
@@ -14,3 +14,13 @@
 extern void unlock_vm_area(struct vm_struct *area);
 
 #endif /* __ASM_XEN_DRIVER_UTIL_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Thu Sep 29 23:28:44 2005
@@ -4,7 +4,7 @@
  * Communication via Xen event channels.
  * Also definitions for the device that demuxes notifications to userspace.
  * 
- * Copyright (c) 2004, K A Fraser
+ * Copyright (c) 2004-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:
@@ -51,24 +51,36 @@
 extern int  bind_ipi_to_irq(int ipi);
 extern void unbind_ipi_from_irq(int ipi);
 
-/* Dynamically bind an event-channel port to Linux IRQ space. */
+/*
+ * Dynamically bind an event-channel port to Linux IRQ space.
+ * BIND:   Returns IRQ or error.
+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
+ */
 extern int  bind_evtchn_to_irq(unsigned int evtchn);
-extern void unbind_evtchn_from_irq(unsigned int evtchn);
+extern void unbind_evtchn_from_irq(unsigned int irq);
 
 /*
  * Dynamically bind an event-channel port to an IRQ-like callback handler.
  * On some platforms this may not be implemented via the Linux IRQ subsystem.
- * You *cannot* trust the irq argument passed to the callback handler.
+ * The IRQ argument passed to the callback handler is the same as returned
+ * from the bind call. It may not correspond to a Linux IRQ number.
+ * BIND:   Returns IRQ or error.
+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
  */
 extern int  bind_evtchn_to_irqhandler(
-    unsigned int evtchn,
-    irqreturn_t (*handler)(int, void *, struct pt_regs *),
-    unsigned long irqflags,
-    const char *devname,
-    void *dev_id);
-extern void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id);
+       unsigned int evtchn,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id);
+extern void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id);
 
-extern void irq_suspend(void);
+/*
+ * Unlike notify_remote_via_evtchn(), this is safe to use across
+ * save/restore. Notifications on a broken connection are silently dropped.
+ */
+void notify_remote_via_irq(int irq);
+
 extern void irq_resume(void);
 
 /* Entry point for notifications into Linux subsystems. */
@@ -79,42 +91,42 @@
 
 static inline void mask_evtchn(int port)
 {
-    shared_info_t *s = HYPERVISOR_shared_info;
-    synch_set_bit(port, &s->evtchn_mask[0]);
+       shared_info_t *s = HYPERVISOR_shared_info;
+       synch_set_bit(port, &s->evtchn_mask[0]);
 }
 
 static inline void unmask_evtchn(int port)
 {
-    shared_info_t *s = HYPERVISOR_shared_info;
-    vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
+       shared_info_t *s = HYPERVISOR_shared_info;
+       vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
 
-    synch_clear_bit(port, &s->evtchn_mask[0]);
+       synch_clear_bit(port, &s->evtchn_mask[0]);
 
-    /*
-     * The following is basically the equivalent of 'hw_resend_irq'. Just like
-     * a real IO-APIC we 'lose the interrupt edge' if the channel is masked.
-     */
-    if (  synch_test_bit        (port,    &s->evtchn_pending[0]) && 
-         !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel) )
-    {
-        vcpu_info->evtchn_upcall_pending = 1;
-        if ( !vcpu_info->evtchn_upcall_mask )
-            force_evtchn_callback();
-    }
+       /*
+        * The following is basically the equivalent of 'hw_resend_irq'. Just
+        * like a real IO-APIC we 'lose the interrupt edge' if the channel is
+        * masked.
+        */
+       if (synch_test_bit         (port,    &s->evtchn_pending[0]) && 
+           !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel)) {
+               vcpu_info->evtchn_upcall_pending = 1;
+               if (!vcpu_info->evtchn_upcall_mask)
+                       force_evtchn_callback();
+       }
 }
 
 static inline void clear_evtchn(int port)
 {
-    shared_info_t *s = HYPERVISOR_shared_info;
-    synch_clear_bit(port, &s->evtchn_pending[0]);
+       shared_info_t *s = HYPERVISOR_shared_info;
+       synch_clear_bit(port, &s->evtchn_pending[0]);
 }
 
-static inline int notify_via_evtchn(int port)
+static inline void notify_remote_via_evtchn(int port)
 {
-    evtchn_op_t op;
-    op.cmd = EVTCHNOP_send;
-    op.u.send.local_port = port;
-    return HYPERVISOR_event_channel_op(&op);
+       evtchn_op_t op;
+       op.cmd = EVTCHNOP_send;
+       op.u.send.local_port = port;
+       (void)HYPERVISOR_event_channel_op(&op);
 }
 
 /*
@@ -133,3 +145,13 @@
 #define EVTCHN_UNBIND _IO('E', 3)
 
 #endif /* __ASM_EVTCHN_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/foreign_page.h
--- a/linux-2.6-xen-sparse/include/asm-xen/foreign_page.h       Thu Sep 29 
22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/foreign_page.h       Thu Sep 29 
23:28:44 2005
@@ -28,3 +28,13 @@
        ( (void (*) (struct page *)) (page)->mapping )
 
 #endif /* __ASM_XEN_FOREIGN_PAGE_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h     Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h     Thu Sep 29 23:28:44 2005
@@ -6,7 +6,7 @@
  * 2. Accessing others' memory reservations via grant references.
  * (i.e., mechanisms for both sender and recipient of grant references)
  * 
- * Copyright (c) 2004, K A Fraser
+ * Copyright (c) 2004-2005, K A Fraser
  * Copyright (c) 2005, Christopher Clark
  */
 
@@ -25,10 +25,10 @@
 #endif
 
 struct gnttab_free_callback {
-    struct gnttab_free_callback *next;
-    void (*fn)(void *);
-    void *arg;
-    u16 count;
+       struct gnttab_free_callback *next;
+       void (*fn)(void *);
+       void *arg;
+       u16 count;
 };
 
 int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
@@ -73,3 +73,13 @@
 #endif
 
 #endif /* __ASM_GNTTAB_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/xen_proc.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xen_proc.h   Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xen_proc.h   Thu Sep 29 23:28:44 2005
@@ -6,8 +6,18 @@
 #include <linux/proc_fs.h>
 
 extern struct proc_dir_entry *create_xen_proc_entry(
-    const char *name, mode_t mode);
+       const char *name, mode_t mode);
 extern void remove_xen_proc_entry(
-    const char *name);
+       const char *name);
 
 #endif /* __ASM_XEN_PROC_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Thu Sep 29 23:28:44 2005
@@ -139,3 +139,13 @@
 #define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
 
 #endif /* _ASM_XEN_XENBUS_H */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Thu Sep 29 22:22:02 2005
+++ b/tools/console/daemon/io.c Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/debugger/gdb/README
--- a/tools/debugger/gdb/README Thu Sep 29 22:22:02 2005
+++ b/tools/debugger/gdb/README Thu Sep 29 23:28:44 2005
@@ -20,10 +20,18 @@
 
 To debug a running guest:
  1. Use 'xm list' to discover its domain id ($domid). 
- 2. Run 'gdbserver-xen 127.0.0.1:9999 --attach $domid'
- 3. Run 'gdb /path/to/vmlinux-syms-2.6.xx-xenU'
+ 2. Run 'gdbserver-xen 127.0.0.1:9999 --attach $domid'.
+ 3. Run 'gdb /path/to/vmlinux-syms-2.6.xx-xenU'.
  4. From within the gdb client session:
     # directory /path/to/linux-2.6.xx-xenU [*]
     # target remote 127.0.0.1:9999
     # bt
     # disass
+
+To debug a crashed guest:
+ 1. Add '(enable-dump yes)' to /etc/xen/xend-config.sxp before
+    starting xend.
+ 2. When the domain crashes, a core file is written to
+    '/var/xen/dump/<domain-name>.<domain-id>.core'.
+ 3. Run 'gdbserver-xen 127.0.0.1:9999 --file <core-file>'.
+ 4. Connect to the server as for a running guest.
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/gen.c
--- a/tools/firmware/vmxassist/gen.c    Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/gen.c    Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/head.S
--- a/tools/firmware/vmxassist/head.S   Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/head.S   Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c  Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/setup.c  Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/vm86.c   Thu Sep 29 23:28:44 2005
@@ -470,10 +470,21 @@
        unsigned long long entry;
 
        /* protected mode: use seg as index into gdt */
-       if (sel == 0 || sel > oldctx.gdtr_limit)
+       if (sel > oldctx.gdtr_limit)
                return 0;
 
+    if (sel == 0) {
+        arbytes->fields.null_bit = 1;
+        return 1;
+    }
+
        entry =  ((unsigned long long *) oldctx.gdtr_base)[sel >> 3];
+
+    /* Check the P bit fisrt*/
+    if (!((entry >> (15+32)) & 0x1) && sel != 0) {
+        return 0;
+    }
+
        *base =  (((entry >> (56-24)) & 0xFF000000) |
                  ((entry >> (32-16)) & 0x00FF0000) |
                  ((entry >> (   16)) & 0x0000FFFF));
@@ -519,22 +530,42 @@
        if (load_seg(regs->ves, &oldctx.es_base,
                                &oldctx.es_limit, &oldctx.es_arbytes))
                oldctx.es_sel = regs->ves;
+    else {
+        load_seg(0, &oldctx.es_base,&oldctx.es_limit, &oldctx.es_arbytes);
+        oldctx.es_sel = 0;
+    }
 
        if (load_seg(regs->uss, &oldctx.ss_base,
                                &oldctx.ss_limit, &oldctx.ss_arbytes))
                oldctx.ss_sel = regs->uss;
+    else {
+        load_seg(0, &oldctx.ss_base, &oldctx.ss_limit, &oldctx.ss_arbytes);
+        oldctx.ss_sel = 0;
+    }
 
        if (load_seg(regs->vds, &oldctx.ds_base,
                                &oldctx.ds_limit, &oldctx.ds_arbytes))
                oldctx.ds_sel = regs->vds;
+    else {
+        load_seg(0, &oldctx.ds_base, &oldctx.ds_limit, &oldctx.ds_arbytes);
+        oldctx.ds_sel = 0;
+    }
 
        if (load_seg(regs->vfs, &oldctx.fs_base,
                                &oldctx.fs_limit, &oldctx.fs_arbytes))
                oldctx.fs_sel = regs->vfs;
+    else {
+        load_seg(0, &oldctx.fs_base, &oldctx.fs_limit, &oldctx.fs_arbytes);
+        oldctx.fs_sel = 0;
+    }
 
        if (load_seg(regs->vgs, &oldctx.gs_base,
                                &oldctx.gs_limit, &oldctx.gs_arbytes))
                oldctx.gs_sel = regs->vgs;
+    else {
+        load_seg(0, &oldctx.gs_base, &oldctx.gs_limit, &oldctx.gs_arbytes);
+        oldctx.gs_sel = 0;
+    }
 
        /* initialize jump environment to warp back to protected mode */
        regs->cs = CODE_SELECTOR;
@@ -752,6 +783,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 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/vmxloader.c
--- a/tools/firmware/vmxassist/vmxloader.c      Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/vmxloader.c      Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Thu Sep 29 22:22:02 2005
+++ b/tools/ioemu/vl.c  Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/web/SrvBase.py
--- a/tools/python/xen/web/SrvBase.py   Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/web/SrvBase.py   Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/web/http.py
--- a/tools/python/xen/web/http.py      Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/web/http.py      Thu Sep 29 23:28:44 2005
@@ -22,6 +22,7 @@
 from  mimetools import Message
 from cStringIO import StringIO
 import math
+import socket
 import time
 import cgi
 
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/PrettyPrint.py
--- a/tools/python/xen/xend/PrettyPrint.py      Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/PrettyPrint.py      Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/XendClient.py       Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/XendDomain.py       Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/DevController.py     Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvDaemon.py Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/server/SrvDmesg.py
--- a/tools/python/xen/xend/server/SrvDmesg.py  Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvDmesg.py  Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvDomain.py Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
tools/python/xen/xend/server/SrvDomainDir.py
--- a/tools/python/xen/xend/server/SrvDomainDir.py      Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvDomainDir.py      Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/server/SrvNode.py
--- a/tools/python/xen/xend/server/SrvNode.py   Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvNode.py   Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py      Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py      Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xm/main.py       Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Thu Sep 29 22:22:02 2005
+++ b/tools/xenstore/xenstored_domain.c Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Thu Sep 29 22:22:02 2005
+++ b/xen/arch/x86/shadow32.c   Thu Sep 29 23:28:44 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;
@@ -1832,7 +1836,7 @@
     }
 #endif
 
-    FSH_LOG("%s(gpfn=%lx, mfn=%lx) c=%08x t=%08x", __func__,
+    FSH_LOG("%s(gpfn=%lx, mfn=%lx) c=%08x t=%08lx", __func__,
             gpfn, mfn, page->count_info, page->u.inuse.type_info);
 
     // XXX this will require some more thought...  Cross-domain sharing and
@@ -3013,7 +3017,7 @@
     l1_pgentry_t guest_pte = *p_guest_pte;
     l1_pgentry_t shadow_pte = *p_shadow_pte;
     l1_pgentry_t snapshot_pte = p_snapshot_pte ? *p_snapshot_pte : l1e_empty();
-    l1_pgentry_t eff_guest_pte;
+    l1_pgentry_t eff_guest_pte = l1e_empty();
     unsigned long mask, eff_guest_pfn, eff_guest_mfn, shadow_mfn;
     int errors = 0, guest_writable;
     int page_table_page;
@@ -3070,7 +3074,7 @@
 
     if ( (l1e_get_flags(shadow_pte) & _PAGE_RW ) && !guest_writable )
     {
-        printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08x 
page_table_page=%d\n",
+        printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx 
page_table_page=%d\n",
                eff_guest_pfn, eff_guest_mfn, shadow_mfn,
                frame_table[eff_guest_mfn].u.inuse.type_info,
                page_table_page);
@@ -3081,7 +3085,7 @@
          (l1e_get_flags(shadow_pte) & _PAGE_RW ) &&
          !(guest_writable && (l1e_get_flags(eff_guest_pte) & _PAGE_DIRTY)) )
     {
-        printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08x 
page_table_page=%d\n",
+        printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx 
page_table_page=%d\n",
                eff_guest_pfn, eff_guest_mfn, shadow_mfn,
                frame_table[eff_guest_mfn].u.inuse.type_info,
                page_table_page);
diff -r 93e27f7ca8a8 -r 61b3b357d827 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Thu Sep 29 22:22:02 2005
+++ b/xen/arch/x86/shadow_public.c      Thu Sep 29 23:28:44 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 93e27f7ca8a8 -r 61b3b357d827 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Thu Sep 29 22:22:02 2005
+++ b/xen/arch/x86/time.c       Thu Sep 29 23:28:44 2005
@@ -119,8 +119,8 @@
         "mov  %4,%%eax ; "
         "mov  %%edx,%4 ; "
         "mul  %5       ; "
+        "xor  %5,%5    ; "
         "add  %4,%%eax ; "
-        "xor  %5,%5    ; "
         "adc  %5,%%edx ; "
         : "=A" (product), "=r" (tmp1), "=r" (tmp2)
         : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (scale->mul_frac) );
diff -r 93e27f7ca8a8 -r 61b3b357d827 xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c       Thu Sep 29 22:22:02 2005
+++ b/xen/arch/x86/vmx_platform.c       Thu Sep 29 23:28:44 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:
diff -r 93e27f7ca8a8 -r 61b3b357d827 
linux-2.6-xen-sparse/include/asm-xen/queues.h
--- a/linux-2.6-xen-sparse/include/asm-xen/queues.h     Thu Sep 29 22:22:02 2005
+++ /dev/null   Thu Sep 29 23:28:44 2005
@@ -1,81 +0,0 @@
-
-/*
- * Oh dear. Task queues were removed from Linux 2.6 and replaced by work 
- * queues. Unfortunately the semantics is not the same. With task queues we 
- * can defer work until a particular event occurs -- this is not
- * straightforwardly done with work queues (queued work is performed asap, or
- * after some fixed timeout). Conversely, work queues are a (slightly) neater
- * way of deferring work to a process context than using task queues in 2.4.
- * 
- * This is a bit of a needless reimplementation -- should have just pulled
- * the code from 2.4, but I tried leveraging work queues to simplify things.
- * They didn't help. :-(
- */
-
-#ifndef __QUEUES_H__
-#define __QUEUES_H__
-
-#include <linux/version.h>
-#include <linux/list.h>
-#include <linux/workqueue.h>
-
-struct tq_struct { 
-    void (*fn)(void *);
-    void *arg;
-    struct list_head list;
-    unsigned long pending;
-};
-#define INIT_TQUEUE(_name, _fn, _arg)               \
-    do {                                            \
-        INIT_LIST_HEAD(&(_name)->list);             \
-        (_name)->pending = 0;                       \
-        (_name)->fn = (_fn); (_name)->arg = (_arg); \
-    } while ( 0 )
-#define DECLARE_TQUEUE(_name, _fn, _arg)            \
-    struct tq_struct _name = { (_fn), (_arg), LIST_HEAD_INIT((_name).list), 0 }
-
-typedef struct {
-    struct list_head list;
-    spinlock_t       lock;
-} task_queue;
-#define DECLARE_TASK_QUEUE(_name) \
-    task_queue _name = { LIST_HEAD_INIT((_name).list), SPIN_LOCK_UNLOCKED }
-
-static inline int queue_task(struct tq_struct *tqe, task_queue *tql)
-{
-    unsigned long flags;
-    if ( test_and_set_bit(0, &tqe->pending) )
-        return 0;
-    spin_lock_irqsave(&tql->lock, flags);
-    list_add_tail(&tqe->list, &tql->list);
-    spin_unlock_irqrestore(&tql->lock, flags);
-    return 1;
-}
-
-static inline void run_task_queue(task_queue *tql)
-{
-    struct list_head head, *ent;
-    struct tq_struct *tqe;
-    unsigned long flags;
-    void (*fn)(void *);
-    void *arg;
-
-    spin_lock_irqsave(&tql->lock, flags);
-    list_add(&head, &tql->list);
-    list_del_init(&tql->list);
-    spin_unlock_irqrestore(&tql->lock, flags);
-
-    while ( !list_empty(&head) )
-    {
-        ent = head.next;
-        list_del_init(ent);
-        tqe = list_entry(ent, struct tq_struct, list);
-        fn  = tqe->fn;
-        arg = tqe->arg;
-        wmb();
-        tqe->pending = 0;
-        fn(arg);
-    }
-}
-
-#endif /* __QUEUES_H__ */

_______________________________________________
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®.