diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-02-08 08:43:25 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-02-08 08:43:25 +0000 |
commit | 43d6e1096b0df2b2ba0780fa41b525e11518e520 (patch) | |
tree | 8ae15a6396fec434d4502937325c32a2b75c7d8b | |
parent | a73520207b4a8a1a7f3533b84377d90dac9ae391 (diff) | |
download | xen-43d6e1096b0df2b2ba0780fa41b525e11518e520.tar.gz xen-43d6e1096b0df2b2ba0780fa41b525e11518e520.tar.bz2 xen-43d6e1096b0df2b2ba0780fa41b525e11518e520.zip |
vmx: Don't enable irq for machine check vmexit handling
We should not enable irq for machine check VMExit
In changeset 18658:824892134573, IRQ is enabled during VMExit except
external interrupt. The exception should apply for machine check also,
because :
a) The mce_logout_lock should be held in irq_disabled context.
b) The machine check event should be handled as quickly as possible,
enable irq will increase the period greatly.
Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r-- | xen/arch/x86/hvm/vmx/vmx.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 66c889bfef..62c923a0a7 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2168,7 +2168,7 @@ static void vmx_failed_vmentry(unsigned int exit_reason, case EXIT_REASON_MCE_DURING_VMENTRY: printk("caused by machine check.\n"); HVMTRACE_0D(MCE); - do_machine_check(regs); + /* Already handled. */ break; default: printk("reason not known yet!"); @@ -2263,7 +2263,7 @@ err: asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) { - unsigned int exit_reason, idtv_info; + unsigned int exit_reason, idtv_info, intr_info = 0, vector = 0; unsigned long exit_qualification, inst_len = 0; struct vcpu *v = current; @@ -2285,8 +2285,22 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) perfc_incra(vmexits, exit_reason); /* Handle the interrupt we missed before allowing any more in. */ - if ( exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT ) + switch ( (uint16_t)exit_reason ) + { + case EXIT_REASON_EXTERNAL_INTERRUPT: vmx_do_extint(regs); + break; + case EXIT_REASON_EXCEPTION_NMI: + intr_info = __vmread(VM_EXIT_INTR_INFO); + BUG_ON(!(intr_info & INTR_INFO_VALID_MASK)); + vector = intr_info & INTR_INFO_VECTOR_MASK; + if ( vector == TRAP_machine_check ) + do_machine_check(regs); + break; + case EXIT_REASON_MCE_DURING_VMENTRY: + do_machine_check(regs); + break; + } /* Now enable interrupts so it's safe to take locks. */ local_irq_enable(); @@ -2296,8 +2310,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) if ( v->arch.hvm_vmx.vmx_realmode ) { - unsigned int vector; - /* Put RFLAGS back the way the guest wants it */ regs->eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_IOPL); regs->eflags |= (v->arch.hvm_vmx.vm86_saved_eflags & X86_EFLAGS_IOPL); @@ -2307,7 +2319,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) switch ( exit_reason ) { case EXIT_REASON_EXCEPTION_NMI: - vector = __vmread(VM_EXIT_INTR_INFO) & INTR_INFO_VECTOR_MASK; if ( vector != TRAP_page_fault && vector != TRAP_nmi && vector != TRAP_machine_check ) @@ -2366,12 +2377,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) * (1) We can get an exception (e.g. #PG) in the guest, or * (2) NMI */ - unsigned int intr_info, vector; - - intr_info = __vmread(VM_EXIT_INTR_INFO); - BUG_ON(!(intr_info & INTR_INFO_VALID_MASK)); - - vector = intr_info & INTR_INFO_VECTOR_MASK; /* * Re-set the NMI shadow if vmexit caused by a guest IRET fault (see 3B @@ -2448,7 +2453,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) break; case TRAP_machine_check: HVMTRACE_0D(MCE); - do_machine_check(regs); + /* Already handled above. */ break; case TRAP_invalid_op: vmx_vmexit_ud_intercept(regs); |