]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Drivers: hv: vmbus: Provide option to skip VMBus unload on panic
authorMichael Kelley <mhklinux@outlook.com>
Tue, 17 Feb 2026 18:23:34 +0000 (10:23 -0800)
committerWei Liu <wei.liu@kernel.org>
Wed, 13 May 2026 22:29:32 +0000 (22:29 +0000)
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>
drivers/hv/channel_mgmt.c
drivers/hv/hyperv_vmbus.h
drivers/hv/vmbus_drv.c
include/linux/hyperv.h

index 84eb0a6a0b5466adee4f5127e67292ba4f4d25a3..89d214dda360a9933d5aef2bae1d51cb2ea347e8 100644 (file)
@@ -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)
index 05a36854389afda72fc84e549fe9f851c04f742c..eb8bdd8bb1f582e8218222d7ae5fd963f8f8ee27 100644 (file)
@@ -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 *))
index d28ff45d4cfddd3262bdd034fe52dd01ea0866b1..c9eeb2ec365dce6865aa61b6e3cd35b994fe83b3 100644 (file)
@@ -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
index 964f1be8150c591c551b99ee437102b656557b4d..41a3d82f0722bde2963661ce5223e30ba0068b99 100644 (file)
@@ -1336,6 +1336,9 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
                        bool fb_overlap_ok);
 void vmbus_free_mmio(resource_size_t start, resource_size_t size);
 
+void vmbus_initiate_unload(bool crash);
+void vmbus_set_skip_unload(bool skip);
+
 /*
  * GUID definitions of various offer types - services offered to the guest.
  */