aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2010-10-12 09:09:06 -0400
committerMichal Marek <mmarek@suse.cz>2010-10-12 09:09:06 -0400
commit239060b93bb30a4ad55f1ecaa512464a035cc5ba (patch)
tree77f79810e57d4fc24356eca0cd6db463e8994128 /arch/mips/kernel/traps.c
parent1408b15b98635a13bad2e2a50b3c2ae2ccdf625b (diff)
parente9203c988234aa512bd45ca32b52e21c7bbfc414 (diff)
Merge branch 'kbuild/rc-fixes' into kbuild/kconfig
We need to revert the temporary hack in 71ebc01, hence the merge.
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 852780868fb4..03ec0019032b 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -25,6 +25,7 @@
25#include <linux/ptrace.h> 25#include <linux/ptrace.h>
26#include <linux/kgdb.h> 26#include <linux/kgdb.h>
27#include <linux/kdebug.h> 27#include <linux/kdebug.h>
28#include <linux/kprobes.h>
28#include <linux/notifier.h> 29#include <linux/notifier.h>
29#include <linux/kdb.h> 30#include <linux/kdb.h>
30 31
@@ -334,7 +335,7 @@ void show_regs(struct pt_regs *regs)
334 __show_regs((struct pt_regs *)regs); 335 __show_regs((struct pt_regs *)regs);
335} 336}
336 337
337void show_registers(const struct pt_regs *regs) 338void show_registers(struct pt_regs *regs)
338{ 339{
339 const int field = 2 * sizeof(unsigned long); 340 const int field = 2 * sizeof(unsigned long);
340 341
@@ -356,9 +357,14 @@ void show_registers(const struct pt_regs *regs)
356 printk("\n"); 357 printk("\n");
357} 358}
358 359
360static int regs_to_trapnr(struct pt_regs *regs)
361{
362 return (regs->cp0_cause >> 2) & 0x1f;
363}
364
359static DEFINE_SPINLOCK(die_lock); 365static DEFINE_SPINLOCK(die_lock);
360 366
361void __noreturn die(const char * str, struct pt_regs * regs) 367void __noreturn die(const char *str, struct pt_regs *regs)
362{ 368{
363 static int die_counter; 369 static int die_counter;
364 int sig = SIGSEGV; 370 int sig = SIGSEGV;
@@ -366,7 +372,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
366 unsigned long dvpret = dvpe(); 372 unsigned long dvpret = dvpe();
367#endif /* CONFIG_MIPS_MT_SMTC */ 373#endif /* CONFIG_MIPS_MT_SMTC */
368 374
369 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);
370 376
371 console_verbose(); 377 console_verbose();
372 spin_lock_irq(&die_lock); 378 spin_lock_irq(&die_lock);
@@ -375,7 +381,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
375 mips_mt_regdump(dvpret); 381 mips_mt_regdump(dvpret);
376#endif /* CONFIG_MIPS_MT_SMTC */ 382#endif /* CONFIG_MIPS_MT_SMTC */
377 383
378 if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) 384 if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP)
379 sig = 0; 385 sig = 0;
380 386
381 printk("%s[#%d]:\n", str, ++die_counter); 387 printk("%s[#%d]:\n", str, ++die_counter);
@@ -449,7 +455,7 @@ asmlinkage void do_be(struct pt_regs *regs)
449 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",
450 data ? "Data" : "Instruction", 456 data ? "Data" : "Instruction",
451 field, regs->cp0_epc, field, regs->regs[31]); 457 field, regs->cp0_epc, field, regs->regs[31]);
452 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)
453 == NOTIFY_STOP) 459 == NOTIFY_STOP)
454 return; 460 return;
455 461
@@ -650,7 +656,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
650{ 656{
651 siginfo_t info; 657 siginfo_t info;
652 658
653 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)
654 == NOTIFY_STOP) 660 == NOTIFY_STOP)
655 return; 661 return;
656 die_if_kernel("FP exception in kernel code", regs); 662 die_if_kernel("FP exception in kernel code", regs);
@@ -713,11 +719,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
713 char b[40]; 719 char b[40];
714 720
715#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP 721#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
716 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)
717 return; 723 return;
718#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ 724#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
719 725
720 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)
721 return; 727 return;
722 728
723 /* 729 /*
@@ -783,6 +789,25 @@ asmlinkage void do_bp(struct pt_regs *regs)
783 if (bcode >= (1 << 10)) 789 if (bcode >= (1 << 10))
784 bcode >>= 10; 790 bcode >>= 10;
785 791
792 /*
793 * notify the kprobe handlers, if instruction is likely to
794 * pertain to them.
795 */
796 switch (bcode) {
797 case BRK_KPROBE_BP:
798 if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
799 return;
800 else
801 break;
802 case BRK_KPROBE_SSTEPBP:
803 if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
804 return;
805 else
806 break;
807 default:
808 break;
809 }
810
786 do_trap_or_bp(regs, bcode, "Break"); 811 do_trap_or_bp(regs, bcode, "Break");
787 return; 812 return;
788 813
@@ -815,7 +840,7 @@ asmlinkage void do_ri(struct pt_regs *regs)
815 unsigned int opcode = 0; 840 unsigned int opcode = 0;
816 int status = -1; 841 int status = -1;
817 842
818 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)
819 == NOTIFY_STOP) 844 == NOTIFY_STOP)
820 return; 845 return;
821 846
@@ -907,11 +932,6 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
907 return NOTIFY_OK; 932 return NOTIFY_OK;
908} 933}
909 934
910static struct notifier_block default_cu2_notifier = {
911 .notifier_call = default_cu2_call,
912 .priority = 0x80000000, /* Run last */
913};
914
915asmlinkage void do_cpu(struct pt_regs *regs) 935asmlinkage void do_cpu(struct pt_regs *regs)
916{ 936{
917 unsigned int __user *epc; 937 unsigned int __user *epc;
@@ -1734,5 +1754,5 @@ void __init trap_init(void)
1734 1754
1735 sort_extable(__start___dbe_table, __stop___dbe_table); 1755 sort_extable(__start___dbe_table, __stop___dbe_table);
1736 1756
1737 register_cu2_notifier(&default_cu2_notifier); 1757 cu2_notifier(default_cu2_call, 0x80000000); /* Run last */
1738} 1758}