diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index a58e215163..10ddc8adaf 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -659,6 +659,7 @@ static void net_tx_action(unsigned long unused) skb->data_len = txreq.size - data_len; skb->len += skb->data_len; + skb->truesize += skb->data_len; skb->dev = netif->dev; skb->protocol = eth_type_trans(skb, skb->dev); 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 e0c05915a5..f7e5425507 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 @@ -1069,6 +1069,11 @@ static int __init wait_for_devices(void) { unsigned long timeout = jiffies + 10*HZ; + if (xen_init() < 0) { + DPRINTK("failed"); + return -ENODEV; + } + while (time_before(jiffies, timeout)) { if (all_devices_ready()) return 0; diff --git a/linux-2.6-xen-sparse/scripts/Makefile.xen b/linux-2.6-xen-sparse/scripts/Makefile.xen index b3ec53a18c..831f68b794 100644 --- a/linux-2.6-xen-sparse/scripts/Makefile.xen +++ b/linux-2.6-xen-sparse/scripts/Makefile.xen @@ -2,9 +2,9 @@ # cherrypickxen($1 = allobj) cherrypickxen = $(foreach var, $(1), \ $(shell o=$(var); \ - c=$${o/%.o/-xen.c}; \ - s=$${o/%.o/-xen.S}; \ - oxen=$${o/%.o/-xen.o}; \ + c=$${o%.o}-xen.c; \ + s=$${o%.o}-xen.S; \ + oxen=$${o%.o}-xen.o; \ [ -f $(srctree)/$(src)/$${c} ] || \ [ -f $(srctree)/$(src)/$${s} ] \ && echo $$oxen \ diff --git a/tools/ioemu/configure b/tools/ioemu/configure index b4bf85cf51..087fc5a9ce 100755 --- a/tools/ioemu/configure +++ b/tools/ioemu/configure @@ -230,7 +230,7 @@ fi if test -z "$vnc"; then -if libvncserver-config --version >& /dev/null; then +if libvncserver-config --version > /dev/null 2>&1; then vnc=yes else vnc=no diff --git a/tools/python/xen/xend/XendBootloader.py b/tools/python/xen/xend/XendBootloader.py index 143bf36904..9c062e4c4b 100644 --- a/tools/python/xen/xend/XendBootloader.py +++ b/tools/python/xen/xend/XendBootloader.py @@ -19,7 +19,7 @@ import sxp from XendLogging import log from XendError import VmError -def bootloader(blexec, disk, quiet = 0, blargs = None): +def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None): """Run the boot loader executable on the given disk and return a config image. @param blexec Binary to use as the boot loader @@ -86,4 +86,10 @@ def bootloader(blexec, disk, quiet = 0, blargs = None): pin = sxp.Parser() pin.input(ret) pin.input_eof() - return pin.val + blcfg = pin.val + + if imgcfg is None: + return blcfg + else: + c = sxp.merge(blcfg, imgcfg) + return c diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index d88799bc7c..f42d992b40 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1633,7 +1633,8 @@ class XendDomainInfo: continue fn = blkdev_uname_to_file(disk) blcfg = bootloader(self.info['bootloader'], fn, 1, - self.info['bootloader_args']) + self.info['bootloader_args'], + self.info['image']) break if blcfg is None: msg = "Had a bootloader specified, but can't find disk" diff --git a/tools/python/xen/xend/server/pciif.py b/tools/python/xen/xend/server/pciif.py index 053b66adcb..16844cc6ff 100644 --- a/tools/python/xen/xend/server/pciif.py +++ b/tools/python/xen/xend/server/pciif.py @@ -94,7 +94,7 @@ class PciController(DevController): else: # Xen 2.0 configuration compatibility - domain = get_param(dev_config, 'domain', 0) + domain = get_param(config, 'domain', 0) bus = get_param(config, 'bus') slot = get_param(config, 'dev') func = get_param(config, 'func') diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index dd7d1675a9..fffa836896 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -448,8 +448,11 @@ def strip(pre, s): def configure_image(vals): """Create the image config. """ + if not vals.builder: + return None config_image = [ vals.builder ] - config_image.append([ 'kernel', os.path.abspath(vals.kernel) ]) + if vals.kernel: + config_image.append([ 'kernel', os.path.abspath(vals.kernel) ]) if vals.ramdisk: config_image.append([ 'ramdisk', os.path.abspath(vals.ramdisk) ]) if vals.cmdline_ip: @@ -616,7 +619,7 @@ def configure_hvm(config_image, vals): if (vals.__dict__[a]): config_image.append([a, vals.__dict__[a]]) -def run_bootloader(vals): +def run_bootloader(vals, config_image): if not os.access(vals.bootloader, os.X_OK): err("Bootloader isn't executable") if len(vals.disk) < 1: @@ -630,7 +633,7 @@ def run_bootloader(vals): vals.bootargs = "--entry=%s" %(vals.bootentry,) return bootloader(vals.bootloader, file, not vals.console_autoconnect, - vals.bootargs) + vals.bootargs, config_image) def make_config(vals): """Create the domain configuration. @@ -662,13 +665,12 @@ def make_config(vals): if vals.tpmif: config.append(['backend', ['tpmif']]) + config_image = configure_image(vals) if vals.bootloader: - config_image = run_bootloader(vals) + config_image = run_bootloader(vals, config_image) config.append(['bootloader', vals.bootloader]) if vals.bootargs: config.append(['bootloader_args'], vals.bootargs) - else: - config_image = configure_image(vals) config.append(['image', config_image]) config_devs = [] diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 3e3a61f59b..bd4b6f08ab 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -753,7 +753,10 @@ int __sync_lazy_execstate(void) switch_required = (this_cpu(curr_vcpu) != current); if ( switch_required ) + { + ASSERT(current == idle_vcpu[smp_processor_id()]); __context_switch(); + } local_irq_restore(flags); diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 7154f78ecf..85a81f103a 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2821,11 +2821,7 @@ asmlinkage void svm_load_cr2(void) struct vcpu *v = current; local_irq_disable(); -#ifdef __i386__ - asm volatile("movl %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2)); -#else - asm volatile("movq %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2)); -#endif + asm volatile("mov %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2)); } asmlinkage void svm_asid(void) diff --git a/xen/arch/x86/hvm/vmx/io.c b/xen/arch/x86/hvm/vmx/io.c index 9835445d61..f2199cbcb1 100644 --- a/xen/arch/x86/hvm/vmx/io.c +++ b/xen/arch/x86/hvm/vmx/io.c @@ -166,20 +166,26 @@ asmlinkage void vmx_intr_assist(void) } has_ext_irq = cpu_has_pending_irq(v); + + if (unlikely(v->arch.hvm_vmx.vector_injected)) { + v->arch.hvm_vmx.vector_injected=0; + if (unlikely(has_ext_irq)) enable_irq_window(v); + return; + } + __vmread(IDT_VECTORING_INFO_FIELD, &idtv_info_field); - if (idtv_info_field & INTR_INFO_VALID_MASK) { + if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) { __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field); __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len); - if (inst_len >= 1 && inst_len <= 15) - __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len); + __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len); - if (idtv_info_field & 0x800) { /* valid error code */ + if (unlikely(idtv_info_field & 0x800)) { /* valid error code */ unsigned long error_code; __vmread(IDT_VECTORING_ERROR_CODE, &error_code); __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); } - if ( has_ext_irq ) + if (unlikely(has_ext_irq)) enable_irq_window(v); HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field); @@ -187,8 +193,9 @@ asmlinkage void vmx_intr_assist(void) return; } - if ( !has_ext_irq ) return; - if ( is_interruptibility_state() ) { /* pre-cleared for emulated instruction */ + if (likely(!has_ext_irq)) return; + + if (unlikely(is_interruptibility_state())) { /* pre-cleared for emulated instruction */ enable_irq_window(v); HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility"); return; diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index ebdd18ee12..0de5144c6b 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -893,6 +893,20 @@ static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs) #define CASE_GET_REG_P(REG, reg) \ case REG_ ## REG: reg_p = (unsigned long *)&(regs->reg); break +#ifdef __i386__ +#define CASE_EXTEND_GET_REG_P +#else +#define CASE_EXTEND_GET_REG_P \ + CASE_GET_REG_P(R8, r8); \ + CASE_GET_REG_P(R9, r9); \ + CASE_GET_REG_P(R10, r10); \ + CASE_GET_REG_P(R11, r11); \ + CASE_GET_REG_P(R12, r12); \ + CASE_GET_REG_P(R13, r13); \ + CASE_GET_REG_P(R14, r14); \ + CASE_GET_REG_P(R15, r15) +#endif + static void vmx_dr_access (unsigned long exit_qualification, struct cpu_user_regs *regs) { unsigned int reg; @@ -908,14 +922,15 @@ static void vmx_dr_access (unsigned long exit_qualification, struct cpu_user_reg "vmx_dr_access : eip=%lx, reg=%d, exit_qualification = %lx", eip, reg, exit_qualification); - switch(exit_qualification & DEBUG_REG_ACCESS_REG) { - CASE_GET_REG_P(EAX, eax); - CASE_GET_REG_P(ECX, ecx); - CASE_GET_REG_P(EDX, edx); - CASE_GET_REG_P(EBX, ebx); - CASE_GET_REG_P(EBP, ebp); - CASE_GET_REG_P(ESI, esi); - CASE_GET_REG_P(EDI, edi); + switch ( exit_qualification & DEBUG_REG_ACCESS_REG ) { + CASE_GET_REG_P(EAX, eax); + CASE_GET_REG_P(ECX, ecx); + CASE_GET_REG_P(EDX, edx); + CASE_GET_REG_P(EBX, ebx); + CASE_GET_REG_P(EBP, ebp); + CASE_GET_REG_P(ESI, esi); + CASE_GET_REG_P(EDI, edi); + CASE_EXTEND_GET_REG_P; case REG_ESP: break; default: @@ -1525,29 +1540,30 @@ static int vmx_set_cr0(unsigned long value) return 1; } -#define CASE_GET_REG(REG, reg) \ +#define CASE_SET_REG(REG, reg) \ + case REG_ ## REG: regs->reg = value; break +#define CASE_GET_REG(REG, reg) \ case REG_ ## REG: value = regs->reg; break -#define CASE_EXTEND_SET_REG \ - CASE_EXTEND_REG(S) -#define CASE_EXTEND_GET_REG \ - CASE_EXTEND_REG(G) +#define CASE_EXTEND_SET_REG \ + CASE_EXTEND_REG(S) +#define CASE_EXTEND_GET_REG \ + CASE_EXTEND_REG(G) #ifdef __i386__ #define CASE_EXTEND_REG(T) #else -#define CASE_EXTEND_REG(T) \ - CASE_ ## T ## ET_REG(R8, r8); \ - CASE_ ## T ## ET_REG(R9, r9); \ +#define CASE_EXTEND_REG(T) \ + CASE_ ## T ## ET_REG(R8, r8); \ + CASE_ ## T ## ET_REG(R9, r9); \ CASE_ ## T ## ET_REG(R10, r10); \ CASE_ ## T ## ET_REG(R11, r11); \ CASE_ ## T ## ET_REG(R12, r12); \ CASE_ ## T ## ET_REG(R13, r13); \ CASE_ ## T ## ET_REG(R14, r14); \ - CASE_ ## T ## ET_REG(R15, r15); + CASE_ ## T ## ET_REG(R15, r15) #endif - /* * Write to control registers */ @@ -1557,31 +1573,28 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs) unsigned long old_cr; struct vcpu *v = current; - switch (gp) { - CASE_GET_REG(EAX, eax); - CASE_GET_REG(ECX, ecx); - CASE_GET_REG(EDX, edx); - CASE_GET_REG(EBX, ebx); - CASE_GET_REG(EBP, ebp); - CASE_GET_REG(ESI, esi); - CASE_GET_REG(EDI, edi); - CASE_EXTEND_GET_REG - case REG_ESP: - __vmread(GUEST_RSP, &value); + switch ( gp ) { + CASE_GET_REG(EAX, eax); + CASE_GET_REG(ECX, ecx); + CASE_GET_REG(EDX, edx); + CASE_GET_REG(EBX, ebx); + CASE_GET_REG(EBP, ebp); + CASE_GET_REG(ESI, esi); + CASE_GET_REG(EDI, edi); + CASE_EXTEND_GET_REG; + case REG_ESP: + __vmread(GUEST_RSP, &value); break; default: printk("invalid gp: %d\n", gp); __hvm_bug(regs); } - HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value); - HVM_DBG_LOG(DBG_LEVEL_1, "current = %lx,", (unsigned long) current); + HVM_DBG_LOG(DBG_LEVEL_1, "CR%d, value = %lx", cr, value); - switch(cr) { + switch ( cr ) { case 0: - { return vmx_set_cr0(value); - } case 3: { unsigned long old_base_mfn, mfn; @@ -1753,11 +1766,6 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs) return 1; } -#define CASE_SET_REG(REG, reg) \ - case REG_ ## REG: \ - regs->reg = value; \ - break - /* * Read from control registers. CR0 and CR4 are read from the shadow. */ @@ -1766,22 +1774,22 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs) unsigned long value; struct vcpu *v = current; - if (cr != 3) + if ( cr != 3 ) __hvm_bug(regs); value = (unsigned long) v->arch.hvm_vmx.cpu_cr3; - switch (gp) { - CASE_SET_REG(EAX, eax); - CASE_SET_REG(ECX, ecx); - CASE_SET_REG(EDX, edx); - CASE_SET_REG(EBX, ebx); - CASE_SET_REG(EBP, ebp); - CASE_SET_REG(ESI, esi); - CASE_SET_REG(EDI, edi); - CASE_EXTEND_SET_REG - case REG_ESP: - __vmwrite(GUEST_RSP, value); + switch ( gp ) { + CASE_SET_REG(EAX, eax); + CASE_SET_REG(ECX, ecx); + CASE_SET_REG(EDX, edx); + CASE_SET_REG(EBX, ebx); + CASE_SET_REG(EBP, ebp); + CASE_SET_REG(ESI, esi); + CASE_SET_REG(EDI, edi); + CASE_EXTEND_SET_REG; + case REG_ESP: + __vmwrite(GUEST_RSP, value); regs->esp = value; break; default: @@ -1789,7 +1797,7 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs) __hvm_bug(regs); } - HVM_DBG_LOG(DBG_LEVEL_VMMU, "mov_from_cr: CR%d, value = %lx,", cr, value); + HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR%d, value = %lx", cr, value); } static int vmx_cr_access(unsigned long exit_qualification, struct cpu_user_regs *regs) @@ -2284,11 +2292,7 @@ asmlinkage void vmx_load_cr2(void) struct vcpu *v = current; local_irq_disable(); -#ifdef __i386__ - asm volatile("movl %0,%%cr2": :"r" (v->arch.hvm_vmx.cpu_cr2)); -#else - asm volatile("movq %0,%%cr2": :"r" (v->arch.hvm_vmx.cpu_cr2)); -#endif + asm volatile("mov %0,%%cr2": :"r" (v->arch.hvm_vmx.cpu_cr2)); } asmlinkage void vmx_trace_vmentry (void) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 58a84d1177..d6d12841b6 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -318,6 +318,7 @@ static void __pirq_guest_eoi(struct domain *d, int irq) { ASSERT(cpus_empty(action->cpu_eoi_map)); desc->handler->end(irq_to_vector(irq)); + spin_unlock_irq(&desc->lock); return; } diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c index 53dec24c38..590e35921e 100644 --- a/xen/arch/x86/smp.c +++ b/xen/arch/x86/smp.c @@ -169,6 +169,7 @@ fastcall void smp_invalidate_interrupt(void) { ack_APIC_irq(); perfc_incrc(ipis); + irq_enter(); if ( !__sync_lazy_execstate() ) { if ( flush_va == FLUSHVA_ALL ) @@ -177,6 +178,7 @@ fastcall void smp_invalidate_interrupt(void) local_flush_tlb_one(flush_va); } cpu_clear(smp_processor_id(), flush_cpumask); + irq_exit(); } void __flush_tlb_mask(cpumask_t mask, unsigned long va) @@ -335,6 +337,8 @@ fastcall void smp_call_function_interrupt(struct cpu_user_regs *regs) if ( !cpu_isset(smp_processor_id(), call_data->selected) ) return; + irq_enter(); + if ( call_data->wait ) { (*func)(info); @@ -347,4 +351,6 @@ fastcall void smp_call_function_interrupt(struct cpu_user_regs *regs) atomic_inc(&call_data->started); (*func)(info); } + + irq_exit(); } diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 76aa48d4cb..64ab6b69bc 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -674,6 +674,8 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs) unsigned long addr, fixup; int rc; + ASSERT(!in_irq()); + __asm__ __volatile__ ("mov %%cr2,%0" : "=r" (addr) : ); DEBUGGER_trap_entry(TRAP_page_fault, regs); diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index b2545bbd26..c4f1c70745 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -68,6 +68,7 @@ struct arch_vmx_struct { struct vmcs_struct *vmcs; /* VMCS pointer in virtual. */ unsigned int launch_cpu; /* VMCS is valid on this CPU. */ u32 exec_control; /* cache of cpu execution control */ + u32 vector_injected; /* if there is vector installed in the INTR_INFO_FIELD */ unsigned long flags; /* VMCS flags */ unsigned long cpu_cr0; /* copy of guest CR0 */ unsigned long cpu_shadow_cr0; /* copy of guest read shadow CR0 */ diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index 864b393e9d..26d497f8a6 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -444,6 +444,7 @@ static inline int __vmx_inject_exception(struct vcpu *v, int trap, int type, static inline int vmx_inject_exception(struct vcpu *v, int trap, int error_code) { + v->arch.hvm_vmx.vector_injected = 1; return __vmx_inject_exception(v, trap, INTR_TYPE_EXCEPTION, error_code); }