summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHidehiro Kawai <hidehiro.kawai.ez@hitachi.com>2016-10-11 16:54:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-11 18:06:32 -0400
commit54c721b857fd45f3ad3bda695ee4f472518db02a (patch)
tree1728c59db0e8908da0a9bd8b420b2bbcd701d576
parent0ee59413c967c35a6dd2dbdab605b4cd42025ee5 (diff)
mips/panic: replace smp_send_stop() with kdump friendly version in panic path
Daniel Walker reported problems which happens when crash_kexec_post_notifiers kernel option is enabled (https://lkml.org/lkml/2015/6/24/44). In that case, smp_send_stop() is called before entering kdump routines which assume other CPUs are still online. As the result, kdump routines fail to save other CPUs' registers. Additionally for MIPS OCTEON, it misses to stop the watchdog timer. To fix this problem, call a new kdump friendly function, crash_smp_send_stop(), instead of the smp_send_stop() when crash_kexec_post_notifiers is enabled. crash_smp_send_stop() is a weak function, and it just call smp_send_stop(). Architecture codes should override it so that kdump can work appropriately. This patch provides MIPS version. Fixes: f06e5153f4ae (kernel/panic.c: add "crash_kexec_post_notifiers" option) Link: http://lkml.kernel.org/r/20160810080950.11028.28000.stgit@sysi4-13.yrl.intra.hitachi.co.jp Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> Reported-by: Daniel Walker <dwalker@fifo99.com> Cc: Dave Young <dyoung@redhat.com> Cc: Baoquan He <bhe@redhat.com> Cc: Vivek Goyal <vgoyal@redhat.com> Cc: Eric Biederman <ebiederm@xmission.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Daniel Walker <dwalker@fifo99.com> Cc: Xunlei Pang <xpang@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Borislav Petkov <bp@suse.de> Cc: David Vrabel <david.vrabel@citrix.com> Cc: Toshi Kani <toshi.kani@hpe.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: David Daney <david.daney@cavium.com> Cc: Aaro Koskinen <aaro.koskinen@iki.fi> Cc: "Steven J. Hill" <steven.hill@cavium.com> Cc: Corey Minyard <cminyard@mvista.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/mips/cavium-octeon/setup.c14
-rw-r--r--arch/mips/include/asm/kexec.h1
-rw-r--r--arch/mips/kernel/crash.c18
-rw-r--r--arch/mips/kernel/machine_kexec.c1
4 files changed, 33 insertions, 1 deletions
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index cb16fcc5f8f0..5537f95b28c9 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -267,6 +267,17 @@ static void octeon_crash_shutdown(struct pt_regs *regs)
267 default_machine_crash_shutdown(regs); 267 default_machine_crash_shutdown(regs);
268} 268}
269 269
270#ifdef CONFIG_SMP
271void octeon_crash_smp_send_stop(void)
272{
273 int cpu;
274
275 /* disable watchdogs */
276 for_each_online_cpu(cpu)
277 cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
278}
279#endif
280
270#endif /* CONFIG_KEXEC */ 281#endif /* CONFIG_KEXEC */
271 282
272#ifdef CONFIG_CAVIUM_RESERVE32 283#ifdef CONFIG_CAVIUM_RESERVE32
@@ -911,6 +922,9 @@ void __init prom_init(void)
911 _machine_kexec_shutdown = octeon_shutdown; 922 _machine_kexec_shutdown = octeon_shutdown;
912 _machine_crash_shutdown = octeon_crash_shutdown; 923 _machine_crash_shutdown = octeon_crash_shutdown;
913 _machine_kexec_prepare = octeon_kexec_prepare; 924 _machine_kexec_prepare = octeon_kexec_prepare;
925#ifdef CONFIG_SMP
926 _crash_smp_send_stop = octeon_crash_smp_send_stop;
927#endif
914#endif 928#endif
915 929
916 octeon_user_io_init(); 930 octeon_user_io_init();
diff --git a/arch/mips/include/asm/kexec.h b/arch/mips/include/asm/kexec.h
index ee25ebbf2a28..493a3cc7c39a 100644
--- a/arch/mips/include/asm/kexec.h
+++ b/arch/mips/include/asm/kexec.h
@@ -45,6 +45,7 @@ extern const unsigned char kexec_smp_wait[];
45extern unsigned long secondary_kexec_args[4]; 45extern unsigned long secondary_kexec_args[4];
46extern void (*relocated_kexec_smp_wait) (void *); 46extern void (*relocated_kexec_smp_wait) (void *);
47extern atomic_t kexec_ready_to_reboot; 47extern atomic_t kexec_ready_to_reboot;
48extern void (*_crash_smp_send_stop)(void);
48#endif 49#endif
49#endif 50#endif
50 51
diff --git a/arch/mips/kernel/crash.c b/arch/mips/kernel/crash.c
index 610f0f3bdb34..1723b1762297 100644
--- a/arch/mips/kernel/crash.c
+++ b/arch/mips/kernel/crash.c
@@ -47,9 +47,14 @@ static void crash_shutdown_secondary(void *passed_regs)
47 47
48static void crash_kexec_prepare_cpus(void) 48static void crash_kexec_prepare_cpus(void)
49{ 49{
50 static int cpus_stopped;
50 unsigned int msecs; 51 unsigned int msecs;
52 unsigned int ncpus;
51 53
52 unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ 54 if (cpus_stopped)
55 return;
56
57 ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
53 58
54 dump_send_ipi(crash_shutdown_secondary); 59 dump_send_ipi(crash_shutdown_secondary);
55 smp_wmb(); 60 smp_wmb();
@@ -64,6 +69,17 @@ static void crash_kexec_prepare_cpus(void)
64 cpu_relax(); 69 cpu_relax();
65 mdelay(1); 70 mdelay(1);
66 } 71 }
72
73 cpus_stopped = 1;
74}
75
76/* Override the weak function in kernel/panic.c */
77void crash_smp_send_stop(void)
78{
79 if (_crash_smp_send_stop)
80 _crash_smp_send_stop();
81
82 crash_kexec_prepare_cpus();
67} 83}
68 84
69#else /* !defined(CONFIG_SMP) */ 85#else /* !defined(CONFIG_SMP) */
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index 50980bf3983e..59725204105c 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -25,6 +25,7 @@ void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
25#ifdef CONFIG_SMP 25#ifdef CONFIG_SMP
26void (*relocated_kexec_smp_wait) (void *); 26void (*relocated_kexec_smp_wait) (void *);
27atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0); 27atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
28void (*_crash_smp_send_stop)(void) = NULL;
28#endif 29#endif
29 30
30int 31int