Skip to content

Commit 9883764

Browse files
Maxim Levitskybonzini
authored andcommitted
SVM: nSVM: correctly restore GIF on vmexit from nesting after migration
Currently code in svm_set_nested_state copies the current vmcb control area to L1 control area (hsave->control), under assumption that it mostly reflects the defaults that kvm choose, and later qemu overrides these defaults with L2 state using standard KVM interfaces, like KVM_SET_REGS. However nested GIF (which is AMD specific thing) is by default is true, and it is copied to hsave area as such. This alone is not a big deal since on VMexit, GIF is always set to false, regardless of what it was on VM entry. However in nested_svm_vmexit we were first were setting GIF to false, but then we overwrite the control fields with value from the hsave area. (including the nested GIF field itself if GIF virtualization is enabled). Now on normal vm entry this is not a problem, since GIF is usually false prior to normal vm entry, and this is the value that copied to hsave, and then restored, but this is not always the case when the nested state is loaded as explained above. To fix this issue, move svm_set_gif after we restore the L1 control state in nested_svm_vmexit, so that even with wrong GIF in the saved L1 control area, we still clear GIF as the spec says. Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> Message-Id: <20200827162720.278690-2-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent cc17b22 commit 9883764

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

arch/x86/kvm/svm/nested.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,6 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
586586
svm->vcpu.arch.mp_state = KVM_MP_STATE_RUNNABLE;
587587

588588
/* Give the current vmcb to the guest */
589-
svm_set_gif(svm, false);
590589

591590
nested_vmcb->save.es = vmcb->save.es;
592591
nested_vmcb->save.cs = vmcb->save.cs;
@@ -632,6 +631,9 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
632631
/* Restore the original control entries */
633632
copy_vmcb_control_area(&vmcb->control, &hsave->control);
634633

634+
/* On vmexit the GIF is set to false */
635+
svm_set_gif(svm, false);
636+
635637
svm->vmcb->control.tsc_offset = svm->vcpu.arch.tsc_offset =
636638
svm->vcpu.arch.l1_tsc_offset;
637639

0 commit comments

Comments
 (0)