• Vitaly Kuznetsov's avatar
    x86/kvm/mmu: fix switch between root and guest MMUs · 74ddf52f
    Vitaly Kuznetsov authored
    commit ad7dc69a upstream.
    
    Commit 14c07ad8 ("x86/kvm/mmu: introduce guest_mmu") brought one subtle
    change: previously, when switching back from L2 to L1, we were resetting
    MMU hooks (like mmu->get_cr3()) in kvm_init_mmu() called from
    nested_vmx_load_cr3() and now we do that in nested_ept_uninit_mmu_context()
    when we re-target vcpu->arch.mmu pointer.
    The change itself looks logical: if nested_ept_init_mmu_context() changes
    something than nested_ept_uninit_mmu_context() restores it back. There is,
    however, one thing: the following call chain:
    
     nested_vmx_load_cr3()
      kvm_mmu_new_cr3()
        __kvm_mmu_new_cr3()
          fast_cr3_switch()
            cached_root_available()
    
    now happens with MMU hooks pointing to the new MMU (root MMU in our case)
    while previously it was happening with the old one. cached_root_available()
    tries to stash current root but it is incorrect to read current CR3 with
    mmu->get_cr3(), we need to use old_mmu->get_cr3() which in case we're
    switching from L2 to L1 is guest_mmu. (BTW, in shadow page tables case this
    is a non-issue because we don't switch MMU).
    
    While we could've tried to guess that we're switching between MMUs and call
    the right ->get_cr3() from cached_root_available() this seems to be overly
    complicated. Instead, just stash the corresponding CR3 when setting
    root_hpa and make cached_root_available() use the stashed value.
    
    Fixes: 14c07ad8 ("x86/kvm/mmu: introduce guest_mmu")
    Signed-off-by: 's avatarVitaly Kuznetsov <vkuznets@redhat.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: 's avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    74ddf52f
Name
Last commit
Last update
Documentation Loading commit data...
LICENSES Loading commit data...
arch Loading commit data...
block Loading commit data...
certs Loading commit data...
crypto Loading commit data...
drivers Loading commit data...
firmware Loading commit data...
fs Loading commit data...
include Loading commit data...
init Loading commit data...
ipc Loading commit data...
kernel Loading commit data...
lib Loading commit data...
mm Loading commit data...
net Loading commit data...
samples Loading commit data...
scripts Loading commit data...
security Loading commit data...
sound Loading commit data...
tools Loading commit data...
usr Loading commit data...
virt Loading commit data...
.clang-format Loading commit data...
.cocciconfig Loading commit data...
.get_maintainer.ignore Loading commit data...
.gitattributes Loading commit data...
.gitignore Loading commit data...
.mailmap Loading commit data...
COPYING Loading commit data...
CREDITS Loading commit data...
Kbuild Loading commit data...
Kconfig Loading commit data...
MAINTAINERS Loading commit data...
Makefile Loading commit data...
README Loading commit data...