diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2018-04-20 10:20:07 -0400 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2018-04-25 11:44:12 -0400 |
commit | 9181010565903a2e4952a073ff29e0990b760f2e (patch) | |
tree | 0ba16518e7ac3cbb0166e98a10d110136bc218a9 | |
parent | 7de712ccc096b81d23cc0a941cd9b8cb3956605d (diff) |
signal/xtensa: 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: Max Filippov <jcmvbkbc@gmail.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: linux-xtensa@linux-xtensa.org
Acked-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r-- | arch/xtensa/kernel/traps.c | 10 | ||||
-rw-r--r-- | arch/xtensa/mm/fault.c | 19 |
2 files changed, 6 insertions, 23 deletions
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 90b509f65b6f..86507fa7c2d7 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c | |||
@@ -323,8 +323,6 @@ do_illegal_instruction(struct pt_regs *regs) | |||
323 | void | 323 | void |
324 | do_unaligned_user (struct pt_regs *regs) | 324 | do_unaligned_user (struct pt_regs *regs) |
325 | { | 325 | { |
326 | siginfo_t info; | ||
327 | |||
328 | __die_if_kernel("Unhandled unaligned exception in kernel", | 326 | __die_if_kernel("Unhandled unaligned exception in kernel", |
329 | regs, SIGKILL); | 327 | regs, SIGKILL); |
330 | 328 | ||
@@ -334,13 +332,7 @@ do_unaligned_user (struct pt_regs *regs) | |||
334 | "(pid = %d, pc = %#010lx)\n", | 332 | "(pid = %d, pc = %#010lx)\n", |
335 | regs->excvaddr, current->comm, | 333 | regs->excvaddr, current->comm, |
336 | task_pid_nr(current), regs->pc); | 334 | task_pid_nr(current), regs->pc); |
337 | clear_siginfo(&info); | 335 | force_sig_fault(SIGBUS, BUS_ADRALN, (void *) regs->excvaddr, current); |
338 | info.si_signo = SIGBUS; | ||
339 | info.si_errno = 0; | ||
340 | info.si_code = BUS_ADRALN; | ||
341 | info.si_addr = (void *) regs->excvaddr; | ||
342 | force_sig_info(SIGBUS, &info, current); | ||
343 | |||
344 | } | 336 | } |
345 | #endif | 337 | #endif |
346 | 338 | ||
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index f9323a3e61ce..c111a833205a 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c | |||
@@ -39,14 +39,13 @@ void do_page_fault(struct pt_regs *regs) | |||
39 | struct mm_struct *mm = current->mm; | 39 | struct mm_struct *mm = current->mm; |
40 | unsigned int exccause = regs->exccause; | 40 | unsigned int exccause = regs->exccause; |
41 | unsigned int address = regs->excvaddr; | 41 | unsigned int address = regs->excvaddr; |
42 | siginfo_t info; | 42 | int code; |
43 | 43 | ||
44 | int is_write, is_exec; | 44 | int is_write, is_exec; |
45 | int fault; | 45 | int fault; |
46 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | 46 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
47 | 47 | ||
48 | clear_siginfo(&info); | 48 | code = SEGV_MAPERR; |
49 | info.si_code = SEGV_MAPERR; | ||
50 | 49 | ||
51 | /* We fault-in kernel-space virtual memory on-demand. The | 50 | /* We fault-in kernel-space virtual memory on-demand. The |
52 | * 'reference' page table is init_mm.pgd. | 51 | * 'reference' page table is init_mm.pgd. |
@@ -92,7 +91,7 @@ retry: | |||
92 | */ | 91 | */ |
93 | 92 | ||
94 | good_area: | 93 | good_area: |
95 | info.si_code = SEGV_ACCERR; | 94 | code = SEGV_ACCERR; |
96 | 95 | ||
97 | if (is_write) { | 96 | if (is_write) { |
98 | if (!(vma->vm_flags & VM_WRITE)) | 97 | if (!(vma->vm_flags & VM_WRITE)) |
@@ -158,11 +157,7 @@ bad_area: | |||
158 | if (user_mode(regs)) { | 157 | if (user_mode(regs)) { |
159 | current->thread.bad_vaddr = address; | 158 | current->thread.bad_vaddr = address; |
160 | current->thread.error_code = is_write; | 159 | current->thread.error_code = is_write; |
161 | info.si_signo = SIGSEGV; | 160 | force_sig_fault(SIGSEGV, code, (void *) address, current); |
162 | info.si_errno = 0; | ||
163 | /* info.si_code has been set above */ | ||
164 | info.si_addr = (void *) address; | ||
165 | force_sig_info(SIGSEGV, &info, current); | ||
166 | return; | 161 | return; |
167 | } | 162 | } |
168 | bad_page_fault(regs, address, SIGSEGV); | 163 | bad_page_fault(regs, address, SIGSEGV); |
@@ -187,11 +182,7 @@ do_sigbus: | |||
187 | * or user mode. | 182 | * or user mode. |
188 | */ | 183 | */ |
189 | current->thread.bad_vaddr = address; | 184 | current->thread.bad_vaddr = address; |
190 | info.si_code = SIGBUS; | 185 | force_sig_fault(SIGBUS, BUS_ADRERR, (void *) address, current); |
191 | info.si_errno = 0; | ||
192 | info.si_code = BUS_ADRERR; | ||
193 | info.si_addr = (void *) address; | ||
194 | force_sig_info(SIGBUS, &info, current); | ||
195 | 186 | ||
196 | /* Kernel mode? Handle exceptions or die */ | 187 | /* Kernel mode? Handle exceptions or die */ |
197 | if (!user_mode(regs)) | 188 | if (!user_mode(regs)) |