diff options
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
| -rw-r--r-- | arch/powerpc/kernel/smp.c | 47 | 
1 files changed, 45 insertions, 2 deletions
| diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index c23ee842c4c3..b7fd6a72aa76 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -61,6 +61,7 @@  #include <asm/cpu_has_feature.h>  #include <asm/ftrace.h>  #include <asm/kup.h> +#include <asm/fadump.h>  #ifdef DEBUG  #include <asm/udbg.h> @@ -621,6 +622,45 @@ 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, 1000000); +#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)  {  	/* @@ -896,7 +936,8 @@ out:  	return tg;  } -static int update_mask_from_threadgroup(cpumask_var_t *mask, struct thread_groups *tg, int cpu, int cpu_group_start) +static int __init update_mask_from_threadgroup(cpumask_var_t *mask, struct thread_groups *tg, +					       int cpu, int cpu_group_start)  {  	int first_thread = cpu_first_thread_sibling(cpu);  	int i; @@ -1635,12 +1676,14 @@ void start_secondary(void *unused)  	BUG();  } +#ifdef CONFIG_PROFILING  int setup_profiling_timer(unsigned int multiplier)  {  	return 0;  } +#endif -static void fixup_topology(void) +static void __init fixup_topology(void)  {  	int i; |