aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/traps.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-08-10 13:46:28 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-10 13:46:28 -0400
commit2f058256cb64e346f4fb4499ff4e0f1c2791a4b4 (patch)
tree91e06602f4d3abb6812ea8c9bc9ba4501e14c84e /arch/ia64/kernel/traps.c
parent0274aa2506fd2fe89a58dd6cd64d3b3f7b976af8 (diff)
parent86b3786078d63242d3194ffc58ae8dae1d1bbef3 (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'arch/ia64/kernel/traps.c')
-rw-r--r--arch/ia64/kernel/traps.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 1861173bd4f6..4440c8343fa4 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -21,12 +21,26 @@
21#include <asm/intrinsics.h> 21#include <asm/intrinsics.h>
22#include <asm/processor.h> 22#include <asm/processor.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <asm/kdebug.h>
24 25
25extern spinlock_t timerlist_lock; 26extern spinlock_t timerlist_lock;
26 27
27fpswa_interface_t *fpswa_interface; 28fpswa_interface_t *fpswa_interface;
28EXPORT_SYMBOL(fpswa_interface); 29EXPORT_SYMBOL(fpswa_interface);
29 30
31struct notifier_block *ia64die_chain;
32static DEFINE_SPINLOCK(die_notifier_lock);
33
34int register_die_notifier(struct notifier_block *nb)
35{
36 int err = 0;
37 unsigned long flags;
38 spin_lock_irqsave(&die_notifier_lock, flags);
39 err = notifier_chain_register(&ia64die_chain, nb);
40 spin_unlock_irqrestore(&die_notifier_lock, flags);
41 return err;
42}
43
30void __init 44void __init
31trap_init (void) 45trap_init (void)
32{ 46{
@@ -76,14 +90,16 @@ die (const char *str, struct pt_regs *regs, long err)
76 .lock_owner_depth = 0 90 .lock_owner_depth = 0
77 }; 91 };
78 static int die_counter; 92 static int die_counter;
93 int cpu = get_cpu();
79 94
80 if (die.lock_owner != smp_processor_id()) { 95 if (die.lock_owner != cpu) {
81 console_verbose(); 96 console_verbose();
82 spin_lock_irq(&die.lock); 97 spin_lock_irq(&die.lock);
83 die.lock_owner = smp_processor_id(); 98 die.lock_owner = cpu;
84 die.lock_owner_depth = 0; 99 die.lock_owner_depth = 0;
85 bust_spinlocks(1); 100 bust_spinlocks(1);
86 } 101 }
102 put_cpu();
87 103
88 if (++die.lock_owner_depth < 3) { 104 if (++die.lock_owner_depth < 3) {
89 printk("%s[%d]: %s %ld [%d]\n", 105 printk("%s[%d]: %s %ld [%d]\n",
@@ -137,6 +153,10 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
137 153
138 switch (break_num) { 154 switch (break_num) {
139 case 0: /* unknown error (used by GCC for __builtin_abort()) */ 155 case 0: /* unknown error (used by GCC for __builtin_abort()) */
156 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
157 == NOTIFY_STOP) {
158 return;
159 }
140 die_if_kernel("bugcheck!", regs, break_num); 160 die_if_kernel("bugcheck!", regs, break_num);
141 sig = SIGILL; code = ILL_ILLOPC; 161 sig = SIGILL; code = ILL_ILLOPC;
142 break; 162 break;
@@ -189,6 +209,15 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
189 sig = SIGILL; code = __ILL_BNDMOD; 209 sig = SIGILL; code = __ILL_BNDMOD;
190 break; 210 break;
191 211
212 case 0x80200:
213 case 0x80300:
214 if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
215 == NOTIFY_STOP) {
216 return;
217 }
218 sig = SIGTRAP; code = TRAP_BRKPT;
219 break;
220
192 default: 221 default:
193 if (break_num < 0x40000 || break_num > 0x100000) 222 if (break_num < 0x40000 || break_num > 0x100000)
194 die_if_kernel("Bad break", regs, break_num); 223 die_if_kernel("Bad break", regs, break_num);
@@ -548,7 +577,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
548#endif 577#endif
549 break; 578 break;
550 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; 579 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
551 case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break; 580 case 36:
581 if (notify_die(DIE_SS, "ss", &regs, vector,
582 vector, SIGTRAP) == NOTIFY_STOP)
583 return;
584 siginfo.si_code = TRAP_TRACE; ifa = 0; break;
552 } 585 }
553 siginfo.si_signo = SIGTRAP; 586 siginfo.si_signo = SIGTRAP;
554 siginfo.si_errno = 0; 587 siginfo.si_errno = 0;