aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/signal.c')
-rw-r--r--arch/ia64/kernel/signal.c71
1 files changed, 23 insertions, 48 deletions
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 0dcd56da6001..aeec8184e862 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -40,47 +40,6 @@
40# define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0]) 40# define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0])
41#endif 41#endif
42 42
43long
44ia64_rt_sigsuspend (sigset_t __user *uset, size_t sigsetsize, struct sigscratch *scr)
45{
46 sigset_t oldset, set;
47
48 /* XXX: Don't preclude handling different sized sigset_t's. */
49 if (sigsetsize != sizeof(sigset_t))
50 return -EINVAL;
51
52 if (!access_ok(VERIFY_READ, uset, sigsetsize))
53 return -EFAULT;
54
55 if (GET_SIGSET(&set, uset))
56 return -EFAULT;
57
58 sigdelsetmask(&set, ~_BLOCKABLE);
59
60 spin_lock_irq(&current->sighand->siglock);
61 {
62 oldset = current->blocked;
63 current->blocked = set;
64 recalc_sigpending();
65 }
66 spin_unlock_irq(&current->sighand->siglock);
67
68 /*
69 * The return below usually returns to the signal handler. We need to
70 * pre-set the correct error code here to ensure that the right values
71 * get saved in sigcontext by ia64_do_signal.
72 */
73 scr->pt.r8 = EINTR;
74 scr->pt.r10 = -1;
75
76 while (1) {
77 current->state = TASK_INTERRUPTIBLE;
78 schedule();
79 if (ia64_do_signal(&oldset, scr, 1))
80 return -EINTR;
81 }
82}
83
84asmlinkage long 43asmlinkage long
85sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2, 44sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2,
86 long arg3, long arg4, long arg5, long arg6, long arg7, 45 long arg3, long arg4, long arg5, long arg6, long arg7,
@@ -477,10 +436,11 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse
477 * Note that `init' is a special process: it doesn't get signals it doesn't want to 436 * Note that `init' is a special process: it doesn't get signals it doesn't want to
478 * handle. Thus you cannot kill init even with a SIGKILL even by mistake. 437 * handle. Thus you cannot kill init even with a SIGKILL even by mistake.
479 */ 438 */
480long 439void
481ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) 440ia64_do_signal (struct sigscratch *scr, long in_syscall)
482{ 441{
483 struct k_sigaction ka; 442 struct k_sigaction ka;
443 sigset_t *oldset;
484 siginfo_t info; 444 siginfo_t info;
485 long restart = in_syscall; 445 long restart = in_syscall;
486 long errno = scr->pt.r8; 446 long errno = scr->pt.r8;
@@ -492,9 +452,11 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
492 * doing anything if so. 452 * doing anything if so.
493 */ 453 */
494 if (!user_mode(&scr->pt)) 454 if (!user_mode(&scr->pt))
495 return 0; 455 return;
496 456
497 if (!oldset) 457 if (test_thread_flag(TIF_RESTORE_SIGMASK))
458 oldset = &current->saved_sigmask;
459 else
498 oldset = &current->blocked; 460 oldset = &current->blocked;
499 461
500 /* 462 /*
@@ -557,8 +519,15 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
557 * Whee! Actually deliver the signal. If the delivery failed, we need to 519 * Whee! Actually deliver the signal. If the delivery failed, we need to
558 * continue to iterate in this loop so we can deliver the SIGSEGV... 520 * continue to iterate in this loop so we can deliver the SIGSEGV...
559 */ 521 */
560 if (handle_signal(signr, &ka, &info, oldset, scr)) 522 if (handle_signal(signr, &ka, &info, oldset, scr)) {
561 return 1; 523 /* a signal was successfully delivered; the saved
524 * sigmask will have been stored in the signal frame,
525 * and will be restored by sigreturn, so we can simply
526 * clear the TIF_RESTORE_SIGMASK flag */
527 if (test_thread_flag(TIF_RESTORE_SIGMASK))
528 clear_thread_flag(TIF_RESTORE_SIGMASK);
529 return;
530 }
562 } 531 }
563 532
564 /* Did we come from a system call? */ 533 /* Did we come from a system call? */
@@ -584,5 +553,11 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
584 } 553 }
585 } 554 }
586 } 555 }
587 return 0; 556
557 /* if there's no signal to deliver, we just put the saved sigmask
558 * back */
559 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
560 clear_thread_flag(TIF_RESTORE_SIGMASK);
561 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
562 }
588} 563}