[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: Allow NMI callback CS to be specified via set_trap_table()



# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1193054672 -3600
# Node ID 42d8dadb5864eac0140262b9475a7b1ed150b607
# Parent  183a2d6eaadf5a24e231de4b473d0ff683ebd2c2
x86: Allow NMI callback CS to be specified via set_trap_table()
hypercall.
Based on a patch by Jan Beulich.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/traps.c                      |   37 ++++++++++++++++++++++++++++++
 xen/arch/x86/x86_32/asm-offsets.c         |    5 +++-
 xen/arch/x86/x86_32/entry.S               |    6 +++-
 xen/arch/x86/x86_64/asm-offsets.c         |    5 +++-
 xen/arch/x86/x86_64/compat/entry.S        |    6 +++-
 xen/arch/x86/x86_64/compat/traps.c        |    6 ++++
 xen/common/kernel.c                       |   34 ---------------------------
 xen/include/asm-ia64/linux-null/asm/nmi.h |    8 +++++-
 xen/include/asm-powerpc/nmi.h             |    3 ++
 xen/include/asm-x86/nmi.h                 |   15 ++++++++++++
 xen/include/xen/nmi.h                     |   15 ------------
 xen/include/xen/sched.h                   |    2 -
 12 files changed, 84 insertions(+), 58 deletions(-)

diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/arch/x86/traps.c      Mon Oct 22 13:04:32 2007 +0100
@@ -2229,6 +2229,37 @@ void __init trap_init(void)
     open_softirq(NMI_SOFTIRQ, nmi_softirq);
 }
 
+long register_guest_nmi_callback(unsigned long address)
+{
+    struct vcpu *v = current;
+    struct domain *d = current->domain;
+    struct trap_info *t = &v->arch.guest_context.trap_ctxt[TRAP_nmi];
+
+    t->vector  = TRAP_nmi;
+    t->flags   = 0;
+    t->cs      = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS;
+    t->address = address;
+    TI_SET_IF(t, 1);
+
+    /*
+     * If no handler was registered we can 'lose the NMI edge'. Re-assert it
+     * now.
+     */
+    if ( (v->vcpu_id == 0) && (arch_get_nmi_reason(d) != 0) )
+        v->nmi_pending = 1;
+
+    return 0;
+}
+
+long unregister_guest_nmi_callback(void)
+{
+    struct vcpu *v = current;
+    struct trap_info *t = &v->arch.guest_context.trap_ctxt[TRAP_nmi];
+
+    memset(t, 0, sizeof(*t));
+
+    return 0;
+}
 
 long do_set_trap_table(XEN_GUEST_HANDLE(trap_info_t) traps)
 {
@@ -2261,6 +2292,12 @@ long do_set_trap_table(XEN_GUEST_HANDLE(
 
         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);
 
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_32/asm-offsets.c
--- a/xen/arch/x86/x86_32/asm-offsets.c Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/arch/x86/x86_32/asm-offsets.c Mon Oct 22 13:04:32 2007 +0100
@@ -66,7 +66,10 @@ void __dummy__(void)
            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_addr, struct vcpu, nmi_addr);
+    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);
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/arch/x86/x86_32/entry.S       Mon Oct 22 13:04:32 2007 +0100
@@ -257,13 +257,15 @@ process_nmi:
         testb $1,VCPU_nmi_masked(%ebx)
         jnz  test_guest_events
         movb $0,VCPU_nmi_pending(%ebx)
-        movl VCPU_nmi_addr(%ebx),%eax
+        movzwl VCPU_nmi_cs(%ebx),%eax
+        movl VCPU_nmi_addr(%ebx),%ecx
         test %eax,%eax
         jz   test_guest_events
         movb $1,VCPU_nmi_masked(%ebx)
         sti
         leal VCPU_trap_bounce(%ebx),%edx
-        movl %eax,TRAPBOUNCE_eip(%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
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/arch/x86/x86_64/asm-offsets.c Mon Oct 22 13:04:32 2007 +0100
@@ -75,7 +75,10 @@ void __dummy__(void)
     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_addr, struct vcpu, nmi_addr);
+    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);
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S        Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/arch/x86/x86_64/compat/entry.S        Mon Oct 22 13:04:32 2007 +0100
@@ -131,13 +131,15 @@ compat_process_nmi:
         testb $1,VCPU_nmi_masked(%rbx)
         jnz   compat_test_guest_events
         movb  $0,VCPU_nmi_pending(%rbx)
-        movl  VCPU_nmi_addr(%rbx),%eax
+        movzwl VCPU_nmi_cs(%rbx),%eax
+        movl  VCPU_nmi_addr(%rbx),%ecx
         testl %eax,%eax
         jz    compat_test_guest_events
         movb  $1,VCPU_nmi_masked(%rbx)
         sti
         leaq  VCPU_trap_bounce(%rbx),%rdx
-        movl  %eax,TRAPBOUNCE_eip(%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
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_64/compat/traps.c
--- a/xen/arch/x86/x86_64/compat/traps.c        Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/arch/x86/x86_64/compat/traps.c        Mon Oct 22 13:04:32 2007 +0100
@@ -294,6 +294,12 @@ int compat_set_trap_table(XEN_GUEST_HAND
         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);
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/common/kernel.c
--- a/xen/common/kernel.c       Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/common/kernel.c       Mon Oct 22 13:04:32 2007 +0100
@@ -247,40 +247,6 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDL
     return -ENOSYS;
 }
 
-#ifndef COMPAT
-
-long register_guest_nmi_callback(unsigned long address)
-{
-    struct vcpu *v = current;
-    struct domain *d = current->domain;
-
-    if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
-        return -EINVAL;
-
-    v->nmi_addr = address;
-#ifdef CONFIG_X86
-    /*
-     * If no handler was registered we can 'lose the NMI edge'. Re-assert it
-     * now.
-     */
-    if ( arch_get_nmi_reason(d) != 0 )
-        v->nmi_pending = 1;
-#endif
-
-    return 0;
-}
-
-long unregister_guest_nmi_callback(void)
-{
-    struct vcpu *v = current;
-
-    v->nmi_addr = 0;
-
-    return 0;
-}
-
-#endif
-
 DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
 {
     struct xennmi_callback cb;
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/asm-ia64/linux-null/asm/nmi.h
--- a/xen/include/asm-ia64/linux-null/asm/nmi.h Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/include/asm-ia64/linux-null/asm/nmi.h Mon Oct 22 13:04:32 2007 +0100
@@ -1,1 +1,7 @@
-/* This file is intentionally left empty. */
+#ifndef __IA64_NMI_H__
+#define __IA64_NMI_H__
+
+#define register_guest_nmi_callback(a)  (-ENOSYS)
+#define unregister_guest_nmi_callback() (-ENOSYS)
+
+#endif /* __IA64_NMI_H__ */
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/asm-powerpc/nmi.h
--- a/xen/include/asm-powerpc/nmi.h     Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/include/asm-powerpc/nmi.h     Mon Oct 22 13:04:32 2007 +0100
@@ -3,4 +3,7 @@
 
 #include <public/nmi.h>
 
+#define register_guest_nmi_callback(a)  (-ENOSYS)
+#define unregister_guest_nmi_callback() (-ENOSYS)
+
 #endif /* ASM_NMI_H */
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/asm-x86/nmi.h
--- a/xen/include/asm-x86/nmi.h Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/include/asm-x86/nmi.h Mon Oct 22 13:04:32 2007 +0100
@@ -23,4 +23,19 @@ void set_nmi_callback(nmi_callback_t cal
  */
 void unset_nmi_callback(void);
  
+/**
+ * register_guest_nmi_callback
+ *
+ * The default NMI handler passes the NMI to a guest callback. This
+ * function registers the address of that callback.
+ */
+long register_guest_nmi_callback(unsigned long address);
+
+/**
+ * unregister_guest_nmi_callback
+ *
+ * Unregister a guest NMI handler.
+ */
+long unregister_guest_nmi_callback(void);
+
 #endif /* ASM_NMI_H */
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/xen/nmi.h
--- a/xen/include/xen/nmi.h     Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/include/xen/nmi.h     Mon Oct 22 13:04:32 2007 +0100
@@ -11,19 +11,4 @@
 
 #include <asm/nmi.h>
 
-/**
- * register_guest_nmi_callback
- *
- * The default NMI handler passes the NMI to a guest callback. This
- * function registers the address of that callback.
- */
-extern long register_guest_nmi_callback(unsigned long address);
-
-/**
- * unregister_guest_nmi_callback
- *
- * Unregister a guest NMI handler.
- */
-extern long unregister_guest_nmi_callback(void);
-
 #endif /* __XEN_NMI_H__ */
diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Mon Oct 22 11:11:04 2007 +0100
+++ b/xen/include/xen/sched.h   Mon Oct 22 13:04:32 2007 +0100
@@ -131,8 +131,6 @@ struct vcpu
     /* Bitmask of CPUs on which this VCPU may run. */
     cpumask_t        cpu_affinity;
 
-    unsigned long    nmi_addr;      /* NMI callback address. */
-
     /* Bitmask of CPUs which are holding onto this VCPU's state. */
     cpumask_t        vcpu_dirty_cpumask;
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.