diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-09 12:58:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-09 12:58:12 -0400 |
commit | 63b12bdb0d21aca527996fb2c547387bfd3e14b8 (patch) | |
tree | 6ab83b2a1c289f30fea18b88f04138ee69c37c6f /arch/cris | |
parent | ad1f5caf34390bb20fdbb4eaf71b0494e89936f0 (diff) | |
parent | 059ade650ae57cfd371af690fdba887af04aded8 (diff) |
Merge branch 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc
Pull arch signal handling cleanup from Richard Weinberger:
"This patch series moves all remaining archs to the get_signal(),
signal_setup_done() and sigsp() functions.
Currently these archs use open coded variants of the said functions.
Further, unused parameters get removed from get_signal_to_deliver(),
tracehook_signal_handler() and signal_delivered().
At the end of the day we save around 500 lines of code."
* 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc: (43 commits)
powerpc: Use sigsp()
openrisc: Use sigsp()
mn10300: Use sigsp()
mips: Use sigsp()
microblaze: Use sigsp()
metag: Use sigsp()
m68k: Use sigsp()
m32r: Use sigsp()
hexagon: Use sigsp()
frv: Use sigsp()
cris: Use sigsp()
c6x: Use sigsp()
blackfin: Use sigsp()
avr32: Use sigsp()
arm64: Use sigsp()
arc: Use sigsp()
sas_ss_flags: Remove nested ternary if
Rip out get_signal_to_deliver()
Clean up signal_delivered()
tracehook_signal_handler: Remove sig, info, ka and regs
...
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/arch-v10/kernel/signal.c | 89 | ||||
-rw-r--r-- | arch/cris/arch-v32/kernel/signal.c | 89 |
2 files changed, 67 insertions, 111 deletions
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index 61ce6273a895..9b32d338838b 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c | |||
@@ -203,15 +203,9 @@ static int setup_sigcontext(struct sigcontext __user *sc, | |||
203 | * - usually on the stack. */ | 203 | * - usually on the stack. */ |
204 | 204 | ||
205 | static inline void __user * | 205 | static inline void __user * |
206 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | 206 | get_sigframe(struct ksignal *ksig, size_t frame_size) |
207 | { | 207 | { |
208 | unsigned long sp = rdusp(); | 208 | unsigned long sp = sigsp(rdusp(), ksig); |
209 | |||
210 | /* This is the X/Open sanctioned signal stack switching. */ | ||
211 | if (ka->sa.sa_flags & SA_ONSTACK) { | ||
212 | if (! on_sig_stack(sp)) | ||
213 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
214 | } | ||
215 | 209 | ||
216 | /* make sure the frame is dword-aligned */ | 210 | /* make sure the frame is dword-aligned */ |
217 | 211 | ||
@@ -228,33 +222,33 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | |||
228 | * user-mode trampoline. | 222 | * user-mode trampoline. |
229 | */ | 223 | */ |
230 | 224 | ||
231 | static int setup_frame(int sig, struct k_sigaction *ka, | 225 | static int setup_frame(struct ksignal *ksig, sigset_t *set, |
232 | sigset_t *set, struct pt_regs *regs) | 226 | struct pt_regs *regs) |
233 | { | 227 | { |
234 | struct sigframe __user *frame; | 228 | struct sigframe __user *frame; |
235 | unsigned long return_ip; | 229 | unsigned long return_ip; |
236 | int err = 0; | 230 | int err = 0; |
237 | 231 | ||
238 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 232 | frame = get_sigframe(ksig, sizeof(*frame)); |
239 | 233 | ||
240 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 234 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
241 | goto give_sigsegv; | 235 | return -EFAULT; |
242 | 236 | ||
243 | err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); | 237 | err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); |
244 | if (err) | 238 | if (err) |
245 | goto give_sigsegv; | 239 | return -EFAULT; |
246 | 240 | ||
247 | if (_NSIG_WORDS > 1) { | 241 | if (_NSIG_WORDS > 1) { |
248 | err |= __copy_to_user(frame->extramask, &set->sig[1], | 242 | err |= __copy_to_user(frame->extramask, &set->sig[1], |
249 | sizeof(frame->extramask)); | 243 | sizeof(frame->extramask)); |
250 | } | 244 | } |
251 | if (err) | 245 | if (err) |
252 | goto give_sigsegv; | 246 | return -EFAULT; |
253 | 247 | ||
254 | /* Set up to return from userspace. If provided, use a stub | 248 | /* Set up to return from userspace. If provided, use a stub |
255 | already in userspace. */ | 249 | already in userspace. */ |
256 | if (ka->sa.sa_flags & SA_RESTORER) { | 250 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
257 | return_ip = (unsigned long)ka->sa.sa_restorer; | 251 | return_ip = (unsigned long)ksig->ka.sa.sa_restorer; |
258 | } else { | 252 | } else { |
259 | /* trampoline - the desired return ip is the retcode itself */ | 253 | /* trampoline - the desired return ip is the retcode itself */ |
260 | return_ip = (unsigned long)&frame->retcode; | 254 | return_ip = (unsigned long)&frame->retcode; |
@@ -265,42 +259,38 @@ static int setup_frame(int sig, struct k_sigaction *ka, | |||
265 | } | 259 | } |
266 | 260 | ||
267 | if (err) | 261 | if (err) |
268 | goto give_sigsegv; | 262 | return -EFAULT; |
269 | 263 | ||
270 | /* Set up registers for signal handler */ | 264 | /* Set up registers for signal handler */ |
271 | 265 | ||
272 | regs->irp = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ | 266 | regs->irp = (unsigned long) ksig->ka.sa.sa_handler; /* what we enter NOW */ |
273 | regs->srp = return_ip; /* what we enter LATER */ | 267 | regs->srp = return_ip; /* what we enter LATER */ |
274 | regs->r10 = sig; /* first argument is signo */ | 268 | regs->r10 = ksig->sig; /* first argument is signo */ |
275 | 269 | ||
276 | /* actually move the usp to reflect the stacked frame */ | 270 | /* actually move the usp to reflect the stacked frame */ |
277 | 271 | ||
278 | wrusp((unsigned long)frame); | 272 | wrusp((unsigned long)frame); |
279 | 273 | ||
280 | return 0; | 274 | return 0; |
281 | |||
282 | give_sigsegv: | ||
283 | force_sigsegv(sig, current); | ||
284 | return -EFAULT; | ||
285 | } | 275 | } |
286 | 276 | ||
287 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 277 | static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, |
288 | sigset_t *set, struct pt_regs *regs) | 278 | struct pt_regs *regs) |
289 | { | 279 | { |
290 | struct rt_sigframe __user *frame; | 280 | struct rt_sigframe __user *frame; |
291 | unsigned long return_ip; | 281 | unsigned long return_ip; |
292 | int err = 0; | 282 | int err = 0; |
293 | 283 | ||
294 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 284 | frame = get_sigframe(ksig, sizeof(*frame)); |
295 | 285 | ||
296 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 286 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
297 | goto give_sigsegv; | 287 | return -EFAULT; |
298 | 288 | ||
299 | err |= __put_user(&frame->info, &frame->pinfo); | 289 | err |= __put_user(&frame->info, &frame->pinfo); |
300 | err |= __put_user(&frame->uc, &frame->puc); | 290 | err |= __put_user(&frame->uc, &frame->puc); |
301 | err |= copy_siginfo_to_user(&frame->info, info); | 291 | err |= copy_siginfo_to_user(&frame->info, &ksig->info); |
302 | if (err) | 292 | if (err) |
303 | goto give_sigsegv; | 293 | return -EFAULT; |
304 | 294 | ||
305 | /* Clear all the bits of the ucontext we don't use. */ | 295 | /* Clear all the bits of the ucontext we don't use. */ |
306 | err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); | 296 | err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); |
@@ -312,12 +302,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
312 | err |= __save_altstack(&frame->uc.uc_stack, rdusp()); | 302 | err |= __save_altstack(&frame->uc.uc_stack, rdusp()); |
313 | 303 | ||
314 | if (err) | 304 | if (err) |
315 | goto give_sigsegv; | 305 | return -EFAULT; |
316 | 306 | ||
317 | /* Set up to return from userspace. If provided, use a stub | 307 | /* Set up to return from userspace. If provided, use a stub |
318 | already in userspace. */ | 308 | already in userspace. */ |
319 | if (ka->sa.sa_flags & SA_RESTORER) { | 309 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
320 | return_ip = (unsigned long)ka->sa.sa_restorer; | 310 | return_ip = (unsigned long)ksig->ka.sa.sa_restorer; |
321 | } else { | 311 | } else { |
322 | /* trampoline - the desired return ip is the retcode itself */ | 312 | /* trampoline - the desired return ip is the retcode itself */ |
323 | return_ip = (unsigned long)&frame->retcode; | 313 | return_ip = (unsigned long)&frame->retcode; |
@@ -329,18 +319,18 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
329 | } | 319 | } |
330 | 320 | ||
331 | if (err) | 321 | if (err) |
332 | goto give_sigsegv; | 322 | return -EFAULT; |
333 | 323 | ||
334 | /* TODO what is the current->exec_domain stuff and invmap ? */ | 324 | /* TODO what is the current->exec_domain stuff and invmap ? */ |
335 | 325 | ||
336 | /* Set up registers for signal handler */ | 326 | /* Set up registers for signal handler */ |
337 | 327 | ||
338 | /* What we enter NOW */ | 328 | /* What we enter NOW */ |
339 | regs->irp = (unsigned long) ka->sa.sa_handler; | 329 | regs->irp = (unsigned long) ksig->ka.sa.sa_handler; |
340 | /* What we enter LATER */ | 330 | /* What we enter LATER */ |
341 | regs->srp = return_ip; | 331 | regs->srp = return_ip; |
342 | /* First argument is signo */ | 332 | /* First argument is signo */ |
343 | regs->r10 = sig; | 333 | regs->r10 = ksig->sig; |
344 | /* Second argument is (siginfo_t *) */ | 334 | /* Second argument is (siginfo_t *) */ |
345 | regs->r11 = (unsigned long)&frame->info; | 335 | regs->r11 = (unsigned long)&frame->info; |
346 | /* Third argument is unused */ | 336 | /* Third argument is unused */ |
@@ -350,19 +340,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
350 | wrusp((unsigned long)frame); | 340 | wrusp((unsigned long)frame); |
351 | 341 | ||
352 | return 0; | 342 | return 0; |
353 | |||
354 | give_sigsegv: | ||
355 | force_sigsegv(sig, current); | ||
356 | return -EFAULT; | ||
357 | } | 343 | } |
358 | 344 | ||
359 | /* | 345 | /* |
360 | * OK, we're invoking a handler | 346 | * OK, we're invoking a handler |
361 | */ | 347 | */ |
362 | 348 | ||
363 | static inline void handle_signal(int canrestart, unsigned long sig, | 349 | static inline void handle_signal(int canrestart, struct ksignal *ksig, |
364 | siginfo_t *info, struct k_sigaction *ka, | 350 | struct pt_regs *regs) |
365 | struct pt_regs *regs) | ||
366 | { | 351 | { |
367 | sigset_t *oldset = sigmask_to_save(); | 352 | sigset_t *oldset = sigmask_to_save(); |
368 | int ret; | 353 | int ret; |
@@ -383,7 +368,7 @@ static inline void handle_signal(int canrestart, unsigned long sig, | |||
383 | /* ERESTARTSYS means to restart the syscall if | 368 | /* ERESTARTSYS means to restart the syscall if |
384 | * there is no handler or the handler was | 369 | * there is no handler or the handler was |
385 | * registered with SA_RESTART */ | 370 | * registered with SA_RESTART */ |
386 | if (!(ka->sa.sa_flags & SA_RESTART)) { | 371 | if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { |
387 | regs->r10 = -EINTR; | 372 | regs->r10 = -EINTR; |
388 | break; | 373 | break; |
389 | } | 374 | } |
@@ -396,13 +381,12 @@ static inline void handle_signal(int canrestart, unsigned long sig, | |||
396 | } | 381 | } |
397 | 382 | ||
398 | /* Set up the stack frame */ | 383 | /* Set up the stack frame */ |
399 | if (ka->sa.sa_flags & SA_SIGINFO) | 384 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
400 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 385 | ret = setup_rt_frame(ksig, oldset, regs); |
401 | else | 386 | else |
402 | ret = setup_frame(sig, ka, oldset, regs); | 387 | ret = setup_frame(ksig, oldset, regs); |
403 | 388 | ||
404 | if (ret == 0) | 389 | signal_setup_done(ret, ksig, 0); |
405 | signal_delivered(sig, info, ka, regs, 0); | ||
406 | } | 390 | } |
407 | 391 | ||
408 | /* | 392 | /* |
@@ -419,9 +403,7 @@ static inline void handle_signal(int canrestart, unsigned long sig, | |||
419 | 403 | ||
420 | void do_signal(int canrestart, struct pt_regs *regs) | 404 | void do_signal(int canrestart, struct pt_regs *regs) |
421 | { | 405 | { |
422 | siginfo_t info; | 406 | struct ksignal ksig; |
423 | int signr; | ||
424 | struct k_sigaction ka; | ||
425 | 407 | ||
426 | /* | 408 | /* |
427 | * We want the common case to go fast, which | 409 | * We want the common case to go fast, which |
@@ -432,10 +414,9 @@ void do_signal(int canrestart, struct pt_regs *regs) | |||
432 | if (!user_mode(regs)) | 414 | if (!user_mode(regs)) |
433 | return; | 415 | return; |
434 | 416 | ||
435 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 417 | if (get_signal(&ksig)) { |
436 | if (signr > 0) { | ||
437 | /* Whee! Actually deliver the signal. */ | 418 | /* Whee! Actually deliver the signal. */ |
438 | handle_signal(canrestart, signr, &info, &ka, regs); | 419 | handle_signal(canrestart, &ksig, regs); |
439 | return; | 420 | return; |
440 | } | 421 | } |
441 | 422 | ||
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index 01d1375c9004..78ce3b1c9bcb 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c | |||
@@ -189,17 +189,9 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
189 | 189 | ||
190 | /* Figure out where to put the new signal frame - usually on the stack. */ | 190 | /* Figure out where to put the new signal frame - usually on the stack. */ |
191 | static inline void __user * | 191 | static inline void __user * |
192 | get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | 192 | get_sigframe(struct ksignal *ksig, size_t frame_size) |
193 | { | 193 | { |
194 | unsigned long sp; | 194 | unsigned long sp = sigsp(rdusp(), ksig); |
195 | |||
196 | sp = rdusp(); | ||
197 | |||
198 | /* This is the X/Open sanctioned signal stack switching. */ | ||
199 | if (ka->sa.sa_flags & SA_ONSTACK) { | ||
200 | if (!on_sig_stack(sp)) | ||
201 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
202 | } | ||
203 | 195 | ||
204 | /* Make sure the frame is dword-aligned. */ | 196 | /* Make sure the frame is dword-aligned. */ |
205 | sp &= ~3; | 197 | sp &= ~3; |
@@ -215,23 +207,22 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
215 | * trampoline. | 207 | * trampoline. |
216 | */ | 208 | */ |
217 | static int | 209 | static int |
218 | setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | 210 | setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) |
219 | struct pt_regs * regs) | ||
220 | { | 211 | { |
221 | int err; | 212 | int err; |
222 | unsigned long return_ip; | 213 | unsigned long return_ip; |
223 | struct signal_frame __user *frame; | 214 | struct signal_frame __user *frame; |
224 | 215 | ||
225 | err = 0; | 216 | err = 0; |
226 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 217 | frame = get_sigframe(ksig, sizeof(*frame)); |
227 | 218 | ||
228 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 219 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
229 | goto give_sigsegv; | 220 | return -EFAULT; |
230 | 221 | ||
231 | err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); | 222 | err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); |
232 | 223 | ||
233 | if (err) | 224 | if (err) |
234 | goto give_sigsegv; | 225 | return -EFAULT; |
235 | 226 | ||
236 | if (_NSIG_WORDS > 1) { | 227 | if (_NSIG_WORDS > 1) { |
237 | err |= __copy_to_user(frame->extramask, &set->sig[1], | 228 | err |= __copy_to_user(frame->extramask, &set->sig[1], |
@@ -239,14 +230,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
239 | } | 230 | } |
240 | 231 | ||
241 | if (err) | 232 | if (err) |
242 | goto give_sigsegv; | 233 | return -EFAULT; |
243 | 234 | ||
244 | /* | 235 | /* |
245 | * Set up to return from user-space. If provided, use a stub | 236 | * Set up to return from user-space. If provided, use a stub |
246 | * already located in user-space. | 237 | * already located in user-space. |
247 | */ | 238 | */ |
248 | if (ka->sa.sa_flags & SA_RESTORER) { | 239 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
249 | return_ip = (unsigned long)ka->sa.sa_restorer; | 240 | return_ip = (unsigned long)ksig->ka.sa.sa_restorer; |
250 | } else { | 241 | } else { |
251 | /* Trampoline - the desired return ip is in the signal return page. */ | 242 | /* Trampoline - the desired return ip is in the signal return page. */ |
252 | return_ip = cris_signal_return_page; | 243 | return_ip = cris_signal_return_page; |
@@ -264,7 +255,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
264 | } | 255 | } |
265 | 256 | ||
266 | if (err) | 257 | if (err) |
267 | goto give_sigsegv; | 258 | return -EFAULT; |
268 | 259 | ||
269 | /* | 260 | /* |
270 | * Set up registers for signal handler. | 261 | * Set up registers for signal handler. |
@@ -273,42 +264,37 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
273 | * Where the code enter later. | 264 | * Where the code enter later. |
274 | * First argument, signo. | 265 | * First argument, signo. |
275 | */ | 266 | */ |
276 | regs->erp = (unsigned long) ka->sa.sa_handler; | 267 | regs->erp = (unsigned long) ksig->ka.sa.sa_handler; |
277 | regs->srp = return_ip; | 268 | regs->srp = return_ip; |
278 | regs->r10 = sig; | 269 | regs->r10 = ksig->sig; |
279 | 270 | ||
280 | /* Actually move the USP to reflect the stacked frame. */ | 271 | /* Actually move the USP to reflect the stacked frame. */ |
281 | wrusp((unsigned long)frame); | 272 | wrusp((unsigned long)frame); |
282 | 273 | ||
283 | return 0; | 274 | return 0; |
284 | |||
285 | give_sigsegv: | ||
286 | force_sigsegv(sig, current); | ||
287 | return -EFAULT; | ||
288 | } | 275 | } |
289 | 276 | ||
290 | static int | 277 | static int |
291 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 278 | setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) |
292 | sigset_t *set, struct pt_regs * regs) | ||
293 | { | 279 | { |
294 | int err; | 280 | int err; |
295 | unsigned long return_ip; | 281 | unsigned long return_ip; |
296 | struct rt_signal_frame __user *frame; | 282 | struct rt_signal_frame __user *frame; |
297 | 283 | ||
298 | err = 0; | 284 | err = 0; |
299 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 285 | frame = get_sigframe(ksig, sizeof(*frame)); |
300 | 286 | ||
301 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 287 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
302 | goto give_sigsegv; | 288 | return -EFAULT; |
303 | 289 | ||
304 | /* TODO: what is the current->exec_domain stuff and invmap ? */ | 290 | /* TODO: what is the current->exec_domain stuff and invmap ? */ |
305 | 291 | ||
306 | err |= __put_user(&frame->info, &frame->pinfo); | 292 | err |= __put_user(&frame->info, &frame->pinfo); |
307 | err |= __put_user(&frame->uc, &frame->puc); | 293 | err |= __put_user(&frame->uc, &frame->puc); |
308 | err |= copy_siginfo_to_user(&frame->info, info); | 294 | err |= copy_siginfo_to_user(&frame->info, &ksig->info); |
309 | 295 | ||
310 | if (err) | 296 | if (err) |
311 | goto give_sigsegv; | 297 | return -EFAULT; |
312 | 298 | ||
313 | /* Clear all the bits of the ucontext we don't use. */ | 299 | /* Clear all the bits of the ucontext we don't use. */ |
314 | err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); | 300 | err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); |
@@ -317,14 +303,14 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
317 | err |= __save_altstack(&frame->uc.uc_stack, rdusp()); | 303 | err |= __save_altstack(&frame->uc.uc_stack, rdusp()); |
318 | 304 | ||
319 | if (err) | 305 | if (err) |
320 | goto give_sigsegv; | 306 | return -EFAULT; |
321 | 307 | ||
322 | /* | 308 | /* |
323 | * Set up to return from user-space. If provided, use a stub | 309 | * Set up to return from user-space. If provided, use a stub |
324 | * already located in user-space. | 310 | * already located in user-space. |
325 | */ | 311 | */ |
326 | if (ka->sa.sa_flags & SA_RESTORER) { | 312 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
327 | return_ip = (unsigned long) ka->sa.sa_restorer; | 313 | return_ip = (unsigned long) ksig->ka.sa.sa_restorer; |
328 | } else { | 314 | } else { |
329 | /* Trampoline - the desired return ip is in the signal return page. */ | 315 | /* Trampoline - the desired return ip is in the signal return page. */ |
330 | return_ip = cris_signal_return_page + 6; | 316 | return_ip = cris_signal_return_page + 6; |
@@ -345,7 +331,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
345 | } | 331 | } |
346 | 332 | ||
347 | if (err) | 333 | if (err) |
348 | goto give_sigsegv; | 334 | return -EFAULT; |
349 | 335 | ||
350 | /* | 336 | /* |
351 | * Set up registers for signal handler. | 337 | * Set up registers for signal handler. |
@@ -356,9 +342,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
356 | * Second argument is (siginfo_t *). | 342 | * Second argument is (siginfo_t *). |
357 | * Third argument is unused. | 343 | * Third argument is unused. |
358 | */ | 344 | */ |
359 | regs->erp = (unsigned long) ka->sa.sa_handler; | 345 | regs->erp = (unsigned long) ksig->ka.sa.sa_handler; |
360 | regs->srp = return_ip; | 346 | regs->srp = return_ip; |
361 | regs->r10 = sig; | 347 | regs->r10 = ksig->sig; |
362 | regs->r11 = (unsigned long) &frame->info; | 348 | regs->r11 = (unsigned long) &frame->info; |
363 | regs->r12 = 0; | 349 | regs->r12 = 0; |
364 | 350 | ||
@@ -366,17 +352,11 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
366 | wrusp((unsigned long)frame); | 352 | wrusp((unsigned long)frame); |
367 | 353 | ||
368 | return 0; | 354 | return 0; |
369 | |||
370 | give_sigsegv: | ||
371 | force_sigsegv(sig, current); | ||
372 | return -EFAULT; | ||
373 | } | 355 | } |
374 | 356 | ||
375 | /* Invoke a signal handler to, well, handle the signal. */ | 357 | /* Invoke a signal handler to, well, handle the signal. */ |
376 | static inline void | 358 | static inline void |
377 | handle_signal(int canrestart, unsigned long sig, | 359 | handle_signal(int canrestart, struct ksignal *ksig, struct pt_regs *regs) |
378 | siginfo_t *info, struct k_sigaction *ka, | ||
379 | struct pt_regs * regs) | ||
380 | { | 360 | { |
381 | sigset_t *oldset = sigmask_to_save(); | 361 | sigset_t *oldset = sigmask_to_save(); |
382 | int ret; | 362 | int ret; |
@@ -404,7 +384,7 @@ handle_signal(int canrestart, unsigned long sig, | |||
404 | * there is no handler, or the handler | 384 | * there is no handler, or the handler |
405 | * was registered with SA_RESTART. | 385 | * was registered with SA_RESTART. |
406 | */ | 386 | */ |
407 | if (!(ka->sa.sa_flags & SA_RESTART)) { | 387 | if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { |
408 | regs->r10 = -EINTR; | 388 | regs->r10 = -EINTR; |
409 | break; | 389 | break; |
410 | } | 390 | } |
@@ -423,13 +403,12 @@ handle_signal(int canrestart, unsigned long sig, | |||
423 | } | 403 | } |
424 | 404 | ||
425 | /* Set up the stack frame. */ | 405 | /* Set up the stack frame. */ |
426 | if (ka->sa.sa_flags & SA_SIGINFO) | 406 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) |
427 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 407 | ret = setup_rt_frame(ksig, oldset, regs); |
428 | else | 408 | else |
429 | ret = setup_frame(sig, ka, oldset, regs); | 409 | ret = setup_frame(ksig, oldset, regs); |
430 | 410 | ||
431 | if (ret == 0) | 411 | signal_setup_done(ret, ksig, 0); |
432 | signal_delivered(sig, info, ka, regs, 0); | ||
433 | } | 412 | } |
434 | 413 | ||
435 | /* | 414 | /* |
@@ -446,9 +425,7 @@ handle_signal(int canrestart, unsigned long sig, | |||
446 | void | 425 | void |
447 | do_signal(int canrestart, struct pt_regs *regs) | 426 | do_signal(int canrestart, struct pt_regs *regs) |
448 | { | 427 | { |
449 | int signr; | 428 | struct ksignal ksig; |
450 | siginfo_t info; | ||
451 | struct k_sigaction ka; | ||
452 | 429 | ||
453 | /* | 430 | /* |
454 | * The common case should go fast, which is why this point is | 431 | * The common case should go fast, which is why this point is |
@@ -458,11 +435,9 @@ do_signal(int canrestart, struct pt_regs *regs) | |||
458 | if (!user_mode(regs)) | 435 | if (!user_mode(regs)) |
459 | return; | 436 | return; |
460 | 437 | ||
461 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 438 | if (get_signal(&ksig)) { |
462 | |||
463 | if (signr > 0) { | ||
464 | /* Whee! Actually deliver the signal. */ | 439 | /* Whee! Actually deliver the signal. */ |
465 | handle_signal(canrestart, signr, &info, &ka, regs); | 440 | handle_signal(canrestart, &ksig, regs); |
466 | return; | 441 | return; |
467 | } | 442 | } |
468 | 443 | ||