diff options
-rw-r--r-- | arch/mips/kernel/traps.c | 25 |
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 | ||
360 | static int regs_to_trapnr(struct pt_regs *regs) | ||
361 | { | ||
362 | return (regs->cp0_cause >> 2) & 0x1f; | ||
363 | } | ||
364 | |||
360 | static DEFINE_SPINLOCK(die_lock); | 365 | static DEFINE_SPINLOCK(die_lock); |
361 | 366 | ||
362 | void __noreturn die(const char * str, struct pt_regs * regs) | 367 | void __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 | ||