diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2020-05-18 13:08:37 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2020-06-01 04:26:03 -0400 |
commit | c513f484c5582a8efadf3d72298e2285b041536e (patch) | |
tree | b8450accf8e427bb6e7ceaa9c4711bae0bc2d6c9 /arch/x86/kvm/svm/svm.c | |
parent | ca46d739e3caf44dcd3db9eb8da30d0ff3aa9180 (diff) | |
download | lwn-c513f484c5582a8efadf3d72298e2285b041536e.tar.gz lwn-c513f484c5582a8efadf3d72298e2285b041536e.zip |
KVM: nSVM: leave guest mode when clearing EFER.SVME
According to the AMD manual, the effect of turning off EFER.SVME while a
guest is running is undefined. We make it leave guest mode immediately,
similar to the effect of clearing the VMX bit in MSR_IA32_FEAT_CTL.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/svm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm/svm.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index bc08221f6743..b4db9a980469 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -265,6 +265,7 @@ static int get_npt_level(struct kvm_vcpu *vcpu) void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) { + struct vcpu_svm *svm = to_svm(vcpu); vcpu->arch.efer = efer; if (!npt_enabled) { @@ -275,8 +276,13 @@ void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) efer &= ~EFER_LME; } - to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME; - mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR); + if (!(efer & EFER_SVME)) { + svm_leave_nested(svm); + svm_set_gif(svm, true); + } + + svm->vmcb->save.efer = efer | EFER_SVME; + mark_dirty(svm->vmcb, VMCB_CR); } static int is_external_interrupt(u32 info) |