ia64/xen-unstable
changeset 13375:160ff08f8b1f
[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@xensource.com>
to/from VMX mode. Also cleans up code a bit.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kfraser@localhost.localdomain |
---|---|
date | Wed Jan 10 16:17:35 2007 +0000 (2007-01-10) |
parents | 5c5d9692f559 |
children | aa127e545b73 |
files | xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/x86_32/exits.S xen/arch/x86/hvm/vmx/x86_64/exits.S xen/arch/x86/oprofile/nmi_int.c xen/arch/x86/traps.c |
line diff
1.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c Wed Jan 10 15:05:00 2007 +0000 1.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Wed Jan 10 16:17:35 2007 +0000 1.3 @@ -278,7 +278,14 @@ static void vmx_set_host_env(struct vcpu 1.4 host_env.tr_base = (unsigned long) &init_tss[cpu]; 1.5 __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector); 1.6 __vmwrite(HOST_TR_BASE, host_env.tr_base); 1.7 - __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); 1.8 + 1.9 + /* 1.10 + * Skip end of cpu_user_regs when entering the hypervisor because the 1.11 + * CPU does not save context onto the stack. SS,RSP,CS,RIP,RFLAGS,etc 1.12 + * all get saved into the VMCS instead. 1.13 + */ 1.14 + __vmwrite(HOST_RSP, 1.15 + (unsigned long)&get_cpu_info()->guest_cpu_user_regs.error_code); 1.16 } 1.17 1.18 static void construct_vmcs(struct vcpu *v)
2.1 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S Wed Jan 10 15:05:00 2007 +0000 2.2 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S Wed Jan 10 16:17:35 2007 +0000 2.3 @@ -29,35 +29,7 @@ 2.4 andl $~3,reg; \ 2.5 movl (reg),reg; 2.6 2.7 -/* 2.8 - * At VMExit time the processor saves the guest selectors, esp, eip, 2.9 - * and eflags. Therefore we don't save them, but simply decrement 2.10 - * the kernel stack pointer to make it consistent with the stack frame 2.11 - * at usual interruption time. The eflags of the host is not saved by VMX, 2.12 - * and we set it to the fixed value. 2.13 - * 2.14 - * We also need the room, especially because orig_eax field is used 2.15 - * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following: 2.16 - * (10) u32 gs; 2.17 - * (9) u32 fs; 2.18 - * (8) u32 ds; 2.19 - * (7) u32 es; 2.20 - * <- get_stack_bottom() (= HOST_ESP) 2.21 - * (6) u32 ss; 2.22 - * (5) u32 esp; 2.23 - * (4) u32 eflags; 2.24 - * (3) u32 cs; 2.25 - * (2) u32 eip; 2.26 - * (2/1) u16 entry_vector; 2.27 - * (1/1) u16 error_code; 2.28 - * However, get_stack_bottom() actually returns 20 bytes before the real 2.29 - * bottom of the stack to allow space for: 2.30 - * domain pointer, DS, ES, FS, GS. Therefore, we effectively skip 6 registers. 2.31 - */ 2.32 - 2.33 -#define NR_SKIPPED_REGS 6 /* See the above explanation */ 2.34 #define HVM_SAVE_ALL_NOSEGREGS \ 2.35 - subl $(NR_SKIPPED_REGS*4), %esp; \ 2.36 movl $0, 0xc(%esp); /* XXX why do we need to force eflags==0 ?? */ \ 2.37 pushl %eax; \ 2.38 pushl %ebp; \ 2.39 @@ -74,8 +46,7 @@ 2.40 popl %esi; \ 2.41 popl %edi; \ 2.42 popl %ebp; \ 2.43 - popl %eax; \ 2.44 - addl $(NR_SKIPPED_REGS*4), %esp 2.45 + popl %eax 2.46 2.47 ALIGN 2.48 ENTRY(vmx_asm_vmexit_handler)
3.1 --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S Wed Jan 10 15:05:00 2007 +0000 3.2 +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S Wed Jan 10 16:17:35 2007 +0000 3.3 @@ -29,31 +29,7 @@ 3.4 andq $~7,reg; \ 3.5 movq (reg),reg; 3.6 3.7 -/* 3.8 - * At VMExit time the processor saves the guest selectors, rsp, rip, 3.9 - * and rflags. Therefore we don't save them, but simply decrement 3.10 - * the kernel stack pointer to make it consistent with the stack frame 3.11 - * at usual interruption time. The rflags of the host is not saved by VMX, 3.12 - * and we set it to the fixed value. 3.13 - * 3.14 - * We also need the room, especially because orig_eax field is used 3.15 - * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following: 3.16 - * (10) u64 gs; 3.17 - * (9) u64 fs; 3.18 - * (8) u64 ds; 3.19 - * (7) u64 es; 3.20 - * <- get_stack_bottom() (= HOST_ESP) 3.21 - * (6) u64 ss; 3.22 - * (5) u64 rsp; 3.23 - * (4) u64 rflags; 3.24 - * (3) u64 cs; 3.25 - * (2) u64 rip; 3.26 - * (2/1) u32 entry_vector; 3.27 - * (1/1) u32 error_code; 3.28 - */ 3.29 -#define NR_SKIPPED_REGS 6 /* See the above explanation */ 3.30 #define HVM_SAVE_ALL_NOSEGREGS \ 3.31 - subq $(NR_SKIPPED_REGS*8), %rsp; \ 3.32 pushq %rdi; \ 3.33 pushq %rsi; \ 3.34 pushq %rdx; \ 3.35 @@ -85,8 +61,7 @@ 3.36 popq %rcx; \ 3.37 popq %rdx; \ 3.38 popq %rsi; \ 3.39 - popq %rdi; \ 3.40 - addq $(NR_SKIPPED_REGS*8), %rsp; 3.41 + popq %rdi 3.42 3.43 ALIGN 3.44 ENTRY(vmx_asm_vmexit_handler)
4.1 --- a/xen/arch/x86/oprofile/nmi_int.c Wed Jan 10 15:05:00 2007 +0000 4.2 +++ b/xen/arch/x86/oprofile/nmi_int.c Wed Jan 10 16:17:35 2007 +0000 4.3 @@ -42,7 +42,7 @@ extern int is_profiled(struct domain *d) 4.4 extern size_t strlcpy(char *dest, const char *src, size_t size); 4.5 4.6 4.7 -int nmi_callback(struct cpu_user_regs *regs, int cpu) 4.8 +static int nmi_callback(struct cpu_user_regs *regs, int cpu) 4.9 { 4.10 int xen_mode, ovf; 4.11
5.1 --- a/xen/arch/x86/traps.c Wed Jan 10 15:05:00 2007 +0000 5.2 +++ b/xen/arch/x86/traps.c Wed Jan 10 16:17:35 2007 +0000 5.3 @@ -1854,7 +1854,7 @@ static int dummy_nmi_callback(struct cpu 5.4 } 5.5 5.6 static nmi_callback_t nmi_callback = dummy_nmi_callback; 5.7 - 5.8 + 5.9 asmlinkage void do_nmi(struct cpu_user_regs *regs) 5.10 { 5.11 unsigned int cpu = smp_processor_id();