aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 21:11:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 21:11:45 -0400
commitf9369910a6225b8d4892c3f20ae740a711cd5ace (patch)
tree8650ff79d7607bceb35509c028400ecf1c317de0 /arch/alpha
parent05f144a0d5c2207a0349348127f996e104ad7404 (diff)
parent415d04d08fec74b226c92c1fb54ad117c9c6bac4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull first series of signal handling cleanups from Al Viro: "This is just the first part of the queue (about a half of it); assorted fixes all over the place in signal handling. This one ends with all sigsuspend() implementations switched to generic one (->saved_sigmask-based). With this, a bunch of assorted old buglets are fixed and most of the missing bits of NOTIFY_RESUME hookup are in place. Two more fixes sit in arm and um trees respectively, and there's a couple of broken ones that need obvious fixes - parisc and avr32 check TIF_NOTIFY_RESUME only on one of two codepaths; fixes for that will happen in the next series" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (55 commits) unicore32: if there's no handler we need to restore sigmask, syscall or no syscall xtensa: add handling of TIF_NOTIFY_RESUME microblaze: drop 'oldset' argument of do_notify_resume() microblaze: handle TIF_NOTIFY_RESUME score: add handling of NOTIFY_RESUME to do_notify_resume() m68k: add TIF_NOTIFY_RESUME and handle it. sparc: kill ancient comment in sparc_sigaction() h8300: missing checks of __get_user()/__put_user() return values frv: missing checks of __get_user()/__put_user() return values cris: missing checks of __get_user()/__put_user() return values powerpc: missing checks of __get_user()/__put_user() return values sh: missing checks of __get_user()/__put_user() return values sparc: missing checks of __get_user()/__put_user() return values avr32: struct old_sigaction is never used m32r: struct old_sigaction is never used xtensa: xtensa_sigaction doesn't exist alpha: tidy signal delivery up score: don't open-code force_sigsegv() cris: don't open-code force_sigsegv() blackfin: don't open-code force_sigsegv() ...
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/kernel/signal.c80
1 files changed, 27 insertions, 53 deletions
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 35f2ef44de12..10ab2d74ecbb 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -34,9 +34,6 @@
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35 35
36asmlinkage void ret_from_sys_call(void); 36asmlinkage void ret_from_sys_call(void);
37static void do_signal(struct pt_regs *, struct switch_stack *,
38 unsigned long, unsigned long);
39
40 37
41/* 38/*
42 * The OSF/1 sigprocmask calling sequence is different from the 39 * The OSF/1 sigprocmask calling sequence is different from the
@@ -121,17 +118,8 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
121SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask) 118SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
122{ 119{
123 sigset_t blocked; 120 sigset_t blocked;
124
125 current->saved_sigmask = current->blocked;
126
127 mask &= _BLOCKABLE;
128 siginitset(&blocked, mask); 121 siginitset(&blocked, mask);
129 set_current_blocked(&blocked); 122 return sigsuspend(&blocked);
130
131 current->state = TASK_INTERRUPTIBLE;
132 schedule();
133 set_thread_flag(TIF_RESTORE_SIGMASK);
134 return -ERESTARTNOHAND;
135} 123}
136 124
137asmlinkage int 125asmlinkage int
@@ -376,11 +364,11 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
376 oldsp = rdusp(); 364 oldsp = rdusp();
377 frame = get_sigframe(ka, oldsp, sizeof(*frame)); 365 frame = get_sigframe(ka, oldsp, sizeof(*frame));
378 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 366 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
379 goto give_sigsegv; 367 return -EFAULT;
380 368
381 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp); 369 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
382 if (err) 370 if (err)
383 goto give_sigsegv; 371 return -EFAULT;
384 372
385 /* Set up to return from userspace. If provided, use a stub 373 /* Set up to return from userspace. If provided, use a stub
386 already in userspace. */ 374 already in userspace. */
@@ -396,7 +384,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
396 384
397 /* Check that everything was written properly. */ 385 /* Check that everything was written properly. */
398 if (err) 386 if (err)
399 goto give_sigsegv; 387 return err;
400 388
401 /* "Return" to the handler */ 389 /* "Return" to the handler */
402 regs->r26 = r26; 390 regs->r26 = r26;
@@ -410,12 +398,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
410 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 398 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
411 current->comm, current->pid, frame, regs->pc, regs->r26); 399 current->comm, current->pid, frame, regs->pc, regs->r26);
412#endif 400#endif
413
414 return 0; 401 return 0;
415
416give_sigsegv:
417 force_sigsegv(sig, current);
418 return -EFAULT;
419} 402}
420 403
421static int 404static int
@@ -428,7 +411,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
428 oldsp = rdusp(); 411 oldsp = rdusp();
429 frame = get_sigframe(ka, oldsp, sizeof(*frame)); 412 frame = get_sigframe(ka, oldsp, sizeof(*frame));
430 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 413 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
431 goto give_sigsegv; 414 return -EFAULT;
432 415
433 err |= copy_siginfo_to_user(&frame->info, info); 416 err |= copy_siginfo_to_user(&frame->info, info);
434 417
@@ -443,7 +426,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
443 set->sig[0], oldsp); 426 set->sig[0], oldsp);
444 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 427 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
445 if (err) 428 if (err)
446 goto give_sigsegv; 429 return -EFAULT;
447 430
448 /* Set up to return from userspace. If provided, use a stub 431 /* Set up to return from userspace. If provided, use a stub
449 already in userspace. */ 432 already in userspace. */
@@ -459,7 +442,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
459 } 442 }
460 443
461 if (err) 444 if (err)
462 goto give_sigsegv; 445 return -EFAULT;
463 446
464 /* "Return" to the handler */ 447 /* "Return" to the handler */
465 regs->r26 = r26; 448 regs->r26 = r26;
@@ -475,31 +458,37 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
475#endif 458#endif
476 459
477 return 0; 460 return 0;
478
479give_sigsegv:
480 force_sigsegv(sig, current);
481 return -EFAULT;
482} 461}
483 462
484 463
485/* 464/*
486 * OK, we're invoking a handler. 465 * OK, we're invoking a handler.
487 */ 466 */
488static inline int 467static inline void
489handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 468handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
490 sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) 469 struct pt_regs * regs, struct switch_stack *sw)
491{ 470{
471 sigset_t *oldset = &current->blocked;
492 int ret; 472 int ret;
493 473
474 if (test_thread_flag(TIF_RESTORE_SIGMASK))
475 oldset = &current->saved_sigmask;
476
494 if (ka->sa.sa_flags & SA_SIGINFO) 477 if (ka->sa.sa_flags & SA_SIGINFO)
495 ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); 478 ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
496 else 479 else
497 ret = setup_frame(sig, ka, oldset, regs, sw); 480 ret = setup_frame(sig, ka, oldset, regs, sw);
498 481
499 if (ret == 0) 482 if (ret) {
500 block_sigmask(ka, sig); 483 force_sigsegv(sig, current);
501 484 return;
502 return ret; 485 }
486 block_sigmask(ka, sig);
487 /* A signal was successfully delivered, and the
488 saved sigmask was stored on the signal frame,
489 and will be restored by sigreturn. So we can
490 simply clear the restore sigmask flag. */
491 clear_thread_flag(TIF_RESTORE_SIGMASK);
503} 492}
504 493
505static inline void 494static inline void
@@ -547,12 +536,6 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
547 int signr; 536 int signr;
548 unsigned long single_stepping = ptrace_cancel_bpt(current); 537 unsigned long single_stepping = ptrace_cancel_bpt(current);
549 struct k_sigaction ka; 538 struct k_sigaction ka;
550 sigset_t *oldset;
551
552 if (test_thread_flag(TIF_RESTORE_SIGMASK))
553 oldset = &current->saved_sigmask;
554 else
555 oldset = &current->blocked;
556 539
557 /* This lets the debugger run, ... */ 540 /* This lets the debugger run, ... */
558 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 541 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -564,14 +547,7 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
564 /* Whee! Actually deliver the signal. */ 547 /* Whee! Actually deliver the signal. */
565 if (r0) 548 if (r0)
566 syscall_restart(r0, r19, regs, &ka); 549 syscall_restart(r0, r19, regs, &ka);
567 if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) { 550 handle_signal(signr, &ka, &info, regs, sw);
568 /* A signal was successfully delivered, and the
569 saved sigmask was stored on the signal frame,
570 and will be restored by sigreturn. So we can
571 simply clear the restore sigmask flag. */
572 if (test_thread_flag(TIF_RESTORE_SIGMASK))
573 clear_thread_flag(TIF_RESTORE_SIGMASK);
574 }
575 if (single_stepping) 551 if (single_stepping)
576 ptrace_set_bpt(current); /* re-set bpt */ 552 ptrace_set_bpt(current); /* re-set bpt */
577 return; 553 return;
@@ -596,10 +572,8 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
596 } 572 }
597 573
598 /* If there's no signal to deliver, we just restore the saved mask. */ 574 /* If there's no signal to deliver, we just restore the saved mask. */
599 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 575 if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
600 clear_thread_flag(TIF_RESTORE_SIGMASK); 576 set_current_blocked(&current->saved_sigmask);
601 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
602 }
603 577
604 if (single_stepping) 578 if (single_stepping)
605 ptrace_set_bpt(current); /* re-set breakpoint */ 579 ptrace_set_bpt(current); /* re-set breakpoint */
@@ -610,7 +584,7 @@ do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
610 unsigned long thread_info_flags, 584 unsigned long thread_info_flags,
611 unsigned long r0, unsigned long r19) 585 unsigned long r0, unsigned long r19)
612{ 586{
613 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 587 if (thread_info_flags & _TIF_SIGPENDING)
614 do_signal(regs, sw, r0, r19); 588 do_signal(regs, sw, r0, r19);
615 589
616 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 590 if (thread_info_flags & _TIF_NOTIFY_RESUME) {