Skip to content

Commit b9af641

Browse files
Anirudh Rayabharam (Microsoft)liuw
authored andcommitted
x86/hyperv: fix kexec crash due to VP assist page corruption
commit 9636be8 ("x86/hyperv: Fix hyperv_pcpu_input_arg handling when CPUs go online/offline") introduces a new cpuhp state for hyperv initialization. cpuhp_setup_state() returns the state number if state is CPUHP_AP_ONLINE_DYN or CPUHP_BP_PREPARE_DYN and 0 for all other states. For the hyperv case, since a new cpuhp state was introduced it would return 0. However, in hv_machine_shutdown(), the cpuhp_remove_state() call is conditioned upon "hyperv_init_cpuhp > 0". This will never be true and so hv_cpu_die() won't be called on all CPUs. This means the VP assist page won't be reset. When the kexec kernel tries to setup the VP assist page again, the hypervisor corrupts the memory region of the old VP assist page causing a panic in case the kexec kernel is using that memory elsewhere. This was originally fixed in commit dfe94d4 ("x86/hyperv: Fix kexec panic/hang issues"). Get rid of hyperv_init_cpuhp entirely since we are no longer using a dynamic cpuhp state and use CPUHP_AP_HYPERV_ONLINE directly with cpuhp_remove_state(). Cc: [email protected] Fixes: 9636be8 ("x86/hyperv: Fix hyperv_pcpu_input_arg handling when CPUs go online/offline") Signed-off-by: Anirudh Rayabharam (Microsoft) <[email protected]> Reviewed-by: Vitaly Kuznetsov <[email protected]> Reviewed-by: Michael Kelley <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Wei Liu <[email protected]> Message-ID: <[email protected]>
1 parent 4430556 commit b9af641

File tree

3 files changed

+3
-7
lines changed

3 files changed

+3
-7
lines changed

arch/x86/hyperv/hv_init.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include <clocksource/hyperv_timer.h>
3636
#include <linux/highmem.h>
3737

38-
int hyperv_init_cpuhp;
3938
u64 hv_current_partition_id = ~0ull;
4039
EXPORT_SYMBOL_GPL(hv_current_partition_id);
4140

@@ -607,8 +606,6 @@ void __init hyperv_init(void)
607606

608607
register_syscore_ops(&hv_syscore_ops);
609608

610-
hyperv_init_cpuhp = cpuhp;
611-
612609
if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
613610
hv_get_partition_id();
614611

@@ -637,7 +634,7 @@ void __init hyperv_init(void)
637634
clean_guest_os_id:
638635
wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
639636
hv_ivm_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
640-
cpuhp_remove_state(cpuhp);
637+
cpuhp_remove_state(CPUHP_AP_HYPERV_ONLINE);
641638
free_ghcb_page:
642639
free_percpu(hv_ghcb_pg);
643640
free_vp_assist_page:

arch/x86/include/asm/mshyperv.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ static inline unsigned char hv_get_nmi_reason(void)
4040
}
4141

4242
#if IS_ENABLED(CONFIG_HYPERV)
43-
extern int hyperv_init_cpuhp;
4443
extern bool hyperv_paravisor_present;
4544

4645
extern void *hv_hypercall_pg;

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ static void hv_machine_shutdown(void)
199199
* Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor
200200
* corrupts the old VP Assist Pages and can crash the kexec kernel.
201201
*/
202-
if (kexec_in_progress && hyperv_init_cpuhp > 0)
203-
cpuhp_remove_state(hyperv_init_cpuhp);
202+
if (kexec_in_progress)
203+
cpuhp_remove_state(CPUHP_AP_HYPERV_ONLINE);
204204

205205
/* The function calls stop_other_cpus(). */
206206
native_machine_shutdown();

0 commit comments

Comments
 (0)