ia64/xen-unstable

changeset 7199:abfc9808adb9

Merge.
author jrb44@swoop.cl.cam.ac.uk
date Tue Oct 04 14:22:30 2005 +0100 (2005-10-04)
parents d79ab87e27b8 96cc6aa196b6
children b27d526d4033
files
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c	Mon Oct 03 16:40:27 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c	Tue Oct 04 14:22:30 2005 +0100
     1.3 @@ -49,6 +49,7 @@
     1.4  #include <asm/irq.h>
     1.5  #include <asm/desc.h>
     1.6  #include <asm-xen/xen-public/physdev.h>
     1.7 +#include <asm-xen/xen-public/vcpu.h>
     1.8  #ifdef CONFIG_MATH_EMULATION
     1.9  #include <asm/math_emu.h>
    1.10  #endif
    1.11 @@ -141,6 +142,13 @@ static inline void play_dead(void)
    1.12  }
    1.13  #endif /* CONFIG_HOTPLUG_CPU */
    1.14  
    1.15 +void cpu_restore(void)
    1.16 +{
    1.17 +	play_dead();
    1.18 +	local_irq_enable();
    1.19 +	cpu_idle();
    1.20 +}
    1.21 +
    1.22  /*
    1.23   * The idle thread. There's no useful work to be
    1.24   * done, so just try to conserve power and have a
    1.25 @@ -171,7 +179,7 @@ void cpu_idle (void)
    1.26  				   don't printk. */
    1.27  				__get_cpu_var(cpu_state) = CPU_DEAD;
    1.28  				/* Tell hypervisor to take vcpu down. */
    1.29 -				HYPERVISOR_vcpu_down(cpu);
    1.30 +				HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL);
    1.31  #endif
    1.32  				play_dead();
    1.33  				local_irq_enable();
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c	Mon Oct 03 16:40:27 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Oct 04 14:22:30 2005 +0100
     2.3 @@ -365,6 +365,7 @@ EXPORT_SYMBOL(phys_to_machine_mapping);
     2.4  
     2.5  /* Raw start-of-day parameters from the hypervisor. */
     2.6  start_info_t *xen_start_info;
     2.7 +EXPORT_SYMBOL(xen_start_info);
     2.8  
     2.9  static void __init limit_regions(unsigned long long size)
    2.10  {
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Mon Oct 03 16:40:27 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c	Tue Oct 04 14:22:30 2005 +0100
     3.3 @@ -63,6 +63,7 @@
     3.4  #include <smpboot_hooks.h>
     3.5  
     3.6  #include <asm-xen/evtchn.h>
     3.7 +#include <asm-xen/xen-public/vcpu.h>
     3.8  
     3.9  /* Set if we find a B stepping CPU */
    3.10  static int __initdata smp_b_stepping;
    3.11 @@ -802,7 +803,6 @@ static int __init do_boot_cpu(int apicid
    3.12  	extern void hypervisor_callback(void);
    3.13  	extern void failsafe_callback(void);
    3.14  	extern void smp_trap_init(trap_info_t *);
    3.15 -	int i;
    3.16  
    3.17  	cpu = ++cpucount;
    3.18  	/*
    3.19 @@ -853,12 +853,6 @@ static int __init do_boot_cpu(int apicid
    3.20  	/* FPU is set up to default initial state. */
    3.21  	memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
    3.22  
    3.23 -	/* Virtual IDT is empty at start-of-day. */
    3.24 -	for ( i = 0; i < 256; i++ )
    3.25 -	{
    3.26 -		ctxt.trap_ctxt[i].vector = i;
    3.27 -		ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
    3.28 -	}
    3.29  	smp_trap_init(ctxt.trap_ctxt);
    3.30  
    3.31  	/* No LDT. */
    3.32 @@ -889,11 +883,13 @@ static int __init do_boot_cpu(int apicid
    3.33  
    3.34  	ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
    3.35  
    3.36 -	boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
    3.37 +	boot_error = HYPERVISOR_vcpu_op(VCPUOP_create, cpu, &ctxt);
    3.38  	if (boot_error)
    3.39  		printk("boot error: %ld\n", boot_error);
    3.40  
    3.41  	if (!boot_error) {
    3.42 +		HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
    3.43 +
    3.44  		/*
    3.45  		 * allow APs to start initializing.
    3.46  		 */
    3.47 @@ -1506,7 +1502,7 @@ int __devinit __cpu_up(unsigned int cpu)
    3.48  #ifdef CONFIG_HOTPLUG_CPU
    3.49  #ifdef CONFIG_XEN
    3.50  	/* Tell hypervisor to bring vcpu up. */
    3.51 -	HYPERVISOR_vcpu_up(cpu);
    3.52 +	HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
    3.53  #endif
    3.54  	/* Already up, and in cpu_quiescent now? */
    3.55  	if (cpu_isset(cpu, smp_commenced_mask)) {
    3.56 @@ -1585,61 +1581,49 @@ void smp_resume(void)
    3.57  	local_setup_timer_irq();
    3.58  }
    3.59  
    3.60 -static atomic_t vcpus_rebooting;
    3.61 -
    3.62 -static void restore_vcpu_ready(void)
    3.63 -{
    3.64 -
    3.65 -	atomic_dec(&vcpus_rebooting);
    3.66 -}
    3.67 -
    3.68 -void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
    3.69 -{
    3.70 -	int r;
    3.71 -	int gdt_pages;
    3.72 -	r = HYPERVISOR_vcpu_pickle(vcpu, ctxt);
    3.73 -	if (r != 0)
    3.74 -		panic("pickling vcpu %d -> %d!\n", vcpu, r);
    3.75 -
    3.76 -	/* Translate from machine to physical addresses where necessary,
    3.77 -	   so that they can be translated to our new machine address space
    3.78 -	   after resume.  libxc is responsible for doing this to vcpu0,
    3.79 -	   but we do it to the others. */
    3.80 -	gdt_pages = (ctxt->gdt_ents + 511) / 512;
    3.81 -	ctxt->ctrlreg[3] = machine_to_phys(ctxt->ctrlreg[3]);
    3.82 -	for (r = 0; r < gdt_pages; r++)
    3.83 -		ctxt->gdt_frames[r] = mfn_to_pfn(ctxt->gdt_frames[r]);
    3.84 -}
    3.85 -
    3.86 -int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
    3.87 +void vcpu_prepare(int vcpu)
    3.88  {
    3.89 -	int r;
    3.90 -	int gdt_pages = (ctxt->gdt_ents + 511) / 512;
    3.91 +	extern void hypervisor_callback(void);
    3.92 +	extern void failsafe_callback(void);
    3.93 +	extern void smp_trap_init(trap_info_t *);
    3.94 +	extern void cpu_restore(void);
    3.95 +	vcpu_guest_context_t ctxt;
    3.96 +	struct task_struct *idle = idle_task(vcpu);
    3.97 +
    3.98 +	if (vcpu == 0)
    3.99 +		return;
   3.100  
   3.101 -	/* This is kind of a hack, and implicitly relies on the fact that
   3.102 -	   the vcpu stops in a place where all of the call clobbered
   3.103 -	   registers are already dead. */
   3.104 -	ctxt->user_regs.esp -= 4;
   3.105 -	((unsigned long *)ctxt->user_regs.esp)[0] = ctxt->user_regs.eip;
   3.106 -	ctxt->user_regs.eip = (unsigned long)restore_vcpu_ready;
   3.107 +	memset(&ctxt, 0, sizeof(ctxt));
   3.108 +
   3.109 +	ctxt.user_regs.ds = __USER_DS;
   3.110 +	ctxt.user_regs.es = __USER_DS;
   3.111 +	ctxt.user_regs.fs = 0;
   3.112 +	ctxt.user_regs.gs = 0;
   3.113 +	ctxt.user_regs.ss = __KERNEL_DS;
   3.114 +	ctxt.user_regs.cs = __KERNEL_CS;
   3.115 +	ctxt.user_regs.eip = (unsigned long)cpu_restore;
   3.116 +	ctxt.user_regs.esp = idle->thread.esp;
   3.117 +	ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING1;
   3.118  
   3.119 -	/* De-canonicalise.  libxc handles this for vcpu 0, but we need
   3.120 -	   to do it for the other vcpus. */
   3.121 -	ctxt->ctrlreg[3] = phys_to_machine(ctxt->ctrlreg[3]);
   3.122 -	for (r = 0; r < gdt_pages; r++)
   3.123 -		ctxt->gdt_frames[r] = pfn_to_mfn(ctxt->gdt_frames[r]);
   3.124 +	memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
   3.125 +
   3.126 +	smp_trap_init(ctxt.trap_ctxt);
   3.127 +
   3.128 +	ctxt.ldt_ents = 0;
   3.129 +
   3.130 +	ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[vcpu].address);
   3.131 +	ctxt.gdt_ents      = cpu_gdt_descr[vcpu].size / 8;
   3.132  
   3.133 -	atomic_set(&vcpus_rebooting, 1);
   3.134 -	r = HYPERVISOR_boot_vcpu(vcpu, ctxt);
   3.135 -	if (r != 0) {
   3.136 -		printk(KERN_EMERG "Failed to reboot vcpu %d (%d)\n", vcpu, r);
   3.137 -		return -1;
   3.138 -	}
   3.139 +	ctxt.kernel_ss = __KERNEL_DS;
   3.140 +	ctxt.kernel_sp = idle->thread.esp0;
   3.141  
   3.142 -	/* Make sure we wait for the new vcpu to come up before trying to do
   3.143 -	   anything with it or starting the next one. */
   3.144 -	while (atomic_read(&vcpus_rebooting))
   3.145 -		barrier();
   3.146 +	ctxt.event_callback_cs     = __KERNEL_CS;
   3.147 +	ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
   3.148 +	ctxt.failsafe_callback_cs  = __KERNEL_CS;
   3.149 +	ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
   3.150  
   3.151 -	return 0;
   3.152 +	ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
   3.153 +
   3.154 +	(void)HYPERVISOR_vcpu_op(VCPUOP_create, vcpu, &ctxt);
   3.155 +	(void)HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL);
   3.156  }
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c	Mon Oct 03 16:40:27 2005 +0100
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c	Tue Oct 04 14:22:30 2005 +0100
     4.3 @@ -1012,6 +1012,12 @@ void __init trap_init(void)
     4.4  void smp_trap_init(trap_info_t *trap_ctxt)
     4.5  {
     4.6  	trap_info_t *t = trap_table;
     4.7 +	int i;
     4.8 +
     4.9 +	for (i = 0; i < 256; i++) {
    4.10 +		trap_ctxt[i].vector = i;
    4.11 +		trap_ctxt[i].cs     = FLAT_KERNEL_CS;
    4.12 +	}
    4.13  
    4.14  	for (t = trap_table; t->address; t++) {
    4.15  		trap_ctxt[t->vector].flags = t->flags;
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Mon Oct 03 16:40:27 2005 +0100
     5.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Tue Oct 04 14:22:30 2005 +0100
     5.3 @@ -52,24 +52,30 @@ static int __direct_remap_pfn_range(stru
     5.4  				    pgprot_t prot,
     5.5  				    domid_t  domid)
     5.6  {
     5.7 -	int i;
     5.8 +	int i, rc;
     5.9  	unsigned long start_address;
    5.10 -#define MAX_DIRECTMAP_MMU_QUEUE 130
    5.11 -	mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *v = u, *w = u;
    5.12 +	mmu_update_t *u, *v, *w;
    5.13 +
    5.14 +	u = v = w = (mmu_update_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
    5.15 +	if (u == NULL)
    5.16 +		return -ENOMEM;
    5.17  
    5.18  	start_address = address;
    5.19  
    5.20  	flush_cache_all();
    5.21  
    5.22  	for (i = 0; i < size; i += PAGE_SIZE) {
    5.23 -		if ((v - u) == MAX_DIRECTMAP_MMU_QUEUE) {
    5.24 +		if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
    5.25  			/* Fill in the PTE pointers. */
    5.26 -			generic_page_range(mm, start_address, 
    5.27 -					   address - start_address,
    5.28 -					   direct_remap_area_pte_fn, &w);
    5.29 +			rc = generic_page_range(mm, start_address, 
    5.30 +						address - start_address,
    5.31 +						direct_remap_area_pte_fn, &w);
    5.32 +			if (rc)
    5.33 +				goto out;
    5.34  			w = u;
    5.35 +			rc = -EFAULT;
    5.36  			if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
    5.37 -				return -EFAULT;
    5.38 +				goto out;
    5.39  			v = u;
    5.40  			start_address = address;
    5.41  		}
    5.42 @@ -89,13 +95,19 @@ static int __direct_remap_pfn_range(stru
    5.43  		/* get the ptep's filled in */
    5.44  		generic_page_range(mm, start_address, address - start_address,
    5.45  				   direct_remap_area_pte_fn, &w);
    5.46 +		rc = -EFAULT;
    5.47  		if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
    5.48 -			return -EFAULT;
    5.49 +			goto out;
    5.50  	}
    5.51  
    5.52 +	rc = 0;
    5.53 +
    5.54 + out:
    5.55  	flush_tlb_all();
    5.56  
    5.57 -	return 0;
    5.58 +	free_page((unsigned long)u);
    5.59 +
    5.60 +	return rc;
    5.61  }
    5.62  
    5.63  int direct_remap_pfn_range(struct vm_area_struct *vma,
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Mon Oct 03 16:40:27 2005 +0100
     6.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Tue Oct 04 14:22:30 2005 +0100
     6.3 @@ -629,6 +629,7 @@ void notify_remote_via_irq(int irq)
     6.4  	if (VALID_EVTCHN(evtchn))
     6.5  		notify_remote_via_evtchn(evtchn);
     6.6  }
     6.7 +EXPORT_SYMBOL(notify_remote_via_irq);
     6.8  
     6.9  void irq_resume(void)
    6.10  {
     7.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Mon Oct 03 16:40:27 2005 +0100
     7.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Tue Oct 04 14:22:30 2005 +0100
     7.3 @@ -74,11 +74,8 @@ static int __do_suspend(void *ignore)
     7.4  	extern unsigned long *pfn_to_mfn_frame_list[];
     7.5  
     7.6  #ifdef CONFIG_SMP
     7.7 -	static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
     7.8 -	cpumask_t prev_online_cpus, prev_present_cpus;
     7.9 -
    7.10 -	void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
    7.11 -	int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
    7.12 +	cpumask_t prev_online_cpus;
    7.13 +	int vcpu_prepare(int vcpu);
    7.14  #endif
    7.15  
    7.16  	extern void xencons_resume(void);
    7.17 @@ -132,16 +129,6 @@ static int __do_suspend(void *ignore)
    7.18  
    7.19  	preempt_enable();
    7.20  
    7.21 -#ifdef CONFIG_SMP
    7.22 -	cpus_clear(prev_present_cpus);
    7.23 -	for_each_present_cpu(i) {
    7.24 -		if (i == 0)
    7.25 -			continue;
    7.26 -		save_vcpu_context(i, &suspended_cpu_records[i]);
    7.27 -		cpu_set(i, prev_present_cpus);
    7.28 -	}
    7.29 -#endif
    7.30 -
    7.31  	gnttab_suspend();
    7.32  
    7.33  #ifdef __i386__
    7.34 @@ -189,11 +176,6 @@ static int __do_suspend(void *ignore)
    7.35  
    7.36  	time_resume();
    7.37  
    7.38 -#ifdef CONFIG_SMP
    7.39 -	for_each_cpu_mask(i, prev_present_cpus)
    7.40 -		restore_vcpu_context(i, &suspended_cpu_records[i]);
    7.41 -#endif
    7.42 -
    7.43  	__sti();
    7.44  
    7.45  	xencons_resume();
    7.46 @@ -201,6 +183,9 @@ static int __do_suspend(void *ignore)
    7.47  	xenbus_resume();
    7.48  
    7.49  #ifdef CONFIG_SMP
    7.50 +	for_each_present_cpu(i)
    7.51 +		vcpu_prepare(i);
    7.52 +
    7.53   out_reenable_cpus:
    7.54  	for_each_cpu_mask(i, prev_online_cpus) {
    7.55  		j = cpu_up(i);
     8.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile	Mon Oct 03 16:40:27 2005 +0100
     8.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile	Tue Oct 04 14:22:30 2005 +0100
     8.3 @@ -51,7 +51,7 @@ bootflag-y			+= ../../../i386/kernel/boo
     8.4  cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../../i386/kernel/cpuid.o
     8.5  topology-y                     += ../../../i386/mach-default/topology.o
     8.6  #swiotlb-$(CONFIG_SWIOTLB)      += ../../../ia64/lib/swiotlb.o
     8.7 -microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../../i386/kernel/microcode.o
     8.8 +microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
     8.9  intel_cacheinfo-y		+= ../../../i386/kernel/cpu/intel_cacheinfo.o
    8.10  quirks-y			+= ../../i386/kernel/quirks.o
    8.11  
     9.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Mon Oct 03 16:40:27 2005 +0100
     9.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Tue Oct 04 14:22:30 2005 +0100
     9.3 @@ -86,6 +86,7 @@ DEFINE_PER_CPU(int, nr_multicall_ents);
     9.4  
     9.5  /* Raw start-of-day parameters from the hypervisor. */
     9.6  start_info_t *xen_start_info;
     9.7 +EXPORT_SYMBOL(xen_start_info);
     9.8  #endif
     9.9  
    9.10  /*
    10.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c	Mon Oct 03 16:40:27 2005 +0100
    10.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c	Tue Oct 04 14:22:30 2005 +0100
    10.3 @@ -62,8 +62,8 @@
    10.4  #include <asm/nmi.h>
    10.5  #ifdef CONFIG_XEN
    10.6  #include <asm/arch_hooks.h>
    10.7 -
    10.8  #include <asm-xen/evtchn.h>
    10.9 +#include <asm-xen/xen-public/vcpu.h>
   10.10  #endif
   10.11  
   10.12  /* Change for real CPU hotplug. Note other files need to be fixed
   10.13 @@ -742,12 +742,6 @@ static int __cpuinit do_boot_cpu(int cpu
   10.14  	/* FPU is set up to default initial state. */
   10.15  	memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
   10.16  
   10.17 -	/* Virtual IDT is empty at start-of-day. */
   10.18 -	for ( i = 0; i < 256; i++ )
   10.19 -	{
   10.20 -		ctxt.trap_ctxt[i].vector = i;
   10.21 -		ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
   10.22 -	}
   10.23  	smp_trap_init(ctxt.trap_ctxt);
   10.24  
   10.25  	/* No LDT. */
   10.26 @@ -777,11 +771,13 @@ static int __cpuinit do_boot_cpu(int cpu
   10.27  
   10.28  	ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
   10.29  
   10.30 -	boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
   10.31 +	boot_error  = HYPERVISOR_vcpu_op(VCPUOP_create, cpu, &ctxt);
   10.32  	if (boot_error)
   10.33  		printk("boot error: %ld\n", boot_error);
   10.34  
   10.35  	if (!boot_error) {
   10.36 +		HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
   10.37 +
   10.38  		/*
   10.39  		 * allow APs to start initializing.
   10.40  		 */
   10.41 @@ -1267,13 +1263,8 @@ void smp_resume(void)
   10.42  	local_setup_timer_irq();
   10.43  }
   10.44  
   10.45 -void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
   10.46 +void vcpu_prepare(int vcpu)
   10.47  {
   10.48  }
   10.49  
   10.50 -int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
   10.51 -{
   10.52 -	return 0;
   10.53 -}
   10.54 -
   10.55  #endif
    11.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c	Mon Oct 03 16:40:27 2005 +0100
    11.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c	Tue Oct 04 14:22:30 2005 +0100
    11.3 @@ -956,6 +956,12 @@ void __init trap_init(void)
    11.4  void smp_trap_init(trap_info_t *trap_ctxt)
    11.5  {
    11.6  	trap_info_t *t = trap_table;
    11.7 +	int i;
    11.8 +
    11.9 +	for (i = 0; i < 256; i++) {
   11.10 +		trap_ctxt[i].vector = i;
   11.11 +		trap_ctxt[i].cs     = FLAT_KERNEL_CS;
   11.12 +	}
   11.13  
   11.14  	for (t = trap_table; t->address; t++) {
   11.15  		trap_ctxt[t->vector].flags = t->flags;
    12.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c	Mon Oct 03 16:40:27 2005 +0100
    12.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c	Tue Oct 04 14:22:30 2005 +0100
    12.3 @@ -30,7 +30,8 @@
    12.4  
    12.5  enum {
    12.6  	TPM_MINOR = 224,	/* officially assigned */
    12.7 -	TPM_BUFSIZE = 2048,
    12.8 +	TPM_MIN_BUFSIZE = 2048,
    12.9 +	TPM_MAX_BUFSIZE = 65536,
   12.10  	TPM_NUM_DEVICES = 256,
   12.11  	TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
   12.12  };
   12.13 @@ -63,7 +64,7 @@ static void user_reader_timeout(unsigned
   12.14  
   12.15  	down(&chip->buffer_mutex);
   12.16  	atomic_set(&chip->data_pending, 0);
   12.17 -	memset(chip->data_buffer, 0, TPM_BUFSIZE);
   12.18 +	memset(chip->data_buffer, 0, chip->vendor->buffersize);
   12.19  	up(&chip->buffer_mutex);
   12.20  }
   12.21  
   12.22 @@ -458,7 +459,8 @@ int tpm_open(struct inode *inode, struct
   12.23  
   12.24  	spin_unlock(&driver_lock);
   12.25  
   12.26 -	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
   12.27 +	chip->data_buffer = kmalloc(chip->vendor->buffersize * sizeof(u8),
   12.28 +	                            GFP_KERNEL);
   12.29  	if (chip->data_buffer == NULL) {
   12.30  		chip->num_opens--;
   12.31  		put_device(chip->dev);
   12.32 @@ -507,8 +509,8 @@ ssize_t tpm_write(struct file * file, co
   12.33  
   12.34  	down(&chip->buffer_mutex);
   12.35  
   12.36 -	if (in_size > TPM_BUFSIZE)
   12.37 -		in_size = TPM_BUFSIZE;
   12.38 +	if (in_size > chip->vendor->buffersize)
   12.39 +		in_size = chip->vendor->buffersize;
   12.40  
   12.41  	if (copy_from_user
   12.42  	    (chip->data_buffer, (void __user *) buf, in_size)) {
   12.43 @@ -517,7 +519,9 @@ ssize_t tpm_write(struct file * file, co
   12.44  	}
   12.45  
   12.46  	/* atomic tpm command send and result receive */
   12.47 -	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
   12.48 +	out_size = tpm_transmit(chip,
   12.49 +	                        chip->data_buffer,
   12.50 +	                        chip->vendor->buffersize);
   12.51  
   12.52  	atomic_set(&chip->data_pending, out_size);
   12.53  	up(&chip->buffer_mutex);
   12.54 @@ -667,6 +671,12 @@ int tpm_register_hardware_nopci(struct d
   12.55  
   12.56  	chip->vendor = entry;
   12.57  
   12.58 +	if (entry->buffersize < TPM_MIN_BUFSIZE) {
   12.59 +		entry->buffersize = TPM_MIN_BUFSIZE;
   12.60 +	} else if (entry->buffersize > TPM_MAX_BUFSIZE) {
   12.61 +		entry->buffersize = TPM_MAX_BUFSIZE;
   12.62 +	}
   12.63 +
   12.64  	chip->dev_num = -1;
   12.65  
   12.66  	for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
    13.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h	Mon Oct 03 16:40:27 2005 +0100
    13.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h	Tue Oct 04 14:22:30 2005 +0100
    13.3 @@ -62,6 +62,7 @@ struct tpm_vendor_specific {
    13.4  	u8 req_complete_val;
    13.5  	u8 req_canceled;
    13.6  	u16 base;		/* TPM base address */
    13.7 +	u32 buffersize;         /* The device's requested buffersize */
    13.8  
    13.9  	int (*recv) (struct tpm_chip *, u8 *, size_t);
   13.10  	int (*send) (struct tpm_chip *, u8 *, size_t);
    14.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Mon Oct 03 16:40:27 2005 +0100
    14.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Tue Oct 04 14:22:30 2005 +0100
    14.3 @@ -445,6 +445,7 @@ static struct tpm_vendor_specific tpm_xe
    14.4  	.base = 0,
    14.5  	.attr = TPM_DEVICE_ATTRS,
    14.6  	.miscdev.fops = &tpm_xen_ops,
    14.7 +	.buffersize = 64 * 1024,
    14.8  };
    14.9  
   14.10  static struct device tpm_device = {
   14.11 @@ -477,6 +478,8 @@ static int __init init_xen(void)
   14.12  		return rc;
   14.13  	}
   14.14  
   14.15 +	tpm_xen.buffersize = tpmfe.max_tx_size;
   14.16 +
   14.17  	if ((rc = tpm_register_hardware_nopci(&tpm_device, &tpm_xen)) < 0) {
   14.18  		device_unregister(&tpm_device);
   14.19  		tpm_fe_unregister_receiver();
    15.1 --- a/linux-2.6-xen-sparse/include/asm-generic/pgtable.h	Mon Oct 03 16:40:27 2005 +0100
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,221 +0,0 @@
    15.4 -#ifndef _ASM_GENERIC_PGTABLE_H
    15.5 -#define _ASM_GENERIC_PGTABLE_H
    15.6 -
    15.7 -#ifndef __HAVE_ARCH_PTEP_ESTABLISH
    15.8 -/*
    15.9 - * Establish a new mapping:
   15.10 - *  - flush the old one
   15.11 - *  - update the page tables
   15.12 - *  - inform the TLB about the new one
   15.13 - *
   15.14 - * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock.
   15.15 - *
   15.16 - * Note: the old pte is known to not be writable, so we don't need to
   15.17 - * worry about dirty bits etc getting lost.
   15.18 - */
   15.19 -#ifndef __HAVE_ARCH_SET_PTE_ATOMIC
   15.20 -#define ptep_establish(__vma, __address, __ptep, __entry)		\
   15.21 -do {				  					\
   15.22 -	set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);	\
   15.23 -	flush_tlb_page(__vma, __address);				\
   15.24 -} while (0)
   15.25 -#else /* __HAVE_ARCH_SET_PTE_ATOMIC */
   15.26 -#define ptep_establish(__vma, __address, __ptep, __entry)		\
   15.27 -do {				  					\
   15.28 -	set_pte_atomic(__ptep, __entry);				\
   15.29 -	flush_tlb_page(__vma, __address);				\
   15.30 -} while (0)
   15.31 -#endif /* __HAVE_ARCH_SET_PTE_ATOMIC */
   15.32 -#endif
   15.33 -
   15.34 -#ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
   15.35 -/*
   15.36 - * Largely same as above, but only sets the access flags (dirty,
   15.37 - * accessed, and writable). Furthermore, we know it always gets set
   15.38 - * to a "more permissive" setting, which allows most architectures
   15.39 - * to optimize this.
   15.40 - */
   15.41 -#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
   15.42 -do {				  					  \
   15.43 -	set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);	  \
   15.44 -	flush_tlb_page(__vma, __address);				  \
   15.45 -} while (0)
   15.46 -#endif
   15.47 -
   15.48 -#ifndef __HAVE_ARCH_PTEP_ESTABLISH_NEW
   15.49 -/*
   15.50 - * Establish a mapping where none previously existed
   15.51 - */
   15.52 -#define ptep_establish_new(__vma, __address, __ptep, __entry)		\
   15.53 -do {									\
   15.54 -	set_pte(__ptep, __entry);					\
   15.55 -} while (0)
   15.56 -#endif
   15.57 -
   15.58 -#ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
   15.59 -#define ptep_test_and_clear_young(__vma, __address, __ptep)		\
   15.60 -({									\
   15.61 -	pte_t __pte = *(__ptep);					\
   15.62 -	int r = 1;							\
   15.63 -	if (!pte_young(__pte))						\
   15.64 -		r = 0;							\
   15.65 -	else								\
   15.66 -		set_pte_at((__vma)->vm_mm, (__address),			\
   15.67 -			   (__ptep), pte_mkold(__pte));			\
   15.68 -	r;								\
   15.69 -})
   15.70 -#endif
   15.71 -
   15.72 -#ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
   15.73 -#define ptep_clear_flush_young(__vma, __address, __ptep)		\
   15.74 -({									\
   15.75 -	int __young;							\
   15.76 -	__young = ptep_test_and_clear_young(__vma, __address, __ptep);	\
   15.77 -	if (__young)							\
   15.78 -		flush_tlb_page(__vma, __address);			\
   15.79 -	__young;							\
   15.80 -})
   15.81 -#endif
   15.82 -
   15.83 -#ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
   15.84 -#define ptep_test_and_clear_dirty(__vma, __address, __ptep)		\
   15.85 -({									\
   15.86 -	pte_t __pte = *__ptep;						\
   15.87 -	int r = 1;							\
   15.88 -	if (!pte_dirty(__pte))						\
   15.89 -		r = 0;							\
   15.90 -	else								\
   15.91 -		set_pte_at((__vma)->vm_mm, (__address), (__ptep),	\
   15.92 -			   pte_mkclean(__pte));				\
   15.93 -	r;								\
   15.94 -})
   15.95 -#endif
   15.96 -
   15.97 -#ifndef __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
   15.98 -#define ptep_clear_flush_dirty(__vma, __address, __ptep)		\
   15.99 -({									\
  15.100 -	int __dirty;							\
  15.101 -	__dirty = ptep_test_and_clear_dirty(__vma, __address, __ptep);	\
  15.102 -	if (__dirty)							\
  15.103 -		flush_tlb_page(__vma, __address);			\
  15.104 -	__dirty;							\
  15.105 -})
  15.106 -#endif
  15.107 -
  15.108 -#ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
  15.109 -#define ptep_get_and_clear(__mm, __address, __ptep)			\
  15.110 -({									\
  15.111 -	pte_t __pte = *(__ptep);					\
  15.112 -	pte_clear((__mm), (__address), (__ptep));			\
  15.113 -	__pte;								\
  15.114 -})
  15.115 -#endif
  15.116 -
  15.117 -#ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
  15.118 -#define ptep_clear_flush(__vma, __address, __ptep)			\
  15.119 -({									\
  15.120 -	pte_t __pte;							\
  15.121 -	__pte = ptep_get_and_clear((__vma)->vm_mm, __address, __ptep);	\
  15.122 -	flush_tlb_page(__vma, __address);				\
  15.123 -	__pte;								\
  15.124 -})
  15.125 -#endif
  15.126 -
  15.127 -#ifndef __HAVE_ARCH_PTEP_SET_WRPROTECT
  15.128 -static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
  15.129 -{
  15.130 -	pte_t old_pte = *ptep;
  15.131 -	set_pte_at(mm, address, ptep, pte_wrprotect(old_pte));
  15.132 -}
  15.133 -#endif
  15.134 -
  15.135 -#ifndef __HAVE_ARCH_PTE_SAME
  15.136 -#define pte_same(A,B)	(pte_val(A) == pte_val(B))
  15.137 -#endif
  15.138 -
  15.139 -#ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
  15.140 -#define page_test_and_clear_dirty(page) (0)
  15.141 -#endif
  15.142 -
  15.143 -#ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
  15.144 -#define page_test_and_clear_young(page) (0)
  15.145 -#endif
  15.146 -
  15.147 -#ifndef __HAVE_ARCH_PGD_OFFSET_GATE
  15.148 -#define pgd_offset_gate(mm, addr)	pgd_offset(mm, addr)
  15.149 -#endif
  15.150 -
  15.151 -#ifndef __HAVE_ARCH_LAZY_MMU_PROT_UPDATE
  15.152 -#define lazy_mmu_prot_update(pte)	do { } while (0)
  15.153 -#endif
  15.154 -
  15.155 -/*
  15.156 - * When walking page tables, get the address of the next boundary,
  15.157 - * or the end address of the range if that comes earlier.  Although no
  15.158 - * vma end wraps to 0, rounded up __boundary may wrap to 0 throughout.
  15.159 - */
  15.160 -
  15.161 -#define pgd_addr_end(addr, end)						\
  15.162 -({	unsigned long __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK;	\
  15.163 -	(__boundary - 1 < (end) - 1)? __boundary: (end);		\
  15.164 -})
  15.165 -
  15.166 -#ifndef pud_addr_end
  15.167 -#define pud_addr_end(addr, end)						\
  15.168 -({	unsigned long __boundary = ((addr) + PUD_SIZE) & PUD_MASK;	\
  15.169 -	(__boundary - 1 < (end) - 1)? __boundary: (end);		\
  15.170 -})
  15.171 -#endif
  15.172 -
  15.173 -#ifndef pmd_addr_end
  15.174 -#define pmd_addr_end(addr, end)						\
  15.175 -({	unsigned long __boundary = ((addr) + PMD_SIZE) & PMD_MASK;	\
  15.176 -	(__boundary - 1 < (end) - 1)? __boundary: (end);		\
  15.177 -})
  15.178 -#endif
  15.179 -
  15.180 -#ifndef __ASSEMBLY__
  15.181 -/*
  15.182 - * When walking page tables, we usually want to skip any p?d_none entries;
  15.183 - * and any p?d_bad entries - reporting the error before resetting to none.
  15.184 - * Do the tests inline, but report and clear the bad entry in mm/memory.c.
  15.185 - */
  15.186 -void pgd_clear_bad(pgd_t *);
  15.187 -void pud_clear_bad(pud_t *);
  15.188 -void pmd_clear_bad(pmd_t *);
  15.189 -
  15.190 -static inline int pgd_none_or_clear_bad(pgd_t *pgd)
  15.191 -{
  15.192 -	if (pgd_none(*pgd))
  15.193 -		return 1;
  15.194 -	if (unlikely(pgd_bad(*pgd))) {
  15.195 -		pgd_clear_bad(pgd);
  15.196 -		return 1;
  15.197 -	}
  15.198 -	return 0;
  15.199 -}
  15.200 -
  15.201 -static inline int pud_none_or_clear_bad(pud_t *pud)
  15.202 -{
  15.203 -	if (pud_none(*pud))
  15.204 -		return 1;
  15.205 -	if (unlikely(pud_bad(*pud))) {
  15.206 -		pud_clear_bad(pud);
  15.207 -		return 1;
  15.208 -	}
  15.209 -	return 0;
  15.210 -}
  15.211 -
  15.212 -static inline int pmd_none_or_clear_bad(pmd_t *pmd)
  15.213 -{
  15.214 -	if (pmd_none(*pmd))
  15.215 -		return 1;
  15.216 -	if (unlikely(pmd_bad(*pmd))) {
  15.217 -		pmd_clear_bad(pmd);
  15.218 -		return 1;
  15.219 -	}
  15.220 -	return 0;
  15.221 -}
  15.222 -#endif /* !__ASSEMBLY__ */
  15.223 -
  15.224 -#endif /* _ASM_GENERIC_PGTABLE_H */
    16.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h	Mon Oct 03 16:40:27 2005 +0100
    16.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h	Tue Oct 04 14:22:30 2005 +0100
    16.3 @@ -316,26 +316,10 @@ HYPERVISOR_vm_assist(
    16.4  }
    16.5  
    16.6  static inline int
    16.7 -HYPERVISOR_boot_vcpu(
    16.8 -	unsigned long vcpu, vcpu_guest_context_t *ctxt)
    16.9 -{
   16.10 -	return _hypercall2(int, boot_vcpu, vcpu, ctxt);
   16.11 -}
   16.12 -
   16.13 -static inline int
   16.14 -HYPERVISOR_vcpu_up(
   16.15 -	int vcpu)
   16.16 +HYPERVISOR_vcpu_op(
   16.17 +	int cmd, int vcpuid, void *extra_args)
   16.18  {
   16.19 -	return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
   16.20 -			   (vcpu << SCHEDOP_vcpushift), 0);
   16.21 -}
   16.22 -
   16.23 -static inline int
   16.24 -HYPERVISOR_vcpu_pickle(
   16.25 -	int vcpu, vcpu_guest_context_t *ctxt)
   16.26 -{
   16.27 -	return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
   16.28 -			   (vcpu << SCHEDOP_vcpushift), ctxt);
   16.29 +	return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
   16.30  }
   16.31  
   16.32  static inline int
   16.33 @@ -357,24 +341,6 @@ HYPERVISOR_suspend(
   16.34  	return ret;
   16.35  }
   16.36  
   16.37 -static inline int
   16.38 -HYPERVISOR_vcpu_down(
   16.39 -	int vcpu)
   16.40 -{
   16.41 -	int ret;
   16.42 -	unsigned long ign1;
   16.43 -	/* Yes, I really do want to clobber edx here: when we resume a
   16.44 -	   vcpu after unpickling a multi-processor domain, it returns
   16.45 -	   here, but clobbers all of the call clobbered registers. */
   16.46 -	__asm__ __volatile__ (
   16.47 -		TRAP_INSTR
   16.48 -		: "=a" (ret), "=b" (ign1)
   16.49 -		: "0" (__HYPERVISOR_sched_op),
   16.50 -		"1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
   16.51 -		: "memory", "ecx", "edx" );
   16.52 -	return ret;
   16.53 -}
   16.54 -
   16.55  #endif /* __HYPERCALL_H__ */
   16.56  
   16.57  /*
    17.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Mon Oct 03 16:40:27 2005 +0100
    17.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Tue Oct 04 14:22:30 2005 +0100
    17.3 @@ -412,17 +412,6 @@ do {				  					\
    17.4  	ptep_set_access_flags(__vma, __address, __ptep, __entry, 1);	\
    17.5  } while (0)
    17.6  
    17.7 -#define __HAVE_ARCH_PTEP_ESTABLISH_NEW
    17.8 -#define ptep_establish_new(__vma, __address, __ptep, __entry)		\
    17.9 -do {				  					\
   17.10 -	if (likely((__vma)->vm_mm == current->mm)) {			\
   17.11 -		BUG_ON(HYPERVISOR_update_va_mapping((__address),	\
   17.12 -					     __entry, 0));		\
   17.13 -	} else {							\
   17.14 -		xen_l1_entry_update((__ptep), (__entry));	\
   17.15 -	}								\
   17.16 -} while (0)
   17.17 -
   17.18  #ifndef CONFIG_XEN_SHADOW_MODE
   17.19  void make_lowmem_page_readonly(void *va);
   17.20  void make_lowmem_page_writable(void *va);
    18.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h	Mon Oct 03 16:40:27 2005 +0100
    18.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h	Tue Oct 04 14:22:30 2005 +0100
    18.3 @@ -601,24 +601,6 @@ HYPERVISOR_vm_assist(
    18.4      return 1;
    18.5  }
    18.6  
    18.7 -static inline int
    18.8 -HYPERVISOR_boot_vcpu(
    18.9 -    unsigned long vcpu, vcpu_guest_context_t *ctxt)
   18.10 -{
   18.11 -#if 0
   18.12 -    int ret;
   18.13 -    unsigned long ign1, ign2;
   18.14 -
   18.15 -    __asm__ __volatile__ (
   18.16 -        TRAP_INSTR
   18.17 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   18.18 -	: "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt)
   18.19 -	: "memory");
   18.20 -
   18.21 -    return ret;
   18.22 -#endif
   18.23 -    return 1;
   18.24 -}
   18.25  #endif
   18.26  
   18.27  #endif /* __HYPERCALL_H__ */
    19.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h	Mon Oct 03 16:40:27 2005 +0100
    19.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h	Tue Oct 04 14:22:30 2005 +0100
    19.3 @@ -302,26 +302,10 @@ HYPERVISOR_vm_assist(
    19.4  }
    19.5  
    19.6  static inline int
    19.7 -HYPERVISOR_boot_vcpu(
    19.8 -	unsigned long vcpu, vcpu_guest_context_t *ctxt)
    19.9 -{
   19.10 -	return _hypercall2(int, boot_vcpu, vcpu, ctxt);
   19.11 -}
   19.12 -
   19.13 -static inline int
   19.14 -HYPERVISOR_vcpu_up(
   19.15 -	int vcpu)
   19.16 +HYPERVISOR_vcpu_op(
   19.17 +	int cmd, int vcpuid, void *extra_args)
   19.18  {
   19.19 -	return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
   19.20 -			   (vcpu << SCHEDOP_vcpushift), 0);
   19.21 -}
   19.22 -
   19.23 -static inline int
   19.24 -HYPERVISOR_vcpu_pickle(
   19.25 -	int vcpu, vcpu_guest_context_t *ctxt)
   19.26 -{
   19.27 -	return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
   19.28 -			   (vcpu << SCHEDOP_vcpushift), ctxt);
   19.29 +	return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
   19.30  }
   19.31  
   19.32  static inline int
    20.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Mon Oct 03 16:40:27 2005 +0100
    20.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Tue Oct 04 14:22:30 2005 +0100
    20.3 @@ -1,4 +1,5 @@
    20.4  # Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
    20.5 +# Copyright (C) 2005 XenSource Ltd
    20.6  
    20.7  # This file is subject to the terms and conditions of the GNU General
    20.8  # Public License.  See the file "COPYING" in the main directory of
    20.9 @@ -15,7 +16,6 @@ from xen.util.xpopen import xPopen3
   20.10  
   20.11  import xen.lowlevel.xc
   20.12  
   20.13 -import XendDomainInfo
   20.14  from xen.xend.xenstore.xsutil import IntroduceDomain
   20.15  
   20.16  from XendError import XendError
   20.17 @@ -42,58 +42,75 @@ def read_exact(fd, size, errmsg):
   20.18          raise XendError(errmsg)
   20.19      return buf
   20.20  
   20.21 -def save(xd, fd, dominfo, live):
   20.22 +def save(fd, dominfo, live):
   20.23      write_exact(fd, SIGNATURE, "could not write guest state file: signature")
   20.24  
   20.25      config = sxp.to_string(dominfo.sxpr())
   20.26 -    write_exact(fd, pack("!i", len(config)),
   20.27 -                "could not write guest state file: config len")
   20.28 -    write_exact(fd, config, "could not write guest state file: config")
   20.29 +
   20.30 +    domain_name = dominfo.getName()
   20.31 +
   20.32 +    if live:
   20.33 +        dominfo.setName('migrating-' + domain_name)
   20.34 +
   20.35 +    try:
   20.36 +        write_exact(fd, pack("!i", len(config)),
   20.37 +                    "could not write guest state file: config len")
   20.38 +        write_exact(fd, config, "could not write guest state file: config")
   20.39  
   20.40 -    # xc_save takes three customization parameters: maxit, max_f, and flags
   20.41 -    # the last controls whether or not save is 'live', while the first two
   20.42 -    # further customize behaviour when 'live' save is enabled. Passing "0"
   20.43 -    # simply uses the defaults compiled into libxenguest; see the comments 
   20.44 -    # and/or code in xc_linux_save() for more information. 
   20.45 -    cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
   20.46 -           str(dominfo.getDomid()), "0", "0", str(int(live)) ]
   20.47 -    log.info("[xc_save] " + join(cmd))
   20.48 -    child = xPopen3(cmd, True, -1, [fd, xc.handle()])
   20.49 +        # xc_save takes three customization parameters: maxit, max_f, and
   20.50 +        # flags the last controls whether or not save is 'live', while the
   20.51 +        # first two further customize behaviour when 'live' save is
   20.52 +        # enabled. Passing "0" simply uses the defaults compiled into
   20.53 +        # libxenguest; see the comments and/or code in xc_linux_save() for
   20.54 +        # more information.
   20.55 +        cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
   20.56 +               str(dominfo.getDomid()), "0", "0", str(int(live)) ]
   20.57 +        log.info("[xc_save] " + join(cmd))
   20.58 +        child = xPopen3(cmd, True, -1, [fd, xc.handle()])
   20.59      
   20.60 -    lasterr = ""
   20.61 -    p = select.poll()
   20.62 -    p.register(child.fromchild.fileno())
   20.63 -    p.register(child.childerr.fileno())
   20.64 -    while True: 
   20.65 -        r = p.poll()
   20.66 -        for (fd, event) in r:
   20.67 -            if not event & select.POLLIN:
   20.68 -                continue
   20.69 -            if fd == child.childerr.fileno():
   20.70 -                l = child.childerr.readline()
   20.71 -                log.error(l.rstrip())
   20.72 -                lasterr = l.rstrip()
   20.73 -            if fd == child.fromchild.fileno():
   20.74 -                l = child.fromchild.readline()
   20.75 -                if l.rstrip() == "suspend":
   20.76 -                    log.info("suspending %d" % dominfo.getDomid())
   20.77 -                    xd.domain_shutdown(dominfo.getDomid(), reason='suspend')
   20.78 -                    dominfo.state_wait(XendDomainInfo.STATE_VM_SUSPENDED)
   20.79 -                    log.info("suspend %d done" % dominfo.getDomid())
   20.80 -                    child.tochild.write("done\n")
   20.81 -                    child.tochild.flush()
   20.82 -        if filter(lambda (fd, event): event & select.POLLHUP, r):
   20.83 -            break
   20.84 +        lasterr = ""
   20.85 +        p = select.poll()
   20.86 +        p.register(child.fromchild.fileno())
   20.87 +        p.register(child.childerr.fileno())
   20.88 +        while True: 
   20.89 +            r = p.poll()
   20.90 +            for (fd, event) in r:
   20.91 +                if not event & select.POLLIN:
   20.92 +                    continue
   20.93 +                if fd == child.childerr.fileno():
   20.94 +                    l = child.childerr.readline()
   20.95 +                    log.error(l.rstrip())
   20.96 +                    lasterr = l.rstrip()
   20.97 +                if fd == child.fromchild.fileno():
   20.98 +                    l = child.fromchild.readline()
   20.99 +                    if l.rstrip() == "suspend":
  20.100 +                        log.info("suspending %d", dominfo.getDomid())
  20.101 +                        dominfo.shutdown('suspend')
  20.102 +                        dominfo.waitForShutdown()
  20.103 +                        log.info("suspend %d done", dominfo.getDomid())
  20.104 +                        child.tochild.write("done\n")
  20.105 +                        child.tochild.flush()
  20.106 +            if filter(lambda (fd, event): event & select.POLLHUP, r):
  20.107 +                break
  20.108  
  20.109 -    if child.wait() >> 8 == 127:
  20.110 -        lasterr = "popen %s failed" % PATH_XC_SAVE
  20.111 -    if child.wait() != 0:
  20.112 -        raise XendError("xc_save failed: %s" % lasterr)
  20.113 +        if child.wait() >> 8 == 127:
  20.114 +            lasterr = "popen %s failed" % PATH_XC_SAVE
  20.115 +        if child.wait() != 0:
  20.116 +            raise XendError("xc_save failed: %s" % lasterr)
  20.117  
  20.118 -    dominfo.destroy()
  20.119 -    return None
  20.120 +        dominfo.destroyDomain()
  20.121 +    except Exception, exn:
  20.122 +        log.exception("Save failed on domain %s (%d).", domain_name,
  20.123 +                      dominfo.getDomid())
  20.124 +        try:
  20.125 +            if live:
  20.126 +                dominfo.setName(domain_name)
  20.127 +        except:
  20.128 +            log.exception("Failed to reset the migrating domain's name")
  20.129 +        raise Exception, exn
  20.130  
  20.131 -def restore(fd):
  20.132 +
  20.133 +def restore(xd, fd):
  20.134      signature = read_exact(fd, len(SIGNATURE),
  20.135          "not a valid guest state file: signature read")
  20.136      if signature != SIGNATURE:
  20.137 @@ -112,71 +129,72 @@ def restore(fd):
  20.138          raise XendError("not a valid guest state file: config parse")
  20.139  
  20.140      vmconfig = p.get_val()
  20.141 -    dominfo = XendDomainInfo.restore(vmconfig)
  20.142 +
  20.143 +    dominfo = xd.restore_(vmconfig)
  20.144  
  20.145 -    l = read_exact(fd, sizeof_unsigned_long,
  20.146 -                   "not a valid guest state file: pfn count read")
  20.147 -    nr_pfns = unpack("=L", l)[0]   # XXX endianess
  20.148 -    if nr_pfns > 1024*1024:     # XXX
  20.149 -        raise XendError(
  20.150 -            "not a valid guest state file: pfn count out of range")
  20.151 +    assert dominfo.store_channel
  20.152 +    assert dominfo.console_channel
  20.153  
  20.154 -    if dominfo.store_channel:
  20.155 -        store_evtchn = dominfo.store_channel.port2
  20.156 -    else:
  20.157 -        store_evtchn = 0
  20.158 +    try:
  20.159 +        l = read_exact(fd, sizeof_unsigned_long,
  20.160 +                       "not a valid guest state file: pfn count read")
  20.161 +        nr_pfns = unpack("=L", l)[0]   # XXX endianess
  20.162 +        if nr_pfns > 1024*1024:     # XXX
  20.163 +            raise XendError(
  20.164 +                "not a valid guest state file: pfn count out of range")
  20.165  
  20.166 -    if dominfo.console_channel:
  20.167 +        store_evtchn = dominfo.store_channel.port2
  20.168          console_evtchn = dominfo.console_channel.port2
  20.169 -    else:
  20.170 -        console_evtchn = 0
  20.171  
  20.172 -    cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
  20.173 -           str(dominfo.getDomid()), str(nr_pfns),
  20.174 -           str(store_evtchn), str(console_evtchn)]
  20.175 -    log.info("[xc_restore] " + join(cmd))
  20.176 -    child = xPopen3(cmd, True, -1, [fd, xc.handle()])
  20.177 -    child.tochild.close()
  20.178 +        cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
  20.179 +               str(dominfo.getDomid()), str(nr_pfns),
  20.180 +               str(store_evtchn), str(console_evtchn)]
  20.181 +        log.info("[xc_restore] " + join(cmd))
  20.182 +        child = xPopen3(cmd, True, -1, [fd, xc.handle()])
  20.183 +        child.tochild.close()
  20.184  
  20.185 -    lasterr = ""
  20.186 -    p = select.poll()
  20.187 -    p.register(child.fromchild.fileno())
  20.188 -    p.register(child.childerr.fileno())
  20.189 -    while True:
  20.190 -        r = p.poll()
  20.191 -        for (fd, event) in r:
  20.192 -            if not event & select.POLLIN:
  20.193 -                continue
  20.194 -            if fd == child.childerr.fileno():
  20.195 -                l = child.childerr.readline()
  20.196 -                log.error(l.rstrip())
  20.197 -                lasterr = l.rstrip()
  20.198 -            if fd == child.fromchild.fileno():
  20.199 -                l = child.fromchild.readline()
  20.200 -                while l:
  20.201 -                    log.info(l.rstrip())
  20.202 -                    m = re.match(r"^(store-mfn) (\d+)\n$", l)
  20.203 -                    if m:
  20.204 -                        if dominfo.store_channel:
  20.205 +        lasterr = ""
  20.206 +        p = select.poll()
  20.207 +        p.register(child.fromchild.fileno())
  20.208 +        p.register(child.childerr.fileno())
  20.209 +        while True:
  20.210 +            r = p.poll()
  20.211 +            for (fd, event) in r:
  20.212 +                if not event & select.POLLIN:
  20.213 +                    continue
  20.214 +                if fd == child.childerr.fileno():
  20.215 +                    l = child.childerr.readline()
  20.216 +                    log.error(l.rstrip())
  20.217 +                    lasterr = l.rstrip()
  20.218 +                if fd == child.fromchild.fileno():
  20.219 +                    l = child.fromchild.readline()
  20.220 +                    while l:
  20.221 +                        log.info(l.rstrip())
  20.222 +                        m = re.match(r"^(store-mfn) (\d+)\n$", l)
  20.223 +                        if m:
  20.224                              store_mfn = int(m.group(2))
  20.225                              dominfo.setStoreRef(store_mfn)
  20.226                              IntroduceDomain(dominfo.getDomid(),
  20.227                                              store_mfn,
  20.228                                              dominfo.store_channel.port1,
  20.229                                              dominfo.getDomainPath())
  20.230 -                    m = re.match(r"^(console-mfn) (\d+)\n$", l)
  20.231 -                    if m:
  20.232 -                        dominfo.setConsoleRef(int(m.group(2)))
  20.233 -                    try:
  20.234 -                        l = child.fromchild.readline()
  20.235 -                    except:
  20.236 -                        l = None
  20.237 -        if filter(lambda (fd, event): event & select.POLLHUP, r):
  20.238 -            break
  20.239 +                        m = re.match(r"^(console-mfn) (\d+)\n$", l)
  20.240 +                        if m:
  20.241 +                            dominfo.setConsoleRef(int(m.group(2)))
  20.242 +                        try:
  20.243 +                            l = child.fromchild.readline()
  20.244 +                        except:
  20.245 +                            l = None
  20.246 +            if filter(lambda (fd, event): event & select.POLLHUP, r):
  20.247 +                break
  20.248  
  20.249 -    if child.wait() >> 8 == 127:
  20.250 -        lasterr = "popen %s failed" % PATH_XC_RESTORE
  20.251 -    if child.wait() != 0:
  20.252 -        raise XendError("xc_restore failed: %s" % lasterr)
  20.253 +        if child.wait() >> 8 == 127:
  20.254 +            lasterr = "popen %s failed" % PATH_XC_RESTORE
  20.255 +        if child.wait() != 0:
  20.256 +            raise XendError("xc_restore failed: %s" % lasterr)
  20.257  
  20.258 -    return dominfo
  20.259 +        return dominfo
  20.260 +    except:
  20.261 +        log.exception("Restore failed")
  20.262 +        dominfo.destroy()
  20.263 +        raise
    21.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Oct 03 16:40:27 2005 +0100
    21.2 +++ b/tools/python/xen/xend/XendDomain.py	Tue Oct 04 14:22:30 2005 +0100
    21.3 @@ -22,14 +22,16 @@
    21.4   Needs to be persistent for one uptime.
    21.5  """
    21.6  import os
    21.7 +import string
    21.8  import threading
    21.9  
   21.10  import xen.lowlevel.xc
   21.11  
   21.12 +import XendDomainInfo
   21.13 +
   21.14  from xen.xend import sxp
   21.15  from xen.xend import XendRoot
   21.16  from xen.xend import XendCheckpoint
   21.17 -from xen.xend.XendDomainInfo import XendDomainInfo
   21.18  from xen.xend import EventServer
   21.19  from xen.xend.XendError import XendError
   21.20  from xen.xend.XendLogging import log
   21.21 @@ -45,21 +47,10 @@ eserver = EventServer.instance()
   21.22  
   21.23  PRIV_DOMAIN = 0
   21.24  
   21.25 -class XendDomainDict(dict):
   21.26 -    def get_by_name(self, name):
   21.27 -        try:
   21.28 -            return filter(lambda d: d.getName() == name, self.values())[0]
   21.29 -        except IndexError, err:
   21.30 -            return None
   21.31 -
   21.32  class XendDomain:
   21.33      """Index of all domains. Singleton.
   21.34      """
   21.35  
   21.36 -    """Dict of domain info indexed by domain id."""
   21.37 -    domains = None
   21.38 -
   21.39 -
   21.40      ## public:
   21.41      
   21.42      def __init__(self):
   21.43 @@ -68,19 +59,30 @@ class XendDomain:
   21.44          # to import XendDomain from XendDomainInfo causes unbounded recursion.
   21.45          # So we stuff the XendDomain instance (self) into xroot's components.
   21.46          xroot.add_component("xen.xend.XendDomain", self)
   21.47 -        self.domains = XendDomainDict()
   21.48 -        self.refresh_lock = threading.Condition()
   21.49 +        self.domains = {}
   21.50 +        self.domains_lock = threading.Condition()
   21.51          self.watchReleaseDomain()
   21.52 -        self.refresh()
   21.53 -        self.dom0_setup()
   21.54 +
   21.55 +        self.domains_lock.acquire()
   21.56 +        try:
   21.57 +            self.refresh()
   21.58 +            self.dom0_setup()
   21.59 +        finally:
   21.60 +            self.domains_lock.release()
   21.61 +
   21.62  
   21.63      def list(self):
   21.64          """Get list of domain objects.
   21.65  
   21.66          @return: domain objects
   21.67          """
   21.68 -        self.refresh()
   21.69 -        return self.domains.values()
   21.70 +        self.domains_lock.acquire()
   21.71 +        try:
   21.72 +            self.refresh()
   21.73 +            return self.domains.values()
   21.74 +        finally:
   21.75 +            self.domains_lock.release()
   21.76 +
   21.77  
   21.78      def list_sorted(self):
   21.79          """Get list of domain objects, sorted by name.
   21.80 @@ -103,7 +105,12 @@ class XendDomain:
   21.81      ## private:
   21.82  
   21.83      def onReleaseDomain(self):
   21.84 -        self.refresh()
   21.85 +        self.domains_lock.acquire()
   21.86 +        try:
   21.87 +            self.refresh()
   21.88 +        finally:
   21.89 +            self.domains_lock.release()
   21.90 +            
   21.91  
   21.92      def watchReleaseDomain(self):
   21.93          from xen.xend.xenstore.xswatch import xswatch
   21.94 @@ -133,16 +140,8 @@ class XendDomain:
   21.95          return dominfo
   21.96  
   21.97  
   21.98 -    def recreate_domain(self, xeninfo):
   21.99 -        """Refresh initial domain info from db."""
  21.100 -
  21.101 -        dominfo = XendDomainInfo.recreate(xeninfo)
  21.102 -        self._add_domain(dominfo)
  21.103 -        return dominfo
  21.104 -
  21.105 -
  21.106      def dom0_setup(self):
  21.107 -        dom0 = self.domain_lookup(PRIV_DOMAIN)
  21.108 +        dom0 = self.domains[PRIV_DOMAIN]
  21.109          dom0.dom0_enforce_vcpus()
  21.110  
  21.111  
  21.112 @@ -179,50 +178,33 @@ class XendDomain:
  21.113      def refresh(self):
  21.114          """Refresh domain list from Xen.
  21.115          """
  21.116 -        self.refresh_lock.acquire()
  21.117 -        try:
  21.118 -            doms = self.xen_domains()
  21.119 -            for d in self.domains.values():
  21.120 -                info = doms.get(d.getDomid())
  21.121 -                if info:
  21.122 -                    d.update(info)
  21.123 -                else:
  21.124 -                    self._delete_domain(d.getDomid())
  21.125 -            for d in doms:
  21.126 -                if d not in self.domains and not doms[d]['dying']:
  21.127 -                    try:
  21.128 -                        self.recreate_domain(doms[d])
  21.129 -                    except:
  21.130 -                        if d == PRIV_DOMAIN:
  21.131 -                            log.exception(
  21.132 -                                "Failed to recreate information for domain "
  21.133 -                                "%d.  Doing nothing except crossing my "
  21.134 -                                "fingers.", d)
  21.135 -                        else:
  21.136 -                            log.exception(
  21.137 -                                "Failed to recreate information for domain "
  21.138 -                                "%d.  Destroying it in the hope of "
  21.139 -                                "recovery.", d)
  21.140 -                            try:
  21.141 -                                xc.domain_destroy(dom = d)
  21.142 -                            except:
  21.143 -                                log.exception('Destruction of %d failed.', d)
  21.144 -        finally:
  21.145 -            self.refresh_lock.release()
  21.146 -
  21.147 -
  21.148 -    def update_domain(self, id):
  21.149 -        """Update information for a single domain.
  21.150 -
  21.151 -        @param id: domain id
  21.152 -        """
  21.153 -        dominfo = self.xen_domain(id)
  21.154 -        if dominfo:
  21.155 -            d = self.domains.get(id)
  21.156 -            if d:
  21.157 -                d.update(dominfo)
  21.158 -        else:
  21.159 -            self._delete_domain(id)
  21.160 +        doms = self.xen_domains()
  21.161 +        for d in self.domains.values():
  21.162 +            info = doms.get(d.getDomid())
  21.163 +            if info:
  21.164 +                d.update(info)
  21.165 +            else:
  21.166 +                self._delete_domain(d.getDomid())
  21.167 +        for d in doms:
  21.168 +            if d not in self.domains and not doms[d]['dying']:
  21.169 +                try:
  21.170 +                    dominfo = XendDomainInfo.recreate(doms[d])
  21.171 +                    self._add_domain(dominfo)
  21.172 +                except:
  21.173 +                    if d == PRIV_DOMAIN:
  21.174 +                        log.exception(
  21.175 +                            "Failed to recreate information for domain "
  21.176 +                            "%d.  Doing nothing except crossing my "
  21.177 +                            "fingers.", d)
  21.178 +                    else:
  21.179 +                        log.exception(
  21.180 +                            "Failed to recreate information for domain "
  21.181 +                            "%d.  Destroying it in the hope of "
  21.182 +                            "recovery.", d)
  21.183 +                        try:
  21.184 +                            xc.domain_destroy(dom = d)
  21.185 +                        except:
  21.186 +                            log.exception('Destruction of %d failed.', d)
  21.187  
  21.188  
  21.189      ## public:
  21.190 @@ -233,9 +215,14 @@ class XendDomain:
  21.191          @param config: configuration
  21.192          @return: domain
  21.193          """
  21.194 -        dominfo = XendDomainInfo.create(config)
  21.195 -        self._add_domain(dominfo)
  21.196 -        return dominfo
  21.197 +        self.domains_lock.acquire()
  21.198 +        try:
  21.199 +            dominfo = XendDomainInfo.create(config)
  21.200 +            self._add_domain(dominfo)
  21.201 +            return dominfo
  21.202 +        finally:
  21.203 +            self.domains_lock.release()
  21.204 +
  21.205  
  21.206      def domain_configure(self, config):
  21.207          """Configure an existing domain.
  21.208 @@ -252,39 +239,110 @@ class XendDomain:
  21.209          """
  21.210  
  21.211          try:
  21.212 -            fd = os.open(src, os.O_RDONLY)
  21.213 -            dominfo = XendCheckpoint.restore(fd)
  21.214 -            self._add_domain(dominfo)
  21.215 -            return dominfo
  21.216 +            return self.domain_restore_fd(os.open(src, os.O_RDONLY))
  21.217          except OSError, ex:
  21.218              raise XendError("can't read guest state file %s: %s" %
  21.219                              (src, ex[1]))
  21.220  
  21.221 -    def domain_get(self, id):
  21.222 -        """Get up-to-date info about a domain.
  21.223 +    def domain_restore_fd(self, fd):
  21.224 +        """Restore a domain from the given file descriptor."""
  21.225 +
  21.226 +        try:
  21.227 +            XendCheckpoint.restore(self, fd)
  21.228 +        except Exception, ex:
  21.229 +            log.exception("Restore failed")
  21.230 +            raise
  21.231 +
  21.232 +
  21.233 +    def restore_(self, config):
  21.234 +        """Create a domain as part of the restore process.  This is called
  21.235 +        only from {@link XendCheckpoint}.
  21.236  
  21.237 -        @param id: domain id
  21.238 -        @return: domain object (or None)
  21.239 +        A restore request comes into XendDomain through {@link
  21.240 +        #domain_restore} or {@link #domain_restore_fd}.  That request is
  21.241 +        forwarded immediately to XendCheckpoint which, when it is ready, will
  21.242 +        call this method.  It is necessary to come through here rather than go
  21.243 +        directly to {@link XendDomainInfo.restore} because we need to
  21.244 +        serialise the domain creation process, but cannot lock
  21.245 +        domain_restore_fd as a whole, otherwise we will deadlock waiting for
  21.246 +        the old domain to die.
  21.247          """
  21.248 -        self.update_domain(id)
  21.249 -        return self.domains.get(id)
  21.250 +        self.domains_lock.acquire()
  21.251 +        try:
  21.252 +            dominfo = XendDomainInfo.restore(config)
  21.253 +            self._add_domain(dominfo)
  21.254 +            return dominfo
  21.255 +        finally:
  21.256 +            self.domains_lock.release()
  21.257  
  21.258  
  21.259      def domain_lookup(self, id):
  21.260 -        self.refresh()
  21.261 -        return self.domains.get(id)
  21.262 +        self.domains_lock.acquire()
  21.263 +        try:
  21.264 +            self.refresh()
  21.265 +            return self.domains.get(id)
  21.266 +        finally:
  21.267 +            self.domains_lock.release()
  21.268 +
  21.269 +
  21.270 +    def domain_lookup_nr(self, id):
  21.271 +        self.domains_lock.acquire()
  21.272 +        try:
  21.273 +            return self.domains.get(id)
  21.274 +        finally:
  21.275 +            self.domains_lock.release()
  21.276 +
  21.277 +
  21.278 +    def domain_lookup_by_name_or_id(self, name):
  21.279 +        self.domains_lock.acquire()
  21.280 +        try:
  21.281 +            self.refresh()
  21.282 +            return self.domain_lookup_by_name_or_id_nr(name)
  21.283 +        finally:
  21.284 +            self.domains_lock.release()
  21.285 +
  21.286 +
  21.287 +    def domain_lookup_by_name_or_id_nr(self, name):
  21.288 +        self.domains_lock.acquire()
  21.289 +        try:
  21.290 +            dominfo = self.domain_lookup_by_name_nr(name)
  21.291  
  21.292 -    def domain_lookup_by_name(self, name):
  21.293 -        self.refresh()
  21.294 -        dominfo = self.domains.get_by_name(name)
  21.295 -        if not dominfo:
  21.296 -            try:
  21.297 -                id = int(name)
  21.298 -                dominfo = self.domain_lookup(id)
  21.299 -            except ValueError:
  21.300 -                pass
  21.301 -        return dominfo
  21.302 +            if dominfo:
  21.303 +                return dominfo
  21.304 +            else:
  21.305 +                try:
  21.306 +                    return self.domains.get(int(name))
  21.307 +                except ValueError:
  21.308 +                    return None
  21.309 +        finally:
  21.310 +            self.domains_lock.release()
  21.311 +
  21.312  
  21.313 +    def domain_lookup_by_name_nr(self, name):
  21.314 +        self.domains_lock.acquire()
  21.315 +        try:
  21.316 +            matching = filter(lambda d: d.getName() == name,
  21.317 +                              self.domains.values())
  21.318 +            n = len(matching)
  21.319 +            if n == 1:
  21.320 +                return matching[0]
  21.321 +            elif n > 1:
  21.322 +                raise XendError(
  21.323 +                    'Name uniqueness has been violated for name %s' % name)
  21.324 +            else:
  21.325 +                return None
  21.326 +        finally:
  21.327 +            self.domains_lock.release()
  21.328 +
  21.329 +
  21.330 +    def privilegedDomain(self):
  21.331 +        self.domains_lock.acquire()
  21.332 +        try:
  21.333 +            return self.domains[PRIV_DOMAIN]
  21.334 +        finally:
  21.335 +            self.domains_lock.release()
  21.336 +
  21.337 + 
  21.338      def domain_unpause(self, id):
  21.339          """Unpause domain execution.
  21.340  
  21.341 @@ -312,32 +370,22 @@ class XendDomain:
  21.342              raise XendError(str(ex))
  21.343  
  21.344  
  21.345 -    def domain_shutdown(self, domid, reason='poweroff'):
  21.346 +    def domain_shutdown(self, domid, reason = 'poweroff'):
  21.347          """Shutdown domain (nicely).
  21.348 -         - poweroff: restart according to exit code and restart mode
  21.349 -         - reboot:   restart on exit
  21.350 -         - halt:     do not restart
  21.351  
  21.352 -         Returns immediately.
  21.353 -
  21.354 -        @param id:     domain id
  21.355 -        @param reason: shutdown type: poweroff, reboot, suspend, halt
  21.356 +        @param reason: shutdown reason: poweroff, reboot, suspend, halt
  21.357          """
  21.358 -        self.callInfo(domid, XendDomainInfo.shutdown, reason)
  21.359 +        self.callInfo(domid, XendDomainInfo.XendDomainInfo.shutdown, reason)
  21.360  
  21.361  
  21.362      def domain_sysrq(self, domid, key):
  21.363          """Send a SysRq to the specified domain."""
  21.364 -        return self.callInfo(domid, XendDomainInfo.send_sysrq, key)
  21.365 +        return self.callInfo(domid, XendDomainInfo.XendDomainInfo.send_sysrq,
  21.366 +                             key)
  21.367  
  21.368  
  21.369 -    def domain_destroy(self, domid, reason='halt'):
  21.370 -        """Terminate domain immediately.
  21.371 -        - halt:   cancel any restart for the domain
  21.372 -        - reboot  schedule a restart for the domain
  21.373 -
  21.374 -        @param domid: domain id
  21.375 -        """
  21.376 +    def domain_destroy(self, domid):
  21.377 +        """Terminate domain immediately."""
  21.378  
  21.379          if domid == PRIV_DOMAIN:
  21.380              raise XendError("Cannot destroy privileged domain %i" % domid)
  21.381 @@ -364,19 +412,8 @@ class XendDomain:
  21.382          port = xroot.get_xend_relocation_port()
  21.383          sock = relocate.setupRelocation(dst, port)
  21.384  
  21.385 -        # temporarily rename domain for localhost migration
  21.386 -        if dst == "localhost":
  21.387 -            dominfo.setName("tmp-" + dominfo.getName())
  21.388 -
  21.389 -        try:
  21.390 -            XendCheckpoint.save(self, sock.fileno(), dominfo, live)
  21.391 -        except:
  21.392 -            if dst == "localhost":
  21.393 -                dominfo.setName(
  21.394 -                    string.replace(dominfo.getName(), "tmp-", "", 1))
  21.395 -            raise
  21.396 +        XendCheckpoint.save(sock.fileno(), dominfo, live)
  21.397          
  21.398 -        return None
  21.399  
  21.400      def domain_save(self, id, dst):
  21.401          """Start saving a domain to file.
  21.402 @@ -391,7 +428,7 @@ class XendDomain:
  21.403              fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
  21.404  
  21.405              # For now we don't support 'live checkpoint' 
  21.406 -            return XendCheckpoint.save(self, fd, dominfo, False)
  21.407 +            return XendCheckpoint.save(fd, dominfo, False)
  21.408  
  21.409          except OSError, ex:
  21.410              raise XendError("can't write guest state file %s: %s" %
  21.411 @@ -456,32 +493,39 @@ class XendDomain:
  21.412      def domain_device_create(self, domid, devconfig):
  21.413          """Create a new device for the specified domain.
  21.414          """
  21.415 -        return self.callInfo(domid, XendDomainInfo.device_create, devconfig)
  21.416 +        return self.callInfo(domid,
  21.417 +                             XendDomainInfo.XendDomainInfo.device_create,
  21.418 +                             devconfig)
  21.419  
  21.420  
  21.421      def domain_device_configure(self, domid, devconfig, devid):
  21.422          """Configure an existing device in the specified domain.
  21.423          @return: updated device configuration
  21.424          """
  21.425 -        return self.callInfo(domid, XendDomainInfo.device_configure,
  21.426 +        return self.callInfo(domid,
  21.427 +                             XendDomainInfo.XendDomainInfo.device_configure,
  21.428                               devconfig, devid)
  21.429  
  21.430      
  21.431      def domain_device_refresh(self, domid, devtype, devid):
  21.432          """Refresh a device."""
  21.433 -        return self.callInfo(domid, XendDomainInfo.device_refresh, devtype,
  21.434 -                             devid)
  21.435 +        return self.callInfo(domid,
  21.436 +                             XendDomainInfo.XendDomainInfo.device_refresh,
  21.437 +                             devtype, devid)
  21.438  
  21.439  
  21.440      def domain_device_destroy(self, domid, devtype, devid):
  21.441          """Destroy a device."""
  21.442 -        return self.callInfo(domid, XendDomainInfo.destroyDevice, devtype,
  21.443 -                             devid)
  21.444 +        return self.callInfo(domid,
  21.445 +                             XendDomainInfo.XendDomainInfo.destroyDevice,
  21.446 +                             devtype, devid)
  21.447  
  21.448  
  21.449      def domain_devtype_ls(self, domid, devtype):
  21.450          """Get list of device sxprs for the specified domain."""
  21.451 -        return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
  21.452 +        return self.callInfo(domid,
  21.453 +                             XendDomainInfo.XendDomainInfo.getDeviceSxprs,
  21.454 +                             devtype)
  21.455  
  21.456  
  21.457      def domain_vif_limit_set(self, id, vif, credit, period):
  21.458 @@ -525,7 +569,8 @@ class XendDomain:
  21.459  
  21.460          @param mem: memory target (in MiB)
  21.461          """
  21.462 -        self.callInfo(domid, XendDomainInfo.setMemoryTarget, mem << 10)
  21.463 +        self.callInfo(domid, XendDomainInfo.XendDomainInfo.setMemoryTarget,
  21.464 +                      mem << 10)
  21.465  
  21.466  
  21.467      def domain_vcpu_hotplug(self, domid, vcpu, state):
  21.468 @@ -534,12 +579,13 @@ class XendDomain:
  21.469          @param vcpu: target VCPU in domain
  21.470          @param state: which state VCPU will become
  21.471          """
  21.472 -        self.callInfo(domid, XendDomainInfo.vcpu_hotplug, vcpu, state)
  21.473 +        self.callInfo(domid, XendDomainInfo.XendDomainInfo.vcpu_hotplug, vcpu,
  21.474 +                      state)
  21.475  
  21.476  
  21.477      def domain_dumpcore(self, domid):
  21.478          """Save a core dump for a crashed domain."""
  21.479 -        self.callInfo(domid, XendDomainInfo.dumpCore)
  21.480 +        self.callInfo(domid, XendDomainInfo.XendDomainInfo.dumpCore)
  21.481  
  21.482  
  21.483      ## private:
    22.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Oct 03 16:40:27 2005 +0100
    22.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Oct 04 14:22:30 2005 +0100
    22.3 @@ -59,12 +59,16 @@ DOMAIN_SUSPEND  = 2
    22.4  """Shutdown code for crash."""
    22.5  DOMAIN_CRASH    = 3
    22.6  
    22.7 +"""Shutdown code for halt."""
    22.8 +DOMAIN_HALT     = 4
    22.9 +
   22.10  """Map shutdown codes to strings."""
   22.11  shutdown_reasons = {
   22.12      DOMAIN_POWEROFF: "poweroff",
   22.13      DOMAIN_REBOOT  : "reboot",
   22.14      DOMAIN_SUSPEND : "suspend",
   22.15      DOMAIN_CRASH   : "crash",
   22.16 +    DOMAIN_HALT    : "halt"
   22.17      }
   22.18  
   22.19  restart_modes = [
   22.20 @@ -76,7 +80,6 @@ restart_modes = [
   22.21  
   22.22  STATE_VM_OK         = "ok"
   22.23  STATE_VM_TERMINATED = "terminated"
   22.24 -STATE_VM_SUSPENDED  = "suspended"
   22.25  
   22.26  """Flag for a block device backend domain."""
   22.27  SIF_BLK_BE_DOMAIN = (1<<4)
   22.28 @@ -116,6 +119,68 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [
   22.29      ]
   22.30  
   22.31  
   22.32 +def create(config):
   22.33 +    """Create a VM from a configuration.
   22.34 +
   22.35 +    @param config    configuration
   22.36 +    @raise: VmError for invalid configuration
   22.37 +    """
   22.38 +
   22.39 +    log.debug("XendDomainInfo.create(%s)", config)
   22.40 +
   22.41 +    vm = XendDomainInfo(getUuid(), parseConfig(config))
   22.42 +    vm.construct()
   22.43 +    vm.refreshShutdown()
   22.44 +    return vm
   22.45 +
   22.46 +
   22.47 +def recreate(xeninfo):
   22.48 +    """Create the VM object for an existing domain.  The domain must not
   22.49 +    be dying, as the paths in the store should already have been removed,
   22.50 +    and asking us to recreate them causes problems."""
   22.51 +
   22.52 +    log.debug("XendDomainInfo.recreate(%s)", xeninfo)
   22.53 +
   22.54 +    assert not xeninfo['dying']
   22.55 +
   22.56 +    domid = xeninfo['dom']
   22.57 +    try:
   22.58 +        dompath = GetDomainPath(domid)
   22.59 +        if not dompath:
   22.60 +            raise XendError(
   22.61 +                'No domain path in store for existing domain %d' % domid)
   22.62 +        vmpath = xstransact.Read(dompath, "vm")
   22.63 +        if not vmpath:
   22.64 +            raise XendError(
   22.65 +                'No vm path in store for existing domain %d' % domid)
   22.66 +        uuid = xstransact.Read(vmpath, "uuid")
   22.67 +        if not uuid:
   22.68 +            raise XendError(
   22.69 +                'No vm/uuid path in store for existing domain %d' % domid)
   22.70 +
   22.71 +        log.info("Recreating domain %d, UUID %s.", domid, uuid)
   22.72 +
   22.73 +        vm = XendDomainInfo(uuid, xeninfo, domid, True)
   22.74 +
   22.75 +    except Exception, exn:
   22.76 +        log.warn(str(exn))
   22.77 +
   22.78 +        uuid = getUuid()
   22.79 +
   22.80 +        log.info("Recreating domain %d with new UUID %s.", domid, uuid)
   22.81 +
   22.82 +        vm = XendDomainInfo(uuid, xeninfo, domid, True)
   22.83 +        vm.storeVmDetails()
   22.84 +        vm.storeDomDetails()
   22.85 +
   22.86 +    vm.create_channel()
   22.87 +    if domid == 0:
   22.88 +        vm.initStoreConnection()
   22.89 +
   22.90 +    vm.refreshShutdown(xeninfo)
   22.91 +    return vm
   22.92 +
   22.93 +
   22.94  def restore(config):
   22.95      """Create a domain and a VM object to do a restore.
   22.96  
   22.97 @@ -130,7 +195,7 @@ def restore(config):
   22.98      except TypeError, exn:
   22.99          raise VmError('Invalid ssidref in config: %s' % exn)
  22.100  
  22.101 -    vm = XendDomainInfo(uuid, XendDomainInfo.parseConfig(config),
  22.102 +    vm = XendDomainInfo(uuid, parseConfig(config),
  22.103                          xc.domain_create(ssidref = ssidref))
  22.104      vm.storeVmDetails()
  22.105      vm.configure()
  22.106 @@ -139,10 +204,87 @@ def restore(config):
  22.107      return vm
  22.108  
  22.109  
  22.110 -def domain_exists(name):
  22.111 +def parseConfig(config):
  22.112 +    def get_cfg(name, conv = None):
  22.113 +        val = sxp.child_value(config, name)
  22.114 +
  22.115 +        if conv and not val is None:
  22.116 +            try:
  22.117 +                return conv(val)
  22.118 +            except TypeError, exn:
  22.119 +                raise VmError(
  22.120 +                    'Invalid setting %s = %s in configuration: %s' %
  22.121 +                    (name, val, str(exn)))
  22.122 +        else:
  22.123 +            return val
  22.124 +
  22.125 +
  22.126 +    log.debug("parseConfig: config is %s" % str(config))
  22.127 +
  22.128 +    result = {}
  22.129 +
  22.130 +    for e in ROUNDTRIPPING_CONFIG_ENTRIES:
  22.131 +        result[e[0]] = get_cfg(e[0], e[1])
  22.132 +
  22.133 +    result['memory']       = get_cfg('memory',     int)
  22.134 +    result['mem_kb']       = get_cfg('mem_kb',     int)
  22.135 +    result['maxmem']       = get_cfg('maxmem',     int)
  22.136 +    result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
  22.137 +    result['cpu']          = get_cfg('cpu',        int)
  22.138 +    result['image']        = get_cfg('image')
  22.139 +
  22.140 +    try:
  22.141 +        if result['image']:
  22.142 +            result['vcpus'] = int(sxp.child_value(result['image'],
  22.143 +                                                  'vcpus', 1))
  22.144 +        else:
  22.145 +            result['vcpus'] = 1
  22.146 +    except TypeError, exn:
  22.147 +        raise VmError(
  22.148 +            'Invalid configuration setting: vcpus = %s: %s' %
  22.149 +            (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
  22.150 +
  22.151 +    result['backend'] = []
  22.152 +    for c in sxp.children(config, 'backend'):
  22.153 +        result['backend'].append(sxp.name(sxp.child0(c)))
  22.154 +
  22.155 +    result['device'] = []
  22.156 +    for d in sxp.children(config, 'device'):
  22.157 +        c = sxp.child0(d)
  22.158 +        result['device'].append((sxp.name(c), c))
  22.159 +
  22.160 +    # Configuration option "restart" is deprecated.  Parse it, but
  22.161 +    # let on_xyz override it if they are present.
  22.162 +    restart = get_cfg('restart')
  22.163 +    if restart:
  22.164 +        def handle_restart(event, val):
  22.165 +            if not event in result:
  22.166 +                result[event] = val
  22.167 +
  22.168 +        if restart == "onreboot":
  22.169 +            handle_restart('on_poweroff', 'destroy')
  22.170 +            handle_restart('on_reboot',   'restart')
  22.171 +            handle_restart('on_crash',    'destroy')
  22.172 +        elif restart == "always":
  22.173 +            handle_restart('on_poweroff', 'restart')
  22.174 +            handle_restart('on_reboot',   'restart')
  22.175 +            handle_restart('on_crash',    'restart')
  22.176 +        elif restart == "never":
  22.177 +            handle_restart('on_poweroff', 'destroy')
  22.178 +            handle_restart('on_reboot',   'destroy')
  22.179 +            handle_restart('on_crash',    'destroy')
  22.180 +        else:
  22.181 +            log.warn("Ignoring malformed and deprecated config option "
  22.182 +                     "restart = %s", restart)
  22.183 +
  22.184 +    log.debug("parseConfig: result is %s" % str(result))
  22.185 +    return result
  22.186 +
  22.187 +
  22.188 +def domain_by_name(name):
  22.189      # See comment in XendDomain constructor.
  22.190      xd = get_component('xen.xend.XendDomain')
  22.191 -    return xd.domain_lookup_by_name(name)
  22.192 +    return xd.domain_lookup_by_name_nr(name)
  22.193  
  22.194  def shutdown_reason(code):
  22.195      """Get a shutdown reason from a code.
  22.196 @@ -177,152 +319,6 @@ class XendDomainInfo:
  22.197      MINIMUM_RESTART_TIME = 20
  22.198  
  22.199  
  22.200 -    def create(cls, config):
  22.201 -        """Create a VM from a configuration.
  22.202 -
  22.203 -        @param config    configuration
  22.204 -        @raise: VmError for invalid configuration
  22.205 -        """
  22.206 -
  22.207 -        log.debug("XendDomainInfo.create(%s)", config)
  22.208 -        
  22.209 -        vm = cls(getUuid(), cls.parseConfig(config))
  22.210 -        vm.construct()
  22.211 -        vm.refreshShutdown()
  22.212 -        return vm
  22.213 -
  22.214 -    create = classmethod(create)
  22.215 -
  22.216 -
  22.217 -    def recreate(cls, xeninfo):
  22.218 -        """Create the VM object for an existing domain.  The domain must not
  22.219 -        be dying, as the paths in the store should already have been removed,
  22.220 -        and asking us to recreate them causes problems."""
  22.221 -
  22.222 -        log.debug("XendDomainInfo.recreate(%s)", xeninfo)
  22.223 -
  22.224 -        assert not xeninfo['dying']
  22.225 -
  22.226 -        domid = xeninfo['dom']
  22.227 -        try:
  22.228 -            dompath = GetDomainPath(domid)
  22.229 -            if not dompath:
  22.230 -                raise XendError(
  22.231 -                    'No domain path in store for existing domain %d' % domid)
  22.232 -            vmpath = xstransact.Read(dompath, "vm")
  22.233 -            if not vmpath:
  22.234 -                raise XendError(
  22.235 -                    'No vm path in store for existing domain %d' % domid)
  22.236 -            uuid = xstransact.Read(vmpath, "uuid")
  22.237 -            if not uuid:
  22.238 -                raise XendError(
  22.239 -                    'No vm/uuid path in store for existing domain %d' % domid)
  22.240 -
  22.241 -            log.info("Recreating domain %d, UUID %s.", domid, uuid)
  22.242 -
  22.243 -            vm = cls(uuid, xeninfo, domid, True)
  22.244 -
  22.245 -        except Exception, exn:
  22.246 -            log.warn(str(exn))
  22.247 -
  22.248 -            uuid = getUuid()
  22.249 -
  22.250 -            log.info("Recreating domain %d with new UUID %s.", domid, uuid)
  22.251 -
  22.252 -            vm = cls(uuid, xeninfo, domid, True)
  22.253 -            vm.storeVmDetails()
  22.254 -            vm.storeDomDetails()
  22.255 -
  22.256 -        vm.create_channel()
  22.257 -        if domid == 0:
  22.258 -            vm.initStoreConnection()
  22.259 -
  22.260 -        vm.refreshShutdown(xeninfo)
  22.261 -        return vm
  22.262 -
  22.263 -    recreate = classmethod(recreate)
  22.264 -
  22.265 -
  22.266 -    def parseConfig(cls, config):
  22.267 -        def get_cfg(name, conv = None):
  22.268 -            val = sxp.child_value(config, name)
  22.269 -
  22.270 -            if conv and not val is None:
  22.271 -                try:
  22.272 -                    return conv(val)
  22.273 -                except TypeError, exn:
  22.274 -                    raise VmError(
  22.275 -                        'Invalid setting %s = %s in configuration: %s' %
  22.276 -                        (name, val, str(exn)))
  22.277 -            else:
  22.278 -                return val
  22.279 -
  22.280 -
  22.281 -        log.debug("parseConfig: config is %s" % str(config))
  22.282 -
  22.283 -        result = {}
  22.284 -
  22.285 -        for e in ROUNDTRIPPING_CONFIG_ENTRIES:
  22.286 -            result[e[0]] = get_cfg(e[0], e[1])
  22.287 -
  22.288 -        result['memory']       = get_cfg('memory',     int)
  22.289 -        result['mem_kb']       = get_cfg('mem_kb',     int)
  22.290 -        result['maxmem']       = get_cfg('maxmem',     int)
  22.291 -        result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
  22.292 -        result['cpu']          = get_cfg('cpu',        int)
  22.293 -        result['image']        = get_cfg('image')
  22.294 -
  22.295 -        try:
  22.296 -            if result['image']:
  22.297 -                result['vcpus'] = int(sxp.child_value(result['image'],
  22.298 -                                                      'vcpus', 1))
  22.299 -            else:
  22.300 -                result['vcpus'] = 1
  22.301 -        except TypeError, exn:
  22.302 -            raise VmError(
  22.303 -                'Invalid configuration setting: vcpus = %s: %s' %
  22.304 -                (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
  22.305 -
  22.306 -        result['backend'] = []
  22.307 -        for c in sxp.children(config, 'backend'):
  22.308 -            result['backend'].append(sxp.name(sxp.child0(c)))
  22.309 -
  22.310 -        result['device'] = []
  22.311 -        for d in sxp.children(config, 'device'):
  22.312 -            c = sxp.child0(d)
  22.313 -            result['device'].append((sxp.name(c), c))
  22.314 -
  22.315 -        # Configuration option "restart" is deprecated.  Parse it, but
  22.316 -        # let on_xyz override it if they are present.
  22.317 -        restart = get_cfg('restart')
  22.318 -        if restart:
  22.319 -            def handle_restart(event, val):
  22.320 -                if not event in result:
  22.321 -                    result[event] = val
  22.322 -
  22.323 -            if restart == "onreboot":
  22.324 -                handle_restart('on_poweroff', 'destroy')
  22.325 -                handle_restart('on_reboot',   'restart')
  22.326 -                handle_restart('on_crash',    'destroy')
  22.327 -            elif restart == "always":
  22.328 -                handle_restart('on_poweroff', 'restart')
  22.329 -                handle_restart('on_reboot',   'restart')
  22.330 -                handle_restart('on_crash',    'restart')
  22.331 -            elif restart == "never":
  22.332 -                handle_restart('on_poweroff', 'destroy')
  22.333 -                handle_restart('on_reboot',   'destroy')
  22.334 -                handle_restart('on_crash',    'destroy')
  22.335 -            else:
  22.336 -                log.warn("Ignoring malformed and deprecated config option "
  22.337 -                         "restart = %s", restart)
  22.338 -
  22.339 -        log.debug("parseConfig: result is %s" % str(result))
  22.340 -        return result
  22.341 -
  22.342 -
  22.343 -    parseConfig = classmethod(parseConfig)
  22.344 -
  22.345 -    
  22.346      def __init__(self, uuid, info, domid = None, augment = False):
  22.347  
  22.348          self.uuid = uuid
  22.349 @@ -627,21 +623,22 @@ class XendDomainInfo:
  22.350                      # The domain no longer exists.  This will occur if we have
  22.351                      # scheduled a timer to check for shutdown timeouts and the
  22.352                      # shutdown succeeded.  It will also occur if someone
  22.353 -                    # destroys a domain beneath us.  We clean up, just in
  22.354 -                    # case.
  22.355 +                    # destroys a domain beneath us.  We clean up the domain,
  22.356 +                    # just in case, but we can't clean up the VM, because that
  22.357 +                    # VM may have migrated to a different domain on this
  22.358 +                    # machine.
  22.359                      self.cleanupDomain()
  22.360 -                    self.cleanupVm()
  22.361                      return
  22.362  
  22.363              if xeninfo['dying']:
  22.364                  # Dying means that a domain has been destroyed, but has not
  22.365 -                # yet been cleaned up by Xen.  This could persist indefinitely
  22.366 -                # if, for example, another domain has some of its pages
  22.367 -                # mapped.  We might like to diagnose this problem in the
  22.368 -                # future, but for now all we do is make sure that it's not
  22.369 -                # us holding the pages, by calling the cleanup methods.
  22.370 +                # yet been cleaned up by Xen.  This state could persist
  22.371 +                # indefinitely if, for example, another domain has some of its
  22.372 +                # pages mapped.  We might like to diagnose this problem in the
  22.373 +                # future, but for now all we do is make sure that it's not us
  22.374 +                # holding the pages, by calling cleanupDomain.  We can't
  22.375 +                # clean up the VM, as above.
  22.376                  self.cleanupDomain()
  22.377 -                self.cleanupVm()
  22.378                  return
  22.379  
  22.380              elif xeninfo['crashed']:
  22.381 @@ -654,10 +651,11 @@ class XendDomainInfo:
  22.382                  restart_reason = 'crash'
  22.383  
  22.384              elif xeninfo['shutdown']:
  22.385 -                if self.readDom('xend/shutdown'):
  22.386 +                if self.readDom('xend/shutdown_completed'):
  22.387                      # We've seen this shutdown already, but we are preserving
  22.388                      # the domain for debugging.  Leave it alone.
  22.389 -                    pass
  22.390 +                    return
  22.391 +
  22.392                  else:
  22.393                      reason = shutdown_reason(xeninfo['shutdown_reason'])
  22.394  
  22.395 @@ -667,7 +665,7 @@ class XendDomainInfo:
  22.396                      self.clearRestart()
  22.397  
  22.398                      if reason == 'suspend':
  22.399 -                        self.state_set(STATE_VM_SUSPENDED)
  22.400 +                        self.state_set(STATE_VM_TERMINATED)
  22.401                          # Don't destroy the domain.  XendCheckpoint will do
  22.402                          # this once it has finished.
  22.403                      elif reason in ['poweroff', 'reboot']:
  22.404 @@ -704,7 +702,7 @@ class XendDomainInfo:
  22.405          if not reason in shutdown_reasons.values():
  22.406              raise XendError('invalid reason:' + reason)
  22.407          self.storeDom("control/shutdown", reason)
  22.408 -        if not reason == 'suspend':
  22.409 +        if reason != 'suspend':
  22.410              self.storeDom('xend/shutdown_start_time', time.time())
  22.411  
  22.412  
  22.413 @@ -723,11 +721,6 @@ class XendDomainInfo:
  22.414           "rename-restart" : self.renameRestart}[self.info['on_' + reason]]()
  22.415  
  22.416  
  22.417 -    def preserve(self):
  22.418 -        log.info("Preserving dead domain %s (%d).", self.info['name'],
  22.419 -                 self.domid)
  22.420 -
  22.421 -
  22.422      def renameRestart(self):
  22.423          self.restart(True)
  22.424  
  22.425 @@ -817,9 +810,9 @@ class XendDomainInfo:
  22.426  
  22.427      ## public:
  22.428  
  22.429 -    def state_wait(self, state):
  22.430 +    def waitForShutdown(self):
  22.431          self.state_updated.acquire()
  22.432 -        while self.state != state:
  22.433 +        while self.state == STATE_VM_OK:
  22.434              self.state_updated.wait()
  22.435          self.state_updated.release()
  22.436  
  22.437 @@ -953,10 +946,8 @@ class XendDomainInfo:
  22.438              if c in '_-.:/+': continue
  22.439              if c in string.ascii_letters: continue
  22.440              raise VmError('invalid vm name')
  22.441 -        dominfo = domain_exists(name)
  22.442 -        # When creating or rebooting, a domain with my name should not exist.
  22.443 -        # When restoring, a domain with my name will exist, but it should have
  22.444 -        # my domain id.
  22.445 +
  22.446 +        dominfo = domain_by_name(name)
  22.447          if not dominfo:
  22.448              return
  22.449          if dominfo.is_terminated():
  22.450 @@ -1059,7 +1050,6 @@ class XendDomainInfo:
  22.451          """Cleanup domain resources; release devices.  Idempotent.  Nothrow
  22.452          guarantee."""
  22.453  
  22.454 -        self.state_set(STATE_VM_TERMINATED)
  22.455          self.release_devices()
  22.456          self.closeStoreChannel()
  22.457          self.closeConsoleChannel()
  22.458 @@ -1092,8 +1082,14 @@ class XendDomainInfo:
  22.459  
  22.460          log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
  22.461  
  22.462 +        self.cleanupVm()
  22.463 +        self.destroyDomain()
  22.464 +
  22.465 +
  22.466 +    def destroyDomain(self):
  22.467 +        log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
  22.468 +
  22.469          self.cleanupDomain()
  22.470 -        self.cleanupVm()
  22.471          
  22.472          try:
  22.473              if self.domid is not None:
  22.474 @@ -1101,6 +1097,8 @@ class XendDomainInfo:
  22.475          except Exception:
  22.476              log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
  22.477  
  22.478 +        self.state_set(STATE_VM_TERMINATED)
  22.479 +
  22.480  
  22.481      ## private:
  22.482  
  22.483 @@ -1248,14 +1246,18 @@ class XendDomainInfo:
  22.484  
  22.485          try:
  22.486              if rename:
  22.487 -                self.preserveShutdownDomain()
  22.488 +                self.preserveForRestart()
  22.489              else:
  22.490 -                self.cleanupDomain()
  22.491                  self.destroy()
  22.492                  
  22.493              try:
  22.494                  xd = get_component('xen.xend.XendDomain')
  22.495 -                xd.domain_unpause(xd.domain_create(config).getDomid())
  22.496 +                new_dom = xd.domain_create(config)
  22.497 +                try:
  22.498 +                    xc.domain_unpause(new_dom.getDomid())
  22.499 +                except:
  22.500 +                    new_dom.destroy()
  22.501 +                    raise
  22.502              except Exception, exn:
  22.503                  log.exception('Failed to restart domain %d.', self.domid)
  22.504          finally:
  22.505 @@ -1265,7 +1267,7 @@ class XendDomainInfo:
  22.506          #        self.exportToDB()
  22.507  
  22.508  
  22.509 -    def preserveShutdownDomain(self):
  22.510 +    def preserveForRestart(self):
  22.511          """Preserve a domain that has been shut down, by giving it a new UUID,
  22.512          cloning the VM details, and giving it a new name.  This allows us to
  22.513          keep this domain for debugging, but restart a new one in its place
  22.514 @@ -1281,8 +1283,14 @@ class XendDomainInfo:
  22.515          self.uuid = new_uuid
  22.516          self.vmpath = VMROOT + new_uuid
  22.517          self.storeVmDetails()
  22.518 -        self.storeDom('vm', self.vmpath)
  22.519 -        self.storeDom('xend/shutdown', 'True')
  22.520 +        self.preserve()
  22.521 +
  22.522 +
  22.523 +    def preserve(self):
  22.524 +        log.info("Preserving dead domain %s (%d).", self.info['name'],
  22.525 +                 self.domid)
  22.526 +        self.storeDom('xend/shutdown_completed', 'True')
  22.527 +        self.set_state(STATE_VM_TERMINATED)
  22.528  
  22.529  
  22.530      def generateShutdownName(self):
    23.1 --- a/tools/python/xen/xend/server/DevController.py	Mon Oct 03 16:40:27 2005 +0100
    23.2 +++ b/tools/python/xen/xend/server/DevController.py	Tue Oct 04 14:22:30 2005 +0100
    23.3 @@ -189,8 +189,17 @@ class DevController:
    23.4          """
    23.5  
    23.6          import xen.xend.XendDomain
    23.7 -        backdom = xen.xend.XendDomain.instance().domain_lookup_by_name(
    23.8 -            sxp.child_value(config, 'backend', '0'))
    23.9 +        xd = xen.xend.XendDomain.instance()
   23.10 +
   23.11 +        backdom_name = sxp.child_value(config, 'backend')
   23.12 +        if backdom_name:
   23.13 +            backdom = xd.domain_lookup_by_name_or_id_nr(backdom_name)
   23.14 +        else:
   23.15 +            backdom = xd.privilegedDomain()
   23.16 +
   23.17 +        if not backdom:
   23.18 +            raise VmError("Cannot configure device for unknown backend %s" %
   23.19 +                          backdom_name)
   23.20  
   23.21          frontpath = self.frontendPath(devid)
   23.22          backpath  = self.backendPath(backdom, devid)
   23.23 @@ -221,7 +230,7 @@ class DevController:
   23.24  
   23.25          return "%s/backend/%s/%s/%d" % (backdom.getDomainPath(),
   23.26                                          self.deviceClass,
   23.27 -                                        self.vm.getUuid(), devid)
   23.28 +                                        self.vm.getDomid(), devid)
   23.29  
   23.30  
   23.31      def frontendPath(self, devid):
    24.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Mon Oct 03 16:40:27 2005 +0100
    24.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Tue Oct 04 14:22:30 2005 +0100
    24.3 @@ -38,7 +38,7 @@ class SrvDomainDir(SrvDir):
    24.4          self.xd = XendDomain.instance()
    24.5  
    24.6      def domain(self, x):
    24.7 -        dom = self.xd.domain_lookup_by_name(x)
    24.8 +        dom = self.xd.domain_lookup_by_name_or_id(x)
    24.9          if not dom:
   24.10              raise XendError('No such domain ' + str(x))
   24.11          return SrvDomain(dom)
    25.1 --- a/tools/python/xen/xend/server/relocate.py	Mon Oct 03 16:40:27 2005 +0100
    25.2 +++ b/tools/python/xen/xend/server/relocate.py	Tue Oct 04 14:22:30 2005 +0100
    25.3 @@ -28,7 +28,6 @@ from xen.xend import EventServer
    25.4  from xen.xend.XendError import XendError
    25.5  from xen.xend import XendRoot
    25.6  from xen.xend.XendLogging import log
    25.7 -from xen.xend import XendCheckpoint
    25.8  
    25.9  
   25.10  eserver = EventServer.instance()
   25.11 @@ -120,7 +119,8 @@ class RelocationProtocol(protocol.Protoc
   25.12          if self.transport:
   25.13              self.send_reply(["ready", name])
   25.14              self.transport.sock.setblocking(1)
   25.15 -            XendCheckpoint.restore(self.transport.sock.fileno())
   25.16 +            xd = xroot.get_component("xen.xend.XendDomain")
   25.17 +            xd.domain_restore_fd(self.transport.sock.fileno())
   25.18              self.transport.sock.setblocking(0)
   25.19          else:
   25.20              log.error(name + ": no transport")
    26.1 --- a/xen/arch/x86/x86_32/entry.S	Mon Oct 03 16:40:27 2005 +0100
    26.2 +++ b/xen/arch/x86/x86_32/entry.S	Tue Oct 04 14:22:30 2005 +0100
    26.3 @@ -808,7 +808,7 @@ ENTRY(hypercall_table)
    26.4          .long do_vm_assist
    26.5          .long do_update_va_mapping_otherdomain
    26.6          .long do_switch_vm86
    26.7 -        .long do_boot_vcpu
    26.8 +        .long do_vcpu_op
    26.9          .long do_ni_hypercall       /* 25 */
   26.10          .long do_mmuext_op
   26.11          .long do_acm_op             /* 27 */
   26.12 @@ -841,7 +841,7 @@ ENTRY(hypercall_args_table)
   26.13          .byte 2 /* do_vm_assist         */
   26.14          .byte 5 /* do_update_va_mapping_otherdomain */
   26.15          .byte 0 /* do_switch_vm86       */
   26.16 -        .byte 2 /* do_boot_vcpu         */
   26.17 +        .byte 3 /* do_vcpu_op           */
   26.18          .byte 0 /* do_ni_hypercall      */  /* 25 */
   26.19          .byte 4 /* do_mmuext_op         */
   26.20          .byte 1 /* do_acm_op            */
    27.1 --- a/xen/arch/x86/x86_64/entry.S	Mon Oct 03 16:40:27 2005 +0100
    27.2 +++ b/xen/arch/x86/x86_64/entry.S	Tue Oct 04 14:22:30 2005 +0100
    27.3 @@ -629,7 +629,7 @@ ENTRY(hypercall_table)
    27.4          .quad do_vm_assist
    27.5          .quad do_update_va_mapping_otherdomain
    27.6          .quad do_switch_to_user
    27.7 -        .quad do_boot_vcpu
    27.8 +        .quad do_vcpu_op
    27.9          .quad do_set_segment_base   /* 25 */
   27.10          .quad do_mmuext_op
   27.11          .quad do_acm_op
   27.12 @@ -662,7 +662,7 @@ ENTRY(hypercall_args_table)
   27.13          .byte 2 /* do_vm_assist         */
   27.14          .byte 4 /* do_update_va_mapping_otherdomain */
   27.15          .byte 0 /* do_switch_to_user    */
   27.16 -        .byte 2 /* do_boot_vcpu         */
   27.17 +        .byte 3 /* do_vcpu_op           */
   27.18          .byte 2 /* do_set_segment_base  */  /* 25 */
   27.19          .byte 4 /* do_mmuext_op         */
   27.20          .byte 1 /* do_acm_op            */
    28.1 --- a/xen/common/domain.c	Mon Oct 03 16:40:27 2005 +0100
    28.2 +++ b/xen/common/domain.c	Tue Oct 04 14:22:30 2005 +0100
    28.3 @@ -18,6 +18,7 @@
    28.4  #include <xen/domain_page.h>
    28.5  #include <asm/debugger.h>
    28.6  #include <public/dom0_ops.h>
    28.7 +#include <public/vcpu.h>
    28.8  
    28.9  /* Both these structures are protected by the domlist_lock. */
   28.10  rwlock_t domlist_lock = RW_LOCK_UNLOCKED;
   28.11 @@ -366,37 +367,17 @@ int set_info_guest(struct domain *d, dom
   28.12      return rc;
   28.13  }
   28.14  
   28.15 -/*
   28.16 - * final_setup_guest is used for final setup and launching of domains other
   28.17 - * than domain 0. ie. the domains that are being built by the userspace dom0
   28.18 - * domain builder.
   28.19 - */
   28.20 -long do_boot_vcpu(unsigned long vcpu, struct vcpu_guest_context *ctxt) 
   28.21 +int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) 
   28.22  {
   28.23 -    struct domain *d = current->domain;
   28.24      struct vcpu *v;
   28.25 -    int rc = 0;
   28.26 -    struct vcpu_guest_context *c;
   28.27 +    int rc;
   28.28  
   28.29 -    if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] != NULL) )
   28.30 -        return -EINVAL;
   28.31 +    ASSERT(d->vcpu[vcpuid] == NULL);
   28.32  
   28.33 -    if ( alloc_vcpu_struct(d, vcpu) == NULL )
   28.34 +    if ( alloc_vcpu_struct(d, vcpuid) == NULL )
   28.35          return -ENOMEM;
   28.36  
   28.37 -    if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
   28.38 -    {
   28.39 -        rc = -ENOMEM;
   28.40 -        goto out;
   28.41 -    }
   28.42 -
   28.43 -    if ( copy_from_user(c, ctxt, sizeof(*c)) )
   28.44 -    {
   28.45 -        rc = -EFAULT;
   28.46 -        goto out;
   28.47 -    }
   28.48 -
   28.49 -    v = d->vcpu[vcpu];
   28.50 +    v = d->vcpu[vcpuid];
   28.51  
   28.52      atomic_set(&v->pausecnt, 0);
   28.53      v->cpumap = CPUMAP_RUNANYWHERE;
   28.54 @@ -405,22 +386,73 @@ long do_boot_vcpu(unsigned long vcpu, st
   28.55  
   28.56      arch_do_boot_vcpu(v);
   28.57  
   28.58 -    if ( (rc = arch_set_info_guest(v, c)) != 0 )
   28.59 +    if ( (rc = arch_set_info_guest(v, ctxt)) != 0 )
   28.60          goto out;
   28.61  
   28.62      sched_add_domain(v);
   28.63  
   28.64 -    /* domain_unpause_by_systemcontroller */
   28.65 -    if ( test_and_clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) )
   28.66 -        vcpu_wake(v);
   28.67 +    set_bit(_VCPUF_down, &v->vcpu_flags);
   28.68 +    clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
   28.69  
   28.70 -    xfree(c);
   28.71      return 0;
   28.72  
   28.73   out:
   28.74 -    xfree(c);
   28.75 -    arch_free_vcpu_struct(d->vcpu[vcpu]);
   28.76 -    d->vcpu[vcpu] = NULL;
   28.77 +    arch_free_vcpu_struct(d->vcpu[vcpuid]);
   28.78 +    d->vcpu[vcpuid] = NULL;
   28.79 +    return rc;
   28.80 +}
   28.81 +
   28.82 +long do_vcpu_op(int cmd, int vcpuid, void *arg)
   28.83 +{
   28.84 +    struct domain *d = current->domain;
   28.85 +    struct vcpu *v;
   28.86 +    struct vcpu_guest_context *ctxt;
   28.87 +    long rc = 0;
   28.88 +
   28.89 +    if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
   28.90 +        return -EINVAL;
   28.91 +
   28.92 +    if ( ((v = d->vcpu[vcpuid]) == NULL) && (cmd != VCPUOP_create) )
   28.93 +        return -ENOENT;
   28.94 +
   28.95 +    switch ( cmd )
   28.96 +    {
   28.97 +    case VCPUOP_create:
   28.98 +        if ( (ctxt = xmalloc(struct vcpu_guest_context)) == NULL )
   28.99 +        {
  28.100 +            rc = -ENOMEM;
  28.101 +            break;
  28.102 +        }
  28.103 +
  28.104 +        if ( copy_from_user(ctxt, arg, sizeof(*ctxt)) )
  28.105 +        {
  28.106 +            xfree(ctxt);
  28.107 +            rc = -EFAULT;
  28.108 +            break;
  28.109 +        }
  28.110 +
  28.111 +        LOCK_BIGLOCK(d);
  28.112 +        rc = (d->vcpu[vcpuid] == NULL) ? boot_vcpu(d, vcpuid, ctxt) : -EEXIST;
  28.113 +        UNLOCK_BIGLOCK(d);
  28.114 +
  28.115 +        xfree(ctxt);
  28.116 +        break;
  28.117 +
  28.118 +    case VCPUOP_up:
  28.119 +        if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
  28.120 +            vcpu_wake(v);
  28.121 +        break;
  28.122 +
  28.123 +    case VCPUOP_down:
  28.124 +        if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
  28.125 +            vcpu_sleep_nosync(v);
  28.126 +        break;
  28.127 +
  28.128 +    case VCPUOP_is_up:
  28.129 +        rc = !test_bit(_VCPUF_down, &v->vcpu_flags);
  28.130 +        break;
  28.131 +    }
  28.132 +
  28.133      return rc;
  28.134  }
  28.135  
    29.1 --- a/xen/common/sched_sedf.c	Mon Oct 03 16:40:27 2005 +0100
    29.2 +++ b/xen/common/sched_sedf.c	Tue Oct 04 14:22:30 2005 +0100
    29.3 @@ -500,9 +500,15 @@ static inline void update_queues(s_time_
    29.4                    curinf->vcpu->domain->domain_id,
    29.5                    curinf->vcpu->vcpu_id);
    29.6              __del_from_queue(curinf->vcpu);
    29.7 -   
    29.8 +
    29.9              /*move them to their next period*/
   29.10              curinf->deadl_abs += curinf->period;
   29.11 +            /*ensure that the start of the next period is in the future*/
   29.12 +            if (unlikely(PERIOD_BEGIN(curinf) < now)) {
   29.13 +                curinf->deadl_abs += 
   29.14 +                    (DIV_UP(now - PERIOD_BEGIN(curinf),
   29.15 +                           curinf->period)) * curinf->period;
   29.16 +            }
   29.17              /*and put them back into the queue*/
   29.18              __add_to_waitqueue_sort(curinf->vcpu);
   29.19              continue;
   29.20 @@ -645,7 +651,7 @@ static inline struct task_slice sedf_do_
   29.21                                                          s_time_t end_xt, struct list_head *extraq[], int cpu) {
   29.22      struct task_slice   ret;
   29.23      struct sedf_vcpu_info *runinf;
   29.24 - 
   29.25 +    ASSERT(end_xt > now);
   29.26      /* Enough time left to use for extratime? */
   29.27      if (end_xt - now < EXTRA_QUANTUM)
   29.28          goto return_idle;
    30.1 --- a/xen/common/schedule.c	Mon Oct 03 16:40:27 2005 +0100
    30.2 +++ b/xen/common/schedule.c	Tue Oct 04 14:22:30 2005 +0100
    30.3 @@ -270,69 +270,6 @@ static long do_yield(void)
    30.4      return 0;
    30.5  }
    30.6  
    30.7 -/* Mark target vcpu as non-runnable so it is not scheduled */
    30.8 -static long do_vcpu_down(int vcpu)
    30.9 -{
   30.10 -    struct vcpu *target;
   30.11 -    
   30.12 -    if ( vcpu > MAX_VIRT_CPUS )
   30.13 -        return -EINVAL;
   30.14 -
   30.15 -    target = current->domain->vcpu[vcpu];
   30.16 -    if ( target == NULL )
   30.17 -        return -ESRCH;
   30.18 -    set_bit(_VCPUF_down, &target->vcpu_flags);
   30.19 -
   30.20 -    return 0;
   30.21 -}
   30.22 -
   30.23 -/* Mark target vcpu as runnable and wake it */
   30.24 -static long do_vcpu_up(int vcpu)
   30.25 -{
   30.26 -    struct vcpu *target;
   30.27 -   
   30.28 -    if (vcpu > MAX_VIRT_CPUS)
   30.29 -        return -EINVAL;
   30.30 -
   30.31 -    target = current->domain->vcpu[vcpu];
   30.32 -    if ( target == NULL )
   30.33 -        return -ESRCH;
   30.34 -    clear_bit(_VCPUF_down, &target->vcpu_flags);
   30.35 -    /* wake vcpu */
   30.36 -    vcpu_wake(target);
   30.37 -
   30.38 -    return 0;
   30.39 -}
   30.40 -
   30.41 -static long do_vcpu_pickle(int vcpu, unsigned long arg)
   30.42 -{
   30.43 -    struct vcpu *v;
   30.44 -    vcpu_guest_context_t *c;
   30.45 -    int ret = 0;
   30.46 -
   30.47 -    if (vcpu >= MAX_VIRT_CPUS)
   30.48 -        return -EINVAL;
   30.49 -    v = current->domain->vcpu[vcpu];
   30.50 -    if (!v)
   30.51 -        return -ESRCH;
   30.52 -    /* Don't pickle vcpus which are currently running */
   30.53 -    if (!test_bit(_VCPUF_down, &v->vcpu_flags)) {
   30.54 -        return -EBUSY;
   30.55 -    }
   30.56 -    c = xmalloc(vcpu_guest_context_t);
   30.57 -    if (!c)
   30.58 -        return -ENOMEM;
   30.59 -    arch_getdomaininfo_ctxt(v, c);
   30.60 -    if (copy_to_user((vcpu_guest_context_t *)arg,
   30.61 -                     (const vcpu_guest_context_t *)c, sizeof(*c)))
   30.62 -        ret = -EFAULT;
   30.63 -    xfree(c);
   30.64 -    return ret;
   30.65 -}
   30.66 -
   30.67 -/*
   30.68 - * Demultiplex scheduler-related hypercalls.
   30.69 - */
   30.70  long do_sched_op(unsigned long op, unsigned long arg)
   30.71  {
   30.72      long ret = 0;
   30.73 @@ -359,21 +296,6 @@ long do_sched_op(unsigned long op, unsig
   30.74          domain_shutdown((u8)(op >> SCHEDOP_reasonshift));
   30.75          break;
   30.76      }
   30.77 -    case SCHEDOP_vcpu_down:
   30.78 -    {
   30.79 -        ret = do_vcpu_down((int)(op >> SCHEDOP_vcpushift));
   30.80 -        break;
   30.81 -    }
   30.82 -    case SCHEDOP_vcpu_up:
   30.83 -    {
   30.84 -        ret = do_vcpu_up((int)(op >> SCHEDOP_vcpushift));
   30.85 -        break;
   30.86 -    }
   30.87 -    case SCHEDOP_vcpu_pickle:
   30.88 -    {
   30.89 -        ret = do_vcpu_pickle((int)(op >> SCHEDOP_vcpushift), arg);
   30.90 -        break;
   30.91 -    }
   30.92  
   30.93      default:
   30.94          ret = -ENOSYS;
   30.95 @@ -395,8 +317,8 @@ long do_set_timer_op(s_time_t timeout)
   30.96      return 0;
   30.97  }
   30.98  
   30.99 -/** sched_id - fetch ID of current scheduler */
  30.100 -int sched_id()
  30.101 +/* sched_id - fetch ID of current scheduler */
  30.102 +int sched_id(void)
  30.103  {
  30.104      return ops.sched_id;
  30.105  }
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/xen/include/public/vcpu.h	Tue Oct 04 14:22:30 2005 +0100
    31.3 @@ -0,0 +1,55 @@
    31.4 +/******************************************************************************
    31.5 + * vcpu.h
    31.6 + * 
    31.7 + * VCPU creation and hotplug.
    31.8 + * 
    31.9 + * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
   31.10 + */
   31.11 +
   31.12 +#ifndef __XEN_PUBLIC_VCPU_H__
   31.13 +#define __XEN_PUBLIC_VCPU_H__
   31.14 +
   31.15 +/*
   31.16 + * Prototype for this hypercall is:
   31.17 + *  int vcpu_op(int cmd, int vcpuid, void *extra_args)
   31.18 + * @cmd        == VCPUOP_??? (VCPU operation).
   31.19 + * @vcpuid     == VCPU to operate on.
   31.20 + * @extra_args == Operation-specific extra arguments (NULL if none).
   31.21 + */
   31.22 +
   31.23 +/*
   31.24 + * Create a new VCPU. This must be called before a VCPU can be referred to
   31.25 + * in any other hypercall (e.g., to bind event channels). The new VCPU
   31.26 + * will not run until it is brought up by VCPUOP_up.
   31.27 + * 
   31.28 + * @extra_arg == pointer to vcpu_guest_context structure containing initial
   31.29 + *               state for the new VCPU.
   31.30 + */
   31.31 +#define VCPUOP_create               0
   31.32 +
   31.33 +/*
   31.34 + * Bring up a newly-created or previously brought-down VCPU. This makes the
   31.35 + * VCPU runnable.
   31.36 + */
   31.37 +#define VCPUOP_up                   1
   31.38 +
   31.39 +/*
   31.40 + * Bring down a VCPU (i.e., make it non-runnable).
   31.41 + * There are a few caveats that callers should observe:
   31.42 + *  1. This operation may return, and VCPU_is_up may return false, before the
   31.43 + *     VCPU stops running (i.e., the command is asynchronous). It is a good
   31.44 + *     idea to ensure that the VCPU has entered a non-critical loop before
   31.45 + *     bringing it down. Alternatively, this operation is guaranteed
   31.46 + *     synchronous if invoked by the VCPU itself.
   31.47 + *  2. After a VCPU is created, there is currently no way to drop all its
   31.48 + *     references to domain memory. Even a VCPU that is down still holds
   31.49 + *     memory references via its pagetable base pointer and GDT. It is good
   31.50 + *     practise to move a VCPU onto an 'idle' or default page table, LDT and
   31.51 + *     GDT before bringing it down.
   31.52 + */
   31.53 +#define VCPUOP_down                 2
   31.54 +
   31.55 +/* Returns 1 if the given VCPU is up. */
   31.56 +#define VCPUOP_is_up                3
   31.57 +
   31.58 +#endif /* __XEN_PUBLIC_VCPU_H__ */
    32.1 --- a/xen/include/public/xen.h	Mon Oct 03 16:40:27 2005 +0100
    32.2 +++ b/xen/include/public/xen.h	Tue Oct 04 14:22:30 2005 +0100
    32.3 @@ -55,7 +55,7 @@
    32.4  #define __HYPERVISOR_update_va_mapping_otherdomain 22
    32.5  #define __HYPERVISOR_switch_vm86          23 /* x86/32 only */
    32.6  #define __HYPERVISOR_switch_to_user       23 /* x86/64 only */
    32.7 -#define __HYPERVISOR_boot_vcpu            24
    32.8 +#define __HYPERVISOR_vcpu_op              24
    32.9  #define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
   32.10  #define __HYPERVISOR_mmuext_op            26
   32.11  #define __HYPERVISOR_acm_op               27
   32.12 @@ -201,12 +201,8 @@ struct mmuext_op {
   32.13  #define SCHEDOP_yield           0   /* Give up the CPU voluntarily.       */
   32.14  #define SCHEDOP_block           1   /* Block until an event is received.  */
   32.15  #define SCHEDOP_shutdown        2   /* Stop executing this domain.        */
   32.16 -#define SCHEDOP_vcpu_down       3   /* make target VCPU not-runnable.     */
   32.17 -#define SCHEDOP_vcpu_up         4   /* make target VCPU runnable.         */
   32.18 -#define SCHEDOP_vcpu_pickle     5   /* save a vcpu's context to memory.   */
   32.19  #define SCHEDOP_cmdmask       255   /* 8-bit command. */
   32.20  #define SCHEDOP_reasonshift     8   /* 8-bit reason code. (SCHEDOP_shutdown) */
   32.21 -#define SCHEDOP_vcpushift       8   /* 8-bit VCPU target. (SCHEDOP_up|down) */
   32.22  
   32.23  /*
   32.24   * Reason codes for SCHEDOP_shutdown. These may be interpreted by control