diff options
Diffstat (limited to 'arch/ia64/kernel/traps.c')
| -rw-r--r-- | arch/ia64/kernel/traps.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index f970359e7edf..fba5fdd1f968 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
| @@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface; | |||
| 30 | EXPORT_SYMBOL(fpswa_interface); | 30 | EXPORT_SYMBOL(fpswa_interface); |
| 31 | 31 | ||
| 32 | struct notifier_block *ia64die_chain; | 32 | struct notifier_block *ia64die_chain; |
| 33 | static DEFINE_SPINLOCK(die_notifier_lock); | ||
| 34 | 33 | ||
| 35 | int register_die_notifier(struct notifier_block *nb) | 34 | int |
| 35 | register_die_notifier(struct notifier_block *nb) | ||
| 36 | { | 36 | { |
| 37 | int err = 0; | 37 | return notifier_chain_register(&ia64die_chain, nb); |
| 38 | unsigned long flags; | ||
| 39 | spin_lock_irqsave(&die_notifier_lock, flags); | ||
| 40 | err = notifier_chain_register(&ia64die_chain, nb); | ||
| 41 | spin_unlock_irqrestore(&die_notifier_lock, flags); | ||
| 42 | return err; | ||
| 43 | } | 38 | } |
| 39 | EXPORT_SYMBOL_GPL(register_die_notifier); | ||
| 40 | |||
| 41 | int | ||
| 42 | unregister_die_notifier(struct notifier_block *nb) | ||
| 43 | { | ||
| 44 | return notifier_chain_unregister(&ia64die_chain, nb); | ||
| 45 | } | ||
| 46 | EXPORT_SYMBOL_GPL(unregister_die_notifier); | ||
| 44 | 47 | ||
| 45 | void __init | 48 | void __init |
| 46 | trap_init (void) | 49 | trap_init (void) |
| @@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err) | |||
| 105 | if (++die.lock_owner_depth < 3) { | 108 | if (++die.lock_owner_depth < 3) { |
| 106 | printk("%s[%d]: %s %ld [%d]\n", | 109 | printk("%s[%d]: %s %ld [%d]\n", |
| 107 | current->comm, current->pid, str, err, ++die_counter); | 110 | current->comm, current->pid, str, err, ++die_counter); |
| 111 | (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); | ||
| 108 | show_regs(regs); | 112 | show_regs(regs); |
| 109 | } else | 113 | } else |
| 110 | printk(KERN_ERR "Recursive die() failure, output suppressed\n"); | 114 | printk(KERN_ERR "Recursive die() failure, output suppressed\n"); |
| @@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
| 155 | switch (break_num) { | 159 | switch (break_num) { |
| 156 | case 0: /* unknown error (used by GCC for __builtin_abort()) */ | 160 | case 0: /* unknown error (used by GCC for __builtin_abort()) */ |
| 157 | if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) | 161 | if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) |
| 158 | == NOTIFY_STOP) { | 162 | == NOTIFY_STOP) |
| 159 | return; | 163 | return; |
| 160 | } | ||
| 161 | die_if_kernel("bugcheck!", regs, break_num); | 164 | die_if_kernel("bugcheck!", regs, break_num); |
| 162 | sig = SIGILL; code = ILL_ILLOPC; | 165 | sig = SIGILL; code = ILL_ILLOPC; |
| 163 | break; | 166 | break; |
| @@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
| 210 | sig = SIGILL; code = __ILL_BNDMOD; | 213 | sig = SIGILL; code = __ILL_BNDMOD; |
| 211 | break; | 214 | break; |
| 212 | 215 | ||
| 213 | case 0x80200: | ||
| 214 | case 0x80300: | ||
| 215 | if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP) | ||
| 216 | == NOTIFY_STOP) { | ||
| 217 | return; | ||
| 218 | } | ||
| 219 | sig = SIGTRAP; code = TRAP_BRKPT; | ||
| 220 | break; | ||
| 221 | |||
| 222 | default: | 216 | default: |
| 223 | if (break_num < 0x40000 || break_num > 0x100000) | 217 | if (break_num < 0x40000 || break_num > 0x100000) |
| 224 | die_if_kernel("Bad break", regs, break_num); | 218 | die_if_kernel("Bad break", regs, break_num); |
| @@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
| 226 | if (break_num < 0x80000) { | 220 | if (break_num < 0x80000) { |
| 227 | sig = SIGILL; code = __ILL_BREAK; | 221 | sig = SIGILL; code = __ILL_BREAK; |
| 228 | } else { | 222 | } else { |
| 223 | if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP) | ||
| 224 | == NOTIFY_STOP) | ||
| 225 | return; | ||
| 229 | sig = SIGTRAP; code = TRAP_BRKPT; | 226 | sig = SIGTRAP; code = TRAP_BRKPT; |
| 230 | } | 227 | } |
| 231 | } | 228 | } |
| @@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
| 578 | #endif | 575 | #endif |
| 579 | break; | 576 | break; |
| 580 | case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; | 577 | case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; |
| 581 | case 36: | 578 | case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break; |
| 582 | if (notify_die(DIE_SS, "ss", ®s, vector, | ||
| 583 | vector, SIGTRAP) == NOTIFY_STOP) | ||
| 584 | return; | ||
| 585 | siginfo.si_code = TRAP_TRACE; ifa = 0; break; | ||
| 586 | } | 579 | } |
| 580 | if (notify_die(DIE_FAULT, "ia64_fault", ®s, vector, siginfo.si_code, SIGTRAP) | ||
| 581 | == NOTIFY_STOP) | ||
| 582 | return; | ||
| 587 | siginfo.si_signo = SIGTRAP; | 583 | siginfo.si_signo = SIGTRAP; |
| 588 | siginfo.si_errno = 0; | 584 | siginfo.si_errno = 0; |
| 589 | siginfo.si_addr = (void __user *) ifa; | 585 | siginfo.si_addr = (void __user *) ifa; |
