diff options
Diffstat (limited to 'arch/ia64/kernel/traps.c')
| -rw-r--r-- | arch/ia64/kernel/traps.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 3aeaf15e468..d3636e67a98 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -19,10 +19,10 @@ #include <linux/kdebug.h> #include <asm/fpswa.h> -#include <asm/ia32.h> #include <asm/intrinsics.h> #include <asm/processor.h> #include <asm/uaccess.h> +#include <asm/setup.h> fpswa_interface_t *fpswa_interface; EXPORT_SYMBOL(fpswa_interface); @@ -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 { @@ -61,28 +61,36 @@ 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, current->pid, str, err, ++die_counter); - (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); - show_regs(regs); + current->comm, task_pid_nr(current), str, err, ++die_counter); + 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"); bust_spinlocks(0); die.lock_owner = -1; - add_taint(TAINT_DIE); + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); 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; @@ -315,7 +325,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) last.time = current_jiffies + 5 * HZ; printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n", - current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr); + current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr); } } } @@ -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; } @@ -453,7 +464,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, if (code == 8) { # ifdef CONFIG_IA64_PRINT_HAZARDS printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n", - current->comm, current->pid, + current->comm, task_pid_nr(current), regs.cr_iip + ia64_psr(®s)->ri, regs.pr); # endif return; @@ -615,21 +626,13 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, break; case 45: -#ifdef CONFIG_IA32_SUPPORT - if (ia32_exception(®s, isr) == 0) - return; -#endif printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n"); printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", iip, ifa, isr); force_sig(SIGSEGV, current); - break; + return; case 46: -#ifdef CONFIG_IA32_SUPPORT - if (ia32_intercept(®s, isr) == 0) - return; -#endif printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n"); printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n", iip, ifa, isr, iim); @@ -644,6 +647,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); } |
