On Thu, Oct 08, 2026 at 09:53:05AM +0200, Mike Rapoport wrote:
> On Thu, Oct 01, 2026 at 06:22:02AM -0700, Shradha Gupta wrote:
> > ARM64 Hyper-V guests do not run the VMBus kexec cleanup before
> > secondary CPUs are stopped. Consequently, the old VMBus connection
> > and SynIC state remain active when the kexec kernel starts.
> > 
> > Run the VMBus kexec handler from the existing VMBus syscore shutdown
> > callback. syscore_shutdown() runs after device shutdown and before
> > machine shutdown, while all CPUs needed by the SynIC CPU hotplug
> > teardown are still available. Guard the callback with
> > kexec_is_in_progress() so normal restart, halt, and poweroff paths are
> > unchanged.
> > 
> > Use the same path on x86 and remove the architecture-specific handler
> > pointer and the weak setup/remove interfaces. VMBus teardown now
> > precedes hv_stimer_global_cleanup() on x86.
> > 
> > The new x86 ordering relies on commit be0cfab740e5 ("clocksource:
> > hyper-v: Remove support for stimer interrupts in message mode"), which
> > removed the synthetic timer's dependency on VMBus message delivery.
> > Older kernels that retain message-mode stimer interrupts must preserve
> > the existing x86 ordering and therefore require an ARM64-specific
> > backport.
> > 
> > Fixes: 9bbb888824e3 ("arm64: hyperv: Initialize hypervisor on boot")
> > Link: 
> > https://lore.kernel.org/all/[email protected]/
> > Suggested-by: Catalin Marinas <[email protected]>
> > Suggested-by: Michael Kelley <[email protected]>
> > Signed-off-by: Shradha Gupta <[email protected]>
> > ---
> >  arch/x86/kernel/cpu/mshyperv.c | 17 +----------------
> >  drivers/hv/hv_common.c         | 10 ----------
> >  drivers/hv/vmbus_drv.c         | 22 ++++++++++++++--------
> >  include/asm-generic/mshyperv.h |  2 --
> 
> It seems you missed Documentation/virt/hyperv/overview.rst ;)
>

Thanks Mike, I'll address this in the next version. :)
 
> >  4 files changed, 15 insertions(+), 36 deletions(-)
> > 
> > diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> > index b4af7c0a70ac..263f7e7acac0 100644
> > --- a/arch/x86/kernel/cpu/mshyperv.c
> > +++ b/arch/x86/kernel/cpu/mshyperv.c
> > @@ -148,7 +148,6 @@ EXPORT_SYMBOL_GPL(hv_set_msr);
> >  static void (*mshv_handler)(void);
> >  static void (*vmbus_handler)(void);
> >  static void (*hv_stimer0_handler)(void);
> > -static void (*hv_kexec_handler)(void);
> >  static void (*hv_crash_handler)(struct pt_regs *regs);
> >  
> >  DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
> > @@ -215,16 +214,6 @@ void hv_remove_stimer0_handler(void)
> >     hv_stimer0_handler = NULL;
> >  }
> >  
> > -void hv_setup_kexec_handler(void (*handler)(void))
> > -{
> > -   hv_kexec_handler = handler;
> > -}
> > -
> > -void hv_remove_kexec_handler(void)
> > -{
> > -   hv_kexec_handler = NULL;
> > -}
> > -
> >  void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs))
> >  {
> >     hv_crash_handler = handler;
> > @@ -238,13 +227,9 @@ void hv_remove_crash_handler(void)
> >  #ifdef CONFIG_KEXEC_CORE
> >  static void hv_machine_shutdown(void)
> >  {
> > -   if (kexec_in_progress) {
> > +   if (kexec_in_progress)
> >             hv_stimer_global_cleanup();
> >  
> > -           if (hv_kexec_handler)
> > -                   hv_kexec_handler();
> > -   }
> > -
> >     /*
> >      * Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor
> >      * corrupts the old VP Assist Pages and can crash the kexec kernel.
> > diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> > index 31256cb22b39..bb290a5eaf1d 100644
> > --- a/drivers/hv/hv_common.c
> > +++ b/drivers/hv/hv_common.c
> > @@ -681,16 +681,6 @@ void __weak hv_setup_mshv_handler(void 
> > (*handler)(void))
> >  }
> >  EXPORT_SYMBOL_GPL(hv_setup_mshv_handler);
> >  
> > -void __weak hv_setup_kexec_handler(void (*handler)(void))
> > -{
> > -}
> > -EXPORT_SYMBOL_GPL(hv_setup_kexec_handler);
> > -
> > -void __weak hv_remove_kexec_handler(void)
> > -{
> > -}
> > -EXPORT_SYMBOL_GPL(hv_remove_kexec_handler);
> > -
> >  void __weak hv_setup_crash_handler(void (*handler)(struct pt_regs *regs))
> >  {
> >  }
> > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> > index 5ebdbe24b5a1..3532ea779d34 100644
> > --- a/drivers/hv/vmbus_drv.c
> > +++ b/drivers/hv/vmbus_drv.c
> > @@ -33,6 +33,7 @@
> >  #include <linux/sysfb.h>
> >  #include <linux/efi.h>
> >  #include <linux/kernel.h>
> > +#include <linux/kexec.h>
> >  #include <linux/syscore_ops.h>
> >  #include <linux/dma-map-ops.h>
> >  #include <linux/pci.h>
> > @@ -2904,6 +2905,12 @@ static void hv_kexec_handler(void)
> >     cpuhp_remove_state(hyperv_cpuhp_online);
> >  };
> >  
> > +static void hv_vmbus_syscore_shutdown(void *data)
> > +{
> > +   if (kexec_is_in_progress())
> > +           hv_kexec_handler();
> > +}
> > +
> >  static void hv_crash_handler(struct pt_regs *regs)
> >  {
> >     int cpu;
> > @@ -2958,14 +2965,15 @@ static void hv_synic_resume(void *data)
> >      */
> >  }
> >  
> > -/* The callbacks run only on CPU0, with irqs_disabled. */
> > -static const struct syscore_ops hv_synic_syscore_ops = {
> > +/* The suspend and resume callbacks run only on CPU0, with irqs_disabled. 
> > */
> > +static const struct syscore_ops hv_vmbus_syscore_ops = {
> >     .suspend = hv_synic_suspend,
> >     .resume = hv_synic_resume,
> > +   .shutdown = hv_vmbus_syscore_shutdown,
> >  };
> >  
> > -static struct syscore hv_synic_syscore = {
> > -   .ops = &hv_synic_syscore_ops,
> > +static struct syscore hv_vmbus_syscore = {
> > +   .ops = &hv_vmbus_syscore_ops,
> >  };
> >  
> >  static int __init hv_acpi_init(void)
> > @@ -3014,10 +3022,9 @@ static int __init hv_acpi_init(void)
> >     if (ret)
> >             goto cleanup;
> >  
> > -   hv_setup_kexec_handler(hv_kexec_handler);
> >     hv_setup_crash_handler(hv_crash_handler);
> >  
> > -   register_syscore(&hv_synic_syscore);
> > +   register_syscore(&hv_vmbus_syscore);
> >  
> >     return 0;
> >  
> > @@ -3039,9 +3046,8 @@ static void __exit vmbus_exit(void)
> >              */
> >             return;
> >  
> > -   unregister_syscore(&hv_synic_syscore);
> > +   unregister_syscore(&hv_vmbus_syscore);
> >  
> > -   hv_remove_kexec_handler();
> >     hv_remove_crash_handler();
> >     vmbus_connection.conn_state = DISCONNECTED;
> >     hv_stimer_global_cleanup();
> > diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> > index bf601d67cecb..98fe5c0f54ea 100644
> > --- a/include/asm-generic/mshyperv.h
> > +++ b/include/asm-generic/mshyperv.h
> > @@ -183,8 +183,6 @@ void hv_remove_vmbus_handler(void);
> >  void hv_setup_stimer0_handler(void (*handler)(void));
> >  void hv_remove_stimer0_handler(void);
> >  
> > -void hv_setup_kexec_handler(void (*handler)(void));
> > -void hv_remove_kexec_handler(void);
> >  void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
> >  void hv_remove_crash_handler(void);
> >  void hv_setup_mshv_handler(void (*handler)(void));
> > -- 
> > 2.43.0
> 
> -- 
> Sincerely yours,
> Mike.

Reply via email to