Re: [PATCH] powerpc/crash: save cpu register data in crash_smp_send_stop()

2022-06-30 Thread Hari Bathini

Please ignore this thread. Will resend with v2 tag..

On 30/06/22 11:00 am, Hari Bathini wrote:

During kdump, two set of NMI IPIs are sent to secondary CPUs, if
'crash_kexec_post_notifiers' option is set. The first set of NMI IPIs
to stop the CPUs and the other set to collect register data. Instead,
capture register data for secondary CPUs while stopping them itself.
Also, fallback to smp_send_stop() in case the function gets called
without kdump configured.

Signed-off-by: Hari Bathini 
---
  arch/powerpc/include/asm/kexec.h |  1 +
  arch/powerpc/kernel/smp.c| 29 
  arch/powerpc/kexec/crash.c   | 77 +++-
  3 files changed, 57 insertions(+), 50 deletions(-)

diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 2aefe14e1442..cce69101205e 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -83,6 +83,7 @@ extern void default_machine_crash_shutdown(struct pt_regs 
*regs);
  extern int crash_shutdown_register(crash_shutdown_t handler);
  extern int crash_shutdown_unregister(crash_shutdown_t handler);
  
+extern void crash_kexec_prepare(void);

  extern void crash_kexec_secondary(struct pt_regs *regs);
  int __init overlaps_crashkernel(unsigned long start, unsigned long size);
  extern void reserve_crashkernel(void);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index bcefab484ea6..6b850c157a62 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -35,6 +35,7 @@
  #include 
  #include 
  #include 
+#include 
  
  #include 

  #include 
@@ -55,7 +56,6 @@
  #endif
  #include 
  #include 
-#include 
  #include 
  #include 
  #include 
@@ -619,20 +619,6 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct 
pt_regs *))
  }
  #endif
  
-#ifdef CONFIG_NMI_IPI

-static void crash_stop_this_cpu(struct pt_regs *regs)
-#else
-static void crash_stop_this_cpu(void *dummy)
-#endif
-{
-   /*
-* Just busy wait here and avoid marking CPU as offline to ensure
-* register data is captured appropriately.
-*/
-   while (1)
-   cpu_relax();
-}
-
  void crash_smp_send_stop(void)
  {
static bool stopped = false;
@@ -651,11 +637,14 @@ void crash_smp_send_stop(void)
  
  	stopped = true;
  
-#ifdef CONFIG_NMI_IPI

-   smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 100);
-#else
-   smp_call_function(crash_stop_this_cpu, NULL, 0);
-#endif /* CONFIG_NMI_IPI */
+#ifdef CONFIG_KEXEC_CORE
+   if (kexec_crash_image) {
+   crash_kexec_prepare();
+   return;
+   }
+#endif
+
+   smp_send_stop();
  }
  
  #ifdef CONFIG_NMI_IPI

diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
index 80f54723cf6d..252724ed666a 100644
--- a/arch/powerpc/kexec/crash.c
+++ b/arch/powerpc/kexec/crash.c
@@ -40,6 +40,14 @@
  #define REAL_MODE_TIMEOUT 1
  
  static int time_to_dump;

+
+/*
+ * In case of system reset, secondary CPUs enter crash_kexec_secondary with out
+ * having to send an IPI explicitly. So, indicate if the crash is via
+ * system reset to avoid sending another IPI.
+ */
+static int is_via_system_reset;
+
  /*
   * crash_wake_offline should be set to 1 by platforms that intend to wake
   * up offline cpus prior to jumping to a kdump kernel. Currently powernv
@@ -101,7 +109,7 @@ void crash_ipi_callback(struct pt_regs *regs)
/* NOTREACHED */
  }
  
-static void crash_kexec_prepare_cpus(int cpu)

+static void crash_kexec_prepare_cpus(void)
  {
unsigned int msecs;
volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the 
panic cpu */
@@ -113,7 +121,15 @@ static void crash_kexec_prepare_cpus(int cpu)
if (crash_wake_offline)
ncpus = num_present_cpus() - 1;
  
-	crash_send_ipi(crash_ipi_callback);

+   /*
+* If we came in via system reset, secondaries enter via 
crash_kexec_secondary().
+* So, wait a while for the secondary CPUs to enter for that case.
+* Else, send IPI to all other CPUs.
+*/
+   if (is_via_system_reset)
+   mdelay(PRIMARY_TIMEOUT);
+   else
+   crash_send_ipi(crash_ipi_callback);
smp_wmb();
  
  again:

@@ -202,7 +218,7 @@ void crash_kexec_secondary(struct pt_regs *regs)
  
  #else	/* ! CONFIG_SMP */
  
-static void crash_kexec_prepare_cpus(int cpu)

+static void crash_kexec_prepare_cpus(void)
  {
/*
 * move the secondaries to us so that we can copy
@@ -248,6 +264,32 @@ noinstr static void __maybe_unused 
crash_kexec_wait_realmode(int cpu)
  static inline void crash_kexec_wait_realmode(int cpu) {}
  #endif/* CONFIG_SMP && CONFIG_PPC64 */
  
+void crash_kexec_prepare(void)

+{
+   /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
+   printk_deferred_enter();
+
+   /*
+* This function is only called after the system
+* has panicked or is 

[PATCH] powerpc/crash: save cpu register data in crash_smp_send_stop()

2022-06-29 Thread Hari Bathini
During kdump, two set of NMI IPIs are sent to secondary CPUs, if
'crash_kexec_post_notifiers' option is set. The first set of NMI IPIs
to stop the CPUs and the other set to collect register data. Instead,
capture register data for secondary CPUs while stopping them itself.
Also, fallback to smp_send_stop() in case the function gets called
without kdump configured.

Signed-off-by: Hari Bathini 
---
 arch/powerpc/include/asm/kexec.h |  1 +
 arch/powerpc/kernel/smp.c| 29 
 arch/powerpc/kexec/crash.c   | 77 +++-
 3 files changed, 57 insertions(+), 50 deletions(-)

diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 2aefe14e1442..cce69101205e 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -83,6 +83,7 @@ extern void default_machine_crash_shutdown(struct pt_regs 
*regs);
 extern int crash_shutdown_register(crash_shutdown_t handler);
 extern int crash_shutdown_unregister(crash_shutdown_t handler);
 
+extern void crash_kexec_prepare(void);
 extern void crash_kexec_secondary(struct pt_regs *regs);
 int __init overlaps_crashkernel(unsigned long start, unsigned long size);
 extern void reserve_crashkernel(void);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index bcefab484ea6..6b850c157a62 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -55,7 +56,6 @@
 #endif
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -619,20 +619,6 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct 
pt_regs *))
 }
 #endif
 
-#ifdef CONFIG_NMI_IPI
-static void crash_stop_this_cpu(struct pt_regs *regs)
-#else
-static void crash_stop_this_cpu(void *dummy)
-#endif
-{
-   /*
-* Just busy wait here and avoid marking CPU as offline to ensure
-* register data is captured appropriately.
-*/
-   while (1)
-   cpu_relax();
-}
-
 void crash_smp_send_stop(void)
 {
static bool stopped = false;
@@ -651,11 +637,14 @@ void crash_smp_send_stop(void)
 
stopped = true;
 
-#ifdef CONFIG_NMI_IPI
-   smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 100);
-#else
-   smp_call_function(crash_stop_this_cpu, NULL, 0);
-#endif /* CONFIG_NMI_IPI */
+#ifdef CONFIG_KEXEC_CORE
+   if (kexec_crash_image) {
+   crash_kexec_prepare();
+   return;
+   }
+#endif
+
+   smp_send_stop();
 }
 
 #ifdef CONFIG_NMI_IPI
diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
index 80f54723cf6d..252724ed666a 100644
--- a/arch/powerpc/kexec/crash.c
+++ b/arch/powerpc/kexec/crash.c
@@ -40,6 +40,14 @@
 #define REAL_MODE_TIMEOUT  1
 
 static int time_to_dump;
+
+/*
+ * In case of system reset, secondary CPUs enter crash_kexec_secondary with out
+ * having to send an IPI explicitly. So, indicate if the crash is via
+ * system reset to avoid sending another IPI.
+ */
+static int is_via_system_reset;
+
 /*
  * crash_wake_offline should be set to 1 by platforms that intend to wake
  * up offline cpus prior to jumping to a kdump kernel. Currently powernv
@@ -101,7 +109,7 @@ void crash_ipi_callback(struct pt_regs *regs)
/* NOTREACHED */
 }
 
-static void crash_kexec_prepare_cpus(int cpu)
+static void crash_kexec_prepare_cpus(void)
 {
unsigned int msecs;
volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the 
panic cpu */
@@ -113,7 +121,15 @@ static void crash_kexec_prepare_cpus(int cpu)
if (crash_wake_offline)
ncpus = num_present_cpus() - 1;
 
-   crash_send_ipi(crash_ipi_callback);
+   /*
+* If we came in via system reset, secondaries enter via 
crash_kexec_secondary().
+* So, wait a while for the secondary CPUs to enter for that case.
+* Else, send IPI to all other CPUs.
+*/
+   if (is_via_system_reset)
+   mdelay(PRIMARY_TIMEOUT);
+   else
+   crash_send_ipi(crash_ipi_callback);
smp_wmb();
 
 again:
@@ -202,7 +218,7 @@ void crash_kexec_secondary(struct pt_regs *regs)
 
 #else  /* ! CONFIG_SMP */
 
-static void crash_kexec_prepare_cpus(int cpu)
+static void crash_kexec_prepare_cpus(void)
 {
/*
 * move the secondaries to us so that we can copy
@@ -248,6 +264,32 @@ noinstr static void __maybe_unused 
crash_kexec_wait_realmode(int cpu)
 static inline void crash_kexec_wait_realmode(int cpu) {}
 #endif /* CONFIG_SMP && CONFIG_PPC64 */
 
+void crash_kexec_prepare(void)
+{
+   /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
+   printk_deferred_enter();
+
+   /*
+* This function is only called after the system
+* has panicked or is otherwise in a critical state.
+* The minimum amount of code to allow a kexec'd kernel
+* to run successfully needs to happen here.
+*

Re: [PATCH] powerpc/crash: save cpu register data in crash_smp_send_stop()

2022-05-24 Thread Hari Bathini

Hi Nick,

Thanks for the review..

On 10/05/22 2:31 pm, Nicholas Piggin wrote:

Excerpts from Hari Bathini's message of May 7, 2022 2:39 am:

Capture register data for secondary CPUs in crash_smp_send_stop()
instead of doing it much later in crash_kexec_prepare_cpus() function
with another set of NMI IPIs to secondary CPUs. This change avoids
unnecessarily tricky post processing of data to get the right
backtrace for these CPUs.


Is the tricky post processing done in crash tools?


Yeah. In tools like crash-utility that try to make sense of the
register data captured.



Is it buggy in
some situations or just fragile code you want to deprecate? Seems
like a good goal either way



The post processing may need looking up the emergency stack and
eventually tracing back to the regular stack. No code in crash-utility
to handle it currently though. This meant no proper backtrace, with 
crash-utility, for only cases like "crash_kexec_post_notifiers". But

default cases will start having improper backtraces as well with
series [0] moving around crash_smp_send_stop().


I assume the desire to stop secondaries ASAP is not just to get
register data but also to limit the amount of damage they might
cause to the crash process. Can they take interrupts or trigger
the hard lockup watchdog, for example?


True. Intention is to stop secondaries ASAP and make dump capture
as smooth as possible...


-void crash_smp_send_stop(void)
-{
-   static bool stopped = false;
-
-   /*
-* In case of fadump, register data for all CPUs is captured by f/w
-* on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
-* this rtas call to avoid tricky post processing of those CPUs'
-* backtraces.
-*/
-   if (should_fadump_crash())
-   return;


This is not actually code you changed, but I wonder if it's wrong,
if fadump is enabled then panic runs without stopping secondaries?
Doesn't seem quite right.


So far, haven't seen any problem. F/W seems to handle it alright
without having to stop the secondaries before the ibm,os-term call.
But I do agree that stopping secondaries before calling into rtas sounds
like the right thing to do, even if that meant processing more than one
stack to get the proper backtrace..


-
-   if (stopped)
-   return;
-
-   stopped = true;
-
-#ifdef CONFIG_NMI_IPI
-   smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 100);
-#else
-   smp_call_function(crash_stop_this_cpu, NULL, 0);
-#endif /* CONFIG_NMI_IPI */
-}


Now if kexec is not configured do we lose our crash_smp_send_stop
function, or is it only ever called if kexec is enabled?


crash_smp_send_stop() is proposed to be called for both kdump and
non-kdump cases as well with [1].


-
  #ifdef CONFIG_NMI_IPI
  static void nmi_stop_this_cpu(struct pt_regs *regs)
  {
diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
index 22ceeeb705ab..f06dfe71caca 100644
--- a/arch/powerpc/kexec/crash.c
+++ b/arch/powerpc/kexec/crash.c
@@ -25,6 +25,7 @@
  #include 
  #include 
  #include 
+#include 
  
  /*

   * The primary CPU waits a while for all secondary CPUs to enter. This is to
@@ -102,7 +103,7 @@ void crash_ipi_callback(struct pt_regs *regs)
/* NOTREACHED */
  }
  
-static void crash_kexec_prepare_cpus(int cpu)

+static void crash_kexec_prepare_cpus(void)
  {
unsigned int msecs;
volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the 
panic cpu */
@@ -203,7 +204,7 @@ void crash_kexec_secondary(struct pt_regs *regs)
  
  #else	/* ! CONFIG_SMP */
  
-static void crash_kexec_prepare_cpus(int cpu)

+static void crash_kexec_prepare_cpus(void)
  {
/*
 * move the secondaries to us so that we can copy
@@ -249,6 +250,42 @@ static void __maybe_unused crash_kexec_wait_realmode(int 
cpu)
  static inline void crash_kexec_wait_realmode(int cpu) {}
  #endif/* CONFIG_SMP && CONFIG_PPC64 */
  
+void crash_smp_send_stop(void)

+{
+   static int cpus_stopped;
+
+   /*
+* In case of fadump, register data for all CPUs is captured by f/w
+* on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
+* this rtas call to avoid tricky post processing of those CPUs'
+* backtraces.
+*/
+   if (should_fadump_crash())
+   return;
+
+   if (cpus_stopped)
+   return;
+
+   cpus_stopped = 1;
+
+   /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
+   printk_deferred_enter();
+
+   /*
+* This function is only called after the system
+* has panicked or is otherwise in a critical state.
+* The minimum amount of code to allow a kexec'd kernel
+* to run successfully needs to happen here.
+*
+* In practice this means stopping other cpus in
+* an SMP system.
+* The kernel is broken so disable interrupts.
+*/
+   

Re: [PATCH] powerpc/crash: save cpu register data in crash_smp_send_stop()

2022-05-10 Thread Nicholas Piggin
Excerpts from Hari Bathini's message of May 7, 2022 2:39 am:
> Capture register data for secondary CPUs in crash_smp_send_stop()
> instead of doing it much later in crash_kexec_prepare_cpus() function
> with another set of NMI IPIs to secondary CPUs. This change avoids
> unnecessarily tricky post processing of data to get the right
> backtrace for these CPUs.

Is the tricky post processing done in crash tools? Is it buggy in
some situations or just fragile code you want to deprecate? Seems
like a good goal either way

I assume the desire to stop secondaries ASAP is not just to get
register data but also to limit the amount of damage they might
cause to the crash process. Can they take interrupts or trigger
the hard lockup watchdog, for example?

> -void crash_smp_send_stop(void)
> -{
> - static bool stopped = false;
> -
> - /*
> -  * In case of fadump, register data for all CPUs is captured by f/w
> -  * on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
> -  * this rtas call to avoid tricky post processing of those CPUs'
> -  * backtraces.
> -  */
> - if (should_fadump_crash())
> - return;

This is not actually code you changed, but I wonder if it's wrong,
if fadump is enabled then panic runs without stopping secondaries?
Doesn't seem quite right.

> -
> - if (stopped)
> - return;
> -
> - stopped = true;
> -
> -#ifdef CONFIG_NMI_IPI
> - smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 100);
> -#else
> - smp_call_function(crash_stop_this_cpu, NULL, 0);
> -#endif /* CONFIG_NMI_IPI */
> -}

Now if kexec is not configured do we lose our crash_smp_send_stop
function, or is it only ever called if kexec is enabled?

> -
>  #ifdef CONFIG_NMI_IPI
>  static void nmi_stop_this_cpu(struct pt_regs *regs)
>  {
> diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
> index 22ceeeb705ab..f06dfe71caca 100644
> --- a/arch/powerpc/kexec/crash.c
> +++ b/arch/powerpc/kexec/crash.c
> @@ -25,6 +25,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  /*
>   * The primary CPU waits a while for all secondary CPUs to enter. This is to
> @@ -102,7 +103,7 @@ void crash_ipi_callback(struct pt_regs *regs)
>   /* NOTREACHED */
>  }
>  
> -static void crash_kexec_prepare_cpus(int cpu)
> +static void crash_kexec_prepare_cpus(void)
>  {
>   unsigned int msecs;
>   volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the 
> panic cpu */
> @@ -203,7 +204,7 @@ void crash_kexec_secondary(struct pt_regs *regs)
>  
>  #else/* ! CONFIG_SMP */
>  
> -static void crash_kexec_prepare_cpus(int cpu)
> +static void crash_kexec_prepare_cpus(void)
>  {
>   /*
>* move the secondaries to us so that we can copy
> @@ -249,6 +250,42 @@ static void __maybe_unused crash_kexec_wait_realmode(int 
> cpu)
>  static inline void crash_kexec_wait_realmode(int cpu) {}
>  #endif   /* CONFIG_SMP && CONFIG_PPC64 */
>  
> +void crash_smp_send_stop(void)
> +{
> + static int cpus_stopped;
> +
> + /*
> +  * In case of fadump, register data for all CPUs is captured by f/w
> +  * on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
> +  * this rtas call to avoid tricky post processing of those CPUs'
> +  * backtraces.
> +  */
> + if (should_fadump_crash())
> + return;
> +
> + if (cpus_stopped)
> + return;
> +
> + cpus_stopped = 1;
> +
> + /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
> + printk_deferred_enter();
> +
> + /*
> +  * This function is only called after the system
> +  * has panicked or is otherwise in a critical state.
> +  * The minimum amount of code to allow a kexec'd kernel
> +  * to run successfully needs to happen here.
> +  *
> +  * In practice this means stopping other cpus in
> +  * an SMP system.
> +  * The kernel is broken so disable interrupts.
> +  */
> + hard_irq_disable();
> +
> + crash_kexec_prepare_cpus();

This seems to move a bit of the kexec code around so this runs 
before notifiers in the panic path now. Maybe that's okay, I don't
know this code too well, but how feasible would it be to have
crash_stop_this_cpu() call crash_save_cpu()? And keeping the
second IPI.

I do like the idea of removing the second IPI if possible, but
that could be done later by moving the logic into crash_save_cpu()
(it could just poll on a flag until the primary releases it to
the next phase, rather than have the primary send another IPI).

Thanks,
Nick


> +}
> +
>  /*
>   * Register a function to be called on shutdown.  Only use this if you
>   * can't reset your device in the second kernel.
> @@ -312,21 +349,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
>   unsigned int i;
>   int (*old_handler)(struct pt_regs *regs);
>  
> - /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
> - 

[PATCH] powerpc/crash: save cpu register data in crash_smp_send_stop()

2022-05-06 Thread Hari Bathini
Capture register data for secondary CPUs in crash_smp_send_stop()
instead of doing it much later in crash_kexec_prepare_cpus() function
with another set of NMI IPIs to secondary CPUs. This change avoids
unnecessarily tricky post processing of data to get the right
backtrace for these CPUs.

Signed-off-by: Hari Bathini 
---
 arch/powerpc/kernel/smp.c  | 40 --
 arch/powerpc/kexec/crash.c | 58 ++
 2 files changed, 40 insertions(+), 58 deletions(-)

diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index de0f6f09a5dd..7621c3d84c1c 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -60,7 +60,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #ifdef DEBUG
 #include 
@@ -620,45 +619,6 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct 
pt_regs *))
 }
 #endif
 
-#ifdef CONFIG_NMI_IPI
-static void crash_stop_this_cpu(struct pt_regs *regs)
-#else
-static void crash_stop_this_cpu(void *dummy)
-#endif
-{
-   /*
-* Just busy wait here and avoid marking CPU as offline to ensure
-* register data is captured appropriately.
-*/
-   while (1)
-   cpu_relax();
-}
-
-void crash_smp_send_stop(void)
-{
-   static bool stopped = false;
-
-   /*
-* In case of fadump, register data for all CPUs is captured by f/w
-* on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
-* this rtas call to avoid tricky post processing of those CPUs'
-* backtraces.
-*/
-   if (should_fadump_crash())
-   return;
-
-   if (stopped)
-   return;
-
-   stopped = true;
-
-#ifdef CONFIG_NMI_IPI
-   smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 100);
-#else
-   smp_call_function(crash_stop_this_cpu, NULL, 0);
-#endif /* CONFIG_NMI_IPI */
-}
-
 #ifdef CONFIG_NMI_IPI
 static void nmi_stop_this_cpu(struct pt_regs *regs)
 {
diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
index 22ceeeb705ab..f06dfe71caca 100644
--- a/arch/powerpc/kexec/crash.c
+++ b/arch/powerpc/kexec/crash.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * The primary CPU waits a while for all secondary CPUs to enter. This is to
@@ -102,7 +103,7 @@ void crash_ipi_callback(struct pt_regs *regs)
/* NOTREACHED */
 }
 
-static void crash_kexec_prepare_cpus(int cpu)
+static void crash_kexec_prepare_cpus(void)
 {
unsigned int msecs;
volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the 
panic cpu */
@@ -203,7 +204,7 @@ void crash_kexec_secondary(struct pt_regs *regs)
 
 #else  /* ! CONFIG_SMP */
 
-static void crash_kexec_prepare_cpus(int cpu)
+static void crash_kexec_prepare_cpus(void)
 {
/*
 * move the secondaries to us so that we can copy
@@ -249,6 +250,42 @@ static void __maybe_unused crash_kexec_wait_realmode(int 
cpu)
 static inline void crash_kexec_wait_realmode(int cpu) {}
 #endif /* CONFIG_SMP && CONFIG_PPC64 */
 
+void crash_smp_send_stop(void)
+{
+   static int cpus_stopped;
+
+   /*
+* In case of fadump, register data for all CPUs is captured by f/w
+* on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
+* this rtas call to avoid tricky post processing of those CPUs'
+* backtraces.
+*/
+   if (should_fadump_crash())
+   return;
+
+   if (cpus_stopped)
+   return;
+
+   cpus_stopped = 1;
+
+   /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
+   printk_deferred_enter();
+
+   /*
+* This function is only called after the system
+* has panicked or is otherwise in a critical state.
+* The minimum amount of code to allow a kexec'd kernel
+* to run successfully needs to happen here.
+*
+* In practice this means stopping other cpus in
+* an SMP system.
+* The kernel is broken so disable interrupts.
+*/
+   hard_irq_disable();
+
+   crash_kexec_prepare_cpus();
+}
+
 /*
  * Register a function to be called on shutdown.  Only use this if you
  * can't reset your device in the second kernel.
@@ -312,21 +349,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
unsigned int i;
int (*old_handler)(struct pt_regs *regs);
 
-   /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */
-   printk_deferred_enter();
-
-   /*
-* This function is only called after the system
-* has panicked or is otherwise in a critical state.
-* The minimum amount of code to allow a kexec'd kernel
-* to run successfully needs to happen here.
-*
-* In practice this means stopping other cpus in
-* an SMP system.
-* The kernel is broken so disable interrupts.
-*/
-   hard_irq_disable();
-
/*
 * Make a note of crashing cpu.