WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] Merge.

# 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

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