aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@in.ibm.com>2005-06-25 17:58:14 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 19:24:52 -0400
commita3ea8ac8468f5c7fc65684331dfba3260d5b2d93 (patch)
tree403ad71dc1c7f00a1b3717fbe0fe1bf3554a8287 /arch/i386/kernel
parent4d55476c3f889e0f30d88e22da4682b5f10394ff (diff)
[PATCH] Kexec: Kexec on panic fix with nmi watchdog enabled
o Problem: Kexec on panic hangs if first kernel is booted with nmi_watchdog command line parameter. This problem occurs because kexec crash shutdown code replaces the NMI callback handler. This handler saves the cpu register states and halts the cpu. If system is booted with nmi_watchdog parameter, then crashing cpu also runs this nmi handler and halts itself. o This patch fixes the problem by keeping a track of crashing cpu and not executing the new nmi handler on crashing cpu. o There is a dependence on smp_processor_id() function which might return insane value for cpu, if cpu field of thread_info is corrupted. Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel')
-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)