aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/traps.c')
-rw-r--r--arch/ia64/kernel/traps.c44
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;
30EXPORT_SYMBOL(fpswa_interface); 30EXPORT_SYMBOL(fpswa_interface);
31 31
32struct notifier_block *ia64die_chain; 32struct notifier_block *ia64die_chain;
33static DEFINE_SPINLOCK(die_notifier_lock);
34 33
35int register_die_notifier(struct notifier_block *nb) 34int
35register_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}
39EXPORT_SYMBOL_GPL(register_die_notifier);
40
41int
42unregister_die_notifier(struct notifier_block *nb)
43{
44 return notifier_chain_unregister(&ia64die_chain, nb);
45}
46EXPORT_SYMBOL_GPL(unregister_die_notifier);
44 47
45void __init 48void __init
46trap_init (void) 49trap_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", &regs, 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", &regs, 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;