From 02bf186308257db22c05f69db3bc9fd261c273cc Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 16 Aug 2005 18:02:24 +0000 Subject: [PATCH 01/21] Fix context switching race which could cause vcpu_pause() to not actually do its job properly. This requires us to move clearing of VCPUF_running to be protected by the scheduler lock. Signed-off-by: Keir Fraser --- xen/arch/ia64/xenmisc.c | 31 +++---- xen/arch/x86/domain.c | 156 ++++++++++++++++++++------------- xen/arch/x86/vmx.c | 2 +- xen/common/schedule.c | 15 ++-- xen/include/asm-x86/vmx_vmcs.h | 4 +- xen/include/xen/sched.h | 24 ++++- 6 files changed, 140 insertions(+), 92 deletions(-) diff --git a/xen/arch/ia64/xenmisc.c b/xen/arch/ia64/xenmisc.c index 1f2b9c423d..6a79cd9b0b 100644 --- a/xen/arch/ia64/xenmisc.c +++ b/xen/arch/ia64/xenmisc.c @@ -280,7 +280,6 @@ void cs01foo(void) {} unsigned long context_switch_count = 0; -// context_switch void context_switch(struct vcpu *prev, struct vcpu *next) { //printk("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); @@ -290,22 +289,14 @@ void context_switch(struct vcpu *prev, struct vcpu *next) //if (prev->domain->domain_id == 0 && next->domain->domain_id == 1) cs01foo(); //printk("@@sw %d->%d\n",prev->domain->domain_id,next->domain->domain_id); #ifdef CONFIG_VTI - unsigned long psr; - /* Interrupt is enabled after next task is chosen. - * So we have to disable it for stack switch. - */ - local_irq_save(psr); vtm_domain_out(prev); - /* Housekeeping for prev domain */ -#endif // CONFIG_VTI - +#endif context_switch_count++; switch_to(prev,next,prev); #ifdef CONFIG_VTI - /* Post-setup for new domain */ vtm_domain_in(current); - local_irq_restore(psr); -#endif // CONFIG_VTI +#endif + // leave this debug for now: it acts as a heartbeat when more than // one domain is active { @@ -315,25 +306,27 @@ int id = ((struct vcpu *)current)->domain->domain_id & 0xf; if (!cnt[id]--) { printk("%x",id); cnt[id] = 500000; } if (!i--) { printk("+",id); i = 1000000; } } - clear_bit(_VCPUF_running, &prev->vcpu_flags); - //if (!is_idle_task(next->domain) ) - //send_guest_virq(next, VIRQ_TIMER); + #ifdef CONFIG_VTI if (VMX_DOMAIN(current)) vmx_load_all_rr(current); - return; -#else // CONFIG_VTI +#else if (!is_idle_task(current->domain)) { load_region_regs(current); if (vcpu_timer_expired(current)) vcpu_pend_timer(current); } if (vcpu_timer_expired(current)) vcpu_pend_timer(current); -#endif // CONFIG_VTI +#endif +} + +void context_switch_finalise(struct vcpu *next) +{ + /* nothing to do */ } void continue_running(struct vcpu *same) { - /* nothing to do */ + /* nothing to do */ } void panic_domain(struct pt_regs *regs, const char *fmt, ...) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 598c2095ee..7df964347b 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -48,6 +48,8 @@ boolean_param("noreboot", opt_noreboot); struct percpu_ctxt { struct vcpu *curr_vcpu; + unsigned int context_not_finalised; + unsigned int dirty_segment_mask; } __cacheline_aligned; static struct percpu_ctxt percpu_ctxt[NR_CPUS]; @@ -541,51 +543,59 @@ void toggle_guest_mode(struct vcpu *v) __r; }) #if CONFIG_VMX -#define load_msrs(_p, _n) if (vmx_switch_on) vmx_load_msrs((_p), (_n)) +#define load_msrs(n) if (vmx_switch_on) vmx_load_msrs(n) #else -#define load_msrs(_p, _n) ((void)0) +#define load_msrs(n) ((void)0) #endif -static void load_segments(struct vcpu *p, struct vcpu *n) +/* + * save_segments() writes a mask of segments which are dirty (non-zero), + * allowing load_segments() to avoid some expensive segment loads and + * MSR writes. + */ +#define DIRTY_DS 0x01 +#define DIRTY_ES 0x02 +#define DIRTY_FS 0x04 +#define DIRTY_GS 0x08 +#define DIRTY_FS_BASE 0x10 +#define DIRTY_GS_BASE_USER 0x20 + +static void load_segments(struct vcpu *n) { - struct vcpu_guest_context *pctxt = &p->arch.guest_context; struct vcpu_guest_context *nctxt = &n->arch.guest_context; int all_segs_okay = 1; + unsigned int dirty_segment_mask, cpu = smp_processor_id(); + + /* Load and clear the dirty segment mask. */ + dirty_segment_mask = percpu_ctxt[cpu].dirty_segment_mask; + percpu_ctxt[cpu].dirty_segment_mask = 0; /* Either selector != 0 ==> reload. */ - if ( unlikely(pctxt->user_regs.ds | nctxt->user_regs.ds) ) + if ( unlikely((dirty_segment_mask & DIRTY_DS) | nctxt->user_regs.ds) ) all_segs_okay &= loadsegment(ds, nctxt->user_regs.ds); /* Either selector != 0 ==> reload. */ - if ( unlikely(pctxt->user_regs.es | nctxt->user_regs.es) ) + if ( unlikely((dirty_segment_mask & DIRTY_ES) | nctxt->user_regs.es) ) all_segs_okay &= loadsegment(es, nctxt->user_regs.es); /* * Either selector != 0 ==> reload. * Also reload to reset FS_BASE if it was non-zero. */ - if ( unlikely(pctxt->user_regs.fs | - pctxt->fs_base | + if ( unlikely((dirty_segment_mask & (DIRTY_FS | DIRTY_FS_BASE)) | nctxt->user_regs.fs) ) - { all_segs_okay &= loadsegment(fs, nctxt->user_regs.fs); - if ( pctxt->user_regs.fs ) /* != 0 selector kills fs_base */ - pctxt->fs_base = 0; - } /* * Either selector != 0 ==> reload. * Also reload to reset GS_BASE if it was non-zero. */ - if ( unlikely(pctxt->user_regs.gs | - pctxt->gs_base_user | + if ( unlikely((dirty_segment_mask & (DIRTY_GS | DIRTY_GS_BASE_USER)) | nctxt->user_regs.gs) ) { /* Reset GS_BASE with user %gs? */ - if ( pctxt->user_regs.gs || !nctxt->gs_base_user ) + if ( (dirty_segment_mask & DIRTY_GS) || !nctxt->gs_base_user ) all_segs_okay &= loadsegment(gs, nctxt->user_regs.gs); - if ( pctxt->user_regs.gs ) /* != 0 selector kills gs_base_user */ - pctxt->gs_base_user = 0; } /* This can only be non-zero if selector is NULL. */ @@ -650,7 +660,9 @@ static void load_segments(struct vcpu *p, struct vcpu *n) static void save_segments(struct vcpu *v) { - struct cpu_user_regs *regs = &v->arch.guest_context.user_regs; + struct vcpu_guest_context *ctxt = &v->arch.guest_context; + struct cpu_user_regs *regs = &ctxt->user_regs; + unsigned int dirty_segment_mask = 0; if ( VMX_DOMAIN(v) ) rdmsrl(MSR_SHADOW_GS_BASE, v->arch.arch_vmx.msr_content.shadow_gs); @@ -659,18 +671,34 @@ static void save_segments(struct vcpu *v) __asm__ __volatile__ ( "movl %%es,%0" : "=m" (regs->es) ); __asm__ __volatile__ ( "movl %%fs,%0" : "=m" (regs->fs) ); __asm__ __volatile__ ( "movl %%gs,%0" : "=m" (regs->gs) ); -} -static void clear_segments(void) -{ - __asm__ __volatile__ ( - " movl %0,%%ds; " - " movl %0,%%es; " - " movl %0,%%fs; " - " movl %0,%%gs; " - ""safe_swapgs" " - " movl %0,%%gs" - : : "r" (0) ); + if ( regs->ds ) + dirty_segment_mask |= DIRTY_DS; + + if ( regs->es ) + dirty_segment_mask |= DIRTY_ES; + + if ( regs->fs ) + { + dirty_segment_mask |= DIRTY_FS; + ctxt->fs_base = 0; /* != 0 selector kills fs_base */ + } + else if ( ctxt->fs_base ) + { + dirty_segment_mask |= DIRTY_FS_BASE; + } + + if ( regs->gs ) + { + dirty_segment_mask |= DIRTY_GS; + ctxt->gs_base_user = 0; /* != 0 selector kills gs_base_user */ + } + else if ( ctxt->gs_base_user ) + { + dirty_segment_mask |= DIRTY_GS_BASE_USER; + } + + percpu_ctxt[smp_processor_id()].dirty_segment_mask = dirty_segment_mask; } long do_switch_to_user(void) @@ -706,10 +734,9 @@ long do_switch_to_user(void) #elif defined(__i386__) -#define load_segments(_p, _n) ((void)0) -#define load_msrs(_p, _n) ((void)0) -#define save_segments(_p) ((void)0) -#define clear_segments() ((void)0) +#define load_segments(n) ((void)0) +#define load_msrs(n) ((void)0) +#define save_segments(p) ((void)0) static inline void switch_kernel_stack(struct vcpu *n, unsigned int cpu) { @@ -726,9 +753,9 @@ static inline void switch_kernel_stack(struct vcpu *n, unsigned int cpu) static void __context_switch(void) { struct cpu_user_regs *stack_regs = guest_cpu_user_regs(); - unsigned int cpu = smp_processor_id(); - struct vcpu *p = percpu_ctxt[cpu].curr_vcpu; - struct vcpu *n = current; + unsigned int cpu = smp_processor_id(); + struct vcpu *p = percpu_ctxt[cpu].curr_vcpu; + struct vcpu *n = current; if ( !is_idle_task(p->domain) ) { @@ -786,23 +813,27 @@ static void __context_switch(void) void context_switch(struct vcpu *prev, struct vcpu *next) { - struct vcpu *realprev; - - local_irq_disable(); + unsigned int cpu = smp_processor_id(); set_current(next); - if ( ((realprev = percpu_ctxt[smp_processor_id()].curr_vcpu) == next) || - is_idle_task(next->domain) ) - { - local_irq_enable(); - } - else + if ( (percpu_ctxt[cpu].curr_vcpu != next) && !is_idle_task(next->domain) ) { __context_switch(); + percpu_ctxt[cpu].context_not_finalised = 1; + } +} + +void context_switch_finalise(struct vcpu *next) +{ + unsigned int cpu = smp_processor_id(); + + if ( percpu_ctxt[cpu].context_not_finalised ) + { + percpu_ctxt[cpu].context_not_finalised = 0; + + BUG_ON(percpu_ctxt[cpu].curr_vcpu != next); - local_irq_enable(); - if ( VMX_DOMAIN(next) ) { vmx_restore_msrs(next); @@ -810,19 +841,11 @@ void context_switch(struct vcpu *prev, struct vcpu *next) else { load_LDT(next); - load_segments(realprev, next); - load_msrs(realprev, next); + load_segments(next); + load_msrs(next); } } - /* - * We do this late on because it doesn't need to be protected by the - * schedule_lock, and because we want this to be the very last use of - * 'prev' (after this point, a dying domain's info structure may be freed - * without warning). - */ - clear_bit(_VCPUF_running, &prev->vcpu_flags); - schedule_tail(next); BUG(); } @@ -835,12 +858,19 @@ void continue_running(struct vcpu *same) int __sync_lazy_execstate(void) { - if ( percpu_ctxt[smp_processor_id()].curr_vcpu == current ) - return 0; - __context_switch(); - load_LDT(current); - clear_segments(); - return 1; + unsigned long flags; + int switch_required; + + local_irq_save(flags); + + switch_required = (percpu_ctxt[smp_processor_id()].curr_vcpu != current); + + if ( switch_required ) + __context_switch(); + + local_irq_restore(flags); + + return switch_required; } void sync_lazy_execstate_cpu(unsigned int cpu) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index bf9fc928df..f7c39b8346 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -65,7 +65,7 @@ static u32 msr_data_index[VMX_MSR_COUNT] = * are not modified once set for generic domains, we don't save them, * but simply reset them to the values set at percpu_traps_init(). */ -void vmx_load_msrs(struct vcpu *p, struct vcpu *n) +void vmx_load_msrs(struct vcpu *n) { struct msr_state *host_state; host_state = &percpu_msr[smp_processor_id()]; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 422f4f48ae..6cf1b7858d 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -474,13 +474,14 @@ static void __enter_scheduler(void) set_ac_timer(&schedule_data[cpu].s_timer, now + r_time); - /* Must be protected by the schedule_lock! */ - set_bit(_VCPUF_running, &next->vcpu_flags); - - spin_unlock_irq(&schedule_data[cpu].schedule_lock); - if ( unlikely(prev == next) ) + { + spin_unlock_irq(&schedule_data[cpu].schedule_lock); return continue_running(prev); + } + + clear_bit(_VCPUF_running, &prev->vcpu_flags); + set_bit(_VCPUF_running, &next->vcpu_flags); perfc_incrc(sched_ctx); @@ -517,6 +518,10 @@ static void __enter_scheduler(void) next->domain->domain_id, next->vcpu_id); context_switch(prev, next); + + spin_unlock_irq(&schedule_data[cpu].schedule_lock); + + context_switch_finalise(next); } /* No locking needed -- pointer comparison is safe :-) */ diff --git a/xen/include/asm-x86/vmx_vmcs.h b/xen/include/asm-x86/vmx_vmcs.h index 987e4e79e6..49a7d1c0bf 100644 --- a/xen/include/asm-x86/vmx_vmcs.h +++ b/xen/include/asm-x86/vmx_vmcs.h @@ -28,10 +28,10 @@ extern int start_vmx(void); extern void stop_vmx(void); #if defined (__x86_64__) -extern void vmx_load_msrs(struct vcpu *p, struct vcpu *n); +extern void vmx_load_msrs(struct vcpu *n); void vmx_restore_msrs(struct vcpu *d); #else -#define vmx_load_msrs(_p, _n) ((void)0) +#define vmx_load_msrs(_n) ((void)0) #define vmx_restore_msrs(_v) ((void)0) #endif diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 45e04fc93d..e0ea2f756d 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -258,12 +258,32 @@ extern void sync_lazy_execstate_mask(cpumask_t mask); extern void sync_lazy_execstate_all(void); extern int __sync_lazy_execstate(void); -/* Called by the scheduler to switch to another vcpu. */ +/* + * Called by the scheduler to switch to another VCPU. On entry, although + * VCPUF_running is no longer asserted for @prev, its context is still running + * on the local CPU and is not committed to memory. The local scheduler lock + * is therefore still held, and interrupts are disabled, because the local CPU + * is in an inconsistent state. + * + * The callee must ensure that the local CPU is no longer running in @prev's + * context, and that the context is saved to memory, before returning. + * Alternatively, if implementing lazy context switching, it suffices to ensure + * that invoking __sync_lazy_execstate() will switch and commit @prev's state. + */ extern void context_switch( struct vcpu *prev, struct vcpu *next); -/* Called by the scheduler to continue running the current vcpu. */ +/* + * On some architectures (notably x86) it is not possible to entirely load + * @next's context with interrupts disabled. These may implement a function to + * finalise loading the new context after interrupts are re-enabled. This + * function is not given @prev and is not permitted to access it. + */ +extern void context_switch_finalise( + struct vcpu *next); + +/* Called by the scheduler to continue running the current VCPU. */ extern void continue_running( struct vcpu *same); From b09f19bf24bd4800516e8528716ed6ce82627813 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 16 Aug 2005 18:12:19 +0000 Subject: [PATCH 02/21] Add a couple of well chosen assertions to new context switch code. Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 7df964347b..ad8716aac6 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -815,6 +815,8 @@ void context_switch(struct vcpu *prev, struct vcpu *next) { unsigned int cpu = smp_processor_id(); + ASSERT(!local_irq_is_enabled()); + set_current(next); if ( (percpu_ctxt[cpu].curr_vcpu != next) && !is_idle_task(next->domain) ) @@ -828,6 +830,8 @@ void context_switch_finalise(struct vcpu *next) { unsigned int cpu = smp_processor_id(); + ASSERT(local_irq_is_enabled()); + if ( percpu_ctxt[cpu].context_not_finalised ) { percpu_ctxt[cpu].context_not_finalised = 0; From 91b0f0040ea4e3766020b938db5bce1ed4cc9b51 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 16 Aug 2005 19:38:22 +0000 Subject: [PATCH 03/21] Really randomise MAC addresses for multi-VIF guests. Reseeding on every VIF doesn;t work as timeofday doesn't change quickly enough. Signed-off-by: Jim Dykman Signed-off-by: Keir Fraser --- tools/python/xen/xm/create.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 72aa2a3f63..1d37f222ed 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -380,7 +380,6 @@ def randomMAC(): @return: MAC address string """ - random.seed() mac = [ 0xaa, 0x00, 0x00, random.randint(0x00, 0x7f), random.randint(0x00, 0xff), @@ -689,6 +688,7 @@ def balloon_out(dom0_min_mem, opts): del xc def main(argv): + random.seed() opts = gopts args = opts.parse(argv) if opts.vals.help: From 8b799c9ee64bcc7a9883aca42978c77717f0de67 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Tue, 16 Aug 2005 20:00:53 +0000 Subject: [PATCH 04/21] Yet another work-around in the network-bridge script From: Zhai, Edwin [edwin.zhai@intel.com] Signed-off-by: ian@xensource.com --- tools/examples/network-bridge | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/examples/network-bridge b/tools/examples/network-bridge index 24df59809a..bb4055c0f0 100755 --- a/tools/examples/network-bridge +++ b/tools/examples/network-bridge @@ -187,6 +187,7 @@ op_start () { ifconfig ${netdev} 0.0.0.0 down fi fi + del_addrs ${netdev} ip link set ${netdev} name p${netdev} ip link set veth0 name ${netdev} ifconfig p${netdev} -arp down From 72593432a519af4b6eed451fa4653992eb46755e Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 08:26:58 +0000 Subject: [PATCH 05/21] Avoid spurious "Ignoring shutdown request" messages, fix memory leak and simplif y code. Also fix whitespace. Signed-off-by: Christian Limpach --- linux-2.6-xen-sparse/arch/xen/kernel/reboot.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c index d11eb8987a..d2e204d12d 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c @@ -256,19 +256,23 @@ static void shutdown_handler(struct xenbus_watch *watch, const char *node) char *str; str = (char *)xenbus_read("control", "shutdown", NULL); - /* Ignore read errors and recursive shutdown events. */ - if (IS_ERR(str) || !strcmp(str, __stringify(SHUTDOWN_INVALID))) + /* Ignore read errors. */ + if (IS_ERR(str)) return; + if (strlen(str) == 0) { + kfree(str); + return; + } - xenbus_printf("control", "shutdown", "%i", SHUTDOWN_INVALID); + xenbus_printf("control", "shutdown", ""); - if (strcmp(str, "poweroff") == 0) { + if (strcmp(str, "poweroff") == 0) shutting_down = SHUTDOWN_POWEROFF; - } else if (strcmp(str, "reboot") == 0) { + else if (strcmp(str, "reboot") == 0) shutting_down = SHUTDOWN_REBOOT; - } else if (strcmp(str, "suspend") == 0) { + else if (strcmp(str, "suspend") == 0) shutting_down = SHUTDOWN_SUSPEND; - } else { + else { printk("Ignoring shutdown request: %s\n", str); shutting_down = SHUTDOWN_INVALID; } From 135f79ef6f7d2bd94d48012b07a251494e5f6c8b Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 08:52:04 +0000 Subject: [PATCH 06/21] Fix compile warning from zero-length printf format string. Signed-off-by: Christian Limpach --- linux-2.6-xen-sparse/arch/xen/kernel/reboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c index d2e204d12d..445daf01e6 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c @@ -264,7 +264,7 @@ static void shutdown_handler(struct xenbus_watch *watch, const char *node) return; } - xenbus_printf("control", "shutdown", ""); + xenbus_write("control", "shutdown", "", O_CREAT); if (strcmp(str, "poweroff") == 0) shutting_down = SHUTDOWN_POWEROFF; From 208cd71bf7861896b0c5bc443d571d9208ba0aa6 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 09:50:26 +0000 Subject: [PATCH 07/21] Add support for XENSTORED_TRACE to enable trace output from xenstored. Set XENSTORED_TRACE in /usr/sbin/xenstored's environment to enable the trace output. Signed-off-by: Christian Limpach --- tools/misc/xend | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/misc/xend b/tools/misc/xend index 5abcdc6e04..db868b5c67 100644 --- a/tools/misc/xend +++ b/tools/misc/xend @@ -117,11 +117,15 @@ def stop_xcs(): return def start_xenstored(): - s,o = commands.getstatusoutput("/usr/sbin/xenstored --pid-file=/var/run/xenstore.pid"); + XENSTORED_TRACE = os.getenv("XENSTORED_TRACE") + cmd = "/usr/sbin/xenstored --pid-file=/var/run/xenstore.pid" + if XENSTORED_TRACE: + cmd += " -T /var/log/xenstored-trace.log" + s,o = commands.getstatusoutput(cmd) def start_consoled(): if os.fork() == 0: - os.execvp('/usr/sbin/xenconsoled', ['/usr/sbin/xenconsoled']); + os.execvp('/usr/sbin/xenconsoled', ['/usr/sbin/xenconsoled']) def main(): try: From 9c07496f46ea70780cfee6a7ba5094692d4757cb Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 09:59:04 +0000 Subject: [PATCH 08/21] xenbus build and license fixes. --- .../drivers/xen/xenbus/xenbus_comms.h | 29 ++++++++++++- linux-2.6-xen-sparse/include/asm-xen/xenbus.h | 6 ++- tools/xenstore/Makefile | 21 ++++------ tools/xenstore/xenstored.h | 42 +++++++++++-------- 4 files changed, 64 insertions(+), 34 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h index 2e7df51b31..d8657212ed 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h @@ -1,6 +1,33 @@ -/* Private include for xenbus communications. */ +/* + * Private include for xenbus communications. + * + * Copyright (C) 2005 Rusty Russell, IBM Corporation + * + * This file may be distributed separately from the Linux kernel, or + * incorporated into other software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + #ifndef _XENBUS_COMMS_H #define _XENBUS_COMMS_H + int xs_init(void); int xb_init_comms(void); void xb_suspend_comms(void); diff --git a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h index 0f30dc8ebe..8e9593ff90 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h @@ -1,5 +1,3 @@ -#ifndef _ASM_XEN_XENBUS_H -#define _ASM_XEN_XENBUS_H /****************************************************************************** * xenbus.h * @@ -28,6 +26,10 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ + +#ifndef _ASM_XEN_XENBUS_H +#define _ASM_XEN_XENBUS_H + #include #include #include diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index 915f4de04b..db0d039292 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -24,7 +24,7 @@ TESTDIR = `pwd`/testsuite/tmp TESTFLAGS= -DTESTING TESTENV = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR) -all: xen xenstored libxenstore.a libxenstore-pic.a +all: xen xenstored libxenstore.so testcode: xen xs_test xenstored_test xs_random xs_dom0_test @@ -53,20 +53,14 @@ xs_test_lib.o: xs.c talloc_test.o: talloc.c $(COMPILE.c) -o $@ $< -LIB_OBJS := xs.o xs_lib.o - -LIB_OBJS_A := $(patsubst %.o,libxenstore.a(%.o),$(LIB_OBJS)) -LIB_OBJS_PIC := $(patsubst %.o,libxenstore-pic.a(%.opic),$(LIB_OBJS)) - -libxenstore.a: $(LIB_OBJS_A) - -libxenstore-pic.a: $(LIB_OBJS_PIC) +libxenstore.so: xs.opic xs_lib.opic + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenstore.so -shared -o $@ $^ clean: testsuite-clean - rm -f *.o *.opic *.a + rm -f *.o *.opic *.so rm -f xen xenstored xs_random xs_stress xs_crashme rm -f xs_test xenstored_test xs_dom0_test - -$(RM) $(PROG_DEP) + $(RM) $(PROG_DEP) print-dir: @echo -n tools/xenstore: @@ -117,15 +111,14 @@ TAGS: tarball: clean cd .. && tar -c -j -v -h -f xenstore.tar.bz2 xenstore/ -install: xenstored libxenstore.a libxenstore-pic.a +install: xenstored libxenstore.so $(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored $(INSTALL_DIR) -p $(DESTDIR)/usr/sbin $(INSTALL_DIR) -p $(DESTDIR)/usr/include $(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR) - $(INSTALL_DATA) libxenstore.a $(DESTDIR)/usr/$(LIBDIR) - $(INSTALL_DATA) libxenstore-pic.a $(DESTDIR)/usr/$(LIBDIR) + $(INSTALL_DATA) libxenstore.so $(DESTDIR)/usr/$(LIBDIR) $(INSTALL_DATA) xs.h $(DESTDIR)/usr/include $(INSTALL_DATA) xs_lib.h $(DESTDIR)/usr/include diff --git a/tools/xenstore/xenstored.h b/tools/xenstore/xenstored.h index 784ec987a8..441b95fecd 100644 --- a/tools/xenstore/xenstored.h +++ b/tools/xenstore/xenstored.h @@ -1,21 +1,29 @@ -/* - Simple prototyle Xen Store Daemon providing simple tree-like database. - Copyright (C) 2005 Rusty Russell IBM Corporation +/* + * Simple prototyle Xen Store Daemon providing simple tree-like database. + * Copyright (C) 2005 Rusty Russell IBM Corporation + * + * This file may be distributed separately from the Linux kernel, or + * incorporated into other software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef _XENSTORED_H #define _XENSTORED_H From 6b2e5410964d72f8ee8b99e268f2c8b90bac7751 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 10:18:13 +0000 Subject: [PATCH 09/21] Clear "/control/shutdown" node on domain restore. Signed-off-by: Christian Limpach --- tools/python/xen/xend/XendDomainInfo.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 7e0c07ab53..570bb6dbda 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -208,6 +208,7 @@ class XendDomainInfo: log.debug('restoring with ssidref='+str(ssidref)) id = xc.domain_create(ssidref = ssidref) vm.setdom(id) + vm.clear_shutdown() try: vm.restore = True vm.construct(config) @@ -979,6 +980,11 @@ class XendDomainInfo: if not reason in ['suspend']: self.shutdown_pending = {'start':time.time(), 'reason':reason} + def clear_shutdown(self): + db = self.db.addChild("/control") + db['shutdown'] = "" + db.saveDB(save=True) + def send_sysrq(self, key=0): db = self.db.addChild("/control"); db['sysrq'] = '%c' % key; From f9c5a6235f538ea0b0aebd12ab851c88f986cd38 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 10:18:34 +0000 Subject: [PATCH 10/21] Recreate watches on domain restore. Signed-off-by: Christian Limpach --- .../drivers/xen/xenbus/xenbus_probe.c | 1 + linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 12 ++++++++++++ linux-2.6-xen-sparse/include/asm-xen/xenbus.h | 1 + 3 files changed, 14 insertions(+) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index e5c625d752..63923361a1 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -309,6 +309,7 @@ void xenbus_suspend(void) void xenbus_resume(void) { xb_init_comms(); + reregister_xenbus_watches(); up(&xenbus_lock); } diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c index 211677b35d..2e9c79361d 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c @@ -496,6 +496,18 @@ void unregister_xenbus_watch(struct xenbus_watch *watch) watch->node, err); } +/* Re-register callbacks to all watches. */ +void reregister_xenbus_watches(void) +{ + struct xenbus_watch *watch; + char token[sizeof(watch) * 2 + 1]; + + list_for_each_entry(watch, &watches, list) { + sprintf(token, "%lX", (long)watch); + xs_watch(watch->node, token); + } +} + static int watch_thread(void *unused) { for (;;) { diff --git a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h index 8e9593ff90..8ffbcb75ef 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h @@ -121,6 +121,7 @@ void unregister_xenstore_notifier(struct notifier_block *nb); int register_xenbus_watch(struct xenbus_watch *watch); void unregister_xenbus_watch(struct xenbus_watch *watch); +void reregister_xenbus_watches(void); /* Called from xen core code. */ void xenbus_suspend(void); From 55b8547307b6dd2ce04be58e82222f4abacf0d67 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 10:35:39 +0000 Subject: [PATCH 11/21] Python build fix. --- tools/python/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/setup.py b/tools/python/setup.py index c2c5448d5e..fdf9a39a40 100644 --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -17,7 +17,7 @@ library_dirs = [ XEN_ROOT + "/tools/libxc", XEN_ROOT + "/tools/xenstore", ] -libraries = [ "xc", "xenstore-pic" ] +libraries = [ "xc", "xenstore" ] xc = Extension("xc", extra_compile_args = extra_compile_args, From fb008da9665c3ac6b7cf09526c98923c098f631d Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 12:25:50 +0000 Subject: [PATCH 12/21] Restore domains with a different uuid than they had. Needed for migration to localhost and migration between hosts with a shared/distributed xenstore. Signed-off-by: Christian Limpach --- tools/python/xen/xend/XendDomain.py | 3 +-- tools/python/xen/xend/XendDomainInfo.py | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 2315aaea20..3959b2e917 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -320,8 +320,7 @@ class XendDomain: @param vmconfig: vm configuration """ config = sxp.child_value(vmconfig, 'config') - uuid = sxp.child_value(vmconfig, 'uuid') - dominfo = XendDomainInfo.restore(self.dbmap, config, uuid=uuid) + dominfo = XendDomainInfo.restore(self.dbmap, config) return dominfo def domain_restore(self, src, progress=False): diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 570bb6dbda..4bacd19deb 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -195,13 +195,15 @@ class XendDomainInfo: recreate = classmethod(recreate) - def restore(cls, parentdb, config, uuid): + def restore(cls, parentdb, config, uuid=None): """Create a domain and a VM object to do a restore. @param parentdb: parent db @param config: domain configuration @param uuid: uuid to use """ + if not uuid: + uuid = getUuid() db = parentdb.addChild(uuid) vm = cls(db) ssidref = int(sxp.child_value(config, 'ssidref')) From 34ef2473015da351dceae5403dbbf128b255418b Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 12:29:34 +0000 Subject: [PATCH 13/21] Another tweak to the network-bridge script. Signed-off-by: ian@xensource.com --- tools/examples/network-bridge | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/examples/network-bridge b/tools/examples/network-bridge index bb4055c0f0..dd4b85f588 100755 --- a/tools/examples/network-bridge +++ b/tools/examples/network-bridge @@ -187,10 +187,9 @@ op_start () { ifconfig ${netdev} 0.0.0.0 down fi fi - del_addrs ${netdev} ip link set ${netdev} name p${netdev} ip link set veth0 name ${netdev} - ifconfig p${netdev} -arp down + ifconfig p${netdev} 0.0.0.0 -arp down ifconfig p${netdev} hw ether fe:ff:ff:ff:ff:ff ifconfig ${netdev} hw ether ${mac} add_to_bridge ${bridge} vif0.0 From 34f71bcc7ce9196ff101ceed2e339af921db984c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 13:33:55 +0000 Subject: [PATCH 14/21] Allocate_empty_lowmem_regions available to non-priv domains and to modules. From Ross Mcilroy. --- linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c | 4 ++-- linux-2.6-xen-sparse/include/asm-xen/hypervisor.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c index bd75d0622d..2c9f9acc3f 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c @@ -35,6 +35,7 @@ #include #include #include +#include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include #include @@ -352,7 +353,6 @@ void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order) balloon_unlock(flags); } -#ifdef CONFIG_XEN_PHYSDEV_ACCESS unsigned long allocate_empty_lowmem_region(unsigned long pages) { @@ -401,4 +401,4 @@ unsigned long allocate_empty_lowmem_region(unsigned long pages) return vstart; } -#endif /* CONFIG_XEN_PHYSDEV_ACCESS */ +EXPORT_SYMBOL(allocate_empty_lowmem_region); diff --git a/linux-2.6-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.6-xen-sparse/include/asm-xen/hypervisor.h index af2dacf9ee..2167a737f7 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.6-xen-sparse/include/asm-xen/hypervisor.h @@ -137,10 +137,8 @@ void xen_invlpg_mask(cpumask_t *mask, unsigned long ptr); void xen_create_contiguous_region(unsigned long vstart, unsigned int order); void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order); -#ifdef CONFIG_XEN_PHYSDEV_ACCESS /* Allocate a contiguous empty region of low memory. Return virtual start. */ unsigned long allocate_empty_lowmem_region(unsigned long pages); -#endif #include From 806ac068522c4ef96a8bf302004d725ab9e20431 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 13:34:42 +0000 Subject: [PATCH 15/21] Fix module build by removing duplicate EXPORT_SYMBOL of dma_alloc_coherent and dma_free_coherent. --- linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c index d767aa6da2..30c2357b4e 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c @@ -115,9 +115,6 @@ EXPORT_SYMBOL(__copy_from_user_ll); EXPORT_SYMBOL(__copy_to_user_ll); EXPORT_SYMBOL(strnlen_user); -EXPORT_SYMBOL(dma_alloc_coherent); -EXPORT_SYMBOL(dma_free_coherent); - #ifdef CONFIG_PCI EXPORT_SYMBOL(pci_mem_start); #endif From 9a0d977633132530791b16d00bcffe04125849e2 Mon Sep 17 00:00:00 2001 From: "vh249@arcadians.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 14:23:16 +0000 Subject: [PATCH 16/21] fix missing swiotlb.c file in linux build after running cleanup. Signed-off-by: Vincent Hanquez --- linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile index 29e7c0344a..58e1498388 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile @@ -44,7 +44,7 @@ c-obj-$(CONFIG_HPET_TIMER) += time_hpet.o c-obj-$(CONFIG_EFI) += efi.o efi_stub.o c-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o c-obj-$(CONFIG_SMP_ALTERNATIVES)+= smpalts.o -c-obj-$(CONFIG_SWIOTLB) += swiotlb.o +obj-$(CONFIG_SWIOTLB) += swiotlb.o EXTRA_AFLAGS := -traditional From 206e4c40331f96941aa4074ac1dbfe73bc1159bd Mon Sep 17 00:00:00 2001 From: "vh249@arcadians.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 15:09:31 +0000 Subject: [PATCH 17/21] have a useful line reporting when IOMMU_BUG_ON trigger Signed-off-by: Vincent Hanquez --- .../arch/xen/i386/kernel/pci-dma.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c index 481b61bc27..c9ade99d64 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c @@ -24,13 +24,13 @@ struct dma_coherent_mem { unsigned long *bitmap; }; -static void iommu_bug(void) -{ - printk(KERN_ALERT "Fatal DMA error! Please use 'swiotlb=force'\n"); - BUG(); -} - -#define IOMMU_BUG_ON(test) do { if (unlikely(test)) iommu_bug(); } while(0) +#define IOMMU_BUG_ON(test) \ +do { \ + if (unlikely(test)) { \ + printk(KERN_ALERT "Fatal DMA error! Please use 'swiotlb=force'\n"); \ + BUG(); \ + } \ +} while(0) int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, From 88f95d50cfb1332776cebe47a929a889b8d82759 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 15:34:58 +0000 Subject: [PATCH 18/21] Formatting cleanup. --- .../arch/xen/i386/kernel/pci-dma.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c index c9ade99d64..054f21d489 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c @@ -24,13 +24,14 @@ struct dma_coherent_mem { unsigned long *bitmap; }; -#define IOMMU_BUG_ON(test) \ -do { \ - if (unlikely(test)) { \ - printk(KERN_ALERT "Fatal DMA error! Please use 'swiotlb=force'\n"); \ - BUG(); \ - } \ -} while(0) +#define IOMMU_BUG_ON(test) \ +do { \ + if (unlikely(test)) { \ + printk(KERN_ALERT "Fatal DMA error! " \ + "Please use 'swiotlb=force'\n"); \ + BUG(); \ + } \ +} while (0) int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, From 81cf88dc9c8db10fe5ab4495c917be4933730a2a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 16:53:30 +0000 Subject: [PATCH 19/21] Fix the skbuff allocator for multi-page buffers. pci-dma.c still needs fixing to recognise contiguous multi-page buffers. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c | 82 +++++++++++++++---- 1 file changed, 66 insertions(+), 16 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c b/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c index 90274fd599..a7fe1519f6 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c @@ -5,8 +5,6 @@ #include #include #include -#include -#include #include #include #include @@ -14,34 +12,86 @@ #include #include #include - -EXPORT_SYMBOL(__dev_alloc_skb); +#include /* Referenced in netback.c. */ /*static*/ kmem_cache_t *skbuff_cachep; -/* Size must be cacheline-aligned (alloc_skb uses SKB_DATA_ALIGN). */ -#define XEN_SKB_SIZE \ - ((PAGE_SIZE - sizeof(struct skb_shared_info)) & ~(SMP_CACHE_BYTES - 1)) +#define MAX_SKBUFF_ORDER 2 +static kmem_cache_t *skbuff_order_cachep[MAX_SKBUFF_ORDER + 1]; struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask) { - struct sk_buff *skb; - skb = alloc_skb_from_cache(skbuff_cachep, length + 16, gfp_mask); - if ( likely(skb != NULL) ) - skb_reserve(skb, 16); - return skb; + struct sk_buff *skb; + int order; + + length = SKB_DATA_ALIGN(length + 16); + order = get_order(length + sizeof(struct skb_shared_info)); + if (order > MAX_SKBUFF_ORDER) { + printk(KERN_ALERT "Attempt to allocate order %d skbuff. " + "Increase MAX_SKBUFF_ORDER.\n", order); + return NULL; + } + + skb = alloc_skb_from_cache( + skbuff_order_cachep[order], length, gfp_mask); + if (skb != NULL) + skb_reserve(skb, 16); + + return skb; } static void skbuff_ctor(void *buf, kmem_cache_t *cachep, unsigned long unused) { - scrub_pages(buf, 1); + int order = 0; + + while (skbuff_order_cachep[order] != cachep) + order++; + + if (order != 0) + xen_create_contiguous_region((unsigned long)buf, order); + + scrub_pages(buf, 1 << order); +} + +static void skbuff_dtor(void *buf, kmem_cache_t *cachep, unsigned long unused) +{ + int order = 0; + + while (skbuff_order_cachep[order] != cachep) + order++; + + if (order != 0) + xen_destroy_contiguous_region((unsigned long)buf, order); } static int __init skbuff_init(void) { - skbuff_cachep = kmem_cache_create( - "xen-skb", PAGE_SIZE, PAGE_SIZE, 0, skbuff_ctor, NULL); - return 0; + static char name[MAX_SKBUFF_ORDER + 1][20]; + unsigned long size; + int order; + + for (order = 0; order <= MAX_SKBUFF_ORDER; order++) { + size = PAGE_SIZE << order; + sprintf(name[order], "xen-skb-%lu", size); + skbuff_order_cachep[order] = kmem_cache_create( + name[order], size, size, 0, skbuff_ctor, skbuff_dtor); + } + + skbuff_cachep = skbuff_order_cachep[0]; + + return 0; } __initcall(skbuff_init); + +EXPORT_SYMBOL(__dev_alloc_skb); + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ From 4ce65049c8a03275ae62e19d066943531017710e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 18:14:46 +0000 Subject: [PATCH 20/21] Fix vmalloc_fault() path for x86/64 XenLinux. There may be a deeper underlying problem w.r.t pagetable initialisation at start of day, but this simple fix is a good workaround until we have time to investigate properly. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c index 874b3afede..c0c5dc86b5 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c @@ -250,7 +250,11 @@ static int vmalloc_fault(unsigned long address) happen within a race in page table update. In the later case just flush. */ - pgd = pgd_offset(current->mm ?: &init_mm, address); + /* On Xen the line below does not always work. Needs investigating! */ + /*pgd = pgd_offset(current->mm ?: &init_mm, address);*/ + pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id()); + pgd += pgd_index(address); + pgd_ref = pgd_offset_k(address); if (pgd_none(*pgd_ref)) return -1; From 7501cca88550678b632d3a0934295c4eb3012bf5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 Aug 2005 18:22:18 +0000 Subject: [PATCH 21/21] We found machines with >32 E820 memory map entries, where Xen fails to boot (but Linux does boot fine). The native Linux (both x86 and x86_86) already has: #define E820MAX 128 /* number of entries in E820MAP */ Signed-off-by: Jun Nakajima --- xen/include/asm-x86/e820.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/include/asm-x86/e820.h b/xen/include/asm-x86/e820.h index f510c7c12b..e346ad64b7 100644 --- a/xen/include/asm-x86/e820.h +++ b/xen/include/asm-x86/e820.h @@ -3,7 +3,7 @@ #include -#define E820MAX 32 +#define E820MAX 128 #define E820_RAM 1 #define E820_RESERVED 2