Commit 37e4c997 authored by Haozhong Zhang's avatar Haozhong Zhang Committed by Paolo Bonzini

KVM: VMX: validate individual bits of guest MSR_IA32_FEATURE_CONTROL

KVM currently does not check the value written to guest
MSR_IA32_FEATURE_CONTROL, though bits corresponding to disabled features
may be set. This patch makes KVM to validate individual bits written to
guest MSR_IA32_FEATURE_CONTROL according to enabled features.
Signed-off-by: default avatarHaozhong Zhang <haozhong.zhang@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 3b84080b
...@@ -612,7 +612,13 @@ struct vcpu_vmx { ...@@ -612,7 +612,13 @@ struct vcpu_vmx {
u32 guest_pkru; u32 guest_pkru;
u32 host_pkru; u32 host_pkru;
/*
* Only bits masked by msr_ia32_feature_control_valid_bits can be set in
* msr_ia32_feature_control. FEATURE_CONTROL_LOCKED is always included
* in msr_ia32_feature_control_valid_bits.
*/
u64 msr_ia32_feature_control; u64 msr_ia32_feature_control;
u64 msr_ia32_feature_control_valid_bits;
}; };
enum segment_cache_field { enum segment_cache_field {
...@@ -2929,6 +2935,14 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) ...@@ -2929,6 +2935,14 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
return 0; return 0;
} }
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;
return !(val & ~valid_bits);
}
/* /*
* Reads an msr value (of 'msr_index') into 'pdata'. * Reads an msr value (of 'msr_index') into 'pdata'.
* Returns 0 on success, non-0 otherwise. * Returns 0 on success, non-0 otherwise.
...@@ -3062,7 +3076,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) ...@@ -3062,7 +3076,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
ret = kvm_set_msr_common(vcpu, msr_info); ret = kvm_set_msr_common(vcpu, msr_info);
break; break;
case MSR_IA32_FEATURE_CONTROL: case MSR_IA32_FEATURE_CONTROL:
if (!nested_vmx_allowed(vcpu) || if (!vmx_feature_control_msr_valid(vcpu, data) ||
(to_vmx(vcpu)->msr_ia32_feature_control & (to_vmx(vcpu)->msr_ia32_feature_control &
FEATURE_CONTROL_LOCKED && !msr_info->host_initiated)) FEATURE_CONTROL_LOCKED && !msr_info->host_initiated))
return 1; return 1;
...@@ -9055,6 +9069,8 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) ...@@ -9055,6 +9069,8 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
goto free_vmcs; goto free_vmcs;
} }
vmx->msr_ia32_feature_control_valid_bits = FEATURE_CONTROL_LOCKED;
return &vmx->vcpu; return &vmx->vcpu;
free_vmcs: free_vmcs:
...@@ -9202,6 +9218,13 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) ...@@ -9202,6 +9218,13 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
vmx->nested.nested_vmx_secondary_ctls_high &= vmx->nested.nested_vmx_secondary_ctls_high &=
~SECONDARY_EXEC_PCOMMIT; ~SECONDARY_EXEC_PCOMMIT;
} }
if (nested_vmx_allowed(vcpu))
to_vmx(vcpu)->msr_ia32_feature_control_valid_bits |=
FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
else
to_vmx(vcpu)->msr_ia32_feature_control_valid_bits &=
~FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
} }
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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment