diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2018-04-19 17:59:56 -0400 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2018-04-25 11:44:10 -0400 |
commit | d1f5bef63fabeba834ed325ccec336ce3612d65c (patch) | |
tree | a5ecd6d1f6156ffa509784ddf08938703db335f7 | |
parent | 0e3d9f1e667bddc746112fa927cec9770f1f4217 (diff) |
signal/sparc: Use force_sig_fault where appropriate
Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.
Simplify this process by using the helper force_sig_fault. Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.
In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.
Cc: David Miller <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r-- | arch/sparc/kernel/process_64.c | 10 | ||||
-rw-r--r-- | arch/sparc/kernel/sys_sparc_32.c | 9 | ||||
-rw-r--r-- | arch/sparc/kernel/sys_sparc_64.c | 8 | ||||
-rw-r--r-- | arch/sparc/kernel/traps_32.c | 21 | ||||
-rw-r--r-- | arch/sparc/kernel/traps_64.c | 145 | ||||
-rw-r--r-- | arch/sparc/mm/fault_32.c | 13 | ||||
-rw-r--r-- | arch/sparc/mm/fault_64.c | 9 |
7 files changed, 37 insertions, 178 deletions
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 2219e55206b4..6c086086ca8f 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -518,15 +518,7 @@ void synchronize_user_stack(void) | |||
518 | 518 | ||
519 | static void stack_unaligned(unsigned long sp) | 519 | static void stack_unaligned(unsigned long sp) |
520 | { | 520 | { |
521 | siginfo_t info; | 521 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) sp, 0, current); |
522 | |||
523 | clear_siginfo(&info); | ||
524 | info.si_signo = SIGBUS; | ||
525 | info.si_errno = 0; | ||
526 | info.si_code = BUS_ADRALN; | ||
527 | info.si_addr = (void __user *) sp; | ||
528 | info.si_trapno = 0; | ||
529 | force_sig_info(SIGBUS, &info, current); | ||
530 | } | 522 | } |
531 | 523 | ||
532 | void fault_in_user_windows(void) | 524 | void fault_in_user_windows(void) |
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 00f6353fe435..7f3d9c59719a 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c | |||
@@ -147,18 +147,11 @@ SYSCALL_DEFINE0(nis_syscall) | |||
147 | asmlinkage void | 147 | asmlinkage void |
148 | sparc_breakpoint (struct pt_regs *regs) | 148 | sparc_breakpoint (struct pt_regs *regs) |
149 | { | 149 | { |
150 | siginfo_t info; | ||
151 | 150 | ||
152 | #ifdef DEBUG_SPARC_BREAKPOINT | 151 | #ifdef DEBUG_SPARC_BREAKPOINT |
153 | printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc); | 152 | printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc); |
154 | #endif | 153 | #endif |
155 | clear_siginfo(&info); | 154 | force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc, 0, current); |
156 | info.si_signo = SIGTRAP; | ||
157 | info.si_errno = 0; | ||
158 | info.si_code = TRAP_BRKPT; | ||
159 | info.si_addr = (void __user *)regs->pc; | ||
160 | info.si_trapno = 0; | ||
161 | force_sig_info(SIGTRAP, &info, current); | ||
162 | 155 | ||
163 | #ifdef DEBUG_SPARC_BREAKPOINT | 156 | #ifdef DEBUG_SPARC_BREAKPOINT |
164 | printk ("TRAP: Returning to space: PC=%x nPC=%x\n", regs->pc, regs->npc); | 157 | printk ("TRAP: Returning to space: PC=%x nPC=%x\n", regs->pc, regs->npc); |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 9ef8de63f28b..7e49bbc925a5 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
@@ -502,7 +502,6 @@ SYSCALL_DEFINE0(nis_syscall) | |||
502 | asmlinkage void sparc_breakpoint(struct pt_regs *regs) | 502 | asmlinkage void sparc_breakpoint(struct pt_regs *regs) |
503 | { | 503 | { |
504 | enum ctx_state prev_state = exception_enter(); | 504 | enum ctx_state prev_state = exception_enter(); |
505 | siginfo_t info; | ||
506 | 505 | ||
507 | if (test_thread_flag(TIF_32BIT)) { | 506 | if (test_thread_flag(TIF_32BIT)) { |
508 | regs->tpc &= 0xffffffff; | 507 | regs->tpc &= 0xffffffff; |
@@ -511,12 +510,7 @@ asmlinkage void sparc_breakpoint(struct pt_regs *regs) | |||
511 | #ifdef DEBUG_SPARC_BREAKPOINT | 510 | #ifdef DEBUG_SPARC_BREAKPOINT |
512 | printk ("TRAP: Entering kernel PC=%lx, nPC=%lx\n", regs->tpc, regs->tnpc); | 511 | printk ("TRAP: Entering kernel PC=%lx, nPC=%lx\n", regs->tpc, regs->tnpc); |
513 | #endif | 512 | #endif |
514 | info.si_signo = SIGTRAP; | 513 | force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->tpc, 0, current); |
515 | info.si_errno = 0; | ||
516 | info.si_code = TRAP_BRKPT; | ||
517 | info.si_addr = (void __user *)regs->tpc; | ||
518 | info.si_trapno = 0; | ||
519 | force_sig_info(SIGTRAP, &info, current); | ||
520 | #ifdef DEBUG_SPARC_BREAKPOINT | 514 | #ifdef DEBUG_SPARC_BREAKPOINT |
521 | printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc); | 515 | printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc); |
522 | #endif | 516 | #endif |
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c index 06f43cf9695f..bcdfc6168dd5 100644 --- a/arch/sparc/kernel/traps_32.c +++ b/arch/sparc/kernel/traps_32.c | |||
@@ -93,8 +93,6 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs) | |||
93 | 93 | ||
94 | void do_hw_interrupt(struct pt_regs *regs, unsigned long type) | 94 | void do_hw_interrupt(struct pt_regs *regs, unsigned long type) |
95 | { | 95 | { |
96 | siginfo_t info; | ||
97 | |||
98 | if(type < 0x80) { | 96 | if(type < 0x80) { |
99 | /* Sun OS's puke from bad traps, Linux survives! */ | 97 | /* Sun OS's puke from bad traps, Linux survives! */ |
100 | printk("Unimplemented Sparc TRAP, type = %02lx\n", type); | 98 | printk("Unimplemented Sparc TRAP, type = %02lx\n", type); |
@@ -104,13 +102,8 @@ void do_hw_interrupt(struct pt_regs *regs, unsigned long type) | |||
104 | if(regs->psr & PSR_PS) | 102 | if(regs->psr & PSR_PS) |
105 | die_if_kernel("Kernel bad trap", regs); | 103 | die_if_kernel("Kernel bad trap", regs); |
106 | 104 | ||
107 | clear_siginfo(&info); | 105 | force_sig_fault(SIGILL, ILL_ILLTRP, |
108 | info.si_signo = SIGILL; | 106 | (void __user *)regs->pc, type - 0x80, current); |
109 | info.si_errno = 0; | ||
110 | info.si_code = ILL_ILLTRP; | ||
111 | info.si_addr = (void __user *)regs->pc; | ||
112 | info.si_trapno = type - 0x80; | ||
113 | force_sig_info(SIGILL, &info, current); | ||
114 | } | 107 | } |
115 | 108 | ||
116 | void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, | 109 | void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, |
@@ -330,19 +323,11 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc | |||
330 | void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc, | 323 | void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc, |
331 | unsigned long psr) | 324 | unsigned long psr) |
332 | { | 325 | { |
333 | siginfo_t info; | ||
334 | |||
335 | #ifdef TRAP_DEBUG | 326 | #ifdef TRAP_DEBUG |
336 | printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n", | 327 | printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n", |
337 | pc, npc, psr); | 328 | pc, npc, psr); |
338 | #endif | 329 | #endif |
339 | clear_siginfo(&info); | 330 | force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)pc, 0, current); |
340 | info.si_signo = SIGBUS; | ||
341 | info.si_errno = 0; | ||
342 | info.si_code = BUS_OBJERR; | ||
343 | info.si_addr = (void __user *)pc; | ||
344 | info.si_trapno = 0; | ||
345 | force_sig_info(SIGBUS, &info, current); | ||
346 | } | 331 | } |
347 | 332 | ||
348 | void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc, | 333 | void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc, |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index b485b49b87a8..aa624ed79db1 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -87,7 +87,6 @@ static void dump_tl1_traplog(struct tl1_traplog *p) | |||
87 | void bad_trap(struct pt_regs *regs, long lvl) | 87 | void bad_trap(struct pt_regs *regs, long lvl) |
88 | { | 88 | { |
89 | char buffer[36]; | 89 | char buffer[36]; |
90 | siginfo_t info; | ||
91 | 90 | ||
92 | if (notify_die(DIE_TRAP, "bad trap", regs, | 91 | if (notify_die(DIE_TRAP, "bad trap", regs, |
93 | 0, lvl, SIGTRAP) == NOTIFY_STOP) | 92 | 0, lvl, SIGTRAP) == NOTIFY_STOP) |
@@ -107,13 +106,8 @@ void bad_trap(struct pt_regs *regs, long lvl) | |||
107 | regs->tpc &= 0xffffffff; | 106 | regs->tpc &= 0xffffffff; |
108 | regs->tnpc &= 0xffffffff; | 107 | regs->tnpc &= 0xffffffff; |
109 | } | 108 | } |
110 | clear_siginfo(&info); | 109 | force_sig_fault(SIGILL, ILL_ILLTRP, |
111 | info.si_signo = SIGILL; | 110 | (void __user *)regs->tpc, lvl, current); |
112 | info.si_errno = 0; | ||
113 | info.si_code = ILL_ILLTRP; | ||
114 | info.si_addr = (void __user *)regs->tpc; | ||
115 | info.si_trapno = lvl; | ||
116 | force_sig_info(SIGILL, &info, current); | ||
117 | } | 111 | } |
118 | 112 | ||
119 | void bad_trap_tl1(struct pt_regs *regs, long lvl) | 113 | void bad_trap_tl1(struct pt_regs *regs, long lvl) |
@@ -192,7 +186,6 @@ EXPORT_SYMBOL_GPL(unregister_dimm_printer); | |||
192 | void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) | 186 | void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) |
193 | { | 187 | { |
194 | enum ctx_state prev_state = exception_enter(); | 188 | enum ctx_state prev_state = exception_enter(); |
195 | siginfo_t info; | ||
196 | 189 | ||
197 | if (notify_die(DIE_TRAP, "instruction access exception", regs, | 190 | if (notify_die(DIE_TRAP, "instruction access exception", regs, |
198 | 0, 0x8, SIGTRAP) == NOTIFY_STOP) | 191 | 0, 0x8, SIGTRAP) == NOTIFY_STOP) |
@@ -207,13 +200,8 @@ void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, un | |||
207 | regs->tpc &= 0xffffffff; | 200 | regs->tpc &= 0xffffffff; |
208 | regs->tnpc &= 0xffffffff; | 201 | regs->tnpc &= 0xffffffff; |
209 | } | 202 | } |
210 | clear_siginfo(&info); | 203 | force_sig_fault(SIGSEGV, SEGV_MAPERR, |
211 | info.si_signo = SIGSEGV; | 204 | (void __user *)regs->tpc, 0, current); |
212 | info.si_errno = 0; | ||
213 | info.si_code = SEGV_MAPERR; | ||
214 | info.si_addr = (void __user *)regs->tpc; | ||
215 | info.si_trapno = 0; | ||
216 | force_sig_info(SIGSEGV, &info, current); | ||
217 | out: | 205 | out: |
218 | exception_exit(prev_state); | 206 | exception_exit(prev_state); |
219 | } | 207 | } |
@@ -232,7 +220,6 @@ void sun4v_insn_access_exception(struct pt_regs *regs, unsigned long addr, unsig | |||
232 | { | 220 | { |
233 | unsigned short type = (type_ctx >> 16); | 221 | unsigned short type = (type_ctx >> 16); |
234 | unsigned short ctx = (type_ctx & 0xffff); | 222 | unsigned short ctx = (type_ctx & 0xffff); |
235 | siginfo_t info; | ||
236 | 223 | ||
237 | if (notify_die(DIE_TRAP, "instruction access exception", regs, | 224 | if (notify_die(DIE_TRAP, "instruction access exception", regs, |
238 | 0, 0x8, SIGTRAP) == NOTIFY_STOP) | 225 | 0, 0x8, SIGTRAP) == NOTIFY_STOP) |
@@ -249,13 +236,7 @@ void sun4v_insn_access_exception(struct pt_regs *regs, unsigned long addr, unsig | |||
249 | regs->tpc &= 0xffffffff; | 236 | regs->tpc &= 0xffffffff; |
250 | regs->tnpc &= 0xffffffff; | 237 | regs->tnpc &= 0xffffffff; |
251 | } | 238 | } |
252 | clear_siginfo(&info); | 239 | force_sig_fault(SIGSEGV, SEGV_MAPERR, (void __user *) addr, 0, current); |
253 | info.si_signo = SIGSEGV; | ||
254 | info.si_errno = 0; | ||
255 | info.si_code = SEGV_MAPERR; | ||
256 | info.si_addr = (void __user *) addr; | ||
257 | info.si_trapno = 0; | ||
258 | force_sig_info(SIGSEGV, &info, current); | ||
259 | } | 240 | } |
260 | 241 | ||
261 | void sun4v_insn_access_exception_tl1(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx) | 242 | void sun4v_insn_access_exception_tl1(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx) |
@@ -310,7 +291,6 @@ bool is_no_fault_exception(struct pt_regs *regs) | |||
310 | void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) | 291 | void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) |
311 | { | 292 | { |
312 | enum ctx_state prev_state = exception_enter(); | 293 | enum ctx_state prev_state = exception_enter(); |
313 | siginfo_t info; | ||
314 | 294 | ||
315 | if (notify_die(DIE_TRAP, "data access exception", regs, | 295 | if (notify_die(DIE_TRAP, "data access exception", regs, |
316 | 0, 0x30, SIGTRAP) == NOTIFY_STOP) | 296 | 0, 0x30, SIGTRAP) == NOTIFY_STOP) |
@@ -341,13 +321,7 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un | |||
341 | if (is_no_fault_exception(regs)) | 321 | if (is_no_fault_exception(regs)) |
342 | return; | 322 | return; |
343 | 323 | ||
344 | clear_siginfo(&info); | 324 | force_sig_fault(SIGSEGV, SEGV_MAPERR, (void __user *)sfar, 0, current); |
345 | info.si_signo = SIGSEGV; | ||
346 | info.si_errno = 0; | ||
347 | info.si_code = SEGV_MAPERR; | ||
348 | info.si_addr = (void __user *)sfar; | ||
349 | info.si_trapno = 0; | ||
350 | force_sig_info(SIGSEGV, &info, current); | ||
351 | out: | 325 | out: |
352 | exception_exit(prev_state); | 326 | exception_exit(prev_state); |
353 | } | 327 | } |
@@ -563,8 +537,6 @@ static void spitfire_cee_log(unsigned long afsr, unsigned long afar, unsigned lo | |||
563 | 537 | ||
564 | static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long tt, int tl1, struct pt_regs *regs) | 538 | static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long tt, int tl1, struct pt_regs *regs) |
565 | { | 539 | { |
566 | siginfo_t info; | ||
567 | |||
568 | printk(KERN_WARNING "CPU[%d]: Uncorrectable Error AFSR[%lx] " | 540 | printk(KERN_WARNING "CPU[%d]: Uncorrectable Error AFSR[%lx] " |
569 | "AFAR[%lx] UDBL[%lx] UDBH[%ld] TT[%lx] TL>1[%d]\n", | 541 | "AFAR[%lx] UDBL[%lx] UDBH[%ld] TT[%lx] TL>1[%d]\n", |
570 | smp_processor_id(), afsr, afar, udbl, udbh, tt, tl1); | 542 | smp_processor_id(), afsr, afar, udbl, udbh, tt, tl1); |
@@ -599,13 +571,7 @@ static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned lon | |||
599 | regs->tpc &= 0xffffffff; | 571 | regs->tpc &= 0xffffffff; |
600 | regs->tnpc &= 0xffffffff; | 572 | regs->tnpc &= 0xffffffff; |
601 | } | 573 | } |
602 | clear_siginfo(&info); | 574 | force_sig_fault(SIGBUS, BUS_OBJERR, (void *)0, 0, current); |
603 | info.si_signo = SIGBUS; | ||
604 | info.si_errno = 0; | ||
605 | info.si_code = BUS_OBJERR; | ||
606 | info.si_addr = (void *)0; | ||
607 | info.si_trapno = 0; | ||
608 | force_sig_info(SIGBUS, &info, current); | ||
609 | } | 575 | } |
610 | 576 | ||
611 | void spitfire_access_error(struct pt_regs *regs, unsigned long status_encoded, unsigned long afar) | 577 | void spitfire_access_error(struct pt_regs *regs, unsigned long status_encoded, unsigned long afar) |
@@ -2195,7 +2161,6 @@ bool sun4v_nonresum_error_user_handled(struct pt_regs *regs, | |||
2195 | 2161 | ||
2196 | if (attrs & SUN4V_ERR_ATTRS_MEMORY) { | 2162 | if (attrs & SUN4V_ERR_ATTRS_MEMORY) { |
2197 | unsigned long addr = ent->err_raddr; | 2163 | unsigned long addr = ent->err_raddr; |
2198 | siginfo_t info; | ||
2199 | 2164 | ||
2200 | if (addr == ~(u64)0) { | 2165 | if (addr == ~(u64)0) { |
2201 | /* This seems highly unlikely to ever occur */ | 2166 | /* This seems highly unlikely to ever occur */ |
@@ -2216,23 +2181,13 @@ bool sun4v_nonresum_error_user_handled(struct pt_regs *regs, | |||
2216 | addr += PAGE_SIZE; | 2181 | addr += PAGE_SIZE; |
2217 | } | 2182 | } |
2218 | } | 2183 | } |
2219 | clear_siginfo(&info); | 2184 | force_sig(SIGKILL, current); |
2220 | info.si_signo = SIGKILL; | ||
2221 | info.si_errno = 0; | ||
2222 | info.si_trapno = 0; | ||
2223 | force_sig_info(info.si_signo, &info, current); | ||
2224 | 2185 | ||
2225 | return true; | 2186 | return true; |
2226 | } | 2187 | } |
2227 | if (attrs & SUN4V_ERR_ATTRS_PIO) { | 2188 | if (attrs & SUN4V_ERR_ATTRS_PIO) { |
2228 | siginfo_t info; | 2189 | force_sig_fault(SIGBUS, BUS_ADRERR, |
2229 | 2190 | (void __user *)sun4v_get_vaddr(regs), 0, current); | |
2230 | clear_siginfo(&info); | ||
2231 | info.si_signo = SIGBUS; | ||
2232 | info.si_code = BUS_ADRERR; | ||
2233 | info.si_addr = (void __user *)sun4v_get_vaddr(regs); | ||
2234 | force_sig_info(info.si_signo, &info, current); | ||
2235 | |||
2236 | return true; | 2191 | return true; |
2237 | } | 2192 | } |
2238 | 2193 | ||
@@ -2369,31 +2324,27 @@ static void do_fpe_common(struct pt_regs *regs) | |||
2369 | regs->tnpc += 4; | 2324 | regs->tnpc += 4; |
2370 | } else { | 2325 | } else { |
2371 | unsigned long fsr = current_thread_info()->xfsr[0]; | 2326 | unsigned long fsr = current_thread_info()->xfsr[0]; |
2372 | siginfo_t info; | 2327 | int code; |
2373 | 2328 | ||
2374 | if (test_thread_flag(TIF_32BIT)) { | 2329 | if (test_thread_flag(TIF_32BIT)) { |
2375 | regs->tpc &= 0xffffffff; | 2330 | regs->tpc &= 0xffffffff; |
2376 | regs->tnpc &= 0xffffffff; | 2331 | regs->tnpc &= 0xffffffff; |
2377 | } | 2332 | } |
2378 | clear_siginfo(&info); | 2333 | code = FPE_FLTUNK; |
2379 | info.si_signo = SIGFPE; | ||
2380 | info.si_errno = 0; | ||
2381 | info.si_addr = (void __user *)regs->tpc; | ||
2382 | info.si_trapno = 0; | ||
2383 | info.si_code = FPE_FLTUNK; | ||
2384 | if ((fsr & 0x1c000) == (1 << 14)) { | 2334 | if ((fsr & 0x1c000) == (1 << 14)) { |
2385 | if (fsr & 0x10) | 2335 | if (fsr & 0x10) |
2386 | info.si_code = FPE_FLTINV; | 2336 | code = FPE_FLTINV; |
2387 | else if (fsr & 0x08) | 2337 | else if (fsr & 0x08) |
2388 | info.si_code = FPE_FLTOVF; | 2338 | code = FPE_FLTOVF; |
2389 | else if (fsr & 0x04) | 2339 | else if (fsr & 0x04) |
2390 | info.si_code = FPE_FLTUND; | 2340 | code = FPE_FLTUND; |
2391 | else if (fsr & 0x02) | 2341 | else if (fsr & 0x02) |
2392 | info.si_code = FPE_FLTDIV; | 2342 | code = FPE_FLTDIV; |
2393 | else if (fsr & 0x01) | 2343 | else if (fsr & 0x01) |
2394 | info.si_code = FPE_FLTRES; | 2344 | code = FPE_FLTRES; |
2395 | } | 2345 | } |
2396 | force_sig_info(SIGFPE, &info, current); | 2346 | force_sig_fault(SIGFPE, code, |
2347 | (void __user *)regs->tpc, 0, current); | ||
2397 | } | 2348 | } |
2398 | } | 2349 | } |
2399 | 2350 | ||
@@ -2436,7 +2387,6 @@ out: | |||
2436 | void do_tof(struct pt_regs *regs) | 2387 | void do_tof(struct pt_regs *regs) |
2437 | { | 2388 | { |
2438 | enum ctx_state prev_state = exception_enter(); | 2389 | enum ctx_state prev_state = exception_enter(); |
2439 | siginfo_t info; | ||
2440 | 2390 | ||
2441 | if (notify_die(DIE_TRAP, "tagged arithmetic overflow", regs, | 2391 | if (notify_die(DIE_TRAP, "tagged arithmetic overflow", regs, |
2442 | 0, 0x26, SIGEMT) == NOTIFY_STOP) | 2392 | 0, 0x26, SIGEMT) == NOTIFY_STOP) |
@@ -2448,13 +2398,8 @@ void do_tof(struct pt_regs *regs) | |||
2448 | regs->tpc &= 0xffffffff; | 2398 | regs->tpc &= 0xffffffff; |
2449 | regs->tnpc &= 0xffffffff; | 2399 | regs->tnpc &= 0xffffffff; |
2450 | } | 2400 | } |
2451 | clear_siginfo(&info); | 2401 | force_sig_fault(SIGEMT, EMT_TAGOVF, |
2452 | info.si_signo = SIGEMT; | 2402 | (void __user *)regs->tpc, 0, current); |
2453 | info.si_errno = 0; | ||
2454 | info.si_code = EMT_TAGOVF; | ||
2455 | info.si_addr = (void __user *)regs->tpc; | ||
2456 | info.si_trapno = 0; | ||
2457 | force_sig_info(SIGEMT, &info, current); | ||
2458 | out: | 2403 | out: |
2459 | exception_exit(prev_state); | 2404 | exception_exit(prev_state); |
2460 | } | 2405 | } |
@@ -2462,7 +2407,6 @@ out: | |||
2462 | void do_div0(struct pt_regs *regs) | 2407 | void do_div0(struct pt_regs *regs) |
2463 | { | 2408 | { |
2464 | enum ctx_state prev_state = exception_enter(); | 2409 | enum ctx_state prev_state = exception_enter(); |
2465 | siginfo_t info; | ||
2466 | 2410 | ||
2467 | if (notify_die(DIE_TRAP, "integer division by zero", regs, | 2411 | if (notify_die(DIE_TRAP, "integer division by zero", regs, |
2468 | 0, 0x28, SIGFPE) == NOTIFY_STOP) | 2412 | 0, 0x28, SIGFPE) == NOTIFY_STOP) |
@@ -2474,13 +2418,8 @@ void do_div0(struct pt_regs *regs) | |||
2474 | regs->tpc &= 0xffffffff; | 2418 | regs->tpc &= 0xffffffff; |
2475 | regs->tnpc &= 0xffffffff; | 2419 | regs->tnpc &= 0xffffffff; |
2476 | } | 2420 | } |
2477 | clear_siginfo(&info); | 2421 | force_sig_fault(SIGFPE, FPE_INTDIV, |
2478 | info.si_signo = SIGFPE; | 2422 | (void __user *)regs->tpc, 0, current); |
2479 | info.si_errno = 0; | ||
2480 | info.si_code = FPE_INTDIV; | ||
2481 | info.si_addr = (void __user *)regs->tpc; | ||
2482 | info.si_trapno = 0; | ||
2483 | force_sig_info(SIGFPE, &info, current); | ||
2484 | out: | 2423 | out: |
2485 | exception_exit(prev_state); | 2424 | exception_exit(prev_state); |
2486 | } | 2425 | } |
@@ -2642,7 +2581,6 @@ void do_illegal_instruction(struct pt_regs *regs) | |||
2642 | unsigned long pc = regs->tpc; | 2581 | unsigned long pc = regs->tpc; |
2643 | unsigned long tstate = regs->tstate; | 2582 | unsigned long tstate = regs->tstate; |
2644 | u32 insn; | 2583 | u32 insn; |
2645 | siginfo_t info; | ||
2646 | 2584 | ||
2647 | if (notify_die(DIE_TRAP, "illegal instruction", regs, | 2585 | if (notify_die(DIE_TRAP, "illegal instruction", regs, |
2648 | 0, 0x10, SIGILL) == NOTIFY_STOP) | 2586 | 0, 0x10, SIGILL) == NOTIFY_STOP) |
@@ -2676,13 +2614,7 @@ void do_illegal_instruction(struct pt_regs *regs) | |||
2676 | } | 2614 | } |
2677 | } | 2615 | } |
2678 | } | 2616 | } |
2679 | clear_siginfo(&info); | 2617 | force_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)pc, 0, current); |
2680 | info.si_signo = SIGILL; | ||
2681 | info.si_errno = 0; | ||
2682 | info.si_code = ILL_ILLOPC; | ||
2683 | info.si_addr = (void __user *)pc; | ||
2684 | info.si_trapno = 0; | ||
2685 | force_sig_info(SIGILL, &info, current); | ||
2686 | out: | 2618 | out: |
2687 | exception_exit(prev_state); | 2619 | exception_exit(prev_state); |
2688 | } | 2620 | } |
@@ -2690,7 +2622,6 @@ out: | |||
2690 | void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) | 2622 | void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) |
2691 | { | 2623 | { |
2692 | enum ctx_state prev_state = exception_enter(); | 2624 | enum ctx_state prev_state = exception_enter(); |
2693 | siginfo_t info; | ||
2694 | 2625 | ||
2695 | if (notify_die(DIE_TRAP, "memory address unaligned", regs, | 2626 | if (notify_die(DIE_TRAP, "memory address unaligned", regs, |
2696 | 0, 0x34, SIGSEGV) == NOTIFY_STOP) | 2627 | 0, 0x34, SIGSEGV) == NOTIFY_STOP) |
@@ -2703,21 +2634,13 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo | |||
2703 | if (is_no_fault_exception(regs)) | 2634 | if (is_no_fault_exception(regs)) |
2704 | return; | 2635 | return; |
2705 | 2636 | ||
2706 | clear_siginfo(&info); | 2637 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)sfar, 0, current); |
2707 | info.si_signo = SIGBUS; | ||
2708 | info.si_errno = 0; | ||
2709 | info.si_code = BUS_ADRALN; | ||
2710 | info.si_addr = (void __user *)sfar; | ||
2711 | info.si_trapno = 0; | ||
2712 | force_sig_info(SIGBUS, &info, current); | ||
2713 | out: | 2638 | out: |
2714 | exception_exit(prev_state); | 2639 | exception_exit(prev_state); |
2715 | } | 2640 | } |
2716 | 2641 | ||
2717 | void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx) | 2642 | void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx) |
2718 | { | 2643 | { |
2719 | siginfo_t info; | ||
2720 | |||
2721 | if (notify_die(DIE_TRAP, "memory address unaligned", regs, | 2644 | if (notify_die(DIE_TRAP, "memory address unaligned", regs, |
2722 | 0, 0x34, SIGSEGV) == NOTIFY_STOP) | 2645 | 0, 0x34, SIGSEGV) == NOTIFY_STOP) |
2723 | return; | 2646 | return; |
@@ -2729,13 +2652,7 @@ void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_c | |||
2729 | if (is_no_fault_exception(regs)) | 2652 | if (is_no_fault_exception(regs)) |
2730 | return; | 2653 | return; |
2731 | 2654 | ||
2732 | clear_siginfo(&info); | 2655 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) addr, 0, current); |
2733 | info.si_signo = SIGBUS; | ||
2734 | info.si_errno = 0; | ||
2735 | info.si_code = BUS_ADRALN; | ||
2736 | info.si_addr = (void __user *) addr; | ||
2737 | info.si_trapno = 0; | ||
2738 | force_sig_info(SIGBUS, &info, current); | ||
2739 | } | 2656 | } |
2740 | 2657 | ||
2741 | /* sun4v_mem_corrupt_detect_precise() - Handle precise exception on an ADI | 2658 | /* sun4v_mem_corrupt_detect_precise() - Handle precise exception on an ADI |
@@ -2788,7 +2705,6 @@ void sun4v_mem_corrupt_detect_precise(struct pt_regs *regs, unsigned long addr, | |||
2788 | void do_privop(struct pt_regs *regs) | 2705 | void do_privop(struct pt_regs *regs) |
2789 | { | 2706 | { |
2790 | enum ctx_state prev_state = exception_enter(); | 2707 | enum ctx_state prev_state = exception_enter(); |
2791 | siginfo_t info; | ||
2792 | 2708 | ||
2793 | if (notify_die(DIE_TRAP, "privileged operation", regs, | 2709 | if (notify_die(DIE_TRAP, "privileged operation", regs, |
2794 | 0, 0x11, SIGILL) == NOTIFY_STOP) | 2710 | 0, 0x11, SIGILL) == NOTIFY_STOP) |
@@ -2798,13 +2714,8 @@ void do_privop(struct pt_regs *regs) | |||
2798 | regs->tpc &= 0xffffffff; | 2714 | regs->tpc &= 0xffffffff; |
2799 | regs->tnpc &= 0xffffffff; | 2715 | regs->tnpc &= 0xffffffff; |
2800 | } | 2716 | } |
2801 | clear_siginfo(&info); | 2717 | force_sig_fault(SIGILL, ILL_PRVOPC, |
2802 | info.si_signo = SIGILL; | 2718 | (void __user *)regs->tpc, 0, current); |
2803 | info.si_errno = 0; | ||
2804 | info.si_code = ILL_PRVOPC; | ||
2805 | info.si_addr = (void __user *)regs->tpc; | ||
2806 | info.si_trapno = 0; | ||
2807 | force_sig_info(SIGILL, &info, current); | ||
2808 | out: | 2719 | out: |
2809 | exception_exit(prev_state); | 2720 | exception_exit(prev_state); |
2810 | } | 2721 | } |
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index 2deb586665b9..9f75b6444bf1 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c | |||
@@ -127,20 +127,11 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, | |||
127 | static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs, | 127 | static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs, |
128 | unsigned long addr) | 128 | unsigned long addr) |
129 | { | 129 | { |
130 | siginfo_t info; | ||
131 | |||
132 | clear_siginfo(&info); | ||
133 | info.si_signo = sig; | ||
134 | info.si_code = code; | ||
135 | info.si_errno = 0; | ||
136 | info.si_addr = (void __user *) addr; | ||
137 | info.si_trapno = 0; | ||
138 | |||
139 | if (unlikely(show_unhandled_signals)) | 130 | if (unlikely(show_unhandled_signals)) |
140 | show_signal_msg(regs, sig, info.si_code, | 131 | show_signal_msg(regs, sig, code, |
141 | addr, current); | 132 | addr, current); |
142 | 133 | ||
143 | force_sig_info (sig, &info, current); | 134 | force_sig_fault(sig, code, (void __user *) addr, 0, current); |
144 | } | 135 | } |
145 | 136 | ||
146 | static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault) | 137 | static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault) |
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 46ccff95d10e..63166fcf9e25 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c | |||
@@ -170,12 +170,7 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | |||
170 | int fault_code) | 170 | int fault_code) |
171 | { | 171 | { |
172 | unsigned long addr; | 172 | unsigned long addr; |
173 | siginfo_t info; | ||
174 | 173 | ||
175 | clear_siginfo(&info); | ||
176 | info.si_code = code; | ||
177 | info.si_signo = sig; | ||
178 | info.si_errno = 0; | ||
179 | if (fault_code & FAULT_CODE_ITLB) { | 174 | if (fault_code & FAULT_CODE_ITLB) { |
180 | addr = regs->tpc; | 175 | addr = regs->tpc; |
181 | } else { | 176 | } else { |
@@ -188,13 +183,11 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | |||
188 | else | 183 | else |
189 | addr = fault_addr; | 184 | addr = fault_addr; |
190 | } | 185 | } |
191 | info.si_addr = (void __user *) addr; | ||
192 | info.si_trapno = 0; | ||
193 | 186 | ||
194 | if (unlikely(show_unhandled_signals)) | 187 | if (unlikely(show_unhandled_signals)) |
195 | show_signal_msg(regs, sig, code, addr, current); | 188 | show_signal_msg(regs, sig, code, addr, current); |
196 | 189 | ||
197 | force_sig_info(sig, &info, current); | 190 | force_sig_fault(sig, code, (void __user *) addr, 0, current); |
198 | } | 191 | } |
199 | 192 | ||
200 | static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn) | 193 | static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn) |