Skip to content

Commit bb00bd9

Browse files
vittyvkbonzini
authored andcommitted
KVM: nSVM: Restore nested control upon leaving SMM
If the VM was migrated while in SMM, no nested state was saved/restored, and therefore svm_leave_smm has to load both save and control area of the vmcb12. Save area is already loaded from HSAVE area, so now load the control area as well from the vmcb12. Signed-off-by: Vitaly Kuznetsov <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 37be407 commit bb00bd9

File tree

3 files changed

+10
-3
lines changed

3 files changed

+10
-3
lines changed

arch/x86/kvm/svm/nested.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ static bool nested_vmcb_valid_sregs(struct kvm_vcpu *vcpu,
308308
return true;
309309
}
310310

311-
static void nested_load_control_from_vmcb12(struct vcpu_svm *svm,
312-
struct vmcb_control_area *control)
311+
void nested_load_control_from_vmcb12(struct vcpu_svm *svm,
312+
struct vmcb_control_area *control)
313313
{
314314
copy_vmcb_control_area(&svm->nested.ctl, control);
315315

arch/x86/kvm/svm/svm.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4362,6 +4362,7 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
43624362
u64 saved_efer = GET_SMSTATE(u64, smstate, 0x7ed0);
43634363
u64 guest = GET_SMSTATE(u64, smstate, 0x7ed8);
43644364
u64 vmcb12_gpa = GET_SMSTATE(u64, smstate, 0x7ee0);
4365+
struct vmcb *vmcb12;
43654366

43664367
if (guest) {
43674368
if (!guest_cpuid_has(vcpu, X86_FEATURE_SVM))
@@ -4377,7 +4378,11 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
43774378
if (svm_allocate_nested(svm))
43784379
return 1;
43794380

4380-
ret = enter_svm_guest_mode(vcpu, vmcb12_gpa, map.hva);
4381+
vmcb12 = map.hva;
4382+
4383+
nested_load_control_from_vmcb12(svm, &vmcb12->control);
4384+
4385+
ret = enter_svm_guest_mode(vcpu, vmcb12_gpa, vmcb12);
43814386
kvm_vcpu_unmap(vcpu, &map, true);
43824387

43834388
/*

arch/x86/kvm/svm/svm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,8 @@ int nested_svm_check_permissions(struct kvm_vcpu *vcpu);
482482
int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
483483
bool has_error_code, u32 error_code);
484484
int nested_svm_exit_special(struct vcpu_svm *svm);
485+
void nested_load_control_from_vmcb12(struct vcpu_svm *svm,
486+
struct vmcb_control_area *control);
485487
void nested_sync_control_from_vmcb02(struct vcpu_svm *svm);
486488
void nested_vmcb02_compute_g_pat(struct vcpu_svm *svm);
487489
void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb);

0 commit comments

Comments
 (0)