aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/vmx.c35
-rw-r--r--arch/x86/kvm/x86.c3
2 files changed, 31 insertions, 7 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 183dc72b2523..e37b2a33fd24 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -373,6 +373,7 @@ struct nested_vmx {
373 * we must keep them pinned while L2 runs. 373 * we must keep them pinned while L2 runs.
374 */ 374 */
375 struct page *apic_access_page; 375 struct page *apic_access_page;
376 u64 msr_ia32_feature_control;
376}; 377};
377 378
378#define POSTED_INTR_ON 0 379#define POSTED_INTR_ON 0
@@ -2282,8 +2283,11 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
2282 2283
2283 switch (msr_index) { 2284 switch (msr_index) {
2284 case MSR_IA32_FEATURE_CONTROL: 2285 case MSR_IA32_FEATURE_CONTROL:
2285 *pdata = 0; 2286 if (nested_vmx_allowed(vcpu)) {
2286 break; 2287 *pdata = to_vmx(vcpu)->nested.msr_ia32_feature_control;
2288 break;
2289 }
2290 return 0;
2287 case MSR_IA32_VMX_BASIC: 2291 case MSR_IA32_VMX_BASIC:
2288 /* 2292 /*
2289 * This MSR reports some information about VMX support. We 2293 * This MSR reports some information about VMX support. We
@@ -2356,14 +2360,24 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
2356 return 1; 2360 return 1;
2357} 2361}
2358 2362
2359static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) 2363static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
2360{ 2364{
2365 u32 msr_index = msr_info->index;
2366 u64 data = msr_info->data;
2367 bool host_initialized = msr_info->host_initiated;
2368
2361 if (!nested_vmx_allowed(vcpu)) 2369 if (!nested_vmx_allowed(vcpu))
2362 return 0; 2370 return 0;
2363 2371
2364 if (msr_index == MSR_IA32_FEATURE_CONTROL) 2372 if (msr_index == MSR_IA32_FEATURE_CONTROL) {
2365 /* TODO: the right thing. */ 2373 if (!host_initialized &&
2374 to_vmx(vcpu)->nested.msr_ia32_feature_control
2375 & FEATURE_CONTROL_LOCKED)
2376 return 0;
2377 to_vmx(vcpu)->nested.msr_ia32_feature_control = data;
2366 return 1; 2378 return 1;
2379 }
2380
2367 /* 2381 /*
2368 * No need to treat VMX capability MSRs specially: If we don't handle 2382 * No need to treat VMX capability MSRs specially: If we don't handle
2369 * them, handle_wrmsr will #GP(0), which is correct (they are readonly) 2383 * them, handle_wrmsr will #GP(0), which is correct (they are readonly)
@@ -2494,7 +2508,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
2494 return 1; 2508 return 1;
2495 /* Otherwise falls through */ 2509 /* Otherwise falls through */
2496 default: 2510 default:
2497 if (vmx_set_vmx_msr(vcpu, msr_index, data)) 2511 if (vmx_set_vmx_msr(vcpu, msr_info))
2498 break; 2512 break;
2499 msr = find_msr_entry(vmx, msr_index); 2513 msr = find_msr_entry(vmx, msr_index);
2500 if (msr) { 2514 if (msr) {
@@ -5622,6 +5636,8 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
5622 struct kvm_segment cs; 5636 struct kvm_segment cs;
5623 struct vcpu_vmx *vmx = to_vmx(vcpu); 5637 struct vcpu_vmx *vmx = to_vmx(vcpu);
5624 struct vmcs *shadow_vmcs; 5638 struct vmcs *shadow_vmcs;
5639 const u64 VMXON_NEEDED_FEATURES = FEATURE_CONTROL_LOCKED
5640 | FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
5625 5641
5626 /* The Intel VMX Instruction Reference lists a bunch of bits that 5642 /* The Intel VMX Instruction Reference lists a bunch of bits that
5627 * are prerequisite to running VMXON, most notably cr4.VMXE must be 5643 * are prerequisite to running VMXON, most notably cr4.VMXE must be
@@ -5650,6 +5666,13 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
5650 skip_emulated_instruction(vcpu); 5666 skip_emulated_instruction(vcpu);
5651 return 1; 5667 return 1;
5652 } 5668 }
5669
5670 if ((vmx->nested.msr_ia32_feature_control & VMXON_NEEDED_FEATURES)
5671 != VMXON_NEEDED_FEATURES) {
5672 kvm_inject_gp(vcpu, 0);
5673 return 1;
5674 }
5675
5653 if (enable_shadow_vmcs) { 5676 if (enable_shadow_vmcs) {
5654 shadow_vmcs = alloc_vmcs(); 5677 shadow_vmcs = alloc_vmcs();
5655 if (!shadow_vmcs) 5678 if (!shadow_vmcs)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index abbcaa7f6e8f..d2caeb9e592f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -850,7 +850,8 @@ static u32 msrs_to_save[] = {
850#ifdef CONFIG_X86_64 850#ifdef CONFIG_X86_64
851 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, 851 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
852#endif 852#endif
853 MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA 853 MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
854 MSR_IA32_FEATURE_CONTROL
854}; 855};
855 856
856static unsigned num_msrs_to_save; 857static unsigned num_msrs_to_save;