|
@@ -357,9 +357,14 @@ void show_registers(struct pt_regs *regs)
|
|
|
printk("\n");
|
|
|
}
|
|
|
|
|
|
+static int regs_to_trapnr(struct pt_regs *regs)
|
|
|
+{
|
|
|
+ return (regs->cp0_cause >> 2) & 0x1f;
|
|
|
+}
|
|
|
+
|
|
|
static DEFINE_SPINLOCK(die_lock);
|
|
|
|
|
|
-void __noreturn die(const char * str, struct pt_regs * regs)
|
|
|
+void __noreturn die(const char *str, struct pt_regs *regs)
|
|
|
{
|
|
|
static int die_counter;
|
|
|
int sig = SIGSEGV;
|
|
@@ -367,7 +372,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
|
|
|
unsigned long dvpret = dvpe();
|
|
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
|
|
|
|
|
- notify_die(DIE_OOPS, str, (struct pt_regs *)regs, SIGSEGV, 0, 0);
|
|
|
+ notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV);
|
|
|
|
|
|
console_verbose();
|
|
|
spin_lock_irq(&die_lock);
|
|
@@ -376,7 +381,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
|
|
|
mips_mt_regdump(dvpret);
|
|
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
|
|
|
|
|
- if (notify_die(DIE_OOPS, str, regs, 0, 0, SIGSEGV) == NOTIFY_STOP)
|
|
|
+ if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP)
|
|
|
sig = 0;
|
|
|
|
|
|
printk("%s[#%d]:\n", str, ++die_counter);
|
|
@@ -450,7 +455,7 @@ asmlinkage void do_be(struct pt_regs *regs)
|
|
|
printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
|
|
|
data ? "Data" : "Instruction",
|
|
|
field, regs->cp0_epc, field, regs->regs[31]);
|
|
|
- if (notify_die(DIE_OOPS, "bus error", regs, SIGBUS, 0, 0)
|
|
|
+ if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS)
|
|
|
== NOTIFY_STOP)
|
|
|
return;
|
|
|
|
|
@@ -651,7 +656,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
|
|
|
{
|
|
|
siginfo_t info;
|
|
|
|
|
|
- if (notify_die(DIE_FP, "FP exception", regs, SIGFPE, 0, 0)
|
|
|
+ if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
|
|
|
== NOTIFY_STOP)
|
|
|
return;
|
|
|
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,
|
|
|
char b[40];
|
|
|
|
|
|
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
|
|
|
- if (kgdb_ll_trap(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP)
|
|
|
+ if (kgdb_ll_trap(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
|
|
|
return;
|
|
|
#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
|
|
|
|
|
|
- if (notify_die(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP)
|
|
|
+ if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
|
|
|
return;
|
|
|
|
|
|
/*
|
|
@@ -790,12 +795,12 @@ asmlinkage void do_bp(struct pt_regs *regs)
|
|
|
*/
|
|
|
switch (bcode) {
|
|
|
case BRK_KPROBE_BP:
|
|
|
- if (notify_die(DIE_BREAK, "debug", regs, bcode, 0, 0) == NOTIFY_STOP)
|
|
|
+ if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
|
|
|
return;
|
|
|
else
|
|
|
break;
|
|
|
case BRK_KPROBE_SSTEPBP:
|
|
|
- if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, 0, 0) == NOTIFY_STOP)
|
|
|
+ if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
|
|
|
return;
|
|
|
else
|
|
|
break;
|
|
@@ -835,7 +840,7 @@ asmlinkage void do_ri(struct pt_regs *regs)
|
|
|
unsigned int opcode = 0;
|
|
|
int status = -1;
|
|
|
|
|
|
- if (notify_die(DIE_RI, "RI Fault", regs, SIGSEGV, 0, 0)
|
|
|
+ if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL)
|
|
|
== NOTIFY_STOP)
|
|
|
return;
|
|
|
|