aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/traps.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 13:24:52 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 13:24:52 -0500
commit21511abd0a248a3f225d3b611cfabb93124605a7 (patch)
treeeb490f94322f3c76169ea7e5ec09524f275f390e /arch/ia64/kernel/traps.c
parent39ce941ec15032c0efc3632b9f00a6b2365e1870 (diff)
parente1b0d4ba46b42909d11ea152a6b56ee76f062ca3 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6: [IA64] make pfm_get_task work with virtual pids [IA64] honor notify_die() returning NOTIFY_STOP [IA64] remove dead code: __cpu_{down,die} from !HOTPLUG_CPU [IA64] Appoint kvm/ia64 Maintainers [IA64] ia64_set_psr should use srlz.i [IA64] Export three symbols for module use [IA64] mca style cleanup [IA64] sn_hwperf semaphore to mutex [IA64] generalize attribute of fsyscall_gtod_data [IA64] efi.c Add /* never reached */ annotation [IA64] efi.c Spelling/punctuation fixes [IA64] Make efi.c mostly fit in 80 columns [IA64] aliasing-test: fix gcc warnings on non-ia64 [IA64] Slim-down __clear_bit_unlock [IA64] Fix the order of atomic operations in restore_previous_kprobes on ia64 [IA64] constify function pointer tables [IA64] fix userspace compile error in gcc_intrin.h
Diffstat (limited to 'arch/ia64/kernel/traps.c')
-rw-r--r--arch/ia64/kernel/traps.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 78d65cb947d2..f0cda765e681 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -35,7 +35,7 @@ trap_init (void)
35 fpswa_interface = __va(ia64_boot_param->fpswa); 35 fpswa_interface = __va(ia64_boot_param->fpswa);
36} 36}
37 37
38void 38int
39die (const char *str, struct pt_regs *regs, long err) 39die (const char *str, struct pt_regs *regs, long err)
40{ 40{
41 static struct { 41 static struct {
@@ -62,8 +62,11 @@ die (const char *str, struct pt_regs *regs, long err)
62 if (++die.lock_owner_depth < 3) { 62 if (++die.lock_owner_depth < 3) {
63 printk("%s[%d]: %s %ld [%d]\n", 63 printk("%s[%d]: %s %ld [%d]\n",
64 current->comm, task_pid_nr(current), str, err, ++die_counter); 64 current->comm, task_pid_nr(current), str, err, ++die_counter);
65 (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); 65 if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
66 show_regs(regs); 66 != NOTIFY_STOP)
67 show_regs(regs);
68 else
69 regs = NULL;
67 } else 70 } else
68 printk(KERN_ERR "Recursive die() failure, output suppressed\n"); 71 printk(KERN_ERR "Recursive die() failure, output suppressed\n");
69 72
@@ -72,17 +75,22 @@ die (const char *str, struct pt_regs *regs, long err)
72 add_taint(TAINT_DIE); 75 add_taint(TAINT_DIE);
73 spin_unlock_irq(&die.lock); 76 spin_unlock_irq(&die.lock);
74 77
78 if (!regs)
79 return 1;
80
75 if (panic_on_oops) 81 if (panic_on_oops)
76 panic("Fatal exception"); 82 panic("Fatal exception");
77 83
78 do_exit(SIGSEGV); 84 do_exit(SIGSEGV);
85 return 0;
79} 86}
80 87
81void 88int
82die_if_kernel (char *str, struct pt_regs *regs, long err) 89die_if_kernel (char *str, struct pt_regs *regs, long err)
83{ 90{
84 if (!user_mode(regs)) 91 if (!user_mode(regs))
85 die(str, regs, err); 92 return die(str, regs, err);
93 return 0;
86} 94}
87 95
88void 96void
@@ -102,7 +110,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
102 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) 110 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
103 == NOTIFY_STOP) 111 == NOTIFY_STOP)
104 return; 112 return;
105 die_if_kernel("bugcheck!", regs, break_num); 113 if (die_if_kernel("bugcheck!", regs, break_num))
114 return;
106 sig = SIGILL; code = ILL_ILLOPC; 115 sig = SIGILL; code = ILL_ILLOPC;
107 break; 116 break;
108 117
@@ -155,8 +164,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
155 break; 164 break;
156 165
157 default: 166 default:
158 if (break_num < 0x40000 || break_num > 0x100000) 167 if ((break_num < 0x40000 || break_num > 0x100000)
159 die_if_kernel("Bad break", regs, break_num); 168 && die_if_kernel("Bad break", regs, break_num))
169 return;
160 170
161 if (break_num < 0x80000) { 171 if (break_num < 0x80000) {
162 sig = SIGILL; code = __ILL_BREAK; 172 sig = SIGILL; code = __ILL_BREAK;
@@ -402,14 +412,15 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
402#endif 412#endif
403 413
404 sprintf(buf, "IA-64 Illegal operation fault"); 414 sprintf(buf, "IA-64 Illegal operation fault");
405 die_if_kernel(buf, &regs, 0); 415 rv.fkt = 0;
416 if (die_if_kernel(buf, &regs, 0))
417 return rv;
406 418
407 memset(&si, 0, sizeof(si)); 419 memset(&si, 0, sizeof(si));
408 si.si_signo = SIGILL; 420 si.si_signo = SIGILL;
409 si.si_code = ILL_ILLOPC; 421 si.si_code = ILL_ILLOPC;
410 si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri); 422 si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri);
411 force_sig_info(SIGILL, &si, current); 423 force_sig_info(SIGILL, &si, current);
412 rv.fkt = 0;
413 return rv; 424 return rv;
414} 425}
415 426
@@ -644,6 +655,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
644 sprintf(buf, "Fault %lu", vector); 655 sprintf(buf, "Fault %lu", vector);
645 break; 656 break;
646 } 657 }
647 die_if_kernel(buf, &regs, error); 658 if (!die_if_kernel(buf, &regs, error))
648 force_sig(SIGILL, current); 659 force_sig(SIGILL, current);
649} 660}