aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/traps.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 6019e9ea9a6b..03ec0019032b 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -357,9 +357,14 @@ void show_registers(struct pt_regs *regs)
357 printk("\n"); 357 printk("\n");
358} 358}
359 359
360static int regs_to_trapnr(struct pt_regs *regs)
361{
362 return (regs->cp0_cause >> 2) & 0x1f;
363}
364
360static DEFINE_SPINLOCK(die_lock); 365static DEFINE_SPINLOCK(die_lock);
361 366
362void __noreturn die(const char * str, struct pt_regs * regs) 367void __noreturn die(const char *str, struct pt_regs *regs)
363{ 368{
364 static int die_counter; 369 static int die_counter;
365 int sig = SIGSEGV; 370 int sig = SIGSEGV;
@@ -367,7 +372,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
367 unsigned long dvpret = dvpe(); 372 unsigned long dvpret = dvpe();
368#endif /* CONFIG_MIPS_MT_SMTC */ 373#endif /* CONFIG_MIPS_MT_SMTC */
369 374
370 notify_die(DIE_OOPS, str, (struct pt_regs *)regs, SIGSEGV, 0, 0); 375 notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV);
371 376
372 console_verbose(); 377 console_verbose();
373 spin_lock_irq(&die_lock); 378 spin_lock_irq(&die_lock);
@@ -376,7 +381,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
376 mips_mt_regdump(dvpret); 381 mips_mt_regdump(dvpret);
377#endif /* CONFIG_MIPS_MT_SMTC */ 382#endif /* CONFIG_MIPS_MT_SMTC */
378 383
379 if (notify_die(DIE_OOPS, str, regs, 0, 0, SIGSEGV) == NOTIFY_STOP) 384 if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP)
380 sig = 0; 385 sig = 0;
381 386
382 printk("%s[#%d]:\n", str, ++die_counter); 387 printk("%s[#%d]:\n", str, ++die_counter);
@@ -450,7 +455,7 @@ asmlinkage void do_be(struct pt_regs *regs)
450 printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n", 455 printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
451 data ? "Data" : "Instruction", 456 data ? "Data" : "Instruction",
452 field, regs->cp0_epc, field, regs->regs[31]); 457 field, regs->cp0_epc, field, regs->regs[31]);
453 if (notify_die(DIE_OOPS, "bus error", regs, SIGBUS, 0, 0) 458 if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS)
454 == NOTIFY_STOP) 459 == NOTIFY_STOP)
455 return; 460 return;
456 461
@@ -651,7 +656,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
651{ 656{
652 siginfo_t info; 657 siginfo_t info;
653 658
654 if (notify_die(DIE_FP, "FP exception", regs, SIGFPE, 0, 0) 659 if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
655 == NOTIFY_STOP) 660 == NOTIFY_STOP)
656 return; 661 return;
657 die_if_kernel("FP exception in kernel code", regs); 662 die_if_kernel("FP exception in kernel code", regs);
@@ -714,11 +719,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
714 char b[40]; 719 char b[40];
715 720
716#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP 721#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
717 if (kgdb_ll_trap(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) 722 if (kgdb_ll_trap(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
718 return; 723 return;
719#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ 724#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
720 725
721 if (notify_die(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) 726 if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
722 return; 727 return;
723 728
724 /* 729 /*
@@ -790,12 +795,12 @@ asmlinkage void do_bp(struct pt_regs *regs)
790 */ 795 */
791 switch (bcode) { 796 switch (bcode) {
792 case BRK_KPROBE_BP: 797 case BRK_KPROBE_BP:
793 if (notify_die(DIE_BREAK, "debug", regs, bcode, 0, 0) == NOTIFY_STOP) 798 if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
794 return; 799 return;
795 else 800 else
796 break; 801 break;
797 case BRK_KPROBE_SSTEPBP: 802 case BRK_KPROBE_SSTEPBP:
798 if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, 0, 0) == NOTIFY_STOP) 803 if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
799 return; 804 return;
800 else 805 else
801 break; 806 break;
@@ -835,7 +840,7 @@ asmlinkage void do_ri(struct pt_regs *regs)
835 unsigned int opcode = 0; 840 unsigned int opcode = 0;
836 int status = -1; 841 int status = -1;
837 842
838 if (notify_die(DIE_RI, "RI Fault", regs, SIGSEGV, 0, 0) 843 if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL)
839 == NOTIFY_STOP) 844 == NOTIFY_STOP)
840 return; 845 return;
841 846