aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r--arch/powerpc/kernel/traps.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1511454c4690..7509aa6474f2 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -31,6 +31,7 @@
31#include <linux/prctl.h> 31#include <linux/prctl.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/kprobes.h> 33#include <linux/kprobes.h>
34#include <linux/kexec.h>
34 35
35#include <asm/kdebug.h> 36#include <asm/kdebug.h>
36#include <asm/pgtable.h> 37#include <asm/pgtable.h>
@@ -95,7 +96,7 @@ static DEFINE_SPINLOCK(die_lock);
95 96
96int die(const char *str, struct pt_regs *regs, long err) 97int die(const char *str, struct pt_regs *regs, long err)
97{ 98{
98 static int die_counter; 99 static int die_counter, crash_dump_start = 0;
99 int nl = 0; 100 int nl = 0;
100 101
101 if (debugger(regs)) 102 if (debugger(regs))
@@ -156,7 +157,21 @@ int die(const char *str, struct pt_regs *regs, long err)
156 print_modules(); 157 print_modules();
157 show_regs(regs); 158 show_regs(regs);
158 bust_spinlocks(0); 159 bust_spinlocks(0);
160
161 if (!crash_dump_start && kexec_should_crash(current)) {
162 crash_dump_start = 1;
163 spin_unlock_irq(&die_lock);
164 crash_kexec(regs);
165 /* NOTREACHED */
166 }
159 spin_unlock_irq(&die_lock); 167 spin_unlock_irq(&die_lock);
168 if (crash_dump_start)
169 /*
170 * Only for soft-reset: Other CPUs will be responded to an IPI
171 * sent by first kexec CPU.
172 */
173 for(;;)
174 ;
160 175
161 if (in_interrupt()) 176 if (in_interrupt())
162 panic("Fatal exception in interrupt"); 177 panic("Fatal exception in interrupt");
@@ -215,8 +230,10 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
215void system_reset_exception(struct pt_regs *regs) 230void system_reset_exception(struct pt_regs *regs)
216{ 231{
217 /* See if any machine dependent calls */ 232 /* See if any machine dependent calls */
218 if (ppc_md.system_reset_exception) 233 if (ppc_md.system_reset_exception) {
219 ppc_md.system_reset_exception(regs); 234 if (ppc_md.system_reset_exception(regs))
235 return;
236 }
220 237
221 die("System Reset", regs, SIGABRT); 238 die("System Reset", regs, SIGABRT);
222 239
@@ -886,12 +903,10 @@ void altivec_unavailable_exception(struct pt_regs *regs)
886 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); 903 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
887} 904}
888 905
889#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
890void performance_monitor_exception(struct pt_regs *regs) 906void performance_monitor_exception(struct pt_regs *regs)
891{ 907{
892 perf_irq(regs); 908 perf_irq(regs);
893} 909}
894#endif
895 910
896#ifdef CONFIG_8xx 911#ifdef CONFIG_8xx
897void SoftwareEmulation(struct pt_regs *regs) 912void SoftwareEmulation(struct pt_regs *regs)