From a0f944eb08a8f49ea11d21cea958b15efb77d53d Mon Sep 17 00:00:00 2001 From: Rohit Vaswani Date: Thu, 26 Jun 2014 21:29:37 -0700 Subject: [PATCH] ARM64: smp: Save CPU registers before IPI_CPU_STOP processing When a kernel panic occurs on one CPU, other CPUs are instructed to stop execution via the IPI_CPU_STOP message. These other CPUs dump their stack, which may not be good enough to reconstruct their context to perform post-mortem analysis. Dump each CPU's context (before it started processing the IPI) into a globally accessible structure and print them on the dmesg/console to allow for easier post-mortem debugging. [eberman@codeaurora.org: make regs_before_stop static] Change-Id: Ifd7589af4327992540196c87f8b640045d7eaf19 Signed-off-by: Rohit Vaswani Signed-off-by: Elliot Berman --- arch/arm64/kernel/smp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 5fddc2c27e12..337ee82472a9 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -49,6 +49,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -835,15 +836,20 @@ void arch_irq_work_raise(void) #endif static DEFINE_RAW_SPINLOCK(stop_lock); + +static DEFINE_PER_CPU(struct pt_regs, regs_before_stop); + /* * ipi_cpu_stop - handle IPI from smp_send_stop() */ -static void ipi_cpu_stop(unsigned int cpu) +static void ipi_cpu_stop(unsigned int cpu, struct pt_regs *regs) { if (system_state == SYSTEM_BOOTING || system_state == SYSTEM_RUNNING) { + per_cpu(regs_before_stop, cpu) = *regs; raw_spin_lock(&stop_lock); pr_crit("CPU%u: stopping\n", cpu); + __show_regs(regs); dump_stack(); raw_spin_unlock(&stop_lock); } @@ -906,7 +912,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) case IPI_CPU_STOP: irq_enter(); - ipi_cpu_stop(cpu); + ipi_cpu_stop(cpu, regs); irq_exit(); break;