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/ia64 | |
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/ia64')
-rw-r--r-- | arch/ia64/include/asm/thread_info.h | 18 | ||||
-rw-r--r-- | arch/ia64/kernel/signal.c | 34 |
2 files changed, 22 insertions, 30 deletions
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index 310d9734f02d..f7ee85378311 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h | |||
@@ -141,7 +141,23 @@ static inline void set_restore_sigmask(void) | |||
141 | { | 141 | { |
142 | struct thread_info *ti = current_thread_info(); | 142 | struct thread_info *ti = current_thread_info(); |
143 | ti->status |= TS_RESTORE_SIGMASK; | 143 | ti->status |= TS_RESTORE_SIGMASK; |
144 | set_bit(TIF_SIGPENDING, &ti->flags); | 144 | WARN_ON(!test_bit(TIF_SIGPENDING, &ti->flags)); |
145 | } | ||
146 | static inline void clear_restore_sigmask(void) | ||
147 | { | ||
148 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | ||
149 | } | ||
150 | static inline bool test_restore_sigmask(void) | ||
151 | { | ||
152 | return current_thread_info()->status & TS_RESTORE_SIGMASK; | ||
153 | } | ||
154 | static inline bool test_and_clear_restore_sigmask(void) | ||
155 | { | ||
156 | struct thread_info *ti = current_thread_info(); | ||
157 | if (!(ti->status & TS_RESTORE_SIGMASK)) | ||
158 | return false; | ||
159 | ti->status &= ~TS_RESTORE_SIGMASK; | ||
160 | return true; | ||
145 | } | 161 | } |
146 | #endif /* !__ASSEMBLY__ */ | 162 | #endif /* !__ASSEMBLY__ */ |
147 | 163 | ||
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 7523501d3bc0..a199be1fe619 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -30,7 +30,6 @@ | |||
30 | 30 | ||
31 | #define DEBUG_SIG 0 | 31 | #define DEBUG_SIG 0 |
32 | #define STACK_ALIGN 16 /* minimal alignment for stack pointer */ | 32 | #define STACK_ALIGN 16 /* minimal alignment for stack pointer */ |
33 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
34 | 33 | ||
35 | #if _NSIG_WORDS > 1 | 34 | #if _NSIG_WORDS > 1 |
36 | # define PUT_SIGSET(k,u) __copy_to_user((u)->sig, (k)->sig, sizeof(sigset_t)) | 35 | # define PUT_SIGSET(k,u) __copy_to_user((u)->sig, (k)->sig, sizeof(sigset_t)) |
@@ -200,7 +199,6 @@ ia64_rt_sigreturn (struct sigscratch *scr) | |||
200 | if (GET_SIGSET(&set, &sc->sc_mask)) | 199 | if (GET_SIGSET(&set, &sc->sc_mask)) |
201 | goto give_sigsegv; | 200 | goto give_sigsegv; |
202 | 201 | ||
203 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
204 | set_current_blocked(&set); | 202 | set_current_blocked(&set); |
205 | 203 | ||
206 | if (restore_sigcontext(sc, scr)) | 204 | if (restore_sigcontext(sc, scr)) |
@@ -415,18 +413,13 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, | |||
415 | } | 413 | } |
416 | 414 | ||
417 | static long | 415 | static long |
418 | handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, | 416 | handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, |
419 | struct sigscratch *scr) | 417 | struct sigscratch *scr) |
420 | { | 418 | { |
421 | if (!setup_frame(sig, ka, info, oldset, scr)) | 419 | if (!setup_frame(sig, ka, info, sigmask_to_save(), scr)) |
422 | return 0; | 420 | return 0; |
423 | 421 | ||
424 | block_sigmask(ka, sig); | 422 | signal_delivered(sig, info, ka, &scr->pt, |
425 | |||
426 | /* | ||
427 | * Let tracing know that we've done the handler setup. | ||
428 | */ | ||
429 | tracehook_signal_handler(sig, info, ka, &scr->pt, | ||
430 | test_thread_flag(TIF_SINGLESTEP)); | 423 | test_thread_flag(TIF_SINGLESTEP)); |
431 | 424 | ||
432 | return 1; | 425 | return 1; |
@@ -440,7 +433,6 @@ void | |||
440 | ia64_do_signal (struct sigscratch *scr, long in_syscall) | 433 | ia64_do_signal (struct sigscratch *scr, long in_syscall) |
441 | { | 434 | { |
442 | struct k_sigaction ka; | 435 | struct k_sigaction ka; |
443 | sigset_t *oldset; | ||
444 | siginfo_t info; | 436 | siginfo_t info; |
445 | long restart = in_syscall; | 437 | long restart = in_syscall; |
446 | long errno = scr->pt.r8; | 438 | long errno = scr->pt.r8; |
@@ -453,11 +445,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) | |||
453 | if (!user_mode(&scr->pt)) | 445 | if (!user_mode(&scr->pt)) |
454 | return; | 446 | return; |
455 | 447 | ||
456 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) | ||
457 | oldset = ¤t->saved_sigmask; | ||
458 | else | ||
459 | oldset = ¤t->blocked; | ||
460 | |||
461 | /* | 448 | /* |
462 | * This only loops in the rare cases of handle_signal() failing, in which case we | 449 | * This only loops in the rare cases of handle_signal() failing, in which case we |
463 | * need to push through a forced SIGSEGV. | 450 | * need to push through a forced SIGSEGV. |
@@ -507,16 +494,8 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) | |||
507 | * Whee! Actually deliver the signal. If the delivery failed, we need to | 494 | * Whee! Actually deliver the signal. If the delivery failed, we need to |
508 | * continue to iterate in this loop so we can deliver the SIGSEGV... | 495 | * continue to iterate in this loop so we can deliver the SIGSEGV... |
509 | */ | 496 | */ |
510 | if (handle_signal(signr, &ka, &info, oldset, scr)) { | 497 | if (handle_signal(signr, &ka, &info, scr)) |
511 | /* | ||
512 | * A signal was successfully delivered; the saved | ||
513 | * sigmask will have been stored in the signal frame, | ||
514 | * and will be restored by sigreturn, so we can simply | ||
515 | * clear the TS_RESTORE_SIGMASK flag. | ||
516 | */ | ||
517 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | ||
518 | return; | 498 | return; |
519 | } | ||
520 | } | 499 | } |
521 | 500 | ||
522 | /* Did we come from a system call? */ | 501 | /* Did we come from a system call? */ |
@@ -538,8 +517,5 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) | |||
538 | 517 | ||
539 | /* if there's no signal to deliver, we just put the saved sigmask | 518 | /* if there's no signal to deliver, we just put the saved sigmask |
540 | * back */ | 519 | * back */ |
541 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { | 520 | restore_saved_sigmask(); |
542 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | ||
543 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
544 | } | ||
545 | } | 521 | } |