]> git.baikalelectronics.ru Git - kernel.git/commit
KVM: nSVM: Preserve registers modifications done before nested_svm_vmexit()
authorVitaly Kuznetsov <vkuznets@redhat.com>
Wed, 27 May 2020 09:01:02 +0000 (11:01 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 27 May 2020 17:11:12 +0000 (13:11 -0400)
commit550a4c2bc10d99017bf2ece5871b15ea873d4ba0
treefe33407b970ccb268674588d0cc91b5776e8e7e7
parentac8376d4765f0ddba72c5b684b832e4f970cf6f4
KVM: nSVM: Preserve registers modifications done before nested_svm_vmexit()

L2 guest hang is observed after 'exit_required' was dropped and nSVM
switched to check_nested_events() completely. The hang is a busy loop when
e.g. KVM is emulating an instruction (e.g. L2 is accessing MMIO space and
we drop to userspace). After nested_svm_vmexit() and when L1 is doing VMRUN
nested guest's RIP is not advanced so KVM goes into emulating the same
instruction which caused nested_svm_vmexit() and the loop continues.

nested_svm_vmexit() is not new, however, with check_nested_events() we're
now calling it later than before. In case by that time KVM has modified
register state we may pick stale values from VMCB when trying to save
nested guest state to nested VMCB.

nVMX code handles this case correctly: sync_vmcs02_to_vmcs12() called from
nested_vmx_vmexit() does e.g 'vmcs12->guest_rip = kvm_rip_read(vcpu)' and
this ensures KVM-made modifications are preserved. Do the same for nSVM.

Generally, nested_vmx_vmexit()/nested_svm_vmexit() need to pick up all
nested guest state modifications done by KVM after vmexit. It would be
great to find a way to express this in a way which would not require to
manually track these changes, e.g. nested_{vmcb,vmcs}_get_field().

Co-debugged-with: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Message-Id: <20200527090102.220647-1-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm/nested.c