Skip to content

Commit be5fa87

Browse files
committed
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>
1 parent 5a30e8a commit be5fa87

3 files changed

Lines changed: 15 additions & 2 deletions

File tree

arch/x86/kvm/svm/nested.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,15 @@ static bool nested_vmcb_check_controls(struct kvm_vcpu *vcpu)
418418
return __nested_vmcb_check_controls(vcpu, ctl);
419419
}
420420

421+
int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu)
422+
{
423+
if (!nested_vmcb_check_save(vcpu) ||
424+
!nested_vmcb_check_controls(vcpu))
425+
return -EINVAL;
426+
427+
return 0;
428+
}
429+
421430
/*
422431
* If a feature is not advertised to L1, clear the corresponding vmcb12
423432
* intercept.
@@ -1028,8 +1037,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu)
10281037
nested_copy_vmcb_control_to_cache(svm, &vmcb12->control);
10291038
nested_copy_vmcb_save_to_cache(svm, &vmcb12->save);
10301039

1031-
if (!nested_vmcb_check_save(vcpu) ||
1032-
!nested_vmcb_check_controls(vcpu)) {
1040+
if (nested_svm_check_cached_vmcb12(vcpu) < 0) {
10331041
vmcb12->control.exit_code = SVM_EXIT_ERR;
10341042
vmcb12->control.exit_info_1 = 0;
10351043
vmcb12->control.exit_info_2 = 0;

arch/x86/kvm/svm/svm.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4880,6 +4880,10 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
48804880
vmcb12 = map.hva;
48814881
nested_copy_vmcb_control_to_cache(svm, &vmcb12->control);
48824882
nested_copy_vmcb_save_to_cache(svm, &vmcb12->save);
4883+
4884+
if (nested_svm_check_cached_vmcb12(vcpu) < 0)
4885+
goto unmap_save;
4886+
48834887
ret = enter_svm_guest_mode(vcpu, smram64->svm_guest_vmcb_gpa, vmcb12, false);
48844888

48854889
if (ret)

arch/x86/kvm/svm/svm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ static inline int nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code)
797797

798798
int nested_svm_exit_handled(struct vcpu_svm *svm);
799799
int nested_svm_check_permissions(struct kvm_vcpu *vcpu);
800+
int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu);
800801
int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
801802
bool has_error_code, u32 error_code);
802803
int nested_svm_exit_special(struct vcpu_svm *svm);

0 commit comments

Comments
 (0)