summaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorDexuan Cui <decui@microsoft.com>2020-12-21 22:55:41 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-01-27 11:54:57 +0100
commit55807e7cb0bc6fa2e57edd946fe4b30a1b7d45d7 (patch)
tree85411c8f524f8c0c051e41c81f0dcb77c310c593 /drivers/hv
parent246ab9b9ed638cd1f633936d5995e4902d3d9829 (diff)
downloadlinux-stable-55807e7cb0bc6fa2e57edd946fe4b30a1b7d45d7.tar.gz
linux-stable-55807e7cb0bc6fa2e57edd946fe4b30a1b7d45d7.tar.bz2
linux-stable-55807e7cb0bc6fa2e57edd946fe4b30a1b7d45d7.zip
x86/hyperv: Fix kexec panic/hang issues
[ Upstream commit dfe94d4086e40e92b1926bddcefa629b791e9b28 ] Currently the kexec kernel can panic or hang due to 2 causes: 1) hv_cpu_die() is not called upon kexec, so the hypervisor corrupts the old VP Assist Pages when the kexec kernel runs. The same issue is fixed for hibernation in commit 421f090c819d ("x86/hyperv: Suspend/resume the VP assist page for hibernation"). Now fix it for kexec. 2) hyperv_cleanup() is called too early. In the kexec path, the other CPUs are stopped in hv_machine_shutdown() -> native_machine_shutdown(), so between hv_kexec_handler() and native_machine_shutdown(), the other CPUs can still try to access the hypercall page and cause panic. The workaround "hv_hypercall_pg = NULL;" in hyperv_cleanup() is unreliabe. Move hyperv_cleanup() to a better place. Signed-off-by: Dexuan Cui <decui@microsoft.com> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Link: https://lore.kernel.org/r/20201222065541.24312-1-decui@microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/vmbus_drv.c2
1 files changed, 0 insertions, 2 deletions
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 4fad3e6745e5..a5a402e776c7 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -2542,7 +2542,6 @@ static void hv_kexec_handler(void)
/* Make sure conn_state is set as hv_synic_cleanup checks for it */
mb();
cpuhp_remove_state(hyperv_cpuhp_online);
- hyperv_cleanup();
};
static void hv_crash_handler(struct pt_regs *regs)
@@ -2558,7 +2557,6 @@ static void hv_crash_handler(struct pt_regs *regs)
cpu = smp_processor_id();
hv_stimer_cleanup(cpu);
hv_synic_disable_regs(cpu);
- hyperv_cleanup();
};
static int hv_synic_suspend(void)