aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vmx
diff options
context:
space:
mode:
authorTim Deegan <tim@xen.org>2013-02-28 12:42:15 +0000
committerTim Deegan <tim@xen.org>2013-02-28 14:00:18 +0000
commit7dd3b06ff031c9a8c727df16c5def2afb382101c (patch)
tree4617d15f3520481f0629bb3deacf1709993ffb90 /xen/arch/x86/hvm/vmx
parentf0fc1e8294a963528556b0862c06bb3fcf7c390a (diff)
downloadxen-7dd3b06ff031c9a8c727df16c5def2afb382101c.tar.gz
xen-7dd3b06ff031c9a8c727df16c5def2afb382101c.tar.bz2
xen-7dd3b06ff031c9a8c727df16c5def2afb382101c.zip
vmx: fix handling of NMI VMEXIT.
Call do_nmi() directly and explicitly re-enable NMIs rather than raising an NMI through the APIC. Since NMIs are disabled after the VMEXIT, the raised NMI would be blocked until the next IRET instruction (i.e. the next real interrupt, or after scheduling a PV guest) and in the meantime the guest will spin taking NMI VMEXITS. Also, handle NMIs before re-enabling interrupts, since if we handle an interrupt (and therefore IRET) before calling do_nmi(), we may end up running the NMI handler with NMIs enabled. Signed-off-by: Tim Deegan <tim@xen.org> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com>
Diffstat (limited to 'xen/arch/x86/hvm/vmx')
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 53789286ce..04dbefbd2a 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2313,6 +2313,13 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
vector = intr_info & INTR_INFO_VECTOR_MASK;
if ( vector == TRAP_machine_check )
do_machine_check(regs);
+ if ( vector == TRAP_nmi
+ && ((intr_info & INTR_INFO_INTR_TYPE_MASK) ==
+ (X86_EVENTTYPE_NMI << 8)) )
+ {
+ do_nmi(regs);
+ enable_nmis();
+ }
break;
case EXIT_REASON_MCE_DURING_VMENTRY:
do_machine_check(regs);
@@ -2486,7 +2493,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
(X86_EVENTTYPE_NMI << 8) )
goto exit_and_crash;
HVMTRACE_0D(NMI);
- self_nmi(); /* Real NMI, vector 2: normal processing. */
+ /* Already handled above. */
break;
case TRAP_machine_check:
HVMTRACE_0D(MCE);