diff options
| author | Michael Kelley <mhklinux@outlook.com> | 2026-02-17 10:23:34 -0800 |
|---|---|---|
| committer | Wei Liu <wei.liu@kernel.org> | 2026-05-13 22:29:32 +0000 |
| commit | c5c3ef8d49e15d2fc1cec4ad7c91d81b99977440 (patch) | |
| tree | fa1ace008c48099bdbb1b4bc4f4efe81e16a5e0c /drivers/hv | |
| parent | 6e55a8d9f21bcb238596bdd8092c92e74c698a3d (diff) | |
| download | linux-next-c5c3ef8d49e15d2fc1cec4ad7c91d81b99977440.tar.gz linux-next-c5c3ef8d49e15d2fc1cec4ad7c91d81b99977440.zip | |
Drivers: hv: vmbus: Provide option to skip VMBus unload on panic
Currently, VMBus code initiates a VMBus unload in the panic path so
that if a kdump kernel is loaded, it can start fresh in setting up its
own VMBus connection. However, a driver for the VMBus virtual frame
buffer may need to flush dirty portions of the frame buffer back to
the Hyper-V host so that panic information is visible in the graphics
console. To support such flushing, provide exported functions for the
frame buffer driver to specify that the VMBus unload should not be
done by the VMBus driver, and to initiate the VMBus unload itself.
Together these allow a frame buffer driver to delay the VMBus unload
until after it has completed the flush.
Ideally, the VMBus driver could use its own panic-path callback to do
the unload after all frame buffer drivers have finished. But DRM frame
buffer drivers use the kmsg dump callback, and there are no callbacks
after that in the panic path. Hence this somewhat messy approach to
properly sequencing the frame buffer flush and the VMBus unload.
Fixes: 3671f3777758 ("drm/hyperv: Add support for drm_panic")
Signed-off-by: Michael Kelley <mhklinux@outlook.com>
Reviewed-by: Long Li <longli@microsoft.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Diffstat (limited to 'drivers/hv')
| -rw-r--r-- | drivers/hv/channel_mgmt.c | 1 | ||||
| -rw-r--r-- | drivers/hv/hyperv_vmbus.h | 1 | ||||
| -rw-r--r-- | drivers/hv/vmbus_drv.c | 25 |
3 files changed, 19 insertions, 8 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 84eb0a6a0b54..89d214dda360 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -952,6 +952,7 @@ void vmbus_initiate_unload(bool crash) else vmbus_wait_for_unload(); } +EXPORT_SYMBOL_GPL(vmbus_initiate_unload); static void vmbus_setup_channel_state(struct vmbus_channel *channel, struct vmbus_channel_offer_channel *offer) diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 05a36854389a..eb8bdd8bb1f5 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -441,7 +441,6 @@ void hv_vss_deinit(void); int hv_vss_pre_suspend(void); int hv_vss_pre_resume(void); void hv_vss_onchannelcallback(void *context); -void vmbus_initiate_unload(bool crash); static inline void hv_poll_channel(struct vmbus_channel *channel, void (*cb)(void *)) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index d28ff45d4cfd..c9eeb2ec365d 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -69,19 +69,29 @@ bool vmbus_is_confidential(void) } EXPORT_SYMBOL_GPL(vmbus_is_confidential); +static bool skip_vmbus_unload; + +/* + * Allow a VMBus framebuffer driver to specify that in the case of a panic, + * it will do the VMbus unload operation once it has flushed any dirty + * portions of the framebuffer to the Hyper-V host. + */ +void vmbus_set_skip_unload(bool skip) +{ + skip_vmbus_unload = skip; +} +EXPORT_SYMBOL_GPL(vmbus_set_skip_unload); + /* * The panic notifier below is responsible solely for unloading the * vmbus connection, which is necessary in a panic event. - * - * Notice an intrincate relation of this notifier with Hyper-V - * framebuffer panic notifier exists - we need vmbus connection alive - * there in order to succeed, so we need to order both with each other - * [see hvfb_on_panic()] - this is done using notifiers' priorities. */ static int hv_panic_vmbus_unload(struct notifier_block *nb, unsigned long val, void *args) { - vmbus_initiate_unload(true); + if (!skip_vmbus_unload) + vmbus_initiate_unload(true); + return NOTIFY_DONE; } static struct notifier_block hyperv_panic_vmbus_unload_block = { @@ -2897,7 +2907,8 @@ static void hv_crash_handler(struct pt_regs *regs) { int cpu; - vmbus_initiate_unload(true); + if (!skip_vmbus_unload) + vmbus_initiate_unload(true); /* * In crash handler we can't schedule synic cleanup for all CPUs, * doing the cleanup for current CPU only. This should be sufficient |
