• Vitaly Kuznetsov's avatar
    KVM: nSVM: Preserve registers modifications done before nested_svm_vmexit() · b6162e82
    Vitaly Kuznetsov authored
    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: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
    Message-Id: <20200527090102.220647-1-vkuznets@redhat.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    b6162e82
nested.c 26 KB