ARM: kexec: fix kdump register saving on panic()
[ Upstream commit 2d7b3c64431245c95b05a441669c074da10db943 ] 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 0ee59413c967 ("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> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
bb7a554ae7
commit
5e4b5b7194
@ -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;
|
||||
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user