mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 06:34:11 +08:00
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 commit691bd4340b
("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:36be0b9deb
("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>
This commit is contained in:
parent
4679b61f26
commit
5f76f6f5ff
@ -3525,9 +3525,6 @@ static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)
|
|||||||
VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER |
|
VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER |
|
||||||
VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT;
|
VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT;
|
||||||
|
|
||||||
if (kvm_mpx_supported())
|
|
||||||
msrs->exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS;
|
|
||||||
|
|
||||||
/* We support free control of debug control saving. */
|
/* We support free control of debug control saving. */
|
||||||
msrs->exit_ctls_low &= ~VM_EXIT_SAVE_DEBUG_CONTROLS;
|
msrs->exit_ctls_low &= ~VM_EXIT_SAVE_DEBUG_CONTROLS;
|
||||||
|
|
||||||
@ -3544,8 +3541,6 @@ static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)
|
|||||||
VM_ENTRY_LOAD_IA32_PAT;
|
VM_ENTRY_LOAD_IA32_PAT;
|
||||||
msrs->entry_ctls_high |=
|
msrs->entry_ctls_high |=
|
||||||
(VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER);
|
(VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER);
|
||||||
if (kvm_mpx_supported())
|
|
||||||
msrs->entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS;
|
|
||||||
|
|
||||||
/* We support free control of debug control loading. */
|
/* We support free control of debug control loading. */
|
||||||
msrs->entry_ctls_low &= ~VM_ENTRY_LOAD_DEBUG_CONTROLS;
|
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)
|
|||||||
#undef cr4_fixed1_update
|
#undef cr4_fixed1_update
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nested_vmx_entry_exit_ctls_update(struct kvm_vcpu *vcpu)
|
||||||
|
{
|
||||||
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||||
|
|
||||||
|
if (kvm_mpx_supported()) {
|
||||||
|
bool mpx_enabled = guest_cpuid_has(vcpu, X86_FEATURE_MPX);
|
||||||
|
|
||||||
|
if (mpx_enabled) {
|
||||||
|
vmx->nested.msrs.entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS;
|
||||||
|
vmx->nested.msrs.exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS;
|
||||||
|
} else {
|
||||||
|
vmx->nested.msrs.entry_ctls_high &= ~VM_ENTRY_LOAD_BNDCFGS;
|
||||||
|
vmx->nested.msrs.exit_ctls_high &= ~VM_EXIT_CLEAR_BNDCFGS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
|
static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||||
@ -11253,8 +11265,10 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
|
|||||||
to_vmx(vcpu)->msr_ia32_feature_control_valid_bits &=
|
to_vmx(vcpu)->msr_ia32_feature_control_valid_bits &=
|
||||||
~FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
|
~FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
|
||||||
|
|
||||||
if (nested_vmx_allowed(vcpu))
|
if (nested_vmx_allowed(vcpu)) {
|
||||||
nested_vmx_cr_fixed1_bits_update(vcpu);
|
nested_vmx_cr_fixed1_bits_update(vcpu);
|
||||||
|
nested_vmx_entry_exit_ctls_update(vcpu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
|
static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
|
||||||
|
Loading…
Reference in New Issue
Block a user