aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/crash.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/crash.c')
-rw-r--r--arch/i386/kernel/crash.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 31e077bb0caa..a021681d21f8 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -28,6 +28,8 @@
28 28
29 29
30note_buf_t crash_notes[NR_CPUS]; 30note_buf_t crash_notes[NR_CPUS];
31/* This keeps a track of which one is crashing cpu. */
32static int crashing_cpu;
31 33
32static u32 *append_elf_note(u32 *buf, 34static u32 *append_elf_note(u32 *buf,
33 char *name, unsigned type, void *data, size_t data_len) 35 char *name, unsigned type, void *data, size_t data_len)
@@ -113,6 +115,13 @@ static atomic_t waiting_for_crash_ipi;
113static int crash_nmi_callback(struct pt_regs *regs, int cpu) 115static int crash_nmi_callback(struct pt_regs *regs, int cpu)
114{ 116{
115 struct pt_regs fixed_regs; 117 struct pt_regs fixed_regs;
118
119 /* Don't do anything if this handler is invoked on crashing cpu.
120 * Otherwise, system will completely hang. Crashing cpu can get
121 * an NMI if system was initially booted with nmi_watchdog parameter.
122 */
123 if (cpu == crashing_cpu)
124 return 1;
116 local_irq_disable(); 125 local_irq_disable();
117 126
118 /* CPU does not save ss and esp on stack if execution is already 127 /* CPU does not save ss and esp on stack if execution is already
@@ -187,6 +196,9 @@ void machine_crash_shutdown(void)
187 */ 196 */
188 /* The kernel is broken so disable interrupts */ 197 /* The kernel is broken so disable interrupts */
189 local_irq_disable(); 198 local_irq_disable();
199
200 /* Make a note of crashing cpu. Will be used in NMI callback.*/
201 crashing_cpu = smp_processor_id();
190 nmi_shootdown_cpus(); 202 nmi_shootdown_cpus();
191 lapic_shutdown(); 203 lapic_shutdown();
192#if defined(CONFIG_X86_IO_APIC) 204#if defined(CONFIG_X86_IO_APIC)