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

[Xen-changelog] [xen-unstable] [HVM][VMX] Fix problem taking an NMI on entry/exit



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1168445855 0
# Node ID 160ff08f8b1ff4c7dbd79d2b54efc49cc6bd079a
# Parent  5c5d9692f559ab6b8f7cddc32d6f656e1ed3b888
[HVM][VMX] Fix problem taking an NMI on entry/exit
to/from VMX mode. Also cleans up code a bit.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/vmx/vmcs.c         |    9 ++++++++-
 xen/arch/x86/hvm/vmx/x86_32/exits.S |   31 +------------------------------
 xen/arch/x86/hvm/vmx/x86_64/exits.S |   27 +--------------------------
 xen/arch/x86/oprofile/nmi_int.c     |    2 +-
 xen/arch/x86/traps.c                |    2 +-
 5 files changed, 12 insertions(+), 59 deletions(-)

diff -r 5c5d9692f559 -r 160ff08f8b1f xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Wed Jan 10 15:05:00 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Wed Jan 10 16:17:35 2007 +0000
@@ -278,7 +278,14 @@ static void vmx_set_host_env(struct vcpu
     host_env.tr_base = (unsigned long) &init_tss[cpu];
     __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector);
     __vmwrite(HOST_TR_BASE, host_env.tr_base);
-    __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
+
+    /*
+     * Skip end of cpu_user_regs when entering the hypervisor because the
+     * CPU does not save context onto the stack. SS,RSP,CS,RIP,RFLAGS,etc
+     * all get saved into the VMCS instead.
+     */
+    __vmwrite(HOST_RSP,
+              (unsigned long)&get_cpu_info()->guest_cpu_user_regs.error_code);
 }
 
 static void construct_vmcs(struct vcpu *v)
diff -r 5c5d9692f559 -r 160ff08f8b1f xen/arch/x86/hvm/vmx/x86_32/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_32/exits.S       Wed Jan 10 15:05:00 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S       Wed Jan 10 16:17:35 2007 +0000
@@ -29,35 +29,7 @@
         andl $~3,reg;            \
         movl (reg),reg;
 
-/*
- * At VMExit time the processor saves the guest selectors, esp, eip, 
- * and eflags. Therefore we don't save them, but simply decrement 
- * the kernel stack pointer to make it consistent with the stack frame 
- * at usual interruption time. The eflags of the host is not saved by VMX, 
- * and we set it to the fixed value.
- *
- * We also need the room, especially because orig_eax field is used 
- * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following:
- *   (10) u32 gs;                 
- *   (9)  u32 fs;
- *   (8)  u32 ds;
- *   (7)  u32 es;
- *               <- get_stack_bottom() (= HOST_ESP)
- *   (6)  u32 ss;
- *   (5)  u32 esp;
- *   (4)  u32 eflags;
- *   (3)  u32 cs;
- *   (2)  u32 eip;
- * (2/1)  u16 entry_vector;
- * (1/1)  u16 error_code;
- * However, get_stack_bottom() actually returns 20 bytes before the real
- * bottom of the stack to allow space for:
- * domain pointer, DS, ES, FS, GS. Therefore, we effectively skip 6 registers.
- */
-
-#define NR_SKIPPED_REGS 6 /* See the above explanation */
 #define HVM_SAVE_ALL_NOSEGREGS                                              \
-        subl $(NR_SKIPPED_REGS*4), %esp;                                    \
         movl $0, 0xc(%esp);  /* XXX why do we need to force eflags==0 ?? */ \
         pushl %eax;                                                         \
         pushl %ebp;                                                         \
@@ -74,8 +46,7 @@
         popl %esi;                              \
         popl %edi;                              \
         popl %ebp;                              \
-        popl %eax;                              \
-        addl $(NR_SKIPPED_REGS*4), %esp
+        popl %eax
 
         ALIGN
 ENTRY(vmx_asm_vmexit_handler)
diff -r 5c5d9692f559 -r 160ff08f8b1f xen/arch/x86/hvm/vmx/x86_64/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_64/exits.S       Wed Jan 10 15:05:00 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S       Wed Jan 10 16:17:35 2007 +0000
@@ -29,31 +29,7 @@
         andq $~7,reg;            \
         movq (reg),reg;
 
-/*
- * At VMExit time the processor saves the guest selectors, rsp, rip, 
- * and rflags. Therefore we don't save them, but simply decrement 
- * the kernel stack pointer to make it consistent with the stack frame 
- * at usual interruption time. The rflags of the host is not saved by VMX, 
- * and we set it to the fixed value.
- *
- * We also need the room, especially because orig_eax field is used 
- * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following:
- *   (10) u64 gs;                 
- *   (9)  u64 fs;
- *   (8)  u64 ds;
- *   (7)  u64 es;
- *               <- get_stack_bottom() (= HOST_ESP)
- *   (6)  u64 ss;
- *   (5)  u64 rsp;
- *   (4)  u64 rflags;
- *   (3)  u64 cs;
- *   (2)  u64 rip;
- * (2/1)  u32 entry_vector;
- * (1/1)  u32 error_code;
- */
-#define NR_SKIPPED_REGS 6 /* See the above explanation */
 #define HVM_SAVE_ALL_NOSEGREGS                  \
-        subq $(NR_SKIPPED_REGS*8), %rsp;        \
         pushq %rdi;                             \
         pushq %rsi;                             \
         pushq %rdx;                             \
@@ -85,8 +61,7 @@
         popq %rcx;                              \
         popq %rdx;                              \
         popq %rsi;                              \
-        popq %rdi;                              \
-        addq $(NR_SKIPPED_REGS*8), %rsp;
+        popq %rdi
 
         ALIGN
 ENTRY(vmx_asm_vmexit_handler)
diff -r 5c5d9692f559 -r 160ff08f8b1f xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c   Wed Jan 10 15:05:00 2007 +0000
+++ b/xen/arch/x86/oprofile/nmi_int.c   Wed Jan 10 16:17:35 2007 +0000
@@ -42,7 +42,7 @@ extern size_t strlcpy(char *dest, const 
 extern size_t strlcpy(char *dest, const char *src, size_t size);
 
 
-int nmi_callback(struct cpu_user_regs *regs, int cpu)
+static int nmi_callback(struct cpu_user_regs *regs, int cpu)
 {
        int xen_mode, ovf;
 
diff -r 5c5d9692f559 -r 160ff08f8b1f xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Jan 10 15:05:00 2007 +0000
+++ b/xen/arch/x86/traps.c      Wed Jan 10 16:17:35 2007 +0000
@@ -1854,7 +1854,7 @@ static int dummy_nmi_callback(struct cpu
 }
  
 static nmi_callback_t nmi_callback = dummy_nmi_callback;
- 
+
 asmlinkage void do_nmi(struct cpu_user_regs *regs)
 {
     unsigned int cpu = smp_processor_id();

_______________________________________________
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®.