Commit 2d7b3c64 authored by Russell King's avatar Russell King

ARM: kexec: fix kdump register saving on panic()

When a panic() occurs, the kexec code uses smp_send_stop() to stop
the other CPUs, but this results in the CPU register state not being
saved, and gdb is unable to inspect the state of other CPUs.

Commit 0ee59413 ("x86/panic: replace smp_send_stop() with kdump
friendly version in panic path") addressed the issue on x86, but
ignored other architectures.  Address the issue on ARM by splitting
out the crash stop implementation to crash_smp_send_stop() and
adding the necessary protection.
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
parent f2ae9de0
...@@ -95,6 +95,27 @@ void machine_crash_nonpanic_core(void *unused) ...@@ -95,6 +95,27 @@ void machine_crash_nonpanic_core(void *unused)
cpu_relax(); cpu_relax();
} }
void crash_smp_send_stop(void)
{
static int cpus_stopped;
unsigned long msecs;
if (cpus_stopped)
return;
atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
smp_call_function(machine_crash_nonpanic_core, NULL, false);
msecs = 1000; /* Wait at most a second for the other cpus to stop */
while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
mdelay(1);
msecs--;
}
if (atomic_read(&waiting_for_crash_ipi) > 0)
pr_warn("Non-crashing CPUs did not react to IPI\n");
cpus_stopped = 1;
}
static void machine_kexec_mask_interrupts(void) static void machine_kexec_mask_interrupts(void)
{ {
unsigned int i; unsigned int i;
...@@ -120,19 +141,8 @@ static void machine_kexec_mask_interrupts(void) ...@@ -120,19 +141,8 @@ static void machine_kexec_mask_interrupts(void)
void machine_crash_shutdown(struct pt_regs *regs) void machine_crash_shutdown(struct pt_regs *regs)
{ {
unsigned long msecs;
local_irq_disable(); local_irq_disable();
crash_smp_send_stop();
atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
smp_call_function(machine_crash_nonpanic_core, NULL, false);
msecs = 1000; /* Wait at most a second for the other cpus to stop */
while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
mdelay(1);
msecs--;
}
if (atomic_read(&waiting_for_crash_ipi) > 0)
pr_warn("Non-crashing CPUs did not react to IPI\n");
crash_save_cpu(regs, smp_processor_id()); crash_save_cpu(regs, smp_processor_id());
machine_kexec_mask_interrupts(); machine_kexec_mask_interrupts();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment