diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2007-12-19 15:51:01 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2007-12-19 15:51:01 +0000 |
commit | 7f96e0454bd58cc3a5af4f3936fe18e9234e40e5 (patch) | |
tree | 64b17edf8337b89762491dab9de80395c9b33f73 | |
parent | db9b8625ccaa654a9f0395ef500ee83f7b662320 (diff) | |
download | xen-7f96e0454bd58cc3a5af4f3936fe18e9234e40e5.tar.gz xen-7f96e0454bd58cc3a5af4f3936fe18e9234e40e5.tar.bz2 xen-7f96e0454bd58cc3a5af4f3936fe18e9234e40e5.zip |
vmx: Do not set bit 1 of FEATURE_CONTROL MSR if SMX is not supported
by the CPU. Also generally beef up robustness of VMXON instruction.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r-- | xen/arch/x86/hvm/vmx/vmcs.c | 14 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 6 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/vmx/vmx.h | 30 |
3 files changed, 29 insertions, 21 deletions
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 1cb1746516..4ecbccef66 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -274,19 +274,13 @@ int vmx_cpu_up(void) } else { - eax = (IA32_FEATURE_CONTROL_MSR_LOCK | - IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_OUTSIDE_SMX | - IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_INSIDE_SMX); + eax = IA32_FEATURE_CONTROL_MSR_LOCK; + eax |= IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_OUTSIDE_SMX; + if ( test_bit(X86_FEATURE_SMXE, &boot_cpu_data.x86_capability) ) + eax |= IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_INSIDE_SMX; wrmsr(IA32_FEATURE_CONTROL_MSR, eax, 0); } - if ( !tboot_in_measured_env() && - !(eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_OUTSIDE_SMX) ) - { - printk("VMX only allowed in SMX but SMX not active.\n"); - return 0; - } - vmx_init_vmcs_config(); INIT_LIST_HEAD(&this_cpu(active_vmcs_list)); diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index d814e296aa..e8aa866239 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -719,6 +719,7 @@ asmlinkage void do_invalid_op(struct cpu_user_regs *regs) struct bug_frame bug; struct bug_frame_str bug_str; char *filename, *predicate, *eip = (char *)regs->eip; + unsigned long fixup; int id, lineno; DEBUGGER_trap_entry(TRAP_invalid_op, regs); @@ -789,6 +790,11 @@ asmlinkage void do_invalid_op(struct cpu_user_regs *regs) predicate, filename, lineno); die: + if ( (fixup = search_exception_table(regs->eip)) != 0 ) + { + regs->eip = fixup; + return; + } DEBUGGER_trap_fatal(TRAP_invalid_op, regs); show_execution_state(regs); panic("FATAL TRAP: vector = %d (invalid opcode)\n", TRAP_invalid_op); diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index be6e2d7429..af50427ed3 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -240,23 +240,31 @@ static inline void __vm_clear_bit(unsigned long field, unsigned int bit) __vmwrite(field, __vmread(field) & ~(1UL << bit)); } -static inline void __vmxoff (void) +static inline void __vmxoff(void) { - __asm__ __volatile__ ( VMXOFF_OPCODE - ::: "memory"); + asm volatile ( + VMXOFF_OPCODE + : : : "memory" ); } -static inline int __vmxon (u64 addr) +static inline int __vmxon(u64 addr) { int rc; - __asm__ __volatile__ ( VMXON_OPCODE - MODRM_EAX_06 - /* CF==1 or ZF==1 --> rc = -1 */ - "setna %b0 ; neg %0" - : "=q" (rc) - : "0" (0), "a" (&addr) - : "memory"); + asm volatile ( + "1: " VMXON_OPCODE MODRM_EAX_06 "\n" + " setna %b0 ; neg %0\n" /* CF==1 or ZF==1 --> rc = -1 */ + "2:\n" + ".section .fixup,\"ax\"\n" + "3: not %0 ; jmp 2b\n" /* #UD --> rc = -1 */ + ".previous\n" + ".section __ex_table,\"a\"\n" + " "__FIXUP_ALIGN"\n" + " "__FIXUP_WORD" 1b,3b\n" + ".previous\n" + : "=q" (rc) + : "0" (0), "a" (&addr) + : "memory"); return rc; } |