diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2018-04-19 19:13:51 -0400 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2018-09-27 16:11:28 -0400 |
commit | ccebcb1f5f3a85d0d23a23dfa611b28ae1e0f824 (patch) | |
tree | 4edc3cc071f33fed0fa9403d5d87cc4b3c836c47 | |
parent | 5ee527d7cefddebd72970d290e5cc06c9ae32890 (diff) |
signal/unicore32: Generate siginfo in ucs32_notify_die
Pass the signal number, and the signal code, and the faulting
address into uc32_notify_die so the callers do not need
to generate a struct siginfo.
In ucs32_ntoify_die use the newly passed in information to
call force_sig_fault to generate the siginfo and send the error.
This simplifies the code making the chances of bugs much less likely.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r-- | arch/unicore32/include/asm/bug.h | 3 | ||||
-rw-r--r-- | arch/unicore32/kernel/traps.c | 5 | ||||
-rw-r--r-- | arch/unicore32/mm/fault.c | 18 |
3 files changed, 9 insertions, 17 deletions
diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h index 93a56f3e2344..83c7687a0e61 100644 --- a/arch/unicore32/include/asm/bug.h +++ b/arch/unicore32/include/asm/bug.h | |||
@@ -17,6 +17,7 @@ struct siginfo; | |||
17 | 17 | ||
18 | extern void die(const char *msg, struct pt_regs *regs, int err); | 18 | extern void die(const char *msg, struct pt_regs *regs, int err); |
19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, | 19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, |
20 | struct siginfo *info, unsigned long err, unsigned long trap); | 20 | int sig, int code, void __user *addr, |
21 | unsigned long err, unsigned long trap); | ||
21 | 22 | ||
22 | #endif /* __UNICORE_BUG_H__ */ | 23 | #endif /* __UNICORE_BUG_H__ */ |
diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c index c4ac6043ebb0..fb376d83e043 100644 --- a/arch/unicore32/kernel/traps.c +++ b/arch/unicore32/kernel/traps.c | |||
@@ -241,13 +241,14 @@ void die(const char *str, struct pt_regs *regs, int err) | |||
241 | } | 241 | } |
242 | 242 | ||
243 | void uc32_notify_die(const char *str, struct pt_regs *regs, | 243 | void uc32_notify_die(const char *str, struct pt_regs *regs, |
244 | struct siginfo *info, unsigned long err, unsigned long trap) | 244 | int sig, int code, void __user *addr, |
245 | unsigned long err, unsigned long trap) | ||
245 | { | 246 | { |
246 | if (user_mode(regs)) { | 247 | if (user_mode(regs)) { |
247 | current->thread.error_code = err; | 248 | current->thread.error_code = err; |
248 | current->thread.trap_no = trap; | 249 | current->thread.trap_no = trap; |
249 | 250 | ||
250 | force_sig_info(info->si_signo, info, current); | 251 | force_sig_fault(sig, code, addr, current); |
251 | } else | 252 | } else |
252 | die(str, regs, err); | 253 | die(str, regs, err); |
253 | } | 254 | } |
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index 8f12a5b50a42..a942776110a0 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c | |||
@@ -466,7 +466,6 @@ asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr, | |||
466 | struct pt_regs *regs) | 466 | struct pt_regs *regs) |
467 | { | 467 | { |
468 | const struct fsr_info *inf = fsr_info + fsr_fs(fsr); | 468 | const struct fsr_info *inf = fsr_info + fsr_fs(fsr); |
469 | struct siginfo info; | ||
470 | 469 | ||
471 | if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) | 470 | if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) |
472 | return; | 471 | return; |
@@ -474,19 +473,14 @@ asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr, | |||
474 | printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", | 473 | printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", |
475 | inf->name, fsr, addr); | 474 | inf->name, fsr, addr); |
476 | 475 | ||
477 | clear_siginfo(&info); | 476 | uc32_notify_die("", regs, inf->sig, inf->code, (void __user *)addr, |
478 | info.si_signo = inf->sig; | 477 | fsr, 0); |
479 | info.si_errno = 0; | ||
480 | info.si_code = inf->code; | ||
481 | info.si_addr = (void __user *)addr; | ||
482 | uc32_notify_die("", regs, &info, fsr, 0); | ||
483 | } | 478 | } |
484 | 479 | ||
485 | asmlinkage void do_PrefetchAbort(unsigned long addr, | 480 | asmlinkage void do_PrefetchAbort(unsigned long addr, |
486 | unsigned int ifsr, struct pt_regs *regs) | 481 | unsigned int ifsr, struct pt_regs *regs) |
487 | { | 482 | { |
488 | const struct fsr_info *inf = fsr_info + fsr_fs(ifsr); | 483 | const struct fsr_info *inf = fsr_info + fsr_fs(ifsr); |
489 | struct siginfo info; | ||
490 | 484 | ||
491 | if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) | 485 | if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) |
492 | return; | 486 | return; |
@@ -494,10 +488,6 @@ asmlinkage void do_PrefetchAbort(unsigned long addr, | |||
494 | printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", | 488 | printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", |
495 | inf->name, ifsr, addr); | 489 | inf->name, ifsr, addr); |
496 | 490 | ||
497 | clear_siginfo(&info); | 491 | uc32_notify_die("", regs, inf->sig, inf->code, (void __user *)addr, |
498 | info.si_signo = inf->sig; | 492 | ifsr, 0); |
499 | info.si_errno = 0; | ||
500 | info.si_code = inf->code; | ||
501 | info.si_addr = (void __user *)addr; | ||
502 | uc32_notify_die("", regs, &info, ifsr, 0); | ||
503 | } | 493 | } |