aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiran Alon <liran.alon@oracle.com>2018-09-13 20:25:52 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2018-10-01 09:40:57 -0400
commit5f76f6f5ff96587af5acd5930f7d9fea81e0d1a8 (patch)
tree2bf618ad8060f0907b34aa17eabdec37cfc74b7a
parent4679b61f2640e07724507fcd9dc070517bc6e6cb (diff)
KVM: nVMX: Do not expose MPX VMX controls when guest MPX disabled
Before this commit, KVM exposes MPX VMX controls to L1 guest only based on if KVM and host processor supports MPX virtualization. However, these controls should be exposed to guest only in case guest vCPU supports MPX. Without this change, a L1 guest running with kernel which don't have commit 691bd4340bef ("kvm: vmx: allow host to access guest MSR_IA32_BNDCFGS") asserts in QEMU on the following: qemu-kvm: error: failed to set MSR 0xd90 to 0x0 qemu-kvm: .../qemu-2.10.0/target/i386/kvm.c:1801 kvm_put_msrs: Assertion 'ret == cpu->kvm_msr_buf->nmsrs failed' This is because L1 KVM kvm_init_msr_list() will see that vmx_mpx_supported() (As it only checks MPX VMX controls support) and therefore KVM_GET_MSR_INDEX_LIST IOCTL will include MSR_IA32_BNDCFGS. However, later when L1 will attempt to set this MSR via KVM_SET_MSRS IOCTL, it will fail because !guest_cpuid_has_mpx(vcpu). Therefore, fix the issue by exposing MPX VMX controls to L1 guest only when vCPU supports MPX. Fixes: 36be0b9deb23 ("KVM: x86: Add nested virtualization support for MPX") Reported-by: Eyal Moscovici <eyal.moscovici@oracle.com> Reviewed-by: Nikita Leshchenko <nikita.leshchenko@oracle.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Liran Alon <liran.alon@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 8b066480224b..d32e9c5e743b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3525,9 +3525,6 @@ static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)
3525 VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | 3525 VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER |
3526 VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT; 3526 VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT;
3527 3527
3528 if (kvm_mpx_supported())
3529 msrs->exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS;
3530
3531 /* We support free control of debug control saving. */ 3528 /* We support free control of debug control saving. */
3532 msrs->exit_ctls_low &= ~VM_EXIT_SAVE_DEBUG_CONTROLS; 3529 msrs->exit_ctls_low &= ~VM_EXIT_SAVE_DEBUG_CONTROLS;
3533 3530
@@ -3544,8 +3541,6 @@ static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)
3544 VM_ENTRY_LOAD_IA32_PAT; 3541 VM_ENTRY_LOAD_IA32_PAT;
3545 msrs->entry_ctls_high |= 3542 msrs->entry_ctls_high |=
3546 (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER); 3543 (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER);
3547 if (kvm_mpx_supported())
3548 msrs->entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS;
3549 3544
3550 /* We support free control of debug control loading. */ 3545 /* We support free control of debug control loading. */
3551 msrs->entry_ctls_low &= ~VM_ENTRY_LOAD_DEBUG_CONTROLS; 3546 msrs->entry_ctls_low &= ~VM_ENTRY_LOAD_DEBUG_CONTROLS;
@@ -11237,6 +11232,23 @@ static void nested_vmx_cr_fixed1_bits_update(struct kvm_vcpu *vcpu)
11237#undef cr4_fixed1_update 11232#undef cr4_fixed1_update
11238} 11233}
11239 11234
11235static void nested_vmx_entry_exit_ctls_update(struct kvm_vcpu *vcpu)
11236{
11237 struct vcpu_vmx *vmx = to_vmx(vcpu);
11238
11239 if (kvm_mpx_supported()) {
11240 bool mpx_enabled = guest_cpuid_has(vcpu, X86_FEATURE_MPX);
11241
11242 if (mpx_enabled) {
11243 vmx->nested.msrs.entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS;
11244 vmx->nested.msrs.exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS;
11245 } else {
11246 vmx->nested.msrs.entry_ctls_high &= ~VM_ENTRY_LOAD_BNDCFGS;
11247 vmx->nested.msrs.exit_ctls_high &= ~VM_EXIT_CLEAR_BNDCFGS;
11248 }
11249 }
11250}
11251
11240static void vmx_cpuid_update(struct kvm_vcpu *vcpu) 11252static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
11241{ 11253{
11242 struct vcpu_vmx *vmx = to_vmx(vcpu); 11254 struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -11253,8 +11265,10 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
11253 to_vmx(vcpu)->msr_ia32_feature_control_valid_bits &= 11265 to_vmx(vcpu)->msr_ia32_feature_control_valid_bits &=
11254 ~FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX; 11266 ~FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
11255 11267
11256 if (nested_vmx_allowed(vcpu)) 11268 if (nested_vmx_allowed(vcpu)) {
11257 nested_vmx_cr_fixed1_bits_update(vcpu); 11269 nested_vmx_cr_fixed1_bits_update(vcpu);
11270 nested_vmx_entry_exit_ctls_update(vcpu);
11271 }
11258} 11272}
11259 11273
11260static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) 11274static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)