]> www.infradead.org Git - users/dwmw2/linux.git/commit
KVM: x86/xen: avoid blocking in hardirq context in kvm_xen_set_evtchn_fast() xen
authorDavid Woodhouse <dwmw@amazon.co.uk>
Thu, 7 Mar 2024 16:43:51 +0000 (16:43 +0000)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Fri, 8 Mar 2024 18:09:22 +0000 (18:09 +0000)
commitbc0f4206a9a6213956ebdfa635b8f9420cc39780
tree5a56aca38d1bf6064daf91e88fd93cc09e12ee8d
parentd1b97d5ef2428482a69c73b69665a18cc596b54e
KVM: x86/xen: avoid blocking in hardirq context in kvm_xen_set_evtchn_fast()

As described in [1] compiling with CONFIG_PROVE_RAW_LOCK_NESTING shows that
kvm_xen_set_evtchn_fast() is blocking on pfncache locks in IRQ context.
There is only actually blocking with PREEMPT_RT because the locks will
turned into mutexes. There is no 'raw' version of rwlock_t that can be used
to avoid that, so use read_trylock() and treat failure to lock the same as
an invalid cache.

However, with PREEMPT_RT read_lock_irqsave() doesn't actually disable IRQs
either. So open-coding a trylock_irqsave() using local_irq_save() would be
wrong in the PREEMPT_RT case.

In fact, if kvm_xen_set_evtchn_fast() is now going to use a trylock anyway
when invoked in hardirq context, there's actually no *need* for interrupts
to be disabled by any other code path that takes the lock. So just switch
all other users to a plain read_lock() and then the different semantics
on PREEMPT_RT are not an issue.

Add a warning in __kvm_xen_has_interrupt() just to be sure that one never
does occur from interrupt context.

[1] https://lore.kernel.org/lkml/99771ef3a4966a01fefd3adbb2ba9c3a75f97cf2.camel@infradead.org/T/#mbd06e5a04534ce9c0ee94bd8f1e8d942b2d45bd6
Fixes: 77c9b9dea4fb ("KVM: x86/xen: Use fast path for Xen timer delivery")
Fixes: bbe17c625d68 ("KVM: x86/xen: Fix potential deadlock in kvm_xen_update_runstate_guest()")
Co-developed-by: Paul Durrant <pdurrant@amazon.com>
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
arch/x86/kvm/xen.c