aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/signal.c
diff options
context:
space:
mode:
authorKyle McMartin <kyle@parisc-linux.org>2007-01-08 16:28:06 -0500
committerKyle McMartin <kyle@athena.road.mcmartin.ca>2007-02-17 01:06:04 -0500
commit4650f0a5832033c78690811aa9b171764c11fc0f (patch)
tree8f201cd0f556780b5300d0f0e93e30eb31839190 /arch/parisc/kernel/signal.c
parent0bbdac0897a48f415eb788bf3263c92bd5e97ffb (diff)
[PARISC] Add TIF_RESTORE_SIGMASK support
And unmask the pselect6/ppoll system calls. Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc/kernel/signal.c')
-rw-r--r--arch/parisc/kernel/signal.c72
1 files changed, 22 insertions, 50 deletions
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index ee6653edeb7a..8d781b0e668b 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -59,8 +59,6 @@
59 * this. */ 59 * this. */
60#define A(__x) ((unsigned long)(__x)) 60#define A(__x) ((unsigned long)(__x))
61 61
62int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall);
63
64/* 62/*
65 * Atomically swap in the new signal mask, and wait for a signal. 63 * Atomically swap in the new signal mask, and wait for a signal.
66 */ 64 */
@@ -68,49 +66,6 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall);
68#include "sys32.h" 66#include "sys32.h"
69#endif 67#endif
70 68
71asmlinkage int
72sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
73{
74 sigset_t saveset, newset;
75#ifdef __LP64__
76 compat_sigset_t newset32;
77
78 if (is_compat_task()) {
79 /* XXX: Don't preclude handling different sized sigset_t's. */
80 if (sigsetsize != sizeof(compat_sigset_t))
81 return -EINVAL;
82 if (copy_from_user(&newset32, (compat_sigset_t __user *)unewset, sizeof(newset32)))
83 return -EFAULT;
84 sigset_32to64(&newset,&newset32);
85
86 } else
87#endif
88 {
89 /* XXX: Don't preclude handling different sized sigset_t's. */
90 if (sigsetsize != sizeof(sigset_t))
91 return -EINVAL;
92
93 if (copy_from_user(&newset, unewset, sizeof(newset)))
94 return -EFAULT;
95 }
96
97 sigdelsetmask(&newset, ~_BLOCKABLE);
98
99 spin_lock_irq(&current->sighand->siglock);
100 saveset = current->blocked;
101 current->blocked = newset;
102 recalc_sigpending();
103 spin_unlock_irq(&current->sighand->siglock);
104
105 regs->gr[28] = -EINTR;
106 while (1) {
107 current->state = TASK_INTERRUPTIBLE;
108 schedule();
109 if (do_signal(&saveset, regs, 1))
110 return -EINTR;
111 }
112}
113
114/* 69/*
115 * Do a signal return - restore sigcontext. 70 * Do a signal return - restore sigcontext.
116 */ 71 */
@@ -528,12 +483,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
528 * us due to the magic of delayed branching. 483 * us due to the magic of delayed branching.
529 */ 484 */
530 485
531asmlinkage int 486asmlinkage void
532do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall) 487do_signal(struct pt_regs *regs, long in_syscall)
533{ 488{
534 siginfo_t info; 489 siginfo_t info;
535 struct k_sigaction ka; 490 struct k_sigaction ka;
536 int signr; 491 int signr;
492 sigset_t *oldset;
537 493
538 DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n", 494 DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n",
539 oldset, regs, regs->sr[7], in_syscall); 495 oldset, regs, regs->sr[7], in_syscall);
@@ -543,7 +499,9 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
543 we would be called in that case, but for some reason we 499 we would be called in that case, but for some reason we
544 are. */ 500 are. */
545 501
546 if (!oldset) 502 if (test_thread_flag(TIF_RESTORE_SIGMASK))
503 oldset = &current->saved_sigmask;
504 else
547 oldset = &current->blocked; 505 oldset = &current->blocked;
548 506
549 DBG(1,"do_signal: oldset %08lx / %08lx\n", 507 DBG(1,"do_signal: oldset %08lx / %08lx\n",
@@ -592,7 +550,9 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
592 if (handle_signal(signr, &info, &ka, oldset, regs, in_syscall)) { 550 if (handle_signal(signr, &info, &ka, oldset, regs, in_syscall)) {
593 DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n", 551 DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
594 regs->gr[28]); 552 regs->gr[28]);
595 return 1; 553 if (test_thread_flag(TIF_RESTORE_SIGMASK))
554 clear_thread_flag(TIF_RESTORE_SIGMASK);
555 return;
596 } 556 }
597 } 557 }
598 /* end of while(1) looping forever if we can't force a signal */ 558 /* end of while(1) looping forever if we can't force a signal */
@@ -653,5 +613,17 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
653 DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 613 DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n",
654 regs->gr[28]); 614 regs->gr[28]);
655 615
656 return 0; 616 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
617 clear_thread_flag(TIF_RESTORE_SIGMASK);
618 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
619 }
620
621 return;
622}
623
624void do_notify_resume(struct pt_regs *regs, long in_syscall)
625{
626 if (test_thread_flag(TIF_SIGPENDING) ||
627 test_thread_flag(TIF_RESTORE_SIGMASK))
628 do_signal(regs, in_syscall);
657} 629}