[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |