Skip to content

Commit 74347a9

Browse files
Tianyu Lanliuw
authored andcommitted
x86/Hyper-V: Unload vmbus channel in hv panic callback
When kdump is not configured, a Hyper-V VM might still respond to network traffic after a kernel panic when kernel parameter panic=0. The panic CPU goes into an infinite loop with interrupts enabled, and the VMbus driver interrupt handler still works because the VMbus connection is unloaded only in the kdump path. The network responses make the other end of the connection think the VM is still functional even though it has panic'ed, which could affect any failover actions that should be taken. Fix this by unloading the VMbus connection during the panic process. vmbus_initiate_unload() could then be called twice (e.g., by hyperv_panic_event() and hv_crash_handler(), so reset the connection state in vmbus_initiate_unload() to ensure the unload is done only once. Fixes: 81b18bc ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic") Reviewed-by: Michael Kelley <[email protected]> Signed-off-by: Tianyu Lan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Wei Liu <[email protected]>
1 parent 97d9f1c commit 74347a9

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

drivers/hv/channel_mgmt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,9 @@ void vmbus_initiate_unload(bool crash)
839839
{
840840
struct vmbus_channel_message_header hdr;
841841

842+
if (xchg(&vmbus_connection.conn_state, DISCONNECTED) == DISCONNECTED)
843+
return;
844+
842845
/* Pre-Win2012R2 hosts don't support reconnect */
843846
if (vmbus_proto_version < VERSION_WIN8_1)
844847
return;

drivers/hv/vmbus_drv.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,12 @@ static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
5353
{
5454
struct pt_regs *regs;
5555

56-
regs = current_pt_regs();
56+
vmbus_initiate_unload(true);
5757

58-
hyperv_report_panic(regs, val);
58+
if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
59+
regs = current_pt_regs();
60+
hyperv_report_panic(regs, val);
61+
}
5962
return NOTIFY_DONE;
6063
}
6164

@@ -1391,10 +1394,16 @@ static int vmbus_bus_init(void)
13911394
}
13921395

13931396
register_die_notifier(&hyperv_die_block);
1394-
atomic_notifier_chain_register(&panic_notifier_list,
1395-
&hyperv_panic_block);
13961397
}
13971398

1399+
/*
1400+
* Always register the panic notifier because we need to unload
1401+
* the VMbus channel connection to prevent any VMbus
1402+
* activity after the VM panics.
1403+
*/
1404+
atomic_notifier_chain_register(&panic_notifier_list,
1405+
&hyperv_panic_block);
1406+
13981407
vmbus_request_offers();
13991408

14001409
return 0;
@@ -2204,8 +2213,6 @@ static int vmbus_bus_suspend(struct device *dev)
22042213

22052214
vmbus_initiate_unload(false);
22062215

2207-
vmbus_connection.conn_state = DISCONNECTED;
2208-
22092216
/* Reset the event for the next resume. */
22102217
reinit_completion(&vmbus_connection.ready_for_resume_event);
22112218

@@ -2289,7 +2296,6 @@ static void hv_kexec_handler(void)
22892296
{
22902297
hv_stimer_global_cleanup();
22912298
vmbus_initiate_unload(false);
2292-
vmbus_connection.conn_state = DISCONNECTED;
22932299
/* Make sure conn_state is set as hv_synic_cleanup checks for it */
22942300
mb();
22952301
cpuhp_remove_state(hyperv_cpuhp_online);
@@ -2306,7 +2312,6 @@ static void hv_crash_handler(struct pt_regs *regs)
23062312
* doing the cleanup for current CPU only. This should be sufficient
23072313
* for kdump.
23082314
*/
2309-
vmbus_connection.conn_state = DISCONNECTED;
23102315
cpu = smp_processor_id();
23112316
hv_stimer_cleanup(cpu);
23122317
hv_synic_disable_regs(cpu);

0 commit comments

Comments
 (0)