diff options
author | Shane Wang <shane.wang@intel.com> | 2010-04-29 12:09:01 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-19 04:36:34 -0400 |
commit | cafd66595d92591e4bd25c3904e004fc6f897e2d (patch) | |
tree | 42f38daf5d634ccf958da89de2a20937849deb92 | |
parent | f1d86e469b60f9e1afed5c17a6e723c2c9c55ceb (diff) |
KVM: VMX: enable VMXON check with SMX enabled (Intel TXT)
Per document, for feature control MSR:
Bit 1 enables VMXON in SMX operation. If the bit is clear, execution
of VMXON in SMX operation causes a general-protection exception.
Bit 2 enables VMXON outside SMX operation. If the bit is clear, execution
of VMXON outside SMX operation causes a general-protection exception.
This patch is to enable this kind of check with SMX for VMXON in KVM.
Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/include/asm/msr-index.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/tboot.c | 1 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 32 | ||||
-rw-r--r-- | include/linux/tboot.h | 1 |
4 files changed, 26 insertions, 13 deletions
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index bc473acfa7f9..f9324851eba0 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
@@ -202,8 +202,9 @@ | |||
202 | #define MSR_IA32_EBL_CR_POWERON 0x0000002a | 202 | #define MSR_IA32_EBL_CR_POWERON 0x0000002a |
203 | #define MSR_IA32_FEATURE_CONTROL 0x0000003a | 203 | #define MSR_IA32_FEATURE_CONTROL 0x0000003a |
204 | 204 | ||
205 | #define FEATURE_CONTROL_LOCKED (1<<0) | 205 | #define FEATURE_CONTROL_LOCKED (1<<0) |
206 | #define FEATURE_CONTROL_VMXON_ENABLED (1<<2) | 206 | #define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) |
207 | #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) | ||
207 | 208 | ||
208 | #define MSR_IA32_APICBASE 0x0000001b | 209 | #define MSR_IA32_APICBASE 0x0000001b |
209 | #define MSR_IA32_APICBASE_BSP (1<<8) | 210 | #define MSR_IA32_APICBASE_BSP (1<<8) |
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 86c9f91b48ae..46b827778d16 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | /* Global pointer to shared data; NULL means no measured launch. */ | 47 | /* Global pointer to shared data; NULL means no measured launch. */ |
48 | struct tboot *tboot __read_mostly; | 48 | struct tboot *tboot __read_mostly; |
49 | EXPORT_SYMBOL(tboot); | ||
49 | 50 | ||
50 | /* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */ | 51 | /* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */ |
51 | #define AP_WAIT_TIMEOUT 1 | 52 | #define AP_WAIT_TIMEOUT 1 |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c4f3955c64e0..d2a47aefdee7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/ftrace_event.h> | 28 | #include <linux/ftrace_event.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/tboot.h> | ||
30 | #include "kvm_cache_regs.h" | 31 | #include "kvm_cache_regs.h" |
31 | #include "x86.h" | 32 | #include "x86.h" |
32 | 33 | ||
@@ -1272,9 +1273,16 @@ static __init int vmx_disabled_by_bios(void) | |||
1272 | u64 msr; | 1273 | u64 msr; |
1273 | 1274 | ||
1274 | rdmsrl(MSR_IA32_FEATURE_CONTROL, msr); | 1275 | rdmsrl(MSR_IA32_FEATURE_CONTROL, msr); |
1275 | return (msr & (FEATURE_CONTROL_LOCKED | | 1276 | if (msr & FEATURE_CONTROL_LOCKED) { |
1276 | FEATURE_CONTROL_VMXON_ENABLED)) | 1277 | if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX) |
1277 | == FEATURE_CONTROL_LOCKED; | 1278 | && tboot_enabled()) |
1279 | return 1; | ||
1280 | if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX) | ||
1281 | && !tboot_enabled()) | ||
1282 | return 1; | ||
1283 | } | ||
1284 | |||
1285 | return 0; | ||
1278 | /* locked but not enabled */ | 1286 | /* locked but not enabled */ |
1279 | } | 1287 | } |
1280 | 1288 | ||
@@ -1282,21 +1290,23 @@ static int hardware_enable(void *garbage) | |||
1282 | { | 1290 | { |
1283 | int cpu = raw_smp_processor_id(); | 1291 | int cpu = raw_smp_processor_id(); |
1284 | u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); | 1292 | u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); |
1285 | u64 old; | 1293 | u64 old, test_bits; |
1286 | 1294 | ||
1287 | if (read_cr4() & X86_CR4_VMXE) | 1295 | if (read_cr4() & X86_CR4_VMXE) |
1288 | return -EBUSY; | 1296 | return -EBUSY; |
1289 | 1297 | ||
1290 | INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu)); | 1298 | INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu)); |
1291 | rdmsrl(MSR_IA32_FEATURE_CONTROL, old); | 1299 | rdmsrl(MSR_IA32_FEATURE_CONTROL, old); |
1292 | if ((old & (FEATURE_CONTROL_LOCKED | | 1300 | |
1293 | FEATURE_CONTROL_VMXON_ENABLED)) | 1301 | test_bits = FEATURE_CONTROL_LOCKED; |
1294 | != (FEATURE_CONTROL_LOCKED | | 1302 | test_bits |= FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX; |
1295 | FEATURE_CONTROL_VMXON_ENABLED)) | 1303 | if (tboot_enabled()) |
1304 | test_bits |= FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX; | ||
1305 | |||
1306 | if ((old & test_bits) != test_bits) { | ||
1296 | /* enable and lock */ | 1307 | /* enable and lock */ |
1297 | wrmsrl(MSR_IA32_FEATURE_CONTROL, old | | 1308 | wrmsrl(MSR_IA32_FEATURE_CONTROL, old | test_bits); |
1298 | FEATURE_CONTROL_LOCKED | | 1309 | } |
1299 | FEATURE_CONTROL_VMXON_ENABLED); | ||
1300 | write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */ | 1310 | write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */ |
1301 | asm volatile (ASM_VMX_VMXON_RAX | 1311 | asm volatile (ASM_VMX_VMXON_RAX |
1302 | : : "a"(&phys_addr), "m"(phys_addr) | 1312 | : : "a"(&phys_addr), "m"(phys_addr) |
diff --git a/include/linux/tboot.h b/include/linux/tboot.h index bf2a0c748878..1dba6ee55203 100644 --- a/include/linux/tboot.h +++ b/include/linux/tboot.h | |||
@@ -150,6 +150,7 @@ extern int tboot_force_iommu(void); | |||
150 | 150 | ||
151 | #else | 151 | #else |
152 | 152 | ||
153 | #define tboot_enabled() 0 | ||
153 | #define tboot_probe() do { } while (0) | 154 | #define tboot_probe() do { } while (0) |
154 | #define tboot_shutdown(shutdown_type) do { } while (0) | 155 | #define tboot_shutdown(shutdown_type) do { } while (0) |
155 | #define tboot_sleep(sleep_state, pm1a_control, pm1b_control) \ | 156 | #define tboot_sleep(sleep_state, pm1a_control, pm1b_control) \ |