mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-21 11:44:01 +08:00
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>
This commit is contained in:
parent
7d2e8748af
commit
b6162e82ae
@ -491,9 +491,9 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
|
||||
nested_vmcb->save.cr2 = vmcb->save.cr2;
|
||||
nested_vmcb->save.cr4 = svm->vcpu.arch.cr4;
|
||||
nested_vmcb->save.rflags = kvm_get_rflags(&svm->vcpu);
|
||||
nested_vmcb->save.rip = vmcb->save.rip;
|
||||
nested_vmcb->save.rsp = vmcb->save.rsp;
|
||||
nested_vmcb->save.rax = vmcb->save.rax;
|
||||
nested_vmcb->save.rip = kvm_rip_read(&svm->vcpu);
|
||||
nested_vmcb->save.rsp = kvm_rsp_read(&svm->vcpu);
|
||||
nested_vmcb->save.rax = kvm_rax_read(&svm->vcpu);
|
||||
nested_vmcb->save.dr7 = vmcb->save.dr7;
|
||||
nested_vmcb->save.dr6 = svm->vcpu.arch.dr6;
|
||||
nested_vmcb->save.cpl = vmcb->save.cpl;
|
||||
|
Loading…
Reference in New Issue
Block a user