x86: Clean up NMI delivery logic. Allow set_trap_table vector 2 to be
authorKeir Fraser <keir@xensource.com>
Mon, 29 Oct 2007 09:49:39 +0000 (09:49 +0000)
committerKeir Fraser <keir@xensource.com>
Mon, 29 Oct 2007 09:49:39 +0000 (09:49 +0000)
specified as not disabling event delivery, just like any other vector.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/traps.c
xen/arch/x86/x86_32/asm-offsets.c
xen/arch/x86/x86_32/entry.S
xen/arch/x86/x86_64/asm-offsets.c
xen/arch/x86/x86_64/compat/entry.S
xen/arch/x86/x86_64/compat/traps.c
xen/arch/x86/x86_64/entry.S

index 18cfc004232e654e04bd7624d2d9a733ebde5948..9ac1d52cbb5f1c1a0ec0e9b49d596757c72bb6eb 100644 (file)
@@ -413,6 +413,19 @@ static int do_guest_trap(
     return 0;
 }
 
+/*
+ * Called from asm to set up the NMI trapbounce info.
+ * Returns 0 if no callback is set up, else 1.
+ */
+asmlinkage int set_guest_nmi_trapbounce(void)
+{
+    struct vcpu *v = current;
+    struct trap_bounce *tb = &v->arch.trap_bounce;
+    do_guest_trap(TRAP_nmi, guest_cpu_user_regs(), 0);
+    tb->flags &= ~TBF_EXCEPTION; /* not needed for NMI delivery path */
+    return !null_trap_bounce(v, tb);
+}
+
 static inline int do_trap(
     int trapnr, struct cpu_user_regs *regs, int use_error_code)
 {
@@ -2706,12 +2719,6 @@ long do_set_trap_table(XEN_GUEST_HANDLE(trap_info_t) traps)
         if ( cur.address == 0 )
             break;
 
-        if ( (cur.vector == TRAP_nmi) && !TI_GET_IF(&cur) )
-        {
-            rc = -EINVAL;
-            break;
-        }
-
         fixup_guest_code_selector(current->domain, cur.cs);
 
         memcpy(&dst[cur.vector], &cur, sizeof(cur));
index bb59330fbf51b5c6ebce05da8dc4e3ec7921224e..2b757c18e29a2865da5b9f937c27dd07376efbbe 100644 (file)
@@ -65,11 +65,6 @@ void __dummy__(void)
     OFFSET(VCPU_kernel_sp, struct vcpu,
            arch.guest_context.kernel_sp);
     OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
-    OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt);
-    OFFSET(VCPU_nmi_cs, struct vcpu,
-           arch.guest_context.trap_ctxt[TRAP_nmi].cs);
-    OFFSET(VCPU_nmi_addr, struct vcpu,
-           arch.guest_context.trap_ctxt[TRAP_nmi].address);
     OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending);
     OFFSET(VCPU_nmi_masked, struct vcpu, nmi_masked);
     DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events);
index ca1575c1c688f4f2aca29853b2e399d901dd0abd..35273923a57dd9007f6afde1fa190912f26d1ccb 100644 (file)
@@ -259,18 +259,13 @@ process_softirqs:
 process_nmi:
         testb $1,VCPU_nmi_masked(%ebx)
         jnz  test_guest_events
+        sti
         movb $0,VCPU_nmi_pending(%ebx)
-        movzwl VCPU_nmi_cs(%ebx),%eax
-        movl VCPU_nmi_addr(%ebx),%ecx
+        call set_guest_nmi_trapbounce
         test %eax,%eax
-        jz   test_guest_events
+        jz   test_all_events
         movb $1,VCPU_nmi_masked(%ebx)
-        sti
         leal VCPU_trap_bounce(%ebx),%edx
-        movw %ax,TRAPBOUNCE_cs(%edx)
-        movl %ecx,TRAPBOUNCE_eip(%edx)
-        movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx)
-        movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
         call create_bounce_frame
         jmp  test_all_events
 
index bcb025688c4e54dda10ba65330707267763f49c1..9bb41bc79451f28baa758f7b52ba856bced4fd60 100644 (file)
@@ -86,11 +86,6 @@ void __dummy__(void)
     OFFSET(VCPU_kernel_sp, struct vcpu, arch.guest_context.kernel_sp);
     OFFSET(VCPU_kernel_ss, struct vcpu, arch.guest_context.kernel_ss);
     OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
-    OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt);
-    OFFSET(VCPU_nmi_cs, struct vcpu,
-           arch.guest_context.trap_ctxt[TRAP_nmi].cs);
-    OFFSET(VCPU_nmi_addr, struct vcpu,
-           arch.guest_context.trap_ctxt[TRAP_nmi].address);
     OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending);
     OFFSET(VCPU_nmi_masked, struct vcpu, nmi_masked);
     DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events);
index 6d7c693e71c5aff963605524ac02a662bada5bf0..80736ecc3f87a81b54af353eb480ede81c846e10 100644 (file)
@@ -133,18 +133,13 @@ compat_process_softirqs:
 compat_process_nmi:
         testb $1,VCPU_nmi_masked(%rbx)
         jnz   compat_test_guest_events
+        sti
         movb  $0,VCPU_nmi_pending(%rbx)
-        movzwl VCPU_nmi_cs(%rbx),%eax
-        movl  VCPU_nmi_addr(%rbx),%ecx
+        call  set_guest_nmi_trapbounce
         testl %eax,%eax
-        jz    compat_test_guest_events
+        jz    compat_test_all_events
         movb  $1,VCPU_nmi_masked(%rbx)
-        sti
         leaq  VCPU_trap_bounce(%rbx),%rdx
-        movw  %ax,TRAPBOUNCE_cs(%rdx)
-        movl  %ecx,TRAPBOUNCE_eip(%rdx)
-        movw  $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx)
-        movb  $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
         call  compat_create_bounce_frame
         jmp   compat_test_all_events
 
index fddbbd27d825d0f08873f86313ccfae381985c24..65c1e901473e9cbc2347b3d2fdf9f1a9b0b9d0b4 100644 (file)
@@ -315,12 +315,6 @@ int compat_set_trap_table(XEN_GUEST_HANDLE(trap_info_compat_t) traps)
         if ( cur.address == 0 )
             break;
 
-        if ( (cur.vector == TRAP_nmi) && !TI_GET_IF(&cur) )
-        {
-            rc = -EINVAL;
-            break;
-        }
-
         fixup_guest_code_selector(current->domain, cur.cs);
 
         XLAT_trap_info(dst + cur.vector, &cur);
index 34c9c2a9239825a92a9d63f76a63464e87174570..d4b112bc2f972a0a115934d229ed9f4d6e57060c 100644 (file)
@@ -235,15 +235,13 @@ process_softirqs:
 process_nmi:
         testb $1,VCPU_nmi_masked(%rbx)
         jnz  test_guest_events
+        sti
         movb $0,VCPU_nmi_pending(%rbx)
-        movq VCPU_nmi_addr(%rbx),%rax
-        test %rax,%rax
-        jz   test_guest_events
+        call set_guest_nmi_trapbounce
+        test %eax,%eax
+        jz   test_all_events
         movb $1,VCPU_nmi_masked(%rbx)
-        sti
         leaq VCPU_trap_bounce(%rbx),%rdx
-        movq %rax,TRAPBOUNCE_eip(%rdx)
-        movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
         call create_bounce_frame
         jmp  test_all_events