xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2] xen: vmx: Use an INT 2 call to process real NMI's instead of self_nmi() in VMEXIT handler
@ 2012-11-13 20:08 Malcolm Crossley
  2012-11-14 10:06 ` Jan Beulich
  2012-11-22  8:58 ` Jan Beulich
  0 siblings, 2 replies; 21+ messages in thread
From: Malcolm Crossley @ 2012-11-13 20:08 UTC (permalink / raw)
  To: xen-devel; +Cc: tim, eddie.dong, JBeulich, jun.nakajima, Ian.Campbell

The self_nmi() code cause's an NMI to be triggered by sending an APIC message
to the local processor. Unfortunately there is a delay in the delivery of the
APIC message and we may already have re-entered the HVM guest by the time the
NMI is taken. This results in the VMEXIT code calling the self_nmi() function
again. We have seen hundreds of iterations of this VMEXIT/VMENTER loop before
the HVM guest resumes normal operation.

Volume 3 Chapter 27 Section 1 of the Intel SDM states:

An NMI causes subsequent NMIs to be blocked, but only after the VM exit
completes.

So we believe it is safe to directly invoke the INT call as NMI's should
already be blocked.

The INT 2 call will perform an IRET which will unblock later calls to the NMI
handler, according to Intel SDM Volume 3 Chapter 6.7.1. We must ensure that the
IRET from the INT 2 IRET is the first IRET issued to prevent losing an NMI.
Moving the INT 2 call to before the interrupts are enabled should ensure we
don't lose the NMI.

Signed-off-by: Malcolm Crossley <malcolm.crossley@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>

diff -r 62885b3c34c8 -r 7d6fd0219dd7 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2269,6 +2269,14 @@ void vmx_vmexit_handler(struct cpu_user_
         vector = intr_info & INTR_INFO_VECTOR_MASK;
         if ( vector == TRAP_machine_check )
             do_machine_check(regs);
+        else if ( vector == TRAP_nmi &&
+                ( (intr_info & INTR_INFO_INTR_TYPE_MASK) ==
+                  (X86_EVENTTYPE_NMI << 8) ) )
+            /* Must be called before interrupts are enabled to ensure
+             * the NMI handler code is run before the first IRET. The
+             * IRET unblocks subsequent NMI's (Intel SDM Vol 3, 6.7.1)
+             */
+            asm volatile("int $2"); /* Real NMI, vector 2: normal processing */
         break;
     case EXIT_REASON_MCE_DURING_VMENTRY:
         do_machine_check(regs);
@@ -2442,7 +2450,6 @@ void vmx_vmexit_handler(struct cpu_user_
                  (X86_EVENTTYPE_NMI << 8) )
                 goto exit_and_crash;
             HVMTRACE_0D(NMI);
-            self_nmi(); /* Real NMI, vector 2: normal processing. */
             break;
         case TRAP_machine_check:
             HVMTRACE_0D(MCE);

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2012-11-22 10:52 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-13 20:08 [PATCH V2] xen: vmx: Use an INT 2 call to process real NMI's instead of self_nmi() in VMEXIT handler Malcolm Crossley
2012-11-14 10:06 ` Jan Beulich
2012-11-15 16:41   ` Tim Deegan
2012-11-15 16:52     ` Andrew Cooper
2012-11-15 17:25       ` Tim Deegan
2012-11-16  8:17         ` Jan Beulich
2012-11-16  9:59           ` Mats Petersson
2012-11-16 10:18             ` Keir Fraser
2012-11-15 17:03     ` Mats Petersson
2012-11-15 17:15       ` Tim Deegan
2012-11-15 17:33         ` Mats Petersson
2012-11-15 17:44           ` Tim Deegan
2012-11-15 18:23             ` Mats Petersson
2012-11-16  8:07     ` Jan Beulich
2012-11-16 10:56       ` Tim Deegan
2012-11-16 11:23         ` Jan Beulich
2012-11-16 11:52           ` Andrew Cooper
2012-11-16 13:53             ` Tim Deegan
2012-11-16 14:11               ` Andrew Cooper
2012-11-22  8:58 ` Jan Beulich
2012-11-22 10:52   ` Andrew Cooper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).