mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
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: Haozhong Zhang <haozhong.zhang@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
3b84080b95
commit
37e4c997da
1 changed files with 24 additions and 1 deletions
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue