diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-04-22 01:16:34 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-21 23:58:06 -0400 |
commit | 9ef461adf9875a0fcaafe4d152a7557740fa1a25 (patch) | |
tree | 1d07dba7defbf39e67de2d38084b4b9ade9a3d98 /arch/sh/kernel | |
parent | 9ccc9c75c9117d18a9b1f71a21f0066b1eb9db6f (diff) |
sh: switch to saved_sigmask-based sigsuspend()/rt_sigsuspend()
Complete the move of sh64 to it, trim the crap from prototypes,
tidy up a bit. Infrastructure in do_signal() had already been
there, in signal_64 as well as in signal_32 (where it was already
used).
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/signal_32.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/signal_64.c | 72 |
2 files changed, 11 insertions, 65 deletions
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 46c9f9b00b14..04d776f35869 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c | |||
@@ -53,9 +53,7 @@ struct fdpic_func_descriptor { | |||
53 | * Atomically swap in the new signal mask, and wait for a signal. | 53 | * Atomically swap in the new signal mask, and wait for a signal. |
54 | */ | 54 | */ |
55 | asmlinkage int | 55 | asmlinkage int |
56 | sys_sigsuspend(old_sigset_t mask, | 56 | sys_sigsuspend(old_sigset_t mask) |
57 | unsigned long r5, unsigned long r6, unsigned long r7, | ||
58 | struct pt_regs __regs) | ||
59 | { | 57 | { |
60 | sigset_t blocked; | 58 | sigset_t blocked; |
61 | siginitset(&blocked, mask); | 59 | siginitset(&blocked, mask); |
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 3c9a6f7dcdce..8f6ed236c932 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c | |||
@@ -83,11 +83,12 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) | |||
83 | * the kernel can handle, and then we build all the user-level signal handling | 83 | * the kernel can handle, and then we build all the user-level signal handling |
84 | * stack-frames in one go after that. | 84 | * stack-frames in one go after that. |
85 | */ | 85 | */ |
86 | static int do_signal(struct pt_regs *regs, sigset_t *oldset) | 86 | static void do_signal(struct pt_regs *regs) |
87 | { | 87 | { |
88 | siginfo_t info; | 88 | siginfo_t info; |
89 | int signr; | 89 | int signr; |
90 | struct k_sigaction ka; | 90 | struct k_sigaction ka; |
91 | sigset_t *oldset; | ||
91 | 92 | ||
92 | /* | 93 | /* |
93 | * We want the common case to go fast, which | 94 | * We want the common case to go fast, which |
@@ -96,11 +97,11 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
96 | * if so. | 97 | * if so. |
97 | */ | 98 | */ |
98 | if (!user_mode(regs)) | 99 | if (!user_mode(regs)) |
99 | return 1; | 100 | return; |
100 | 101 | ||
101 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) | 102 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) |
102 | oldset = ¤t->saved_sigmask; | 103 | oldset = ¤t->saved_sigmask; |
103 | else if (!oldset) | 104 | else |
104 | oldset = ¤t->blocked; | 105 | oldset = ¤t->blocked; |
105 | 106 | ||
106 | signr = get_signal_to_deliver(&info, &ka, regs, 0); | 107 | signr = get_signal_to_deliver(&info, &ka, regs, 0); |
@@ -118,7 +119,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
118 | 119 | ||
119 | tracehook_signal_handler(signr, &info, &ka, regs, | 120 | tracehook_signal_handler(signr, &info, &ka, regs, |
120 | test_thread_flag(TIF_SINGLESTEP)); | 121 | test_thread_flag(TIF_SINGLESTEP)); |
121 | return 1; | 122 | return; |
122 | } | 123 | } |
123 | } | 124 | } |
124 | 125 | ||
@@ -147,71 +148,18 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
147 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 148 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
148 | } | 149 | } |
149 | 150 | ||
150 | return 0; | 151 | return; |
151 | } | 152 | } |
152 | 153 | ||
153 | /* | 154 | /* |
154 | * Atomically swap in the new signal mask, and wait for a signal. | 155 | * Atomically swap in the new signal mask, and wait for a signal. |
155 | */ | 156 | */ |
156 | asmlinkage int | 157 | asmlinkage int |
157 | sys_sigsuspend(old_sigset_t mask, | 158 | sys_sigsuspend(old_sigset_t mask) |
158 | unsigned long r3, unsigned long r4, unsigned long r5, | ||
159 | unsigned long r6, unsigned long r7, | ||
160 | struct pt_regs * regs) | ||
161 | { | 159 | { |
162 | sigset_t saveset, blocked; | 160 | sigset_t blocked; |
163 | |||
164 | saveset = current->blocked; | ||
165 | |||
166 | mask &= _BLOCKABLE; | ||
167 | siginitset(&blocked, mask); | 161 | siginitset(&blocked, mask); |
168 | set_current_blocked(&blocked); | 162 | return sigsuspend(&blocked); |
169 | |||
170 | REF_REG_RET = -EINTR; | ||
171 | while (1) { | ||
172 | current->state = TASK_INTERRUPTIBLE; | ||
173 | schedule(); | ||
174 | set_restore_sigmask(); | ||
175 | regs->pc += 4; /* because sys_sigreturn decrements the pc */ | ||
176 | if (do_signal(regs, &saveset)) { | ||
177 | /* pc now points at signal handler. Need to decrement | ||
178 | it because entry.S will increment it. */ | ||
179 | regs->pc -= 4; | ||
180 | return -EINTR; | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | |||
185 | asmlinkage int | ||
186 | sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, | ||
187 | unsigned long r4, unsigned long r5, unsigned long r6, | ||
188 | unsigned long r7, | ||
189 | struct pt_regs * regs) | ||
190 | { | ||
191 | sigset_t saveset, newset; | ||
192 | |||
193 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
194 | if (sigsetsize != sizeof(sigset_t)) | ||
195 | return -EINVAL; | ||
196 | |||
197 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
198 | return -EFAULT; | ||
199 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
200 | saveset = current->blocked; | ||
201 | set_current_blocked(&newset); | ||
202 | |||
203 | REF_REG_RET = -EINTR; | ||
204 | while (1) { | ||
205 | current->state = TASK_INTERRUPTIBLE; | ||
206 | schedule(); | ||
207 | regs->pc += 4; /* because sys_sigreturn decrements the pc */ | ||
208 | if (do_signal(regs, &saveset)) { | ||
209 | /* pc now points at signal handler. Need to decrement | ||
210 | it because entry.S will increment it. */ | ||
211 | regs->pc -= 4; | ||
212 | return -EINTR; | ||
213 | } | ||
214 | } | ||
215 | } | 163 | } |
216 | 164 | ||
217 | asmlinkage int | 165 | asmlinkage int |
@@ -732,7 +680,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
732 | asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | 680 | asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) |
733 | { | 681 | { |
734 | if (thread_info_flags & _TIF_SIGPENDING) | 682 | if (thread_info_flags & _TIF_SIGPENDING) |
735 | do_signal(regs, 0); | 683 | do_signal(regs); |
736 | 684 | ||
737 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 685 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
738 | clear_thread_flag(TIF_NOTIFY_RESUME); | 686 | clear_thread_flag(TIF_NOTIFY_RESUME); |