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/mips | |
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/mips')
-rw-r--r-- | arch/mips/kernel/signal-common.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/signal.c | 38 | ||||
-rw-r--r-- | arch/mips/kernel/signal32.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/signal_n32.c | 1 |
4 files changed, 8 insertions, 35 deletions
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 10263b405981..9c60d09e62a7 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h | |||
@@ -19,8 +19,6 @@ | |||
19 | # define DEBUGP(fmt, args...) | 19 | # define DEBUGP(fmt, args...) |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
23 | |||
24 | /* | 22 | /* |
25 | * Determine which stack to use.. | 23 | * Determine which stack to use.. |
26 | */ | 24 | */ |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 8a6e6d116ab0..f2c09cfc60ac 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -339,7 +339,6 @@ asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
339 | if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) | 339 | if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) |
340 | goto badframe; | 340 | goto badframe; |
341 | 341 | ||
342 | sigdelsetmask(&blocked, ~_BLOCKABLE); | ||
343 | set_current_blocked(&blocked); | 342 | set_current_blocked(&blocked); |
344 | 343 | ||
345 | sig = restore_sigcontext(®s, &frame->sf_sc); | 344 | sig = restore_sigcontext(®s, &frame->sf_sc); |
@@ -375,7 +374,6 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
375 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) | 374 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) |
376 | goto badframe; | 375 | goto badframe; |
377 | 376 | ||
378 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
379 | set_current_blocked(&set); | 377 | set_current_blocked(&set); |
380 | 378 | ||
381 | sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); | 379 | sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); |
@@ -514,9 +512,10 @@ struct mips_abi mips_abi = { | |||
514 | .restart = __NR_restart_syscall | 512 | .restart = __NR_restart_syscall |
515 | }; | 513 | }; |
516 | 514 | ||
517 | static int handle_signal(unsigned long sig, siginfo_t *info, | 515 | static void handle_signal(unsigned long sig, siginfo_t *info, |
518 | struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) | 516 | struct k_sigaction *ka, struct pt_regs *regs) |
519 | { | 517 | { |
518 | sigset_t *oldset = sigmask_to_save(); | ||
520 | int ret; | 519 | int ret; |
521 | struct mips_abi *abi = current->thread.abi; | 520 | struct mips_abi *abi = current->thread.abi; |
522 | void *vdso = current->mm->context.vdso; | 521 | void *vdso = current->mm->context.vdso; |
@@ -550,17 +549,14 @@ static int handle_signal(unsigned long sig, siginfo_t *info, | |||
550 | ka, regs, sig, oldset); | 549 | ka, regs, sig, oldset); |
551 | 550 | ||
552 | if (ret) | 551 | if (ret) |
553 | return ret; | 552 | return; |
554 | |||
555 | block_sigmask(ka, sig); | ||
556 | 553 | ||
557 | return ret; | 554 | signal_delivered(sig, info, ka, regs, 0); |
558 | } | 555 | } |
559 | 556 | ||
560 | static void do_signal(struct pt_regs *regs) | 557 | static void do_signal(struct pt_regs *regs) |
561 | { | 558 | { |
562 | struct k_sigaction ka; | 559 | struct k_sigaction ka; |
563 | sigset_t *oldset; | ||
564 | siginfo_t info; | 560 | siginfo_t info; |
565 | int signr; | 561 | int signr; |
566 | 562 | ||
@@ -572,25 +568,10 @@ static void do_signal(struct pt_regs *regs) | |||
572 | if (!user_mode(regs)) | 568 | if (!user_mode(regs)) |
573 | return; | 569 | return; |
574 | 570 | ||
575 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
576 | oldset = ¤t->saved_sigmask; | ||
577 | else | ||
578 | oldset = ¤t->blocked; | ||
579 | |||
580 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 571 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
581 | if (signr > 0) { | 572 | if (signr > 0) { |
582 | /* Whee! Actually deliver the signal. */ | 573 | /* Whee! Actually deliver the signal. */ |
583 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 574 | handle_signal(signr, &info, &ka, regs); |
584 | /* | ||
585 | * A signal was successfully delivered; the saved | ||
586 | * sigmask will have been stored in the signal frame, | ||
587 | * and will be restored by sigreturn, so we can simply | ||
588 | * clear the TIF_RESTORE_SIGMASK flag. | ||
589 | */ | ||
590 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
591 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
592 | } | ||
593 | |||
594 | return; | 575 | return; |
595 | } | 576 | } |
596 | 577 | ||
@@ -614,10 +595,7 @@ static void do_signal(struct pt_regs *regs) | |||
614 | * If there's no signal to deliver, we just put the saved sigmask | 595 | * If there's no signal to deliver, we just put the saved sigmask |
615 | * back | 596 | * back |
616 | */ | 597 | */ |
617 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 598 | restore_saved_sigmask(); |
618 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
619 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
620 | } | ||
621 | } | 599 | } |
622 | 600 | ||
623 | /* | 601 | /* |
@@ -630,7 +608,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, | |||
630 | local_irq_enable(); | 608 | local_irq_enable(); |
631 | 609 | ||
632 | /* deal with pending signal delivery */ | 610 | /* deal with pending signal delivery */ |
633 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 611 | if (thread_info_flags & _TIF_SIGPENDING) |
634 | do_signal(regs); | 612 | do_signal(regs); |
635 | 613 | ||
636 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 614 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index b4fe2eacbd5d..da1b56a39ac7 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
@@ -465,7 +465,6 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
465 | if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask)) | 465 | if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask)) |
466 | goto badframe; | 466 | goto badframe; |
467 | 467 | ||
468 | sigdelsetmask(&blocked, ~_BLOCKABLE); | ||
469 | set_current_blocked(&blocked); | 468 | set_current_blocked(&blocked); |
470 | 469 | ||
471 | sig = restore_sigcontext32(®s, &frame->sf_sc); | 470 | sig = restore_sigcontext32(®s, &frame->sf_sc); |
@@ -503,7 +502,6 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
503 | if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) | 502 | if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) |
504 | goto badframe; | 503 | goto badframe; |
505 | 504 | ||
506 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
507 | set_current_blocked(&set); | 505 | set_current_blocked(&set); |
508 | 506 | ||
509 | sig = restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext); | 507 | sig = restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext); |
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 63ffac9af7c5..3574c145511b 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c | |||
@@ -109,7 +109,6 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
109 | if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) | 109 | if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) |
110 | goto badframe; | 110 | goto badframe; |
111 | 111 | ||
112 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
113 | set_current_blocked(&set); | 112 | set_current_blocked(&set); |
114 | 113 | ||
115 | sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); | 114 | sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); |