KVM: x86/mmu: __kvm_rmap_lock() preemption assert trips on PREEMPT_RT
From: David Woodhouse
Date: Thu Aug 27 2026 - 17:14:50 EST
While soaking unrelated KVM changes on a PREEMPT_RT + lockdep kernel
I hit this, which I don't believe has been reported before:
WARNING: arch/x86/kvm/mmu/mmu.c:920 at __kvm_rmap_lock+0x1a7/0x1e0 [kvm], CPU#16: vmx_apic_update/3708
CPU: 16 UID: 0 PID: 3708 Comm: vmx_apic_update Not tainted 7.2.0-rc7 #52 PREEMPT_{RT,LAZY}
RIP: 0010:__kvm_rmap_lock+0x1a7/0x1e0 [kvm]
Call Trace:
pte_list_add+0x67/0x4d0 [kvm]
__link_shadow_page+0x249/0x480 [kvm]
ept_fetch+0x4d5/0x1220 [kvm]
ept_page_fault+0x60b/0x850 [kvm]
kvm_mmu_do_page_fault+0x252/0x690 [kvm]
That's the lockdep_assert_preemption_disabled() in __kvm_rmap_lock(),
from commit 4834eaded91e ("KVM: x86/mmu: Add infrastructure to allow
walking rmaps outside of mmu_lock").
I don't think this one is just lockdep vs. PREEMPT_RT causing false
positives — the rmap lock is a hand-crafted bit-spinlock, and if a lock
holder is preempted that leaves every other walker of that rmap
spinning and waiting for it (with no tracked owner for PI to boost).
On PREEMPT_RT we genuinely get here without preemption disabled,
because kvm->mmu_lock is a sleeping lock now. Any shadow-MMU fault
on an RT kernel should trip it — this one is the !TDP nested EPT path
(ept_fetch()), and it fires within seconds of running a nested guest
with lockdep enabled.
I guess we fix it by turning the assertion into a preempt_disable() of
its own? Not sufficiently confident in that conclusion to send it in
'diff -up' form though...
Attachment:
smime.p7s
Description: S/MIME cryptographic signature