diff options
author | Guilherme G. Piccoli <gpiccoli@igalia.com> | 2022-08-19 19:17:29 -0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-01-14 10:16:13 +0100 |
commit | 9b267051c82a6f7be6638b6834c10ede312f8335 (patch) | |
tree | b426b86adb978b90ec102168183244efb36ece82 /include | |
parent | 0461a8c278b8fe74d19e58bc224327bef645e295 (diff) | |
download | linux-stable-9b267051c82a6f7be6638b6834c10ede312f8335.tar.gz linux-stable-9b267051c82a6f7be6638b6834c10ede312f8335.tar.bz2 linux-stable-9b267051c82a6f7be6638b6834c10ede312f8335.zip |
video: hyperv_fb: Avoid taking busy spinlock on panic path
[ Upstream commit 1d044ca035dc22df0d3b39e56f2881071d9118bd ]
The Hyper-V framebuffer code registers a panic notifier in order
to try updating its fbdev if the kernel crashed. The notifier
callback is straightforward, but it calls the vmbus_sendpacket()
routine eventually, and such function takes a spinlock for the
ring buffer operations.
Panic path runs in atomic context, with local interrupts and
preemption disabled, and all secondary CPUs shutdown. That said,
taking a spinlock might cause a lockup if a secondary CPU was
disabled with such lock taken. Fix it here by checking if the
ring buffer spinlock is busy on Hyper-V framebuffer panic notifier;
if so, bail-out avoiding the potential lockup scenario.
Cc: Andrea Parri (Microsoft) <parri.andrea@gmail.com>
Cc: Dexuan Cui <decui@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Michael Kelley <mikelley@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Cc: Tianyu Lan <Tianyu.Lan@microsoft.com>
Cc: Wei Liu <wei.liu@kernel.org>
Tested-by: Fabio A M Martins <fabiomirmar@gmail.com>
Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/20220819221731.480795-10-gpiccoli@igalia.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/hyperv.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 1ce131f29f3b..eada4d8d6587 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1269,6 +1269,8 @@ struct hv_ring_buffer_debug_info { int hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, struct hv_ring_buffer_debug_info *debug_info); +bool hv_ringbuffer_spinlock_busy(struct vmbus_channel *channel); + /* Vmbus interface */ #define vmbus_driver_register(driver) \ __vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) |