mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 22:05:24 -04:00
KVM: VMX: Allow userspace to set all supported FEATURE_CONTROL bits
Allow userspace to set all supported bits in MSR IA32_FEATURE_CONTROL irrespective of the guest CPUID model, e.g. via KVM_SET_MSRS. KVM's ABI is that userspace is allowed to set MSRs before CPUID, i.e. can set MSRs to values that would fault according to the guest CPUID model. Signed-off-by: Sean Christopherson <seanjc@google.com> Link: https://lore.kernel.org/r/20220607232353.3375324-2-seanjc@google.com
This commit is contained in:
@@ -1836,12 +1836,38 @@ bool nested_vmx_allowed(struct kvm_vcpu *vcpu)
|
||||
return nested && guest_cpuid_has(vcpu, X86_FEATURE_VMX);
|
||||
}
|
||||
|
||||
static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu,
|
||||
uint64_t val)
|
||||
{
|
||||
uint64_t valid_bits = to_vmx(vcpu)->msr_ia32_feature_control_valid_bits;
|
||||
/*
|
||||
* Userspace is allowed to set any supported IA32_FEATURE_CONTROL regardless of
|
||||
* guest CPUID. Note, KVM allows userspace to set "VMX in SMX" to maintain
|
||||
* backwards compatibility even though KVM doesn't support emulating SMX. And
|
||||
* because userspace set "VMX in SMX", the guest must also be allowed to set it,
|
||||
* e.g. if the MSR is left unlocked and the guest does a RMW operation.
|
||||
*/
|
||||
#define KVM_SUPPORTED_FEATURE_CONTROL (FEAT_CTL_LOCKED | \
|
||||
FEAT_CTL_VMX_ENABLED_INSIDE_SMX | \
|
||||
FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX | \
|
||||
FEAT_CTL_SGX_LC_ENABLED | \
|
||||
FEAT_CTL_SGX_ENABLED | \
|
||||
FEAT_CTL_LMCE_ENABLED)
|
||||
|
||||
return !(val & ~valid_bits);
|
||||
static inline bool vmx_feature_control_msr_valid(struct vcpu_vmx *vmx,
|
||||
struct msr_data *msr)
|
||||
{
|
||||
uint64_t valid_bits;
|
||||
|
||||
/*
|
||||
* Ensure KVM_SUPPORTED_FEATURE_CONTROL is updated when new bits are
|
||||
* exposed to the guest.
|
||||
*/
|
||||
WARN_ON_ONCE(vmx->msr_ia32_feature_control_valid_bits &
|
||||
~KVM_SUPPORTED_FEATURE_CONTROL);
|
||||
|
||||
if (msr->host_initiated)
|
||||
valid_bits = KVM_SUPPORTED_FEATURE_CONTROL;
|
||||
else
|
||||
valid_bits = vmx->msr_ia32_feature_control_valid_bits;
|
||||
|
||||
return !(msr->data & ~valid_bits);
|
||||
}
|
||||
|
||||
static int vmx_get_msr_feature(struct kvm_msr_entry *msr)
|
||||
@@ -2240,7 +2266,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
vcpu->arch.mcg_ext_ctl = data;
|
||||
break;
|
||||
case MSR_IA32_FEAT_CTL:
|
||||
if (!vmx_feature_control_msr_valid(vcpu, data) ||
|
||||
if (!vmx_feature_control_msr_valid(vmx, msr_info) ||
|
||||
(to_vmx(vcpu)->msr_ia32_feature_control &
|
||||
FEAT_CTL_LOCKED && !msr_info->host_initiated))
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user