WARNING - OLD ARCHIVES

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

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Merge xen-unstable into xen-ia64-unstable
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 12 Oct 2005 08:32:13 +0000
Delivery-date: Wed, 12 Oct 2005 08:35:55 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Merge xen-unstable into xen-ia64-unstable, Xen patchbot -unstable <=