diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2018-04-15 20:50:48 -0400 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2018-04-25 11:44:11 -0400 |
commit | bc08c0781dbe5ec996bac1088f944723103729af (patch) | |
tree | 12ff168344f89d72b61dd99851417c564c25c071 /arch/um | |
parent | d1f5bef63fabeba834ed325ccec336ce3612d65c (diff) |
signal/um: 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: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: user-mode-linux-devel@lists.sourceforge.net
Cc: linux-um@lists.infradead.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/kernel/ptrace.c | 13 | ||||
-rw-r--r-- | arch/um/kernel/trap.c | 26 |
2 files changed, 11 insertions, 28 deletions
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index bc2a516c190f..1a1d88a4d940 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -115,17 +115,10 @@ long arch_ptrace(struct task_struct *child, long request, | |||
115 | static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, | 115 | static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, |
116 | int error_code) | 116 | int error_code) |
117 | { | 117 | { |
118 | struct siginfo info; | ||
119 | |||
120 | memset(&info, 0, sizeof(info)); | ||
121 | info.si_signo = SIGTRAP; | ||
122 | info.si_code = TRAP_BRKPT; | ||
123 | |||
124 | /* User-mode eip? */ | ||
125 | info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL; | ||
126 | |||
127 | /* Send us the fake SIGTRAP */ | 118 | /* Send us the fake SIGTRAP */ |
128 | force_sig_info(SIGTRAP, &info, tsk); | 119 | force_sig_fault(SIGTRAP, TRAP_BRKPT, |
120 | /* User-mode eip? */ | ||
121 | UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL, tsk); | ||
129 | } | 122 | } |
130 | 123 | ||
131 | /* | 124 | /* |
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index d4d38520c4c6..d18be983814a 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c | |||
@@ -162,14 +162,9 @@ static void show_segv_info(struct uml_pt_regs *regs) | |||
162 | 162 | ||
163 | static void bad_segv(struct faultinfo fi, unsigned long ip) | 163 | static void bad_segv(struct faultinfo fi, unsigned long ip) |
164 | { | 164 | { |
165 | struct siginfo si; | ||
166 | |||
167 | clear_siginfo(&si); | ||
168 | si.si_signo = SIGSEGV; | ||
169 | si.si_code = SEGV_ACCERR; | ||
170 | si.si_addr = (void __user *) FAULT_ADDRESS(fi); | ||
171 | current->thread.arch.faultinfo = fi; | 165 | current->thread.arch.faultinfo = fi; |
172 | force_sig_info(SIGSEGV, &si, current); | 166 | force_sig_fault(SIGSEGV, SEGV_ACCERR, (void __user *) FAULT_ADDRESS(fi), |
167 | current); | ||
173 | } | 168 | } |
174 | 169 | ||
175 | void fatal_sigsegv(void) | 170 | void fatal_sigsegv(void) |
@@ -215,13 +210,12 @@ void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) | |||
215 | unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | 210 | unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, |
216 | struct uml_pt_regs *regs) | 211 | struct uml_pt_regs *regs) |
217 | { | 212 | { |
218 | struct siginfo si; | ||
219 | jmp_buf *catcher; | 213 | jmp_buf *catcher; |
214 | int si_code; | ||
220 | int err; | 215 | int err; |
221 | int is_write = FAULT_WRITE(fi); | 216 | int is_write = FAULT_WRITE(fi); |
222 | unsigned long address = FAULT_ADDRESS(fi); | 217 | unsigned long address = FAULT_ADDRESS(fi); |
223 | 218 | ||
224 | clear_siginfo(&si); | ||
225 | if (!is_user && regs) | 219 | if (!is_user && regs) |
226 | current->thread.segv_regs = container_of(regs, struct pt_regs, regs); | 220 | current->thread.segv_regs = container_of(regs, struct pt_regs, regs); |
227 | 221 | ||
@@ -241,7 +235,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | |||
241 | 235 | ||
242 | if (SEGV_IS_FIXABLE(&fi)) | 236 | if (SEGV_IS_FIXABLE(&fi)) |
243 | err = handle_page_fault(address, ip, is_write, is_user, | 237 | err = handle_page_fault(address, ip, is_write, is_user, |
244 | &si.si_code); | 238 | &si_code); |
245 | else { | 239 | else { |
246 | err = -EFAULT; | 240 | err = -EFAULT; |
247 | /* | 241 | /* |
@@ -273,18 +267,14 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | |||
273 | show_segv_info(regs); | 267 | show_segv_info(regs); |
274 | 268 | ||
275 | if (err == -EACCES) { | 269 | if (err == -EACCES) { |
276 | si.si_signo = SIGBUS; | ||
277 | si.si_errno = 0; | ||
278 | si.si_code = BUS_ADRERR; | ||
279 | si.si_addr = (void __user *)address; | ||
280 | current->thread.arch.faultinfo = fi; | 270 | current->thread.arch.faultinfo = fi; |
281 | force_sig_info(SIGBUS, &si, current); | 271 | force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, |
272 | current); | ||
282 | } else { | 273 | } else { |
283 | BUG_ON(err != -EFAULT); | 274 | BUG_ON(err != -EFAULT); |
284 | si.si_signo = SIGSEGV; | ||
285 | si.si_addr = (void __user *) address; | ||
286 | current->thread.arch.faultinfo = fi; | 275 | current->thread.arch.faultinfo = fi; |
287 | force_sig_info(SIGSEGV, &si, current); | 276 | force_sig_fault(SIGSEGV, si_code, (void __user *) address, |
277 | current); | ||
288 | } | 278 | } |
289 | 279 | ||
290 | out: | 280 | out: |