|
@@ -35,7 +35,7 @@ trap_init (void)
|
|
|
fpswa_interface = __va(ia64_boot_param->fpswa);
|
|
|
}
|
|
|
|
|
|
-void
|
|
|
+int
|
|
|
die (const char *str, struct pt_regs *regs, long err)
|
|
|
{
|
|
|
static struct {
|
|
@@ -62,8 +62,11 @@ die (const char *str, struct pt_regs *regs, long err)
|
|
|
if (++die.lock_owner_depth < 3) {
|
|
|
printk("%s[%d]: %s %ld [%d]\n",
|
|
|
current->comm, task_pid_nr(current), str, err, ++die_counter);
|
|
|
- (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
|
|
|
- show_regs(regs);
|
|
|
+ if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
|
|
|
+ != NOTIFY_STOP)
|
|
|
+ show_regs(regs);
|
|
|
+ else
|
|
|
+ regs = NULL;
|
|
|
} else
|
|
|
printk(KERN_ERR "Recursive die() failure, output suppressed\n");
|
|
|
|
|
@@ -72,17 +75,22 @@ die (const char *str, struct pt_regs *regs, long err)
|
|
|
add_taint(TAINT_DIE);
|
|
|
spin_unlock_irq(&die.lock);
|
|
|
|
|
|
+ if (!regs)
|
|
|
+ return 1;
|
|
|
+
|
|
|
if (panic_on_oops)
|
|
|
panic("Fatal exception");
|
|
|
|
|
|
do_exit(SIGSEGV);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-void
|
|
|
+int
|
|
|
die_if_kernel (char *str, struct pt_regs *regs, long err)
|
|
|
{
|
|
|
if (!user_mode(regs))
|
|
|
- die(str, regs, err);
|
|
|
+ return die(str, regs, err);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
void
|
|
@@ -102,7 +110,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
|
|
if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
|
|
== NOTIFY_STOP)
|
|
|
return;
|
|
|
- die_if_kernel("bugcheck!", regs, break_num);
|
|
|
+ if (die_if_kernel("bugcheck!", regs, break_num))
|
|
|
+ return;
|
|
|
sig = SIGILL; code = ILL_ILLOPC;
|
|
|
break;
|
|
|
|
|
@@ -155,8 +164,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
- if (break_num < 0x40000 || break_num > 0x100000)
|
|
|
- die_if_kernel("Bad break", regs, break_num);
|
|
|
+ if ((break_num < 0x40000 || break_num > 0x100000)
|
|
|
+ && die_if_kernel("Bad break", regs, break_num))
|
|
|
+ return;
|
|
|
|
|
|
if (break_num < 0x80000) {
|
|
|
sig = SIGILL; code = __ILL_BREAK;
|
|
@@ -402,14 +412,15 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
|
|
|
#endif
|
|
|
|
|
|
sprintf(buf, "IA-64 Illegal operation fault");
|
|
|
- die_if_kernel(buf, ®s, 0);
|
|
|
+ rv.fkt = 0;
|
|
|
+ if (die_if_kernel(buf, ®s, 0))
|
|
|
+ return rv;
|
|
|
|
|
|
memset(&si, 0, sizeof(si));
|
|
|
si.si_signo = SIGILL;
|
|
|
si.si_code = ILL_ILLOPC;
|
|
|
si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(®s)->ri);
|
|
|
force_sig_info(SIGILL, &si, current);
|
|
|
- rv.fkt = 0;
|
|
|
return rv;
|
|
|
}
|
|
|
|
|
@@ -644,6 +655,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
|
|
|
sprintf(buf, "Fault %lu", vector);
|
|
|
break;
|
|
|
}
|
|
|
- die_if_kernel(buf, ®s, error);
|
|
|
- force_sig(SIGILL, current);
|
|
|
+ if (!die_if_kernel(buf, ®s, error))
|
|
|
+ force_sig(SIGILL, current);
|
|
|
}
|