diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 14:53:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 14:53:44 -0400 |
commit | 86c47b70f62a7072d441ba212aab33c2f82627c2 (patch) | |
tree | d03988bd2226966352bb7f3c2e82ff545353d2c4 /arch/tile/kernel | |
parent | 1193755ac6328ad240ba987e6ec41d5e8baf0680 (diff) | |
parent | 44fbbb3dc687c9709a6f2236197316e5c79ab1eb (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.c | 3 | ||||
-rw-r--r-- | arch/tile/kernel/signal.c | 42 |
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 | |||
123 | long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, | 121 | long 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 | |||
42 | SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, | 40 | SYSCALL_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 | ||
245 | static int handle_signal(unsigned long sig, siginfo_t *info, | 242 | static 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 = ¤t->saved_sigmask; | ||
313 | else | ||
314 | oldset = ¤t->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, ¤t->saved_sigmask, NULL); | ||
356 | } | ||
357 | 331 | ||
358 | done: | 332 | done: |
359 | /* Avoid double syscall restart if there are nested signals. */ | 333 | /* Avoid double syscall restart if there are nested signals. */ |