• Sean Christopherson's avatar
    KVM: x86/mmu: Don't leak non-leaf SPTEs when zapping all SPTEs · 524a1e4e
    Sean Christopherson authored
    Pass "all ones" as the end GFN to signal "zap all" for the TDP MMU and
    really zap all SPTEs in this case.  As is, zap_gfn_range() skips non-leaf
    SPTEs whose range exceeds the range to be zapped.  If shadow_phys_bits is
    not aligned to the range size of top-level SPTEs, e.g. 512gb with 4-level
    paging, the "zap all" flows will skip top-level SPTEs whose range extends
    beyond shadow_phys_bits and leak their SPs when the VM is destroyed.
    
    Use the current upper bound (based on host.MAXPHYADDR) to detect that the
    caller wants to zap all SPTEs, e.g. instead of using the max theoretical
    gfn, 1 << (52 - 12).  The more precise upper bound allows the TDP iterator
    to terminate its walk earlier when running on hosts with MAXPHYADDR < 52.
    
    Add a WARN on kmv->arch.tdp_mmu_pages when the TDP MMU is destroyed to
    help future debuggers should KVM decide to leak SPTEs again.
    
    The bug is most easily reproduced by running (and unloading!) KVM in a
    VM whose host.MAXPHYADDR < 39, as the SPTE for gfn=0 will be skipped.
    
      =============================================================================
      BUG kvm_mmu_page_header (Not tainted): Objects remaining in kvm_mmu_page_header on __kmem_cache_shutdown()
      -----------------------------------------------------------------------------
      Slab 0x000000004d8f7af1 objects=22 used=2 fp=0x00000000624d29ac flags=0x4000000000000200(slab|zone=1)
      CPU: 0 PID: 1582 Comm: rmmod Not tainted 5.14.0-rc2+ #420
      Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
      Call Trace:
       dump_stack_lvl+0x45/0x59
       slab_err+0x95/0xc9
       __kmem_cache_shutdown.cold+0x3c/0x158
       kmem_cache_destroy+0x3d/0xf0
       kvm_mmu_module_exit+0xa/0x30 [kvm]
       kvm_arch_exit+0x5d/0x90 [kvm]
       kvm_exit+0x78/0x90 [kvm]
       vmx_exit+0x1a/0x50 [kvm_intel]
       __x64_sys_delete_module+0x13f/0x220
       do_syscall_64+0x3b/0xc0
       entry_SYSCALL_64_after_hwframe+0x44/0xae
    
    Fixes: faaf05b0 ("kvm: x86/mmu: Support zapping SPTEs in the TDP MMU")
    Cc: stable@vger.kernel.org
    Cc: Ben Gardon <bgardon@google.com>
    Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
    Message-Id: <20210812181414.3376143-2-seanjc@google.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    524a1e4e
tdp_mmu.c 44.1 KB