diff options
Diffstat (limited to 'arch/ia64/kernel/traps.c')
-rw-r--r-- | arch/ia64/kernel/traps.c | 35 |
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 | ||
38 | void | 38 | int |
39 | die (const char *str, struct pt_regs *regs, long err) | 39 | die (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 | ||
81 | void | 88 | int |
82 | die_if_kernel (char *str, struct pt_regs *regs, long err) | 89 | die_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 | ||
88 | void | 96 | void |
@@ -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, ®s, 0); | 415 | rv.fkt = 0; |
416 | if (die_if_kernel(buf, ®s, 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(®s)->ri); | 422 | si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(®s)->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, ®s, error); | 658 | if (!die_if_kernel(buf, ®s, error)) |
648 | force_sig(SIGILL, current); | 659 | force_sig(SIGILL, current); |
649 | } | 660 | } |