mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-19 00:01:01 -04:00
KVM: SVM: check validity of VMCB controls when returning from SMM
The VMCB12 is stored in guest memory and can be mangled while in SMM; it is then reloaded by svm_leave_smm(), but it is not checked again for validity. Move the cached vmcb12 control and save consistency checks out of svm_set_nested_state() and into a helper, and reuse it in svm_leave_smm(). Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
@@ -418,6 +418,15 @@ static bool nested_vmcb_check_controls(struct kvm_vcpu *vcpu)
|
||||
return __nested_vmcb_check_controls(vcpu, ctl);
|
||||
}
|
||||
|
||||
int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (!nested_vmcb_check_save(vcpu) ||
|
||||
!nested_vmcb_check_controls(vcpu))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a feature is not advertised to L1, clear the corresponding vmcb12
|
||||
* intercept.
|
||||
@@ -1028,8 +1037,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu)
|
||||
nested_copy_vmcb_control_to_cache(svm, &vmcb12->control);
|
||||
nested_copy_vmcb_save_to_cache(svm, &vmcb12->save);
|
||||
|
||||
if (!nested_vmcb_check_save(vcpu) ||
|
||||
!nested_vmcb_check_controls(vcpu)) {
|
||||
if (nested_svm_check_cached_vmcb12(vcpu) < 0) {
|
||||
vmcb12->control.exit_code = SVM_EXIT_ERR;
|
||||
vmcb12->control.exit_info_1 = 0;
|
||||
vmcb12->control.exit_info_2 = 0;
|
||||
|
||||
@@ -4880,6 +4880,10 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
|
||||
vmcb12 = map.hva;
|
||||
nested_copy_vmcb_control_to_cache(svm, &vmcb12->control);
|
||||
nested_copy_vmcb_save_to_cache(svm, &vmcb12->save);
|
||||
|
||||
if (nested_svm_check_cached_vmcb12(vcpu) < 0)
|
||||
goto unmap_save;
|
||||
|
||||
ret = enter_svm_guest_mode(vcpu, smram64->svm_guest_vmcb_gpa, vmcb12, false);
|
||||
|
||||
if (ret)
|
||||
|
||||
@@ -797,6 +797,7 @@ static inline int nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code)
|
||||
|
||||
int nested_svm_exit_handled(struct vcpu_svm *svm);
|
||||
int nested_svm_check_permissions(struct kvm_vcpu *vcpu);
|
||||
int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu);
|
||||
int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
|
||||
bool has_error_code, u32 error_code);
|
||||
int nested_svm_exit_special(struct vcpu_svm *svm);
|
||||
|
||||
Reference in New Issue
Block a user