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

[Xen-changelog] Merge.



# HG changeset patch
# User jrb44@xxxxxxxxxxxxxxxxxx
# Node ID abfc9808adb939fc3091a629ee0db423dacff16d
# Parent  d79ab87e27b8f88621234f7fb5bfeb24a8d33a89
# Parent  96cc6aa196b6e079488fabcc2eef32c38f7ff890
Merge.

diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Tue Oct  4 
13:22:30 2005
@@ -49,6 +49,7 @@
 #include <asm/irq.h>
 #include <asm/desc.h>
 #include <asm-xen/xen-public/physdev.h>
+#include <asm-xen/xen-public/vcpu.h>
 #ifdef CONFIG_MATH_EMULATION
 #include <asm/math_emu.h>
 #endif
@@ -140,6 +141,13 @@
        BUG();
 }
 #endif /* CONFIG_HOTPLUG_CPU */
+
+void cpu_restore(void)
+{
+       play_dead();
+       local_irq_enable();
+       cpu_idle();
+}
 
 /*
  * The idle thread. There's no useful work to be
@@ -171,7 +179,7 @@
                                   don't printk. */
                                __get_cpu_var(cpu_state) = CPU_DEAD;
                                /* Tell hypervisor to take vcpu down. */
-                               HYPERVISOR_vcpu_down(cpu);
+                               HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL);
 #endif
                                play_dead();
                                local_irq_enable();
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Mon Oct  3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Tue Oct  4 13:22:30 2005
@@ -365,6 +365,7 @@
 
 /* Raw start-of-day parameters from the hypervisor. */
 start_info_t *xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
 
 static void __init limit_regions(unsigned long long size)
 {
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Tue Oct  4 
13:22:30 2005
@@ -63,6 +63,7 @@
 #include <smpboot_hooks.h>
 
 #include <asm-xen/evtchn.h>
+#include <asm-xen/xen-public/vcpu.h>
 
 /* Set if we find a B stepping CPU */
 static int __initdata smp_b_stepping;
@@ -802,7 +803,6 @@
        extern void hypervisor_callback(void);
        extern void failsafe_callback(void);
        extern void smp_trap_init(trap_info_t *);
-       int i;
 
        cpu = ++cpucount;
        /*
@@ -853,12 +853,6 @@
        /* FPU is set up to default initial state. */
        memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
 
-       /* Virtual IDT is empty at start-of-day. */
-       for ( i = 0; i < 256; i++ )
-       {
-               ctxt.trap_ctxt[i].vector = i;
-               ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-       }
        smp_trap_init(ctxt.trap_ctxt);
 
        /* No LDT. */
@@ -889,11 +883,13 @@
 
        ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
 
-       boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
+       boot_error = HYPERVISOR_vcpu_op(VCPUOP_create, cpu, &ctxt);
        if (boot_error)
                printk("boot error: %ld\n", boot_error);
 
        if (!boot_error) {
+               HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
+
                /*
                 * allow APs to start initializing.
                 */
@@ -1506,7 +1502,7 @@
 #ifdef CONFIG_HOTPLUG_CPU
 #ifdef CONFIG_XEN
        /* Tell hypervisor to bring vcpu up. */
-       HYPERVISOR_vcpu_up(cpu);
+       HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
 #endif
        /* Already up, and in cpu_quiescent now? */
        if (cpu_isset(cpu, smp_commenced_mask)) {
@@ -1585,61 +1581,49 @@
        local_setup_timer_irq();
 }
 
-static atomic_t vcpus_rebooting;
-
-static void restore_vcpu_ready(void)
-{
-
-       atomic_dec(&vcpus_rebooting);
-}
-
-void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       int r;
-       int gdt_pages;
-       r = HYPERVISOR_vcpu_pickle(vcpu, ctxt);
-       if (r != 0)
-               panic("pickling vcpu %d -> %d!\n", vcpu, r);
-
-       /* Translate from machine to physical addresses where necessary,
-          so that they can be translated to our new machine address space
-          after resume.  libxc is responsible for doing this to vcpu0,
-          but we do it to the others. */
-       gdt_pages = (ctxt->gdt_ents + 511) / 512;
-       ctxt->ctrlreg[3] = machine_to_phys(ctxt->ctrlreg[3]);
-       for (r = 0; r < gdt_pages; r++)
-               ctxt->gdt_frames[r] = mfn_to_pfn(ctxt->gdt_frames[r]);
-}
-
-int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       int r;
-       int gdt_pages = (ctxt->gdt_ents + 511) / 512;
-
-       /* This is kind of a hack, and implicitly relies on the fact that
-          the vcpu stops in a place where all of the call clobbered
-          registers are already dead. */
-       ctxt->user_regs.esp -= 4;
-       ((unsigned long *)ctxt->user_regs.esp)[0] = ctxt->user_regs.eip;
-       ctxt->user_regs.eip = (unsigned long)restore_vcpu_ready;
-
-       /* De-canonicalise.  libxc handles this for vcpu 0, but we need
-          to do it for the other vcpus. */
-       ctxt->ctrlreg[3] = phys_to_machine(ctxt->ctrlreg[3]);
-       for (r = 0; r < gdt_pages; r++)
-               ctxt->gdt_frames[r] = pfn_to_mfn(ctxt->gdt_frames[r]);
-
-       atomic_set(&vcpus_rebooting, 1);
-       r = HYPERVISOR_boot_vcpu(vcpu, ctxt);
-       if (r != 0) {
-               printk(KERN_EMERG "Failed to reboot vcpu %d (%d)\n", vcpu, r);
-               return -1;
-       }
-
-       /* Make sure we wait for the new vcpu to come up before trying to do
-          anything with it or starting the next one. */
-       while (atomic_read(&vcpus_rebooting))
-               barrier();
-
-       return 0;
-}
+void vcpu_prepare(int vcpu)
+{
+       extern void hypervisor_callback(void);
+       extern void failsafe_callback(void);
+       extern void smp_trap_init(trap_info_t *);
+       extern void cpu_restore(void);
+       vcpu_guest_context_t ctxt;
+       struct task_struct *idle = idle_task(vcpu);
+
+       if (vcpu == 0)
+               return;
+
+       memset(&ctxt, 0, sizeof(ctxt));
+
+       ctxt.user_regs.ds = __USER_DS;
+       ctxt.user_regs.es = __USER_DS;
+       ctxt.user_regs.fs = 0;
+       ctxt.user_regs.gs = 0;
+       ctxt.user_regs.ss = __KERNEL_DS;
+       ctxt.user_regs.cs = __KERNEL_CS;
+       ctxt.user_regs.eip = (unsigned long)cpu_restore;
+       ctxt.user_regs.esp = idle->thread.esp;
+       ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING1;
+
+       memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
+
+       smp_trap_init(ctxt.trap_ctxt);
+
+       ctxt.ldt_ents = 0;
+
+       ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[vcpu].address);
+       ctxt.gdt_ents      = cpu_gdt_descr[vcpu].size / 8;
+
+       ctxt.kernel_ss = __KERNEL_DS;
+       ctxt.kernel_sp = idle->thread.esp0;
+
+       ctxt.event_callback_cs     = __KERNEL_CS;
+       ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
+       ctxt.failsafe_callback_cs  = __KERNEL_CS;
+       ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
+
+       ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
+
+       (void)HYPERVISOR_vcpu_op(VCPUOP_create, vcpu, &ctxt);
+       (void)HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL);
+}
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Mon Oct  3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Tue Oct  4 13:22:30 2005
@@ -1012,6 +1012,12 @@
 void smp_trap_init(trap_info_t *trap_ctxt)
 {
        trap_info_t *t = trap_table;
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               trap_ctxt[i].vector = i;
+               trap_ctxt[i].cs     = FLAT_KERNEL_CS;
+       }
 
        for (t = trap_table; t->address; t++) {
                trap_ctxt[t->vector].flags = t->flags;
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c   Mon Oct  3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c   Tue Oct  4 13:22:30 2005
@@ -52,24 +52,30 @@
                                    pgprot_t prot,
                                    domid_t  domid)
 {
-       int i;
+       int i, rc;
        unsigned long start_address;
-#define MAX_DIRECTMAP_MMU_QUEUE 130
-       mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *v = u, *w = u;
+       mmu_update_t *u, *v, *w;
+
+       u = v = w = (mmu_update_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+       if (u == NULL)
+               return -ENOMEM;
 
        start_address = address;
 
        flush_cache_all();
 
        for (i = 0; i < size; i += PAGE_SIZE) {
-               if ((v - u) == MAX_DIRECTMAP_MMU_QUEUE) {
+               if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
                        /* Fill in the PTE pointers. */
-                       generic_page_range(mm, start_address, 
-                                          address - start_address,
-                                          direct_remap_area_pte_fn, &w);
+                       rc = generic_page_range(mm, start_address, 
+                                               address - start_address,
+                                               direct_remap_area_pte_fn, &w);
+                       if (rc)
+                               goto out;
                        w = u;
+                       rc = -EFAULT;
                        if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
-                               return -EFAULT;
+                               goto out;
                        v = u;
                        start_address = address;
                }
@@ -89,13 +95,19 @@
                /* get the ptep's filled in */
                generic_page_range(mm, start_address, address - start_address,
                                   direct_remap_area_pte_fn, &w);
+               rc = -EFAULT;
                if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
-                       return -EFAULT;
-       }
-
+                       goto out;
+       }
+
+       rc = 0;
+
+ out:
        flush_tlb_all();
 
-       return 0;
+       free_page((unsigned long)u);
+
+       return rc;
 }
 
 int direct_remap_pfn_range(struct vm_area_struct *vma,
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Mon Oct  3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Tue Oct  4 13:22:30 2005
@@ -629,6 +629,7 @@
        if (VALID_EVTCHN(evtchn))
                notify_remote_via_evtchn(evtchn);
 }
+EXPORT_SYMBOL(notify_remote_via_irq);
 
 void irq_resume(void)
 {
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Mon Oct  3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Tue Oct  4 13:22:30 2005
@@ -74,11 +74,8 @@
        extern unsigned long *pfn_to_mfn_frame_list[];
 
 #ifdef CONFIG_SMP
-       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);
+       cpumask_t prev_online_cpus;
+       int vcpu_prepare(int vcpu);
 #endif
 
        extern void xencons_resume(void);
@@ -132,16 +129,6 @@
 
        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
-
        gnttab_suspend();
 
 #ifdef __i386__
@@ -189,18 +176,16 @@
 
        time_resume();
 
+       __sti();
+
+       xencons_resume();
+
+       xenbus_resume();
+
 #ifdef CONFIG_SMP
-       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
+       for_each_present_cpu(i)
+               vcpu_prepare(i);
+
  out_reenable_cpus:
        for_each_cpu_mask(i, prev_online_cpus) {
                j = cpu_up(i);
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile      Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile      Tue Oct  4 
13:22:30 2005
@@ -51,7 +51,7 @@
 cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../../i386/kernel/cpuid.o
 topology-y                     += ../../../i386/mach-default/topology.o
 #swiotlb-$(CONFIG_SWIOTLB)      += ../../../ia64/lib/swiotlb.o
-microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../../i386/kernel/microcode.o
+microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
 intel_cacheinfo-y              += ../../../i386/kernel/cpu/intel_cacheinfo.o
 quirks-y                       += ../../i386/kernel/quirks.o
 
diff -r d79ab87e27b8 -r abfc9808adb9 
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       Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Tue Oct  4 
13:22:30 2005
@@ -86,6 +86,7 @@
 
 /* Raw start-of-day parameters from the hypervisor. */
 start_info_t *xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
 #endif
 
 /*
diff -r d79ab87e27b8 -r abfc9808adb9 
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     Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Tue Oct  4 
13:22:30 2005
@@ -62,8 +62,8 @@
 #include <asm/nmi.h>
 #ifdef CONFIG_XEN
 #include <asm/arch_hooks.h>
-
 #include <asm-xen/evtchn.h>
+#include <asm-xen/xen-public/vcpu.h>
 #endif
 
 /* Change for real CPU hotplug. Note other files need to be fixed
@@ -742,12 +742,6 @@
        /* FPU is set up to default initial state. */
        memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
 
-       /* Virtual IDT is empty at start-of-day. */
-       for ( i = 0; i < 256; i++ )
-       {
-               ctxt.trap_ctxt[i].vector = i;
-               ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-       }
        smp_trap_init(ctxt.trap_ctxt);
 
        /* No LDT. */
@@ -777,11 +771,13 @@
 
        ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
 
-       boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
+       boot_error  = HYPERVISOR_vcpu_op(VCPUOP_create, cpu, &ctxt);
        if (boot_error)
                printk("boot error: %ld\n", boot_error);
 
        if (!boot_error) {
+               HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
+
                /*
                 * allow APs to start initializing.
                 */
@@ -1267,13 +1263,8 @@
        local_setup_timer_irq();
 }
 
-void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-}
-
-int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       return 0;
-}
-
-#endif
+void vcpu_prepare(int vcpu)
+{
+}
+
+#endif
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Tue Oct  4 
13:22:30 2005
@@ -956,6 +956,12 @@
 void smp_trap_init(trap_info_t *trap_ctxt)
 {
        trap_info_t *t = trap_table;
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               trap_ctxt[i].vector = i;
+               trap_ctxt[i].cs     = FLAT_KERNEL_CS;
+       }
 
        for (t = trap_table; t->address; t++) {
                trap_ctxt[t->vector].flags = t->flags;
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c Mon Oct  3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c Tue Oct  4 13:22:30 2005
@@ -30,7 +30,8 @@
 
 enum {
        TPM_MINOR = 224,        /* officially assigned */
-       TPM_BUFSIZE = 2048,
+       TPM_MIN_BUFSIZE = 2048,
+       TPM_MAX_BUFSIZE = 65536,
        TPM_NUM_DEVICES = 256,
        TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
 };
@@ -63,7 +64,7 @@
 
        down(&chip->buffer_mutex);
        atomic_set(&chip->data_pending, 0);
-       memset(chip->data_buffer, 0, TPM_BUFSIZE);
+       memset(chip->data_buffer, 0, chip->vendor->buffersize);
        up(&chip->buffer_mutex);
 }
 
@@ -458,7 +459,8 @@
 
        spin_unlock(&driver_lock);
 
-       chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
+       chip->data_buffer = kmalloc(chip->vendor->buffersize * sizeof(u8),
+                                   GFP_KERNEL);
        if (chip->data_buffer == NULL) {
                chip->num_opens--;
                put_device(chip->dev);
@@ -507,8 +509,8 @@
 
        down(&chip->buffer_mutex);
 
-       if (in_size > TPM_BUFSIZE)
-               in_size = TPM_BUFSIZE;
+       if (in_size > chip->vendor->buffersize)
+               in_size = chip->vendor->buffersize;
 
        if (copy_from_user
            (chip->data_buffer, (void __user *) buf, in_size)) {
@@ -517,7 +519,9 @@
        }
 
        /* atomic tpm command send and result receive */
-       out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
+       out_size = tpm_transmit(chip,
+                               chip->data_buffer,
+                               chip->vendor->buffersize);
 
        atomic_set(&chip->data_pending, out_size);
        up(&chip->buffer_mutex);
@@ -667,6 +671,12 @@
 
        chip->vendor = entry;
 
+       if (entry->buffersize < TPM_MIN_BUFSIZE) {
+               entry->buffersize = TPM_MIN_BUFSIZE;
+       } else if (entry->buffersize > TPM_MAX_BUFSIZE) {
+               entry->buffersize = TPM_MAX_BUFSIZE;
+       }
+
        chip->dev_num = -1;
 
        for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h Mon Oct  3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h Tue Oct  4 13:22:30 2005
@@ -62,6 +62,7 @@
        u8 req_complete_val;
        u8 req_canceled;
        u16 base;               /* TPM base address */
+       u32 buffersize;         /* The device's requested buffersize */
 
        int (*recv) (struct tpm_chip *, u8 *, size_t);
        int (*send) (struct tpm_chip *, u8 *, size_t);
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Mon Oct  3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Tue Oct  4 13:22:30 2005
@@ -445,6 +445,7 @@
        .base = 0,
        .attr = TPM_DEVICE_ATTRS,
        .miscdev.fops = &tpm_xen_ops,
+       .buffersize = 64 * 1024,
 };
 
 static struct device tpm_device = {
@@ -476,6 +477,8 @@
                tpm_fe_unregister_receiver();
                return rc;
        }
+
+       tpm_xen.buffersize = tpmfe.max_tx_size;
 
        if ((rc = tpm_register_hardware_nopci(&tpm_device, &tpm_xen)) < 0) {
                device_unregister(&tpm_device);
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Oct  4 
13:22:30 2005
@@ -316,26 +316,10 @@
 }
 
 static inline int
-HYPERVISOR_boot_vcpu(
-       unsigned long vcpu, vcpu_guest_context_t *ctxt)
-{
-       return _hypercall2(int, boot_vcpu, vcpu, ctxt);
-}
-
-static inline int
-HYPERVISOR_vcpu_up(
-       int vcpu)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
-                          (vcpu << SCHEDOP_vcpushift), 0);
-}
-
-static inline int
-HYPERVISOR_vcpu_pickle(
-       int vcpu, vcpu_guest_context_t *ctxt)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
-                          (vcpu << SCHEDOP_vcpushift), ctxt);
+HYPERVISOR_vcpu_op(
+       int cmd, int vcpuid, void *extra_args)
+{
+       return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
 }
 
 static inline int
@@ -354,24 +338,6 @@
                                         SCHEDOP_reasonshift)), 
                "2" (srec) : "memory", "ecx");
 
-       return ret;
-}
-
-static inline int
-HYPERVISOR_vcpu_down(
-       int vcpu)
-{
-       int ret;
-       unsigned long ign1;
-       /* Yes, I really do want to clobber edx here: when we resume a
-          vcpu after unpickling a multi-processor domain, it returns
-          here, but clobbers all of the call clobbered registers. */
-       __asm__ __volatile__ (
-               TRAP_INSTR
-               : "=a" (ret), "=b" (ign1)
-               : "0" (__HYPERVISOR_sched_op),
-               "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
-               : "memory", "ecx", "edx" );
        return ret;
 }
 
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h   Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h   Tue Oct  4 
13:22:30 2005
@@ -412,17 +412,6 @@
        ptep_set_access_flags(__vma, __address, __ptep, __entry, 1);    \
 } while (0)
 
-#define __HAVE_ARCH_PTEP_ESTABLISH_NEW
-#define ptep_establish_new(__vma, __address, __ptep, __entry)          \
-do {                                                                   \
-       if (likely((__vma)->vm_mm == current->mm)) {                    \
-               BUG_ON(HYPERVISOR_update_va_mapping((__address),        \
-                                            __entry, 0));              \
-       } else {                                                        \
-               xen_l1_entry_update((__ptep), (__entry));       \
-       }                                                               \
-} while (0)
-
 #ifndef CONFIG_XEN_SHADOW_MODE
 void make_lowmem_page_readonly(void *va);
 void make_lowmem_page_writable(void *va);
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h Mon Oct  3 
15:40:27 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h Tue Oct  4 
13:22:30 2005
@@ -601,24 +601,6 @@
     return 1;
 }
 
-static inline int
-HYPERVISOR_boot_vcpu(
-    unsigned long vcpu, vcpu_guest_context_t *ctxt)
-{
-#if 0
-    int ret;
-    unsigned long ign1, ign2;
-
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign1), "=c" (ign2)
-       : "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt)
-       : "memory");
-
-    return ret;
-#endif
-    return 1;
-}
 #endif
 
 #endif /* __HYPERCALL_H__ */
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Mon Oct 
 3 15:40:27 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Tue Oct 
 4 13:22:30 2005
@@ -302,26 +302,10 @@
 }
 
 static inline int
-HYPERVISOR_boot_vcpu(
-       unsigned long vcpu, vcpu_guest_context_t *ctxt)
-{
-       return _hypercall2(int, boot_vcpu, vcpu, ctxt);
-}
-
-static inline int
-HYPERVISOR_vcpu_up(
-       int vcpu)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
-                          (vcpu << SCHEDOP_vcpushift), 0);
-}
-
-static inline int
-HYPERVISOR_vcpu_pickle(
-       int vcpu, vcpu_guest_context_t *ctxt)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
-                          (vcpu << SCHEDOP_vcpushift), ctxt);
+HYPERVISOR_vcpu_op(
+       int cmd, int vcpuid, void *extra_args)
+{
+       return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
 }
 
 static inline int
diff -r d79ab87e27b8 -r abfc9808adb9 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Mon Oct  3 15:40:27 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Tue Oct  4 13:22:30 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
@@ -15,7 +16,6 @@
 
 import xen.lowlevel.xc
 
-import XendDomainInfo
 from xen.xend.xenstore.xsutil import IntroduceDomain
 
 from XendError import XendError
@@ -42,58 +42,75 @@
         raise XendError(errmsg)
     return buf
 
-def save(xd, fd, dominfo, live):
+def save(fd, dominfo, live):
     write_exact(fd, SIGNATURE, "could not write guest state file: signature")
 
     config = sxp.to_string(dominfo.sxpr())
-    write_exact(fd, pack("!i", len(config)),
-                "could not write guest state file: config len")
-    write_exact(fd, config, "could not write guest state file: config")
-
-    # xc_save takes three customization parameters: maxit, max_f, and flags
-    # the last controls whether or not save is 'live', while the first two
-    # further customize behaviour when 'live' save is enabled. Passing "0"
-    # simply uses the defaults compiled into libxenguest; see the comments 
-    # and/or code in xc_linux_save() for more information. 
-    cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
-           str(dominfo.getDomid()), "0", "0", str(int(live)) ]
-    log.info("[xc_save] " + join(cmd))
-    child = xPopen3(cmd, True, -1, [fd, xc.handle()])
+
+    domain_name = dominfo.getName()
+
+    if live:
+        dominfo.setName('migrating-' + domain_name)
+
+    try:
+        write_exact(fd, pack("!i", len(config)),
+                    "could not write guest state file: config len")
+        write_exact(fd, config, "could not write guest state file: config")
+
+        # xc_save takes three customization parameters: maxit, max_f, and
+        # flags the last controls whether or not save is 'live', while the
+        # first two further customize behaviour when 'live' save is
+        # enabled. Passing "0" simply uses the defaults compiled into
+        # libxenguest; see the comments and/or code in xc_linux_save() for
+        # more information.
+        cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
+               str(dominfo.getDomid()), "0", "0", str(int(live)) ]
+        log.info("[xc_save] " + join(cmd))
+        child = xPopen3(cmd, True, -1, [fd, xc.handle()])
     
-    lasterr = ""
-    p = select.poll()
-    p.register(child.fromchild.fileno())
-    p.register(child.childerr.fileno())
-    while True: 
-        r = p.poll()
-        for (fd, event) in r:
-            if not event & select.POLLIN:
-                continue
-            if fd == child.childerr.fileno():
-                l = child.childerr.readline()
-                log.error(l.rstrip())
-                lasterr = l.rstrip()
-            if fd == child.fromchild.fileno():
-                l = child.fromchild.readline()
-                if l.rstrip() == "suspend":
-                    log.info("suspending %d" % dominfo.getDomid())
-                    xd.domain_shutdown(dominfo.getDomid(), reason='suspend')
-                    dominfo.state_wait(XendDomainInfo.STATE_VM_SUSPENDED)
-                    log.info("suspend %d done" % dominfo.getDomid())
-                    child.tochild.write("done\n")
-                    child.tochild.flush()
-        if filter(lambda (fd, event): event & select.POLLHUP, r):
-            break
-
-    if child.wait() >> 8 == 127:
-        lasterr = "popen %s failed" % PATH_XC_SAVE
-    if child.wait() != 0:
-        raise XendError("xc_save failed: %s" % lasterr)
-
-    dominfo.destroy()
-    return None
-
-def restore(fd):
+        lasterr = ""
+        p = select.poll()
+        p.register(child.fromchild.fileno())
+        p.register(child.childerr.fileno())
+        while True: 
+            r = p.poll()
+            for (fd, event) in r:
+                if not event & select.POLLIN:
+                    continue
+                if fd == child.childerr.fileno():
+                    l = child.childerr.readline()
+                    log.error(l.rstrip())
+                    lasterr = l.rstrip()
+                if fd == child.fromchild.fileno():
+                    l = child.fromchild.readline()
+                    if l.rstrip() == "suspend":
+                        log.info("suspending %d", dominfo.getDomid())
+                        dominfo.shutdown('suspend')
+                        dominfo.waitForShutdown()
+                        log.info("suspend %d done", dominfo.getDomid())
+                        child.tochild.write("done\n")
+                        child.tochild.flush()
+            if filter(lambda (fd, event): event & select.POLLHUP, r):
+                break
+
+        if child.wait() >> 8 == 127:
+            lasterr = "popen %s failed" % PATH_XC_SAVE
+        if child.wait() != 0:
+            raise XendError("xc_save failed: %s" % lasterr)
+
+        dominfo.destroyDomain()
+    except Exception, exn:
+        log.exception("Save failed on domain %s (%d).", domain_name,
+                      dominfo.getDomid())
+        try:
+            if live:
+                dominfo.setName(domain_name)
+        except:
+            log.exception("Failed to reset the migrating domain's name")
+        raise Exception, exn
+
+
+def restore(xd, fd):
     signature = read_exact(fd, len(SIGNATURE),
         "not a valid guest state file: signature read")
     if signature != SIGNATURE:
@@ -112,71 +129,72 @@
         raise XendError("not a valid guest state file: config parse")
 
     vmconfig = p.get_val()
-    dominfo = XendDomainInfo.restore(vmconfig)
-
-    l = read_exact(fd, sizeof_unsigned_long,
-                   "not a valid guest state file: pfn count read")
-    nr_pfns = unpack("=L", l)[0]   # XXX endianess
-    if nr_pfns > 1024*1024:     # XXX
-        raise XendError(
-            "not a valid guest state file: pfn count out of range")
-
-    if dominfo.store_channel:
+
+    dominfo = xd.restore_(vmconfig)
+
+    assert dominfo.store_channel
+    assert dominfo.console_channel
+
+    try:
+        l = read_exact(fd, sizeof_unsigned_long,
+                       "not a valid guest state file: pfn count read")
+        nr_pfns = unpack("=L", l)[0]   # XXX endianess
+        if nr_pfns > 1024*1024:     # XXX
+            raise XendError(
+                "not a valid guest state file: pfn count out of range")
+
         store_evtchn = dominfo.store_channel.port2
-    else:
-        store_evtchn = 0
-
-    if dominfo.console_channel:
         console_evtchn = dominfo.console_channel.port2
-    else:
-        console_evtchn = 0
-
-    cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
-           str(dominfo.getDomid()), str(nr_pfns),
-           str(store_evtchn), str(console_evtchn)]
-    log.info("[xc_restore] " + join(cmd))
-    child = xPopen3(cmd, True, -1, [fd, xc.handle()])
-    child.tochild.close()
-
-    lasterr = ""
-    p = select.poll()
-    p.register(child.fromchild.fileno())
-    p.register(child.childerr.fileno())
-    while True:
-        r = p.poll()
-        for (fd, event) in r:
-            if not event & select.POLLIN:
-                continue
-            if fd == child.childerr.fileno():
-                l = child.childerr.readline()
-                log.error(l.rstrip())
-                lasterr = l.rstrip()
-            if fd == child.fromchild.fileno():
-                l = child.fromchild.readline()
-                while l:
-                    log.info(l.rstrip())
-                    m = re.match(r"^(store-mfn) (\d+)\n$", l)
-                    if m:
-                        if dominfo.store_channel:
+
+        cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
+               str(dominfo.getDomid()), str(nr_pfns),
+               str(store_evtchn), str(console_evtchn)]
+        log.info("[xc_restore] " + join(cmd))
+        child = xPopen3(cmd, True, -1, [fd, xc.handle()])
+        child.tochild.close()
+
+        lasterr = ""
+        p = select.poll()
+        p.register(child.fromchild.fileno())
+        p.register(child.childerr.fileno())
+        while True:
+            r = p.poll()
+            for (fd, event) in r:
+                if not event & select.POLLIN:
+                    continue
+                if fd == child.childerr.fileno():
+                    l = child.childerr.readline()
+                    log.error(l.rstrip())
+                    lasterr = l.rstrip()
+                if fd == child.fromchild.fileno():
+                    l = child.fromchild.readline()
+                    while l:
+                        log.info(l.rstrip())
+                        m = re.match(r"^(store-mfn) (\d+)\n$", l)
+                        if m:
                             store_mfn = int(m.group(2))
                             dominfo.setStoreRef(store_mfn)
                             IntroduceDomain(dominfo.getDomid(),
                                             store_mfn,
                                             dominfo.store_channel.port1,
                                             dominfo.getDomainPath())
-                    m = re.match(r"^(console-mfn) (\d+)\n$", l)
-                    if m:
-                        dominfo.setConsoleRef(int(m.group(2)))
-                    try:
-                        l = child.fromchild.readline()
-                    except:
-                        l = None
-        if filter(lambda (fd, event): event & select.POLLHUP, r):
-            break
-
-    if child.wait() >> 8 == 127:
-        lasterr = "popen %s failed" % PATH_XC_RESTORE
-    if child.wait() != 0:
-        raise XendError("xc_restore failed: %s" % lasterr)
-
-    return dominfo
+                        m = re.match(r"^(console-mfn) (\d+)\n$", l)
+                        if m:
+                            dominfo.setConsoleRef(int(m.group(2)))
+                        try:
+                            l = child.fromchild.readline()
+                        except:
+                            l = None
+            if filter(lambda (fd, event): event & select.POLLHUP, r):
+                break
+
+        if child.wait() >> 8 == 127:
+            lasterr = "popen %s failed" % PATH_XC_RESTORE
+        if child.wait() != 0:
+            raise XendError("xc_restore failed: %s" % lasterr)
+
+        return dominfo
+    except:
+        log.exception("Restore failed")
+        dominfo.destroy()
+        raise
diff -r d79ab87e27b8 -r abfc9808adb9 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Oct  3 15:40:27 2005
+++ b/tools/python/xen/xend/XendDomain.py       Tue Oct  4 13:22:30 2005
@@ -22,14 +22,16 @@
  Needs to be persistent for one uptime.
 """
 import os
+import string
 import threading
 
 import xen.lowlevel.xc
+
+import XendDomainInfo
 
 from xen.xend import sxp
 from xen.xend import XendRoot
 from xen.xend import XendCheckpoint
-from xen.xend.XendDomainInfo import XendDomainInfo
 from xen.xend import EventServer
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
@@ -45,20 +47,9 @@
 
 PRIV_DOMAIN = 0
 
-class XendDomainDict(dict):
-    def get_by_name(self, name):
-        try:
-            return filter(lambda d: d.getName() == name, self.values())[0]
-        except IndexError, err:
-            return None
-
 class XendDomain:
     """Index of all domains. Singleton.
     """
-
-    """Dict of domain info indexed by domain id."""
-    domains = None
-
 
     ## public:
     
@@ -68,19 +59,30 @@
         # to import XendDomain from XendDomainInfo causes unbounded recursion.
         # So we stuff the XendDomain instance (self) into xroot's components.
         xroot.add_component("xen.xend.XendDomain", self)
-        self.domains = XendDomainDict()
-        self.refresh_lock = threading.Condition()
+        self.domains = {}
+        self.domains_lock = threading.Condition()
         self.watchReleaseDomain()
-        self.refresh()
-        self.dom0_setup()
+
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            self.dom0_setup()
+        finally:
+            self.domains_lock.release()
+
 
     def list(self):
         """Get list of domain objects.
 
         @return: domain objects
         """
-        self.refresh()
-        return self.domains.values()
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domains.values()
+        finally:
+            self.domains_lock.release()
+
 
     def list_sorted(self):
         """Get list of domain objects, sorted by name.
@@ -103,7 +105,12 @@
     ## private:
 
     def onReleaseDomain(self):
-        self.refresh()
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+        finally:
+            self.domains_lock.release()
+            
 
     def watchReleaseDomain(self):
         from xen.xend.xenstore.xswatch import xswatch
@@ -133,16 +140,8 @@
         return dominfo
 
 
-    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)
+        dom0 = self.domains[PRIV_DOMAIN]
         dom0.dom0_enforce_vcpus()
 
 
@@ -179,50 +178,33 @@
     def refresh(self):
         """Refresh domain list from Xen.
         """
-        self.refresh_lock.acquire()
-        try:
-            doms = self.xen_domains()
-            for d in self.domains.values():
-                info = doms.get(d.getDomid())
-                if info:
-                    d.update(info)
-                else:
-                    self._delete_domain(d.getDomid())
-            for d in doms:
-                if d not in self.domains and not doms[d]['dying']:
-                    try:
-                        self.recreate_domain(doms[d])
-                    except:
-                        if d == PRIV_DOMAIN:
-                            log.exception(
-                                "Failed to recreate information for domain "
-                                "%d.  Doing nothing except crossing my "
-                                "fingers.", d)
-                        else:
-                            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)
-        finally:
-            self.refresh_lock.release()
-
-
-    def update_domain(self, id):
-        """Update information for a single domain.
-
-        @param id: domain id
-        """
-        dominfo = self.xen_domain(id)
-        if dominfo:
-            d = self.domains.get(id)
-            if d:
-                d.update(dominfo)
-        else:
-            self._delete_domain(id)
+        doms = self.xen_domains()
+        for d in self.domains.values():
+            info = doms.get(d.getDomid())
+            if info:
+                d.update(info)
+            else:
+                self._delete_domain(d.getDomid())
+        for d in doms:
+            if d not in self.domains and not doms[d]['dying']:
+                try:
+                    dominfo = XendDomainInfo.recreate(doms[d])
+                    self._add_domain(dominfo)
+                except:
+                    if d == PRIV_DOMAIN:
+                        log.exception(
+                            "Failed to recreate information for domain "
+                            "%d.  Doing nothing except crossing my "
+                            "fingers.", d)
+                    else:
+                        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)
 
 
     ## public:
@@ -233,9 +215,14 @@
         @param config: configuration
         @return: domain
         """
-        dominfo = XendDomainInfo.create(config)
-        self._add_domain(dominfo)
-        return dominfo
+        self.domains_lock.acquire()
+        try:
+            dominfo = XendDomainInfo.create(config)
+            self._add_domain(dominfo)
+            return dominfo
+        finally:
+            self.domains_lock.release()
+
 
     def domain_configure(self, config):
         """Configure an existing domain.
@@ -252,39 +239,110 @@
         """
 
         try:
-            fd = os.open(src, os.O_RDONLY)
-            dominfo = XendCheckpoint.restore(fd)
-            self._add_domain(dominfo)
-            return dominfo
+            return self.domain_restore_fd(os.open(src, os.O_RDONLY))
         except OSError, ex:
             raise XendError("can't read guest state file %s: %s" %
                             (src, ex[1]))
 
-    def domain_get(self, id):
-        """Get up-to-date info about a domain.
-
-        @param id: domain id
-        @return: domain object (or None)
-        """
-        self.update_domain(id)
-        return self.domains.get(id)
+    def domain_restore_fd(self, fd):
+        """Restore a domain from the given file descriptor."""
+
+        try:
+            XendCheckpoint.restore(self, fd)
+        except Exception, ex:
+            log.exception("Restore failed")
+            raise
+
+
+    def restore_(self, config):
+        """Create a domain as part of the restore process.  This is called
+        only from {@link XendCheckpoint}.
+
+        A restore request comes into XendDomain through {@link
+        #domain_restore} or {@link #domain_restore_fd}.  That request is
+        forwarded immediately to XendCheckpoint which, when it is ready, will
+        call this method.  It is necessary to come through here rather than go
+        directly to {@link XendDomainInfo.restore} because we need to
+        serialise the domain creation process, but cannot lock
+        domain_restore_fd as a whole, otherwise we will deadlock waiting for
+        the old domain to die.
+        """
+        self.domains_lock.acquire()
+        try:
+            dominfo = XendDomainInfo.restore(config)
+            self._add_domain(dominfo)
+            return dominfo
+        finally:
+            self.domains_lock.release()
 
 
     def domain_lookup(self, id):
-        self.refresh()
-        return self.domains.get(id)
-
-    def domain_lookup_by_name(self, name):
-        self.refresh()
-        dominfo = self.domains.get_by_name(name)
-        if not dominfo:
-            try:
-                id = int(name)
-                dominfo = self.domain_lookup(id)
-            except ValueError:
-                pass
-        return dominfo
-
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domains.get(id)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_nr(self, id):
+        self.domains_lock.acquire()
+        try:
+            return self.domains.get(id)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_or_id(self, name):
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domain_lookup_by_name_or_id_nr(name)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_or_id_nr(self, name):
+        self.domains_lock.acquire()
+        try:
+            dominfo = self.domain_lookup_by_name_nr(name)
+
+            if dominfo:
+                return dominfo
+            else:
+                try:
+                    return self.domains.get(int(name))
+                except ValueError:
+                    return None
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_nr(self, name):
+        self.domains_lock.acquire()
+        try:
+            matching = filter(lambda d: d.getName() == name,
+                              self.domains.values())
+            n = len(matching)
+            if n == 1:
+                return matching[0]
+            elif n > 1:
+                raise XendError(
+                    'Name uniqueness has been violated for name %s' % name)
+            else:
+                return None
+        finally:
+            self.domains_lock.release()
+
+
+    def privilegedDomain(self):
+        self.domains_lock.acquire()
+        try:
+            return self.domains[PRIV_DOMAIN]
+        finally:
+            self.domains_lock.release()
+
+ 
     def domain_unpause(self, id):
         """Unpause domain execution.
 
@@ -312,32 +370,22 @@
             raise XendError(str(ex))
 
 
-    def domain_shutdown(self, domid, 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
-         - halt:     do not restart
-
-         Returns immediately.
-
-        @param id:     domain id
-        @param reason: shutdown type: poweroff, reboot, suspend, halt
-        """
-        self.callInfo(domid, XendDomainInfo.shutdown, reason)
+
+        @param reason: shutdown reason: poweroff, reboot, suspend, halt
+        """
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.shutdown, reason)
 
 
     def domain_sysrq(self, domid, key):
         """Send a SysRq to the specified domain."""
-        return self.callInfo(domid, XendDomainInfo.send_sysrq, key)
-
-
-    def domain_destroy(self, domid, reason='halt'):
-        """Terminate domain immediately.
-        - halt:   cancel any restart for the domain
-        - reboot  schedule a restart for the domain
-
-        @param domid: domain id
-        """
+        return self.callInfo(domid, XendDomainInfo.XendDomainInfo.send_sysrq,
+                             key)
+
+
+    def domain_destroy(self, domid):
+        """Terminate domain immediately."""
 
         if domid == PRIV_DOMAIN:
             raise XendError("Cannot destroy privileged domain %i" % domid)
@@ -364,19 +412,8 @@
         port = xroot.get_xend_relocation_port()
         sock = relocate.setupRelocation(dst, port)
 
-        # temporarily rename domain for localhost migration
-        if dst == "localhost":
-            dominfo.setName("tmp-" + dominfo.getName())
-
-        try:
-            XendCheckpoint.save(self, sock.fileno(), dominfo, live)
-        except:
-            if dst == "localhost":
-                dominfo.setName(
-                    string.replace(dominfo.getName(), "tmp-", "", 1))
-            raise
+        XendCheckpoint.save(sock.fileno(), dominfo, live)
         
-        return None
 
     def domain_save(self, id, dst):
         """Start saving a domain to file.
@@ -391,7 +428,7 @@
             fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
 
             # For now we don't support 'live checkpoint' 
-            return XendCheckpoint.save(self, fd, dominfo, False)
+            return XendCheckpoint.save(fd, dominfo, False)
 
         except OSError, ex:
             raise XendError("can't write guest state file %s: %s" %
@@ -456,32 +493,39 @@
     def domain_device_create(self, domid, devconfig):
         """Create a new device for the specified domain.
         """
-        return self.callInfo(domid, XendDomainInfo.device_create, devconfig)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.device_create,
+                             devconfig)
 
 
     def domain_device_configure(self, domid, devconfig, devid):
         """Configure an existing device in the specified domain.
         @return: updated device configuration
         """
-        return self.callInfo(domid, XendDomainInfo.device_configure,
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.device_configure,
                              devconfig, devid)
 
     
     def domain_device_refresh(self, domid, devtype, devid):
         """Refresh a device."""
-        return self.callInfo(domid, XendDomainInfo.device_refresh, devtype,
-                             devid)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.device_refresh,
+                             devtype, devid)
 
 
     def domain_device_destroy(self, domid, devtype, devid):
         """Destroy a device."""
-        return self.callInfo(domid, XendDomainInfo.destroyDevice, devtype,
-                             devid)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.destroyDevice,
+                             devtype, devid)
 
 
     def domain_devtype_ls(self, domid, devtype):
         """Get list of device sxprs for the specified domain."""
-        return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.getDeviceSxprs,
+                             devtype)
 
 
     def domain_vif_limit_set(self, id, vif, credit, period):
@@ -525,7 +569,8 @@
 
         @param mem: memory target (in MiB)
         """
-        self.callInfo(domid, XendDomainInfo.setMemoryTarget, mem << 10)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.setMemoryTarget,
+                      mem << 10)
 
 
     def domain_vcpu_hotplug(self, domid, vcpu, state):
@@ -534,12 +579,13 @@
         @param vcpu: target VCPU in domain
         @param state: which state VCPU will become
         """
-        self.callInfo(domid, XendDomainInfo.vcpu_hotplug, vcpu, state)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.vcpu_hotplug, vcpu,
+                      state)
 
 
     def domain_dumpcore(self, domid):
         """Save a core dump for a crashed domain."""
-        self.callInfo(domid, XendDomainInfo.dumpCore)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.dumpCore)
 
 
     ## private:
diff -r d79ab87e27b8 -r abfc9808adb9 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Oct  3 15:40:27 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Oct  4 13:22:30 2005
@@ -59,12 +59,16 @@
 """Shutdown code for crash."""
 DOMAIN_CRASH    = 3
 
+"""Shutdown code for halt."""
+DOMAIN_HALT     = 4
+
 """Map shutdown codes to strings."""
 shutdown_reasons = {
     DOMAIN_POWEROFF: "poweroff",
     DOMAIN_REBOOT  : "reboot",
     DOMAIN_SUSPEND : "suspend",
     DOMAIN_CRASH   : "crash",
+    DOMAIN_HALT    : "halt"
     }
 
 restart_modes = [
@@ -76,7 +80,6 @@
 
 STATE_VM_OK         = "ok"
 STATE_VM_TERMINATED = "terminated"
-STATE_VM_SUSPENDED  = "suspended"
 
 """Flag for a block device backend domain."""
 SIF_BLK_BE_DOMAIN = (1<<4)
@@ -116,6 +119,68 @@
     ]
 
 
+def create(config):
+    """Create a VM from a configuration.
+
+    @param config    configuration
+    @raise: VmError for invalid configuration
+    """
+
+    log.debug("XendDomainInfo.create(%s)", config)
+
+    vm = XendDomainInfo(getUuid(), parseConfig(config))
+    vm.construct()
+    vm.refreshShutdown()
+    return vm
+
+
+def recreate(xeninfo):
+    """Create the VM object for an existing domain.  The domain must not
+    be dying, as the paths in the store should already have been removed,
+    and asking us to recreate them causes problems."""
+
+    log.debug("XendDomainInfo.recreate(%s)", xeninfo)
+
+    assert not xeninfo['dying']
+
+    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)
+
+        log.info("Recreating domain %d, UUID %s.", domid, uuid)
+
+        vm = XendDomainInfo(uuid, xeninfo, domid, True)
+
+    except Exception, exn:
+        log.warn(str(exn))
+
+        uuid = getUuid()
+
+        log.info("Recreating domain %d with new UUID %s.", domid, uuid)
+
+        vm = XendDomainInfo(uuid, xeninfo, domid, True)
+        vm.storeVmDetails()
+        vm.storeDomDetails()
+
+    vm.create_channel()
+    if domid == 0:
+        vm.initStoreConnection()
+
+    vm.refreshShutdown(xeninfo)
+    return vm
+
+
 def restore(config):
     """Create a domain and a VM object to do a restore.
 
@@ -130,7 +195,7 @@
     except TypeError, exn:
         raise VmError('Invalid ssidref in config: %s' % exn)
 
-    vm = XendDomainInfo(uuid, XendDomainInfo.parseConfig(config),
+    vm = XendDomainInfo(uuid, parseConfig(config),
                         xc.domain_create(ssidref = ssidref))
     vm.storeVmDetails()
     vm.configure()
@@ -139,10 +204,87 @@
     return vm
 
 
-def domain_exists(name):
+def parseConfig(config):
+    def get_cfg(name, conv = None):
+        val = sxp.child_value(config, name)
+
+        if conv and not val is None:
+            try:
+                return conv(val)
+            except TypeError, exn:
+                raise VmError(
+                    'Invalid setting %s = %s in configuration: %s' %
+                    (name, val, str(exn)))
+        else:
+            return val
+
+
+    log.debug("parseConfig: config is %s" % str(config))
+
+    result = {}
+
+    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['image']        = get_cfg('image')
+
+    try:
+        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(result['image'], 'vcpus', 1), str(exn)))
+
+    result['backend'] = []
+    for c in sxp.children(config, 'backend'):
+        result['backend'].append(sxp.name(sxp.child0(c)))
+
+    result['device'] = []
+    for d in sxp.children(config, 'device'):
+        c = sxp.child0(d)
+        result['device'].append((sxp.name(c), c))
+
+    # Configuration option "restart" is deprecated.  Parse it, but
+    # let on_xyz override it if they are present.
+    restart = get_cfg('restart')
+    if restart:
+        def handle_restart(event, val):
+            if not event in result:
+                result[event] = val
+
+        if restart == "onreboot":
+            handle_restart('on_poweroff', 'destroy')
+            handle_restart('on_reboot',   'restart')
+            handle_restart('on_crash',    'destroy')
+        elif restart == "always":
+            handle_restart('on_poweroff', 'restart')
+            handle_restart('on_reboot',   'restart')
+            handle_restart('on_crash',    'restart')
+        elif restart == "never":
+            handle_restart('on_poweroff', 'destroy')
+            handle_restart('on_reboot',   'destroy')
+            handle_restart('on_crash',    'destroy')
+        else:
+            log.warn("Ignoring malformed and deprecated config option "
+                     "restart = %s", restart)
+
+    log.debug("parseConfig: result is %s" % str(result))
+    return result
+
+
+def domain_by_name(name):
     # See comment in XendDomain constructor.
     xd = get_component('xen.xend.XendDomain')
-    return xd.domain_lookup_by_name(name)
+    return xd.domain_lookup_by_name_nr(name)
 
 def shutdown_reason(code):
     """Get a shutdown reason from a code.
@@ -177,152 +319,6 @@
     MINIMUM_RESTART_TIME = 20
 
 
-    def create(cls, config):
-        """Create a VM from a configuration.
-
-        @param config    configuration
-        @raise: VmError for invalid configuration
-        """
-
-        log.debug("XendDomainInfo.create(%s)", config)
-        
-        vm = cls(getUuid(), cls.parseConfig(config))
-        vm.construct()
-        vm.refreshShutdown()
-        return vm
-
-    create = classmethod(create)
-
-
-    def recreate(cls, xeninfo):
-        """Create the VM object for an existing domain.  The domain must not
-        be dying, as the paths in the store should already have been removed,
-        and asking us to recreate them causes problems."""
-
-        log.debug("XendDomainInfo.recreate(%s)", xeninfo)
-
-        assert not xeninfo['dying']
-
-        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)
-
-            log.info("Recreating domain %d, UUID %s.", domid, uuid)
-
-            vm = cls(uuid, xeninfo, domid, True)
-
-        except Exception, exn:
-            log.warn(str(exn))
-
-            uuid = getUuid()
-
-            log.info("Recreating domain %d with new UUID %s.", domid, uuid)
-
-            vm = cls(uuid, xeninfo, domid, True)
-            vm.storeVmDetails()
-            vm.storeDomDetails()
-
-        vm.create_channel()
-        if domid == 0:
-            vm.initStoreConnection()
-
-        vm.refreshShutdown(xeninfo)
-        return vm
-
-    recreate = classmethod(recreate)
-
-
-    def parseConfig(cls, config):
-        def get_cfg(name, conv = None):
-            val = sxp.child_value(config, name)
-
-            if conv and not val is None:
-                try:
-                    return conv(val)
-                except TypeError, exn:
-                    raise VmError(
-                        'Invalid setting %s = %s in configuration: %s' %
-                        (name, val, str(exn)))
-            else:
-                return val
-
-
-        log.debug("parseConfig: config is %s" % str(config))
-
-        result = {}
-
-        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['image']        = get_cfg('image')
-
-        try:
-            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(result['image'], 'vcpus', 1), str(exn)))
-
-        result['backend'] = []
-        for c in sxp.children(config, 'backend'):
-            result['backend'].append(sxp.name(sxp.child0(c)))
-
-        result['device'] = []
-        for d in sxp.children(config, 'device'):
-            c = sxp.child0(d)
-            result['device'].append((sxp.name(c), c))
-
-        # Configuration option "restart" is deprecated.  Parse it, but
-        # let on_xyz override it if they are present.
-        restart = get_cfg('restart')
-        if restart:
-            def handle_restart(event, val):
-                if not event in result:
-                    result[event] = val
-
-            if restart == "onreboot":
-                handle_restart('on_poweroff', 'destroy')
-                handle_restart('on_reboot',   'restart')
-                handle_restart('on_crash',    'destroy')
-            elif restart == "always":
-                handle_restart('on_poweroff', 'restart')
-                handle_restart('on_reboot',   'restart')
-                handle_restart('on_crash',    'restart')
-            elif restart == "never":
-                handle_restart('on_poweroff', 'destroy')
-                handle_restart('on_reboot',   'destroy')
-                handle_restart('on_crash',    'destroy')
-            else:
-                log.warn("Ignoring malformed and deprecated config option "
-                         "restart = %s", restart)
-
-        log.debug("parseConfig: result is %s" % str(result))
-        return result
-
-
-    parseConfig = classmethod(parseConfig)
-
-    
     def __init__(self, uuid, info, domid = None, augment = False):
 
         self.uuid = uuid
@@ -627,21 +623,22 @@
                     # The domain no longer exists.  This will occur if we have
                     # scheduled a timer to check for shutdown timeouts and the
                     # shutdown succeeded.  It will also occur if someone
-                    # destroys a domain beneath us.  We clean up, just in
-                    # case.
+                    # destroys a domain beneath us.  We clean up the domain,
+                    # just in case, but we can't clean up the VM, because that
+                    # VM may have migrated to a different domain on this
+                    # machine.
                     self.cleanupDomain()
-                    self.cleanupVm()
                     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 do is make sure that it's not
-                # us holding the pages, by calling the cleanup methods.
+                # yet been cleaned up by Xen.  This state 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 do is make sure that it's not us
+                # holding the pages, by calling cleanupDomain.  We can't
+                # clean up the VM, as above.
                 self.cleanupDomain()
-                self.cleanupVm()
                 return
 
             elif xeninfo['crashed']:
@@ -654,10 +651,11 @@
                 restart_reason = 'crash'
 
             elif xeninfo['shutdown']:
-                if self.readDom('xend/shutdown'):
+                if self.readDom('xend/shutdown_completed'):
                     # We've seen this shutdown already, but we are preserving
                     # the domain for debugging.  Leave it alone.
-                    pass
+                    return
+
                 else:
                     reason = shutdown_reason(xeninfo['shutdown_reason'])
 
@@ -667,7 +665,7 @@
                     self.clearRestart()
 
                     if reason == 'suspend':
-                        self.state_set(STATE_VM_SUSPENDED)
+                        self.state_set(STATE_VM_TERMINATED)
                         # Don't destroy the domain.  XendCheckpoint will do
                         # this once it has finished.
                     elif reason in ['poweroff', 'reboot']:
@@ -704,7 +702,7 @@
         if not reason in shutdown_reasons.values():
             raise XendError('invalid reason:' + reason)
         self.storeDom("control/shutdown", reason)
-        if not reason == 'suspend':
+        if reason != 'suspend':
             self.storeDom('xend/shutdown_start_time', time.time())
 
 
@@ -721,11 +719,6 @@
          "restart"        : self.restart,
          "preserve"       : self.preserve,
          "rename-restart" : self.renameRestart}[self.info['on_' + reason]]()
-
-
-    def preserve(self):
-        log.info("Preserving dead domain %s (%d).", self.info['name'],
-                 self.domid)
 
 
     def renameRestart(self):
@@ -817,9 +810,9 @@
 
     ## public:
 
-    def state_wait(self, state):
+    def waitForShutdown(self):
         self.state_updated.acquire()
-        while self.state != state:
+        while self.state == STATE_VM_OK:
             self.state_updated.wait()
         self.state_updated.release()
 
@@ -953,10 +946,8 @@
             if c in '_-.:/+': continue
             if c in string.ascii_letters: continue
             raise VmError('invalid vm name')
-        dominfo = domain_exists(name)
-        # When creating or rebooting, a domain with my name should not exist.
-        # When restoring, a domain with my name will exist, but it should have
-        # my domain id.
+
+        dominfo = domain_by_name(name)
         if not dominfo:
             return
         if dominfo.is_terminated():
@@ -1059,7 +1050,6 @@
         """Cleanup domain resources; release devices.  Idempotent.  Nothrow
         guarantee."""
 
-        self.state_set(STATE_VM_TERMINATED)
         self.release_devices()
         self.closeStoreChannel()
         self.closeConsoleChannel()
@@ -1092,14 +1082,22 @@
 
         log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
 
+        self.cleanupVm()
+        self.destroyDomain()
+
+
+    def destroyDomain(self):
+        log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
+
         self.cleanupDomain()
-        self.cleanupVm()
         
         try:
             if self.domid is not None:
                 xc.domain_destroy(dom=self.domid)
         except Exception:
             log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
+
+        self.state_set(STATE_VM_TERMINATED)
 
 
     ## private:
@@ -1248,14 +1246,18 @@
 
         try:
             if rename:
-                self.preserveShutdownDomain()
+                self.preserveForRestart()
             else:
-                self.cleanupDomain()
                 self.destroy()
                 
             try:
                 xd = get_component('xen.xend.XendDomain')
-                xd.domain_unpause(xd.domain_create(config).getDomid())
+                new_dom = xd.domain_create(config)
+                try:
+                    xc.domain_unpause(new_dom.getDomid())
+                except:
+                    new_dom.destroy()
+                    raise
             except Exception, exn:
                 log.exception('Failed to restart domain %d.', self.domid)
         finally:
@@ -1265,7 +1267,7 @@
         #        self.exportToDB()
 
 
-    def preserveShutdownDomain(self):
+    def preserveForRestart(self):
         """Preserve a domain that has been shut down, by giving it a new UUID,
         cloning the VM details, and giving it a new name.  This allows us to
         keep this domain for debugging, but restart a new one in its place
@@ -1281,8 +1283,14 @@
         self.uuid = new_uuid
         self.vmpath = VMROOT + new_uuid
         self.storeVmDetails()
-        self.storeDom('vm', self.vmpath)
-        self.storeDom('xend/shutdown', 'True')
+        self.preserve()
+
+
+    def preserve(self):
+        log.info("Preserving dead domain %s (%d).", self.info['name'],
+                 self.domid)
+        self.storeDom('xend/shutdown_completed', 'True')
+        self.set_state(STATE_VM_TERMINATED)
 
 
     def generateShutdownName(self):
diff -r d79ab87e27b8 -r abfc9808adb9 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Mon Oct  3 15:40:27 2005
+++ b/tools/python/xen/xend/server/DevController.py     Tue Oct  4 13:22:30 2005
@@ -189,8 +189,17 @@
         """
 
         import xen.xend.XendDomain
-        backdom = xen.xend.XendDomain.instance().domain_lookup_by_name(
-            sxp.child_value(config, 'backend', '0'))
+        xd = xen.xend.XendDomain.instance()
+
+        backdom_name = sxp.child_value(config, 'backend')
+        if backdom_name:
+            backdom = xd.domain_lookup_by_name_or_id_nr(backdom_name)
+        else:
+            backdom = xd.privilegedDomain()
+
+        if not backdom:
+            raise VmError("Cannot configure device for unknown backend %s" %
+                          backdom_name)
 
         frontpath = self.frontendPath(devid)
         backpath  = self.backendPath(backdom, devid)
@@ -221,7 +230,7 @@
 
         return "%s/backend/%s/%s/%d" % (backdom.getDomainPath(),
                                         self.deviceClass,
-                                        self.vm.getUuid(), devid)
+                                        self.vm.getDomid(), devid)
 
 
     def frontendPath(self, devid):
diff -r d79ab87e27b8 -r abfc9808adb9 
tools/python/xen/xend/server/SrvDomainDir.py
--- a/tools/python/xen/xend/server/SrvDomainDir.py      Mon Oct  3 15:40:27 2005
+++ b/tools/python/xen/xend/server/SrvDomainDir.py      Tue Oct  4 13:22:30 2005
@@ -38,7 +38,7 @@
         self.xd = XendDomain.instance()
 
     def domain(self, x):
-        dom = self.xd.domain_lookup_by_name(x)
+        dom = self.xd.domain_lookup_by_name_or_id(x)
         if not dom:
             raise XendError('No such domain ' + str(x))
         return SrvDomain(dom)
diff -r d79ab87e27b8 -r abfc9808adb9 tools/python/xen/xend/server/relocate.py
--- a/tools/python/xen/xend/server/relocate.py  Mon Oct  3 15:40:27 2005
+++ b/tools/python/xen/xend/server/relocate.py  Tue Oct  4 13:22:30 2005
@@ -28,7 +28,6 @@
 from xen.xend.XendError import XendError
 from xen.xend import XendRoot
 from xen.xend.XendLogging import log
-from xen.xend import XendCheckpoint
 
 
 eserver = EventServer.instance()
@@ -120,7 +119,8 @@
         if self.transport:
             self.send_reply(["ready", name])
             self.transport.sock.setblocking(1)
-            XendCheckpoint.restore(self.transport.sock.fileno())
+            xd = xroot.get_component("xen.xend.XendDomain")
+            xd.domain_restore_fd(self.transport.sock.fileno())
             self.transport.sock.setblocking(0)
         else:
             log.error(name + ": no transport")
diff -r d79ab87e27b8 -r abfc9808adb9 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Mon Oct  3 15:40:27 2005
+++ b/xen/arch/x86/x86_32/entry.S       Tue Oct  4 13:22:30 2005
@@ -808,7 +808,7 @@
         .long do_vm_assist
         .long do_update_va_mapping_otherdomain
         .long do_switch_vm86
-        .long do_boot_vcpu
+        .long do_vcpu_op
         .long do_ni_hypercall       /* 25 */
         .long do_mmuext_op
         .long do_acm_op             /* 27 */
@@ -841,7 +841,7 @@
         .byte 2 /* do_vm_assist         */
         .byte 5 /* do_update_va_mapping_otherdomain */
         .byte 0 /* do_switch_vm86       */
-        .byte 2 /* do_boot_vcpu         */
+        .byte 3 /* do_vcpu_op           */
         .byte 0 /* do_ni_hypercall      */  /* 25 */
         .byte 4 /* do_mmuext_op         */
         .byte 1 /* do_acm_op            */
diff -r d79ab87e27b8 -r abfc9808adb9 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Mon Oct  3 15:40:27 2005
+++ b/xen/arch/x86/x86_64/entry.S       Tue Oct  4 13:22:30 2005
@@ -629,7 +629,7 @@
         .quad do_vm_assist
         .quad do_update_va_mapping_otherdomain
         .quad do_switch_to_user
-        .quad do_boot_vcpu
+        .quad do_vcpu_op
         .quad do_set_segment_base   /* 25 */
         .quad do_mmuext_op
         .quad do_acm_op
@@ -662,7 +662,7 @@
         .byte 2 /* do_vm_assist         */
         .byte 4 /* do_update_va_mapping_otherdomain */
         .byte 0 /* do_switch_to_user    */
-        .byte 2 /* do_boot_vcpu         */
+        .byte 3 /* do_vcpu_op           */
         .byte 2 /* do_set_segment_base  */  /* 25 */
         .byte 4 /* do_mmuext_op         */
         .byte 1 /* do_acm_op            */
diff -r d79ab87e27b8 -r abfc9808adb9 xen/common/domain.c
--- a/xen/common/domain.c       Mon Oct  3 15:40:27 2005
+++ b/xen/common/domain.c       Tue Oct  4 13:22:30 2005
@@ -18,6 +18,7 @@
 #include <xen/domain_page.h>
 #include <asm/debugger.h>
 #include <public/dom0_ops.h>
+#include <public/vcpu.h>
 
 /* Both these structures are protected by the domlist_lock. */
 rwlock_t domlist_lock = RW_LOCK_UNLOCKED;
@@ -366,37 +367,17 @@
     return rc;
 }
 
-/*
- * final_setup_guest is used for final setup and launching of domains other
- * than domain 0. ie. the domains that are being built by the userspace dom0
- * domain builder.
- */
-long do_boot_vcpu(unsigned long vcpu, struct vcpu_guest_context *ctxt) 
-{
-    struct domain *d = current->domain;
-    struct vcpu *v;
-    int rc = 0;
-    struct vcpu_guest_context *c;
-
-    if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] != NULL) )
-        return -EINVAL;
-
-    if ( alloc_vcpu_struct(d, vcpu) == NULL )
+int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) 
+{
+    struct vcpu *v;
+    int rc;
+
+    ASSERT(d->vcpu[vcpuid] == NULL);
+
+    if ( alloc_vcpu_struct(d, vcpuid) == NULL )
         return -ENOMEM;
 
-    if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
-    {
-        rc = -ENOMEM;
-        goto out;
-    }
-
-    if ( copy_from_user(c, ctxt, sizeof(*c)) )
-    {
-        rc = -EFAULT;
-        goto out;
-    }
-
-    v = d->vcpu[vcpu];
+    v = d->vcpu[vcpuid];
 
     atomic_set(&v->pausecnt, 0);
     v->cpumap = CPUMAP_RUNANYWHERE;
@@ -405,22 +386,73 @@
 
     arch_do_boot_vcpu(v);
 
-    if ( (rc = arch_set_info_guest(v, c)) != 0 )
+    if ( (rc = arch_set_info_guest(v, ctxt)) != 0 )
         goto out;
 
     sched_add_domain(v);
 
-    /* domain_unpause_by_systemcontroller */
-    if ( test_and_clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) )
-        vcpu_wake(v);
-
-    xfree(c);
+    set_bit(_VCPUF_down, &v->vcpu_flags);
+    clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
+
     return 0;
 
  out:
-    xfree(c);
-    arch_free_vcpu_struct(d->vcpu[vcpu]);
-    d->vcpu[vcpu] = NULL;
+    arch_free_vcpu_struct(d->vcpu[vcpuid]);
+    d->vcpu[vcpuid] = NULL;
+    return rc;
+}
+
+long do_vcpu_op(int cmd, int vcpuid, void *arg)
+{
+    struct domain *d = current->domain;
+    struct vcpu *v;
+    struct vcpu_guest_context *ctxt;
+    long rc = 0;
+
+    if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
+        return -EINVAL;
+
+    if ( ((v = d->vcpu[vcpuid]) == NULL) && (cmd != VCPUOP_create) )
+        return -ENOENT;
+
+    switch ( cmd )
+    {
+    case VCPUOP_create:
+        if ( (ctxt = xmalloc(struct vcpu_guest_context)) == NULL )
+        {
+            rc = -ENOMEM;
+            break;
+        }
+
+        if ( copy_from_user(ctxt, arg, sizeof(*ctxt)) )
+        {
+            xfree(ctxt);
+            rc = -EFAULT;
+            break;
+        }
+
+        LOCK_BIGLOCK(d);
+        rc = (d->vcpu[vcpuid] == NULL) ? boot_vcpu(d, vcpuid, ctxt) : -EEXIST;
+        UNLOCK_BIGLOCK(d);
+
+        xfree(ctxt);
+        break;
+
+    case VCPUOP_up:
+        if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
+            vcpu_wake(v);
+        break;
+
+    case VCPUOP_down:
+        if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
+            vcpu_sleep_nosync(v);
+        break;
+
+    case VCPUOP_is_up:
+        rc = !test_bit(_VCPUF_down, &v->vcpu_flags);
+        break;
+    }
+
     return rc;
 }
 
diff -r d79ab87e27b8 -r abfc9808adb9 xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   Mon Oct  3 15:40:27 2005
+++ b/xen/common/sched_sedf.c   Tue Oct  4 13:22:30 2005
@@ -500,9 +500,15 @@
                   curinf->vcpu->domain->domain_id,
                   curinf->vcpu->vcpu_id);
             __del_from_queue(curinf->vcpu);
-   
+
             /*move them to their next period*/
             curinf->deadl_abs += curinf->period;
+            /*ensure that the start of the next period is in the future*/
+            if (unlikely(PERIOD_BEGIN(curinf) < now)) {
+                curinf->deadl_abs += 
+                    (DIV_UP(now - PERIOD_BEGIN(curinf),
+                           curinf->period)) * curinf->period;
+            }
             /*and put them back into the queue*/
             __add_to_waitqueue_sort(curinf->vcpu);
             continue;
@@ -645,7 +651,7 @@
                                                         s_time_t end_xt, 
struct list_head *extraq[], int cpu) {
     struct task_slice   ret;
     struct sedf_vcpu_info *runinf;
- 
+    ASSERT(end_xt > now);
     /* Enough time left to use for extratime? */
     if (end_xt - now < EXTRA_QUANTUM)
         goto return_idle;
diff -r d79ab87e27b8 -r abfc9808adb9 xen/common/schedule.c
--- a/xen/common/schedule.c     Mon Oct  3 15:40:27 2005
+++ b/xen/common/schedule.c     Tue Oct  4 13:22:30 2005
@@ -270,69 +270,6 @@
     return 0;
 }
 
-/* Mark target vcpu as non-runnable so it is not scheduled */
-static long do_vcpu_down(int vcpu)
-{
-    struct vcpu *target;
-    
-    if ( vcpu > MAX_VIRT_CPUS )
-        return -EINVAL;
-
-    target = current->domain->vcpu[vcpu];
-    if ( target == NULL )
-        return -ESRCH;
-    set_bit(_VCPUF_down, &target->vcpu_flags);
-
-    return 0;
-}
-
-/* Mark target vcpu as runnable and wake it */
-static long do_vcpu_up(int vcpu)
-{
-    struct vcpu *target;
-   
-    if (vcpu > MAX_VIRT_CPUS)
-        return -EINVAL;
-
-    target = current->domain->vcpu[vcpu];
-    if ( target == NULL )
-        return -ESRCH;
-    clear_bit(_VCPUF_down, &target->vcpu_flags);
-    /* wake vcpu */
-    vcpu_wake(target);
-
-    return 0;
-}
-
-static long do_vcpu_pickle(int vcpu, unsigned long arg)
-{
-    struct vcpu *v;
-    vcpu_guest_context_t *c;
-    int ret = 0;
-
-    if (vcpu >= MAX_VIRT_CPUS)
-        return -EINVAL;
-    v = current->domain->vcpu[vcpu];
-    if (!v)
-        return -ESRCH;
-    /* Don't pickle vcpus which are currently running */
-    if (!test_bit(_VCPUF_down, &v->vcpu_flags)) {
-        return -EBUSY;
-    }
-    c = xmalloc(vcpu_guest_context_t);
-    if (!c)
-        return -ENOMEM;
-    arch_getdomaininfo_ctxt(v, c);
-    if (copy_to_user((vcpu_guest_context_t *)arg,
-                     (const vcpu_guest_context_t *)c, sizeof(*c)))
-        ret = -EFAULT;
-    xfree(c);
-    return ret;
-}
-
-/*
- * Demultiplex scheduler-related hypercalls.
- */
 long do_sched_op(unsigned long op, unsigned long arg)
 {
     long ret = 0;
@@ -359,21 +296,6 @@
         domain_shutdown((u8)(op >> SCHEDOP_reasonshift));
         break;
     }
-    case SCHEDOP_vcpu_down:
-    {
-        ret = do_vcpu_down((int)(op >> SCHEDOP_vcpushift));
-        break;
-    }
-    case SCHEDOP_vcpu_up:
-    {
-        ret = do_vcpu_up((int)(op >> SCHEDOP_vcpushift));
-        break;
-    }
-    case SCHEDOP_vcpu_pickle:
-    {
-        ret = do_vcpu_pickle((int)(op >> SCHEDOP_vcpushift), arg);
-        break;
-    }
 
     default:
         ret = -ENOSYS;
@@ -395,8 +317,8 @@
     return 0;
 }
 
-/** sched_id - fetch ID of current scheduler */
-int sched_id()
+/* sched_id - fetch ID of current scheduler */
+int sched_id(void)
 {
     return ops.sched_id;
 }
diff -r d79ab87e27b8 -r abfc9808adb9 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Mon Oct  3 15:40:27 2005
+++ b/xen/include/public/xen.h  Tue Oct  4 13:22:30 2005
@@ -55,7 +55,7 @@
 #define __HYPERVISOR_update_va_mapping_otherdomain 22
 #define __HYPERVISOR_switch_vm86          23 /* x86/32 only */
 #define __HYPERVISOR_switch_to_user       23 /* x86/64 only */
-#define __HYPERVISOR_boot_vcpu            24
+#define __HYPERVISOR_vcpu_op              24
 #define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
 #define __HYPERVISOR_mmuext_op            26
 #define __HYPERVISOR_acm_op               27
@@ -201,12 +201,8 @@
 #define SCHEDOP_yield           0   /* Give up the CPU voluntarily.       */
 #define SCHEDOP_block           1   /* Block until an event is received.  */
 #define SCHEDOP_shutdown        2   /* Stop executing this domain.        */
-#define SCHEDOP_vcpu_down       3   /* make target VCPU not-runnable.     */
-#define SCHEDOP_vcpu_up         4   /* make target VCPU runnable.         */
-#define SCHEDOP_vcpu_pickle     5   /* save a vcpu's context to memory.   */
 #define SCHEDOP_cmdmask       255   /* 8-bit command. */
 #define SCHEDOP_reasonshift     8   /* 8-bit reason code. (SCHEDOP_shutdown) */
-#define SCHEDOP_vcpushift       8   /* 8-bit VCPU target. (SCHEDOP_up|down) */
 
 /*
  * Reason codes for SCHEDOP_shutdown. These may be interpreted by control 
diff -r d79ab87e27b8 -r abfc9808adb9 xen/include/public/vcpu.h
--- /dev/null   Mon Oct  3 15:40:27 2005
+++ b/xen/include/public/vcpu.h Tue Oct  4 13:22:30 2005
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * vcpu.h
+ * 
+ * VCPU creation and hotplug.
+ * 
+ * Copyright (c) 2005, Keir Fraser <keir@xxxxxxxxxxxxx>
+ */
+
+#ifndef __XEN_PUBLIC_VCPU_H__
+#define __XEN_PUBLIC_VCPU_H__
+
+/*
+ * Prototype for this hypercall is:
+ *  int vcpu_op(int cmd, int vcpuid, void *extra_args)
+ * @cmd        == VCPUOP_??? (VCPU operation).
+ * @vcpuid     == VCPU to operate on.
+ * @extra_args == Operation-specific extra arguments (NULL if none).
+ */
+
+/*
+ * Create a new VCPU. This must be called before a VCPU can be referred to
+ * in any other hypercall (e.g., to bind event channels). The new VCPU
+ * will not run until it is brought up by VCPUOP_up.
+ * 
+ * @extra_arg == pointer to vcpu_guest_context structure containing initial
+ *               state for the new VCPU.
+ */
+#define VCPUOP_create               0
+
+/*
+ * Bring up a newly-created or previously brought-down VCPU. This makes the
+ * VCPU runnable.
+ */
+#define VCPUOP_up                   1
+
+/*
+ * Bring down a VCPU (i.e., make it non-runnable).
+ * There are a few caveats that callers should observe:
+ *  1. This operation may return, and VCPU_is_up may return false, before the
+ *     VCPU stops running (i.e., the command is asynchronous). It is a good
+ *     idea to ensure that the VCPU has entered a non-critical loop before
+ *     bringing it down. Alternatively, this operation is guaranteed
+ *     synchronous if invoked by the VCPU itself.
+ *  2. After a VCPU is created, there is currently no way to drop all its
+ *     references to domain memory. Even a VCPU that is down still holds
+ *     memory references via its pagetable base pointer and GDT. It is good
+ *     practise to move a VCPU onto an 'idle' or default page table, LDT and
+ *     GDT before bringing it down.
+ */
+#define VCPUOP_down                 2
+
+/* Returns 1 if the given VCPU is up. */
+#define VCPUOP_is_up                3
+
+#endif /* __XEN_PUBLIC_VCPU_H__ */
diff -r d79ab87e27b8 -r abfc9808adb9 
linux-2.6-xen-sparse/include/asm-generic/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-generic/pgtable.h        Mon Oct  3 
15:40:27 2005
+++ /dev/null   Tue Oct  4 13:22:30 2005
@@ -1,221 +0,0 @@
-#ifndef _ASM_GENERIC_PGTABLE_H
-#define _ASM_GENERIC_PGTABLE_H
-
-#ifndef __HAVE_ARCH_PTEP_ESTABLISH
-/*
- * Establish a new mapping:
- *  - flush the old one
- *  - update the page tables
- *  - inform the TLB about the new one
- *
- * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock.
- *
- * Note: the old pte is known to not be writable, so we don't need to
- * worry about dirty bits etc getting lost.
- */
-#ifndef __HAVE_ARCH_SET_PTE_ATOMIC
-#define ptep_establish(__vma, __address, __ptep, __entry)              \
-do {                                                                   \
-       set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);       \
-       flush_tlb_page(__vma, __address);                               \
-} while (0)
-#else /* __HAVE_ARCH_SET_PTE_ATOMIC */
-#define ptep_establish(__vma, __address, __ptep, __entry)              \
-do {                                                                   \
-       set_pte_atomic(__ptep, __entry);                                \
-       flush_tlb_page(__vma, __address);                               \
-} while (0)
-#endif /* __HAVE_ARCH_SET_PTE_ATOMIC */
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-/*
- * Largely same as above, but only sets the access flags (dirty,
- * accessed, and writable). Furthermore, we know it always gets set
- * to a "more permissive" setting, which allows most architectures
- * to optimize this.
- */
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-do {                                                                     \
-       set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);         \
-       flush_tlb_page(__vma, __address);                                 \
-} while (0)
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_ESTABLISH_NEW
-/*
- * Establish a mapping where none previously existed
- */
-#define ptep_establish_new(__vma, __address, __ptep, __entry)          \
-do {                                                                   \
-       set_pte(__ptep, __entry);                                       \
-} while (0)
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define ptep_test_and_clear_young(__vma, __address, __ptep)            \
-({                                                                     \
-       pte_t __pte = *(__ptep);                                        \
-       int r = 1;                                                      \
-       if (!pte_young(__pte))                                          \
-               r = 0;                                                  \
-       else                                                            \
-               set_pte_at((__vma)->vm_mm, (__address),                 \
-                          (__ptep), pte_mkold(__pte));                 \
-       r;                                                              \
-})
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-#define ptep_clear_flush_young(__vma, __address, __ptep)               \
-({                                                                     \
-       int __young;                                                    \
-       __young = ptep_test_and_clear_young(__vma, __address, __ptep);  \
-       if (__young)                                                    \
-               flush_tlb_page(__vma, __address);                       \
-       __young;                                                        \
-})
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
-#define ptep_test_and_clear_dirty(__vma, __address, __ptep)            \
-({                                                                     \
-       pte_t __pte = *__ptep;                                          \
-       int r = 1;                                                      \
-       if (!pte_dirty(__pte))                                          \
-               r = 0;                                                  \
-       else                                                            \
-               set_pte_at((__vma)->vm_mm, (__address), (__ptep),       \
-                          pte_mkclean(__pte));                         \
-       r;                                                              \
-})
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
-#define ptep_clear_flush_dirty(__vma, __address, __ptep)               \
-({                                                                     \
-       int __dirty;                                                    \
-       __dirty = ptep_test_and_clear_dirty(__vma, __address, __ptep);  \
-       if (__dirty)                                                    \
-               flush_tlb_page(__vma, __address);                       \
-       __dirty;                                                        \
-})
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
-#define ptep_get_and_clear(__mm, __address, __ptep)                    \
-({                                                                     \
-       pte_t __pte = *(__ptep);                                        \
-       pte_clear((__mm), (__address), (__ptep));                       \
-       __pte;                                                          \
-})
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
-#define ptep_clear_flush(__vma, __address, __ptep)                     \
-({                                                                     \
-       pte_t __pte;                                                    \
-       __pte = ptep_get_and_clear((__vma)->vm_mm, __address, __ptep);  \
-       flush_tlb_page(__vma, __address);                               \
-       __pte;                                                          \
-})
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long 
address, pte_t *ptep)
-{
-       pte_t old_pte = *ptep;
-       set_pte_at(mm, address, ptep, pte_wrprotect(old_pte));
-}
-#endif
-
-#ifndef __HAVE_ARCH_PTE_SAME
-#define pte_same(A,B)  (pte_val(A) == pte_val(B))
-#endif
-
-#ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
-#define page_test_and_clear_dirty(page) (0)
-#endif
-
-#ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
-#define page_test_and_clear_young(page) (0)
-#endif
-
-#ifndef __HAVE_ARCH_PGD_OFFSET_GATE
-#define pgd_offset_gate(mm, addr)      pgd_offset(mm, addr)
-#endif
-
-#ifndef __HAVE_ARCH_LAZY_MMU_PROT_UPDATE
-#define lazy_mmu_prot_update(pte)      do { } while (0)
-#endif
-
-/*
- * When walking page tables, get the address of the next boundary,
- * or the end address of the range if that comes earlier.  Although no
- * vma end wraps to 0, rounded up __boundary may wrap to 0 throughout.
- */
-
-#define pgd_addr_end(addr, end)                                                
\
-({     unsigned long __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK;  \
-       (__boundary - 1 < (end) - 1)? __boundary: (end);                \
-})
-
-#ifndef pud_addr_end
-#define pud_addr_end(addr, end)                                                
\
-({     unsigned long __boundary = ((addr) + PUD_SIZE) & PUD_MASK;      \
-       (__boundary - 1 < (end) - 1)? __boundary: (end);                \
-})
-#endif
-
-#ifndef pmd_addr_end
-#define pmd_addr_end(addr, end)                                                
\
-({     unsigned long __boundary = ((addr) + PMD_SIZE) & PMD_MASK;      \
-       (__boundary - 1 < (end) - 1)? __boundary: (end);                \
-})
-#endif
-
-#ifndef __ASSEMBLY__
-/*
- * When walking page tables, we usually want to skip any p?d_none entries;
- * and any p?d_bad entries - reporting the error before resetting to none.
- * Do the tests inline, but report and clear the bad entry in mm/memory.c.
- */
-void pgd_clear_bad(pgd_t *);
-void pud_clear_bad(pud_t *);
-void pmd_clear_bad(pmd_t *);
-
-static inline int pgd_none_or_clear_bad(pgd_t *pgd)
-{
-       if (pgd_none(*pgd))
-               return 1;
-       if (unlikely(pgd_bad(*pgd))) {
-               pgd_clear_bad(pgd);
-               return 1;
-       }
-       return 0;
-}
-
-static inline int pud_none_or_clear_bad(pud_t *pud)
-{
-       if (pud_none(*pud))
-               return 1;
-       if (unlikely(pud_bad(*pud))) {
-               pud_clear_bad(pud);
-               return 1;
-       }
-       return 0;
-}
-
-static inline int pmd_none_or_clear_bad(pmd_t *pmd)
-{
-       if (pmd_none(*pmd))
-               return 1;
-       if (unlikely(pmd_bad(*pmd))) {
-               pmd_clear_bad(pmd);
-               return 1;
-       }
-       return 0;
-}
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _ASM_GENERIC_PGTABLE_H */

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


 


Rackspace

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