aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 14:53:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 14:53:44 -0400
commit86c47b70f62a7072d441ba212aab33c2f82627c2 (patch)
treed03988bd2226966352bb7f3c2e82ff545353d2c4 /arch/tile/kernel
parent1193755ac6328ad240ba987e6ec41d5e8baf0680 (diff)
parent44fbbb3dc687c9709a6f2236197316e5c79ab1eb (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull third pile of signal handling patches from Al Viro: "This time it's mostly helpers and conversions to them; there's a lot of stuff remaining in the tree, but that'll either go in -rc2 (isolated bug fixes, ideally via arch maintainers' trees) or will sit there until the next cycle." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: x86: get rid of calling do_notify_resume() when returning to kernel mode blackfin: check __get_user() return value whack-a-mole with TIF_FREEZE FRV: Optimise the system call exit path in entry.S [ver #2] FRV: Shrink TIF_WORK_MASK [ver #2] FRV: Prevent syscall exit tracing and notify_resume at end of kernel exceptions new helper: signal_delivered() powerpc: get rid of restore_sigmask() most of set_current_blocked() callers want SIGKILL/SIGSTOP removed from set set_restore_sigmask() is never called without SIGPENDING (and never should be) TIF_RESTORE_SIGMASK can be set only when TIF_SIGPENDING is set don't call try_to_freeze() from do_signal() pull clearing RESTORE_SIGMASK into block_sigmask() sh64: failure to build sigframe != signal without handler openrisc: tracehook_signal_handler() is supposed to be called on success new helper: sigmask_to_save() new helper: restore_saved_sigmask() new helpers: {clear,test,test_and_clear}_restore_sigmask() HAVE_RESTORE_SIGMASK is defined on all architectures now
Diffstat (limited to 'arch/tile/kernel')
-rw-r--r--arch/tile/kernel/compat_signal.c3
-rw-r--r--arch/tile/kernel/signal.c42
2 files changed, 8 insertions, 37 deletions
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index cdef6e5ec022..474571b84085 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -118,8 +118,6 @@ struct compat_rt_sigframe {
118 struct compat_ucontext uc; 118 struct compat_ucontext uc;
119}; 119};
120 120
121#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
122
123long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, 121long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
124 struct compat_sigaction __user *oact, 122 struct compat_sigaction __user *oact,
125 size_t sigsetsize) 123 size_t sigsetsize)
@@ -302,7 +300,6 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
302 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 300 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
303 goto badframe; 301 goto badframe;
304 302
305 sigdelsetmask(&set, ~_BLOCKABLE);
306 set_current_blocked(&set); 303 set_current_blocked(&set);
307 304
308 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 305 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index f79d4b88c747..e29b0553211d 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -37,8 +37,6 @@
37 37
38#define DEBUG_SIG 0 38#define DEBUG_SIG 0
39 39
40#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
41
42SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, 40SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
43 stack_t __user *, uoss, struct pt_regs *, regs) 41 stack_t __user *, uoss, struct pt_regs *, regs)
44{ 42{
@@ -96,7 +94,6 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
96 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 94 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
97 goto badframe; 95 goto badframe;
98 96
99 sigdelsetmask(&set, ~_BLOCKABLE);
100 set_current_blocked(&set); 97 set_current_blocked(&set);
101 98
102 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 99 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
@@ -242,10 +239,11 @@ give_sigsegv:
242 * OK, we're invoking a handler 239 * OK, we're invoking a handler
243 */ 240 */
244 241
245static int handle_signal(unsigned long sig, siginfo_t *info, 242static void handle_signal(unsigned long sig, siginfo_t *info,
246 struct k_sigaction *ka, sigset_t *oldset, 243 struct k_sigaction *ka,
247 struct pt_regs *regs) 244 struct pt_regs *regs)
248{ 245{
246 sigset_t *oldset = sigmask_to_save();
249 int ret; 247 int ret;
250 248
251 /* Are we from a system call? */ 249 /* Are we from a system call? */
@@ -278,15 +276,9 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
278 else 276 else
279#endif 277#endif
280 ret = setup_rt_frame(sig, ka, info, oldset, regs); 278 ret = setup_rt_frame(sig, ka, info, oldset, regs);
281 if (ret == 0) { 279 if (ret)
282 /* This code is only called from system calls or from 280 return;
283 * the work_pending path in the return-to-user code, and 281 signal_delivered(sig, info, ka, regs, 0);
284 * either way we can re-enable interrupts unconditionally.
285 */
286 block_sigmask(ka, sig);
287 }
288
289 return ret;
290} 282}
291 283
292/* 284/*
@@ -299,7 +291,6 @@ void do_signal(struct pt_regs *regs)
299 siginfo_t info; 291 siginfo_t info;
300 int signr; 292 int signr;
301 struct k_sigaction ka; 293 struct k_sigaction ka;
302 sigset_t *oldset;
303 294
304 /* 295 /*
305 * i386 will check if we're coming from kernel mode and bail out 296 * i386 will check if we're coming from kernel mode and bail out
@@ -308,24 +299,10 @@ void do_signal(struct pt_regs *regs)
308 * helpful, we can reinstate the check on "!user_mode(regs)". 299 * helpful, we can reinstate the check on "!user_mode(regs)".
309 */ 300 */
310 301
311 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
312 oldset = &current->saved_sigmask;
313 else
314 oldset = &current->blocked;
315
316 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 302 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
317 if (signr > 0) { 303 if (signr > 0) {
318 /* Whee! Actually deliver the signal. */ 304 /* Whee! Actually deliver the signal. */
319 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 305 handle_signal(signr, &info, &ka, regs);
320 /*
321 * A signal was successfully delivered; the saved
322 * sigmask will have been stored in the signal frame,
323 * and will be restored by sigreturn, so we can simply
324 * clear the TS_RESTORE_SIGMASK flag.
325 */
326 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
327 }
328
329 goto done; 306 goto done;
330 } 307 }
331 308
@@ -350,10 +327,7 @@ void do_signal(struct pt_regs *regs)
350 } 327 }
351 328
352 /* If there's no signal to deliver, just put the saved sigmask back. */ 329 /* If there's no signal to deliver, just put the saved sigmask back. */
353 if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 330 restore_saved_sigmask();
354 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
355 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
356 }
357 331
358done: 332done:
359 /* Avoid double syscall restart if there are nested signals. */ 333 /* Avoid double syscall restart if there are nested signals. */