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/mn10300 | |
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/mn10300')
-rw-r--r-- | arch/mn10300/kernel/signal.c | 39 |
1 files changed, 9 insertions, 30 deletions
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index b8b6aa1a6837..6ab0bee2a54f 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c | |||
@@ -31,8 +31,6 @@ | |||
31 | 31 | ||
32 | #define DEBUG_SIG 0 | 32 | #define DEBUG_SIG 0 |
33 | 33 | ||
34 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
35 | |||
36 | /* | 34 | /* |
37 | * atomically swap in the new signal mask, and wait for a signal. | 35 | * atomically swap in the new signal mask, and wait for a signal. |
38 | */ | 36 | */ |
@@ -163,7 +161,6 @@ asmlinkage long sys_sigreturn(void) | |||
163 | sizeof(frame->extramask))) | 161 | sizeof(frame->extramask))) |
164 | goto badframe; | 162 | goto badframe; |
165 | 163 | ||
166 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
167 | set_current_blocked(&set); | 164 | set_current_blocked(&set); |
168 | 165 | ||
169 | if (restore_sigcontext(current_frame(), &frame->sc, &d0)) | 166 | if (restore_sigcontext(current_frame(), &frame->sc, &d0)) |
@@ -191,7 +188,6 @@ asmlinkage long sys_rt_sigreturn(void) | |||
191 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 188 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
192 | goto badframe; | 189 | goto badframe; |
193 | 190 | ||
194 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
195 | set_current_blocked(&set); | 191 | set_current_blocked(&set); |
196 | 192 | ||
197 | if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0)) | 193 | if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0)) |
@@ -430,8 +426,9 @@ static inline void stepback(struct pt_regs *regs) | |||
430 | */ | 426 | */ |
431 | static int handle_signal(int sig, | 427 | static int handle_signal(int sig, |
432 | siginfo_t *info, struct k_sigaction *ka, | 428 | siginfo_t *info, struct k_sigaction *ka, |
433 | sigset_t *oldset, struct pt_regs *regs) | 429 | struct pt_regs *regs) |
434 | { | 430 | { |
431 | sigset_t *oldset = sigmask_to_save(); | ||
435 | int ret; | 432 | int ret; |
436 | 433 | ||
437 | /* Are we from a system call? */ | 434 | /* Are we from a system call? */ |
@@ -461,11 +458,11 @@ static int handle_signal(int sig, | |||
461 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 458 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
462 | else | 459 | else |
463 | ret = setup_frame(sig, ka, oldset, regs); | 460 | ret = setup_frame(sig, ka, oldset, regs); |
461 | if (ret) | ||
462 | return; | ||
464 | 463 | ||
465 | if (ret == 0) | 464 | signal_delivered(sig, info, ka, regs, |
466 | block_sigmask(ka, sig); | 465 | test_thread_flag(TIF_SINGLESTEP)); |
467 | |||
468 | return ret; | ||
469 | } | 466 | } |
470 | 467 | ||
471 | /* | 468 | /* |
@@ -475,7 +472,6 @@ static void do_signal(struct pt_regs *regs) | |||
475 | { | 472 | { |
476 | struct k_sigaction ka; | 473 | struct k_sigaction ka; |
477 | siginfo_t info; | 474 | siginfo_t info; |
478 | sigset_t *oldset; | ||
479 | int signr; | 475 | int signr; |
480 | 476 | ||
481 | /* we want the common case to go fast, which is why we may in certain | 477 | /* we want the common case to go fast, which is why we may in certain |
@@ -483,23 +479,9 @@ static void do_signal(struct pt_regs *regs) | |||
483 | if (!user_mode(regs)) | 479 | if (!user_mode(regs)) |
484 | return; | 480 | return; |
485 | 481 | ||
486 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
487 | oldset = ¤t->saved_sigmask; | ||
488 | else | ||
489 | oldset = ¤t->blocked; | ||
490 | |||
491 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 482 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
492 | if (signr > 0) { | 483 | if (signr > 0) { |
493 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 484 | if (handle_signal(signr, &info, &ka, regs) == 0) { |
494 | /* a signal was successfully delivered; the saved | ||
495 | * sigmask will have been stored in the signal frame, | ||
496 | * and will be restored by sigreturn, so we can simply | ||
497 | * clear the TIF_RESTORE_SIGMASK flag */ | ||
498 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
499 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
500 | |||
501 | tracehook_signal_handler(signr, &info, &ka, regs, | ||
502 | test_thread_flag(TIF_SINGLESTEP)); | ||
503 | } | 485 | } |
504 | 486 | ||
505 | return; | 487 | return; |
@@ -525,10 +507,7 @@ static void do_signal(struct pt_regs *regs) | |||
525 | 507 | ||
526 | /* if there's no signal to deliver, we just put the saved sigmask | 508 | /* if there's no signal to deliver, we just put the saved sigmask |
527 | * back */ | 509 | * back */ |
528 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 510 | restore_saved_sigmask(); |
529 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
530 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
531 | } | ||
532 | } | 511 | } |
533 | 512 | ||
534 | /* | 513 | /* |
@@ -548,7 +527,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) | |||
548 | } | 527 | } |
549 | 528 | ||
550 | /* deal with pending signal delivery */ | 529 | /* deal with pending signal delivery */ |
551 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 530 | if (thread_info_flags & _TIF_SIGPENDING) |
552 | do_signal(regs); | 531 | do_signal(regs); |
553 | 532 | ||
554 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 533 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |