diff options
Diffstat (limited to 'arch/ppc/kernel/traps.c')
-rw-r--r-- | arch/ppc/kernel/traps.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index d87423d1003..961ede87be7 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -118,6 +118,28 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) info.si_code = code; info.si_addr = (void __user *) addr; force_sig_info(signr, &info, current); + + /* + * Init gets no signals that it doesn't have a handler for. + * That's all very well, but if it has caused a synchronous + * exception and we ignore the resulting signal, it will just + * generate the same exception over and over again and we get + * nowhere. Better to kill it and let the kernel panic. + */ + if (current->pid == 1) { + __sighandler_t handler; + + spin_lock_irq(¤t->sighand->siglock); + handler = current->sighand->action[signr-1].sa.sa_handler; + spin_unlock_irq(¤t->sighand->siglock); + if (handler == SIG_DFL) { + /* init has generated a synchronous exception + and it doesn't have a handler for the signal */ + printk(KERN_CRIT "init has generated signal %d " + "but has no handler for it\n", signr); + do_exit(signr); + } + } } /* @@ -849,10 +871,12 @@ void AltivecAssistException(struct pt_regs *regs) } #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_E500 void PerformanceMonitorException(struct pt_regs *regs) { perf_irq(regs); } +#endif #ifdef CONFIG_FSL_BOOKE void CacheLockingException(struct pt_regs *regs, unsigned long address, |