Skip to content

Commit c6f3576

Browse files
bonzinigregkh
authored andcommitted
KVM: x86: disable MPX if host did not enable MPX XSAVE features
commit a87036add09283e6c4f4103a15c596c67b86ab86 upstream. When eager FPU is disabled, KVM will still see the MPX bit in CPUID and presumably the MPX vmentry and vmexit controls. However, it will not be able to expose the MPX XSAVE features to the guest, because the guest's accessible XSAVE features are always a subset of host_xcr0. In this case, we should disable the MPX CPUID bit, the BNDCFGS MSR, and the MPX vmentry and vmexit controls for nested virtualization. It is then unnecessary to enable guest eager FPU if the guest has the MPX CPUID bit set. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 999b96b commit c6f3576

3 files changed

Lines changed: 17 additions & 18 deletions

File tree

arch/x86/kvm/cpuid.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,18 @@ static u32 xstate_required_size(u64 xstate_bv, bool compacted)
4646
return ret;
4747
}
4848

49+
bool kvm_mpx_supported(void)
50+
{
51+
return ((host_xcr0 & (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR))
52+
&& kvm_x86_ops->mpx_supported());
53+
}
54+
EXPORT_SYMBOL_GPL(kvm_mpx_supported);
55+
4956
u64 kvm_supported_xcr0(void)
5057
{
5158
u64 xcr0 = KVM_SUPPORTED_XCR0 & host_xcr0;
5259

53-
if (!kvm_x86_ops->mpx_supported())
60+
if (!kvm_mpx_supported())
5461
xcr0 &= ~(XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR);
5562

5663
return xcr0;
@@ -97,7 +104,7 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
97104
if (best && (best->eax & (F(XSAVES) | F(XSAVEC))))
98105
best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
99106

100-
vcpu->arch.eager_fpu = use_eager_fpu() || guest_cpuid_has_mpx(vcpu);
107+
vcpu->arch.eager_fpu = use_eager_fpu();
101108
if (vcpu->arch.eager_fpu)
102109
kvm_x86_ops->fpu_activate(vcpu);
103110

@@ -295,7 +302,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
295302
#endif
296303
unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
297304
unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0;
298-
unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0;
305+
unsigned f_mpx = kvm_mpx_supported() ? F(MPX) : 0;
299306
unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0;
300307

301308
/* cpuid 1.edx */

arch/x86/kvm/cpuid.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "x86.h"
55

66
int kvm_update_cpuid(struct kvm_vcpu *vcpu);
7+
bool kvm_mpx_supported(void);
78
struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
89
u32 function, u32 index);
910
int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
@@ -134,14 +135,6 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu)
134135
return best && (best->ebx & bit(X86_FEATURE_RTM));
135136
}
136137

137-
static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu)
138-
{
139-
struct kvm_cpuid_entry2 *best;
140-
141-
best = kvm_find_cpuid_entry(vcpu, 7, 0);
142-
return best && (best->ebx & bit(X86_FEATURE_MPX));
143-
}
144-
145138
static inline bool guest_cpuid_has_pcommit(struct kvm_vcpu *vcpu)
146139
{
147140
struct kvm_cpuid_entry2 *best;

arch/x86/kvm/vmx.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,6 @@ static unsigned long nested_ept_get_cr3(struct kvm_vcpu *vcpu);
863863
static u64 construct_eptp(unsigned long root_hpa);
864864
static void kvm_cpu_vmxon(u64 addr);
865865
static void kvm_cpu_vmxoff(void);
866-
static bool vmx_mpx_supported(void);
867866
static bool vmx_xsaves_supported(void);
868867
static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu);
869868
static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr);
@@ -2541,7 +2540,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
25412540
VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER |
25422541
VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT;
25432542

2544-
if (vmx_mpx_supported())
2543+
if (kvm_mpx_supported())
25452544
vmx->nested.nested_vmx_exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS;
25462545

25472546
/* We support free control of debug control saving. */
@@ -2562,7 +2561,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
25622561
VM_ENTRY_LOAD_IA32_PAT;
25632562
vmx->nested.nested_vmx_entry_ctls_high |=
25642563
(VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER);
2565-
if (vmx_mpx_supported())
2564+
if (kvm_mpx_supported())
25662565
vmx->nested.nested_vmx_entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS;
25672566

25682567
/* We support free control of debug control loading. */
@@ -2813,7 +2812,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
28132812
msr_info->data = vmcs_readl(GUEST_SYSENTER_ESP);
28142813
break;
28152814
case MSR_IA32_BNDCFGS:
2816-
if (!vmx_mpx_supported())
2815+
if (!kvm_mpx_supported())
28172816
return 1;
28182817
msr_info->data = vmcs_read64(GUEST_BNDCFGS);
28192818
break;
@@ -2890,7 +2889,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
28902889
vmcs_writel(GUEST_SYSENTER_ESP, data);
28912890
break;
28922891
case MSR_IA32_BNDCFGS:
2893-
if (!vmx_mpx_supported())
2892+
if (!kvm_mpx_supported())
28942893
return 1;
28952894
vmcs_write64(GUEST_BNDCFGS, data);
28962895
break;
@@ -3363,7 +3362,7 @@ static void init_vmcs_shadow_fields(void)
33633362
for (i = j = 0; i < max_shadow_read_write_fields; i++) {
33643363
switch (shadow_read_write_fields[i]) {
33653364
case GUEST_BNDCFGS:
3366-
if (!vmx_mpx_supported())
3365+
if (!kvm_mpx_supported())
33673366
continue;
33683367
break;
33693368
default:
@@ -10265,7 +10264,7 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
1026510264
vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS);
1026610265
vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP);
1026710266
vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP);
10268-
if (vmx_mpx_supported())
10267+
if (kvm_mpx_supported())
1026910268
vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS);
1027010269
if (nested_cpu_has_xsaves(vmcs12))
1027110270
vmcs12->xss_exit_bitmap = vmcs_read64(XSS_EXIT_BITMAP);

0 commit comments

Comments
 (0)