diff options
author | Kyle McMartin <kyle@parisc-linux.org> | 2007-01-08 16:28:06 -0500 |
---|---|---|
committer | Kyle McMartin <kyle@athena.road.mcmartin.ca> | 2007-02-17 01:06:04 -0500 |
commit | 4650f0a5832033c78690811aa9b171764c11fc0f (patch) | |
tree | 8f201cd0f556780b5300d0f0e93e30eb31839190 /arch/parisc/kernel/signal.c | |
parent | 0bbdac0897a48f415eb788bf3263c92bd5e97ffb (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.c | 72 |
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 | ||
62 | int 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 | ||
71 | asmlinkage int | ||
72 | sys_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(¤t->sighand->siglock); | ||
100 | saveset = current->blocked; | ||
101 | current->blocked = newset; | ||
102 | recalc_sigpending(); | ||
103 | spin_unlock_irq(¤t->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 | ||
531 | asmlinkage int | 486 | asmlinkage void |
532 | do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall) | 487 | do_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 = ¤t->saved_sigmask; | ||
504 | else | ||
547 | oldset = ¤t->blocked; | 505 | oldset = ¤t->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, ¤t->saved_sigmask, NULL); | ||
619 | } | ||
620 | |||
621 | return; | ||
622 | } | ||
623 | |||
624 | void 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 | } |