diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-08-10 13:46:28 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-10 13:46:28 -0400 |
commit | 2f058256cb64e346f4fb4499ff4e0f1c2791a4b4 (patch) | |
tree | 91e06602f4d3abb6812ea8c9bc9ba4501e14c84e /arch/ia64/kernel/traps.c | |
parent | 0274aa2506fd2fe89a58dd6cd64d3b3f7b976af8 (diff) | |
parent | 86b3786078d63242d3194ffc58ae8dae1d1bbef3 (diff) |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'arch/ia64/kernel/traps.c')
-rw-r--r-- | arch/ia64/kernel/traps.c | 39 |
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 | ||
25 | extern spinlock_t timerlist_lock; | 26 | extern spinlock_t timerlist_lock; |
26 | 27 | ||
27 | fpswa_interface_t *fpswa_interface; | 28 | fpswa_interface_t *fpswa_interface; |
28 | EXPORT_SYMBOL(fpswa_interface); | 29 | EXPORT_SYMBOL(fpswa_interface); |
29 | 30 | ||
31 | struct notifier_block *ia64die_chain; | ||
32 | static DEFINE_SPINLOCK(die_notifier_lock); | ||
33 | |||
34 | int 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 | |||
30 | void __init | 44 | void __init |
31 | trap_init (void) | 45 | trap_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", ®s, 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; |