[PATCH v2 5/6] mshv: clean up SynIC state on kexec for L1VH

From: Jork Loeser

Date: Fri Apr 03 2026 - 15:07:03 EST


Register the mshv reboot notifier for all parent partitions, not just
root. Previously the notifier was gated on hv_root_partition(), so on
L1VH (where hv_root_partition() is false) SINT0, SINT5, and SIRBP were
never cleaned up before kexec. The kexec'd kernel then inherited stale
unmasked SINTs and an enabled SIRBP pointing to freed memory.

The L1VH SIRBP also needs special handling: unlike the root partition
where the hypervisor provides the SIRBP page, L1VH must allocate its
own page and program the GPA into the MSR. Add this allocation to
mshv_synic_init() and the corresponding free to mshv_synic_cleanup().

Remove the unnecessary mshv_root_partition_init/exit wrappers and
register the reboot notifier directly in mshv_parent_partition_init().
Make mshv_reboot_nb static since it no longer needs external linkage.

Signed-off-by: Jork Loeser <jloeser@xxxxxxxxxxxxxxxxxxx>
---
drivers/hv/mshv_root_main.c | 21 ++++-----------------
1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index e6509c980763..281f530b68a9 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -2256,20 +2256,10 @@ static int mshv_reboot_notify(struct notifier_block *nb,
return 0;
}

-struct notifier_block mshv_reboot_nb = {
+static struct notifier_block mshv_reboot_nb = {
.notifier_call = mshv_reboot_notify,
};

-static void mshv_root_partition_exit(void)
-{
- unregister_reboot_notifier(&mshv_reboot_nb);
-}
-
-static int __init mshv_root_partition_init(struct device *dev)
-{
- return register_reboot_notifier(&mshv_reboot_nb);
-}
-
static int __init mshv_init_vmm_caps(struct device *dev)
{
int ret;
@@ -2339,8 +2329,7 @@ static int __init mshv_parent_partition_init(void)
if (ret)
goto remove_cpu_state;

- if (hv_root_partition())
- ret = mshv_root_partition_init(dev);
+ ret = register_reboot_notifier(&mshv_reboot_nb);
if (ret)
goto remove_cpu_state;

@@ -2368,8 +2357,7 @@ static int __init mshv_parent_partition_init(void)
deinit_root_scheduler:
root_scheduler_deinit();
exit_partition:
- if (hv_root_partition())
- mshv_root_partition_exit();
+ unregister_reboot_notifier(&mshv_reboot_nb);
remove_cpu_state:
cpuhp_remove_state(mshv_cpuhp_online);
free_synic_pages:
@@ -2387,8 +2375,7 @@ static void __exit mshv_parent_partition_exit(void)
misc_deregister(&mshv_dev);
mshv_irqfd_wq_cleanup();
root_scheduler_deinit();
- if (hv_root_partition())
- mshv_root_partition_exit();
+ unregister_reboot_notifier(&mshv_reboot_nb);
cpuhp_remove_state(mshv_cpuhp_online);
free_percpu(mshv_root.synic_pages);
}
--
2.43.0