[VMX] Check INTR_TYPE is NMI before doing physical NMI processing.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 8 Nov 2006 15:10:21 +0000 (15:10 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 8 Nov 2006 15:10:21 +0000 (15:10 +0000)
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/vmx/vmx.h

index 84febc6b1a67110342b4ea6faebd94f5d5bd72ac..cafa501316192085afa9b1e21cec381faff770f5 100644 (file)
@@ -2112,17 +2112,19 @@ 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 vector;
+        unsigned int intr_info, vector;
 
-        if ( __vmread(VM_EXIT_INTR_INFO, &vector) ||
-             !(vector & INTR_INFO_VALID_MASK) )
-            domain_crash_synchronous();
-        vector &= INTR_INFO_VECTOR_MASK;
+        if ( __vmread(VM_EXIT_INTR_INFO, &intr_info) ||
+             !(intr_info & INTR_INFO_VALID_MASK) )
+            __hvm_bug(regs);
+
+        vector = intr_info & INTR_INFO_VECTOR_MASK;
 
         TRACE_VMEXIT(1, vector);
         perfc_incra(cause_vector, vector);
 
-        switch ( vector ) {
+        switch ( vector )
+        {
 #ifdef XEN_DEBUGGER
         case TRAP_debug:
         {
@@ -2198,7 +2200,10 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
             break;
         }
         case TRAP_nmi:
-            do_nmi(regs);
+            if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI )
+                do_nmi(regs); /* Real NMI, vector 2: normal processing. */
+            else
+                vmx_reflect_exception(v);
             break;
         default:
             vmx_reflect_exception(v);
index 919acdc706e056196a4e0b84a5cfed07f841bf5d..8c9f07a0b7f0a634d7922f334d8bf7f3d5878fc7 100644 (file)
@@ -93,6 +93,7 @@ extern unsigned int cpu_rev;
 #define INTR_INFO_VALID_MASK            0x80000000      /* 31 */
 
 #define INTR_TYPE_EXT_INTR              (0 << 8)    /* external interrupt */
+#define INTR_TYPE_NMI                   (2 << 8)    /* NMI                */
 #define INTR_TYPE_HW_EXCEPTION          (3 << 8)    /* hardware exception */
 #define INTR_TYPE_SW_EXCEPTION          (6 << 8)    /* software exception */