Skip to content

Commit

Permalink
ARM: kexec: fix kdump register saving on panic()
Browse files Browse the repository at this point in the history
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 0ee5941 ("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: Russell King <rmk+kernel@armlinux.org.uk>
  • Loading branch information
Russell King committed May 19, 2018
1 parent f2ae9de commit 2d7b3c6
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions arch/arm/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,27 @@ void machine_crash_nonpanic_core(void *unused)
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)
{
unsigned int i;
Expand All @@ -120,19 +141,8 @@ static void machine_kexec_mask_interrupts(void)

void machine_crash_shutdown(struct pt_regs *regs)
{
unsigned long msecs;

local_irq_disable();

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_smp_send_stop();

crash_save_cpu(regs, smp_processor_id());
machine_kexec_mask_interrupts();
Expand Down

0 comments on commit 2d7b3c6

Please sign in to comment.