Skip to content

Commit 179fb36

Browse files
ryncsnKAGA-KOKO
authored andcommitted
x86/hyperv: Fix kernel panic when kexec on HyperV
After commit 68bb7bf ("X86/Hyper-V: Enable IPI enlightenments"), kexec fails with a kernel panic: kexec_core: Starting new kernel BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v3.0 03/02/2018 RIP: 0010:0xffffc9000001d000 Call Trace: ? __send_ipi_mask+0x1c6/0x2d0 ? hv_send_ipi_mask_allbutself+0x6d/0xb0 ? mp_save_irq+0x70/0x70 ? __ioapic_read_entry+0x32/0x50 ? ioapic_read_entry+0x39/0x50 ? clear_IO_APIC_pin+0xb8/0x110 ? native_stop_other_cpus+0x6e/0x170 ? native_machine_shutdown+0x22/0x40 ? kernel_kexec+0x136/0x156 That happens if hypercall based IPIs are used because the hypercall page is reset very early upon kexec reboot, but kexec sends IPIs to stop CPUs, which invokes the hypercall and dereferences the unusable page. To fix his, reset hv_hypercall_pg to NULL before the page is reset to avoid any misuse, IPI sending will fall back to the non hypercall based method. This only happens on kexec / kdump so just setting the pointer to NULL is good enough. Fixes: 68bb7bf ("X86/Hyper-V: Enable IPI enlightenments") Signed-off-by: Kairui Song <kasong@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: "K. Y. Srinivasan" <kys@microsoft.com> Cc: Haiyang Zhang <haiyangz@microsoft.com> Cc: Stephen Hemminger <sthemmin@microsoft.com> Cc: Sasha Levin <sashal@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Vitaly Kuznetsov <vkuznets@redhat.com> Cc: Dave Young <dyoung@redhat.com> Cc: devel@linuxdriverproject.org Link: https://lkml.kernel.org/r/20190306111827.14131-1-kasong@redhat.com
1 parent 24c4122 commit 179fb36

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

arch/x86/hyperv/hv_init.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,13 @@ void hyperv_cleanup(void)
406406
/* Reset our OS id */
407407
wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
408408

409+
/*
410+
* Reset hypercall page reference before reset the page,
411+
* let hypercall operations fail safely rather than
412+
* panic the kernel for using invalid hypercall page
413+
*/
414+
hv_hypercall_pg = NULL;
415+
409416
/* Reset the hypercall page */
410417
hypercall_msr.as_uint64 = 0;
411418
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);

0 commit comments

Comments
 (0)