• Ben Gardon's avatar
    KVM: x86: Use SRCU to protect zap in __kvm_set_or_clear_apicv_inhibit() · 074c0080
    Ben Gardon authored
    kvm_zap_gfn_range() must be called in an SRCU read-critical section, but
    there is no SRCU annotation in __kvm_set_or_clear_apicv_inhibit(). This
    can lead to the following warning via
    kvm_arch_vcpu_ioctl_set_guest_debug() if a Shadow MMU is in use (TDP
    MMU disabled or nesting):
    
    [ 1416.659809] =============================
    [ 1416.659810] WARNING: suspicious RCU usage
    [ 1416.659839] 6.1.0-dbg-DEV #1 Tainted: G S        I
    [ 1416.659853] -----------------------------
    [ 1416.659854] include/linux/kvm_host.h:954 suspicious rcu_dereference_check() usage!
    [ 1416.659856]
    ...
    [ 1416.659904]  dump_stack_lvl+0x84/0xaa
    [ 1416.659910]  dump_stack+0x10/0x15
    [ 1416.659913]  lockdep_rcu_suspicious+0x11e/0x130
    [ 1416.659919]  kvm_zap_gfn_range+0x226/0x5e0
    [ 1416.659926]  ? kvm_make_all_cpus_request_except+0x18b/0x1e0
    [ 1416.659935]  __kvm_set_or_clear_apicv_inhibit+0xcc/0x100
    [ 1416.659940]  kvm_arch_vcpu_ioctl_set_guest_debug+0x350/0x390
    [ 1416.659946]  kvm_vcpu_ioctl+0x2fc/0x620
    [ 1416.659955]  __se_sys_ioctl+0x77/0xc0
    [ 1416.659962]  __x64_sys_ioctl+0x1d/0x20
    [ 1416.659965]  do_syscall_64+0x3d/0x80
    [ 1416.659969]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
    Always take the KVM SRCU read lock in __kvm_set_or_clear_apicv_inhibit()
    to protect the GFN to memslot translation. The SRCU read lock is not
    technically required when no Shadow MMUs are in use, since the TDP MMU
    walks the paging structures from the roots and does not need to look up
    GFN translations in the memslots, but make the SRCU locking
    unconditional for simplicty.
    
    In most cases, the SRCU locking is taken care of in the vCPU run loop,
    but when called through other ioctls (such as KVM_SET_GUEST_DEBUG)
    there is no srcu_read_lock.
    
    Tested: ran tools/testing/selftests/kvm/x86_64/debug_regs on a DBG
    	build. This patch causes the suspicious RCU warning to disappear.
    	Note that the warning is hit in __kvm_zap_rmaps(), so
    	kvm_memslots_have_rmaps() must return true in order for this to
    	repro (i.e. the TDP MMU must be off or nesting in use.)
    Reported-by: default avatarGreg Thelen <gthelen@google.com>
    Fixes: 36222b11 ("KVM: x86: don't disable APICv memslot when inhibited")
    Signed-off-by: default avatarBen Gardon <bgardon@google.com>
    Message-Id: <20221102205359.1260980-1-bgardon@google.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    074c0080
x86.c 365 KB