aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
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/sparc
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/sparc')
-rw-r--r--arch/sparc/include/asm/thread_info_32.h3
-rw-r--r--arch/sparc/include/asm/thread_info_64.h18
-rw-r--r--arch/sparc/kernel/signal32.c27
-rw-r--r--arch/sparc/kernel/signal_32.c39
-rw-r--r--arch/sparc/kernel/signal_64.c34
5 files changed, 37 insertions, 84 deletions
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index 5af664932452..e6cd224506a9 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -131,8 +131,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
131#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 131#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
132 132
133#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \ 133#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
134 _TIF_SIGPENDING | \ 134 _TIF_SIGPENDING)
135 _TIF_RESTORE_SIGMASK)
136 135
137#endif /* __KERNEL__ */ 136#endif /* __KERNEL__ */
138 137
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 7f0981b09451..cfa8c38fb9c8 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -238,7 +238,23 @@ static inline void set_restore_sigmask(void)
238{ 238{
239 struct thread_info *ti = current_thread_info(); 239 struct thread_info *ti = current_thread_info();
240 ti->status |= TS_RESTORE_SIGMASK; 240 ti->status |= TS_RESTORE_SIGMASK;
241 set_bit(TIF_SIGPENDING, &ti->flags); 241 WARN_ON(!test_bit(TIF_SIGPENDING, &ti->flags));
242}
243static inline void clear_restore_sigmask(void)
244{
245 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
246}
247static inline bool test_restore_sigmask(void)
248{
249 return current_thread_info()->status & TS_RESTORE_SIGMASK;
250}
251static inline bool test_and_clear_restore_sigmask(void)
252{
253 struct thread_info *ti = current_thread_info();
254 if (!(ti->status & TS_RESTORE_SIGMASK))
255 return false;
256 ti->status &= ~TS_RESTORE_SIGMASK;
257 return true;
242} 258}
243#endif /* !__ASSEMBLY__ */ 259#endif /* !__ASSEMBLY__ */
244 260
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index bb1513e45f1a..a53e0a5fd3a3 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -32,8 +32,6 @@
32 32
33#include "sigutil.h" 33#include "sigutil.h"
34 34
35#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
36
37/* This magic should be in g_upper[0] for all upper parts 35/* This magic should be in g_upper[0] for all upper parts
38 * to be valid. 36 * to be valid.
39 */ 37 */
@@ -274,7 +272,6 @@ void do_sigreturn32(struct pt_regs *regs)
274 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32); 272 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
275 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32); 273 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
276 } 274 }
277 sigdelsetmask(&set, ~_BLOCKABLE);
278 set_current_blocked(&set); 275 set_current_blocked(&set);
279 return; 276 return;
280 277
@@ -376,7 +373,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
376 case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32); 373 case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
377 case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); 374 case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
378 } 375 }
379 sigdelsetmask(&set, ~_BLOCKABLE);
380 set_current_blocked(&set); 376 set_current_blocked(&set);
381 return; 377 return;
382segv: 378segv:
@@ -775,7 +771,7 @@ sigsegv:
775 return -EFAULT; 771 return -EFAULT;
776} 772}
777 773
778static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, 774static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
779 siginfo_t *info, 775 siginfo_t *info,
780 sigset_t *oldset, struct pt_regs *regs) 776 sigset_t *oldset, struct pt_regs *regs)
781{ 777{
@@ -787,12 +783,9 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
787 err = setup_frame32(ka, regs, signr, oldset); 783 err = setup_frame32(ka, regs, signr, oldset);
788 784
789 if (err) 785 if (err)
790 return err; 786 return;
791
792 block_sigmask(ka, signr);
793 tracehook_signal_handler(signr, info, ka, regs, 0);
794 787
795 return 0; 788 signal_delivered(signr, info, ka, regs, 0);
796} 789}
797 790
798static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, 791static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -841,14 +834,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs)
841 if (signr > 0) { 834 if (signr > 0) {
842 if (restart_syscall) 835 if (restart_syscall)
843 syscall_restart32(orig_i0, regs, &ka.sa); 836 syscall_restart32(orig_i0, regs, &ka.sa);
844 if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { 837 handle_signal32(signr, &ka, &info, oldset, regs);
845 /* A signal was successfully delivered; the saved
846 * sigmask will have been stored in the signal frame,
847 * and will be restored by sigreturn, so we can simply
848 * clear the TS_RESTORE_SIGMASK flag.
849 */
850 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
851 }
852 return; 838 return;
853 } 839 }
854 if (restart_syscall && 840 if (restart_syscall &&
@@ -872,10 +858,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs)
872 /* If there's no signal to deliver, we just put the saved sigmask 858 /* If there's no signal to deliver, we just put the saved sigmask
873 * back 859 * back
874 */ 860 */
875 if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 861 restore_saved_sigmask();
876 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
877 set_current_blocked(&current->saved_sigmask);
878 }
879} 862}
880 863
881struct sigstack32 { 864struct sigstack32 {
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 6b42e8622d12..68f9c8650af4 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -29,8 +29,6 @@
29 29
30#include "sigutil.h" 30#include "sigutil.h"
31 31
32#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
33
34extern void fpsave(unsigned long *fpregs, unsigned long *fsr, 32extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
35 void *fpqueue, unsigned long *fpqdepth); 33 void *fpqueue, unsigned long *fpqdepth);
36extern void fpload(unsigned long *fpregs, unsigned long *fsr); 34extern void fpload(unsigned long *fpregs, unsigned long *fsr);
@@ -130,7 +128,6 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
130 if (err) 128 if (err)
131 goto segv_and_exit; 129 goto segv_and_exit;
132 130
133 sigdelsetmask(&set, ~_BLOCKABLE);
134 set_current_blocked(&set); 131 set_current_blocked(&set);
135 return; 132 return;
136 133
@@ -197,7 +194,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
197 goto segv; 194 goto segv;
198 } 195 }
199 196
200 sigdelsetmask(&set, ~_BLOCKABLE);
201 set_current_blocked(&set); 197 set_current_blocked(&set);
202 return; 198 return;
203segv: 199segv:
@@ -449,10 +445,11 @@ sigsegv:
449 return -EFAULT; 445 return -EFAULT;
450} 446}
451 447
452static inline int 448static inline void
453handle_signal(unsigned long signr, struct k_sigaction *ka, 449handle_signal(unsigned long signr, struct k_sigaction *ka,
454 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) 450 siginfo_t *info, struct pt_regs *regs)
455{ 451{
452 sigset_t *oldset = sigmask_to_save();
456 int err; 453 int err;
457 454
458 if (ka->sa.sa_flags & SA_SIGINFO) 455 if (ka->sa.sa_flags & SA_SIGINFO)
@@ -461,12 +458,9 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
461 err = setup_frame(ka, regs, signr, oldset); 458 err = setup_frame(ka, regs, signr, oldset);
462 459
463 if (err) 460 if (err)
464 return err; 461 return;
465
466 block_sigmask(ka, signr);
467 tracehook_signal_handler(signr, info, ka, regs, 0);
468 462
469 return 0; 463 signal_delivered(signr, info, ka, regs, 0);
470} 464}
471 465
472static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, 466static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -498,7 +492,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
498{ 492{
499 struct k_sigaction ka; 493 struct k_sigaction ka;
500 int restart_syscall; 494 int restart_syscall;
501 sigset_t *oldset;
502 siginfo_t info; 495 siginfo_t info;
503 int signr; 496 int signr;
504 497
@@ -523,11 +516,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
523 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) 516 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
524 regs->u_regs[UREG_G6] = orig_i0; 517 regs->u_regs[UREG_G6] = orig_i0;
525 518
526 if (test_thread_flag(TIF_RESTORE_SIGMASK))
527 oldset = &current->saved_sigmask;
528 else
529 oldset = &current->blocked;
530
531 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 519 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
532 520
533 /* If the debugger messes with the program counter, it clears 521 /* If the debugger messes with the program counter, it clears
@@ -544,15 +532,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
544 if (signr > 0) { 532 if (signr > 0) {
545 if (restart_syscall) 533 if (restart_syscall)
546 syscall_restart(orig_i0, regs, &ka.sa); 534 syscall_restart(orig_i0, regs, &ka.sa);
547 if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { 535 handle_signal(signr, &ka, &info, regs);
548 /* a signal was successfully delivered; the saved
549 * sigmask will have been stored in the signal frame,
550 * and will be restored by sigreturn, so we can simply
551 * clear the TIF_RESTORE_SIGMASK flag.
552 */
553 if (test_thread_flag(TIF_RESTORE_SIGMASK))
554 clear_thread_flag(TIF_RESTORE_SIGMASK);
555 }
556 return; 536 return;
557 } 537 }
558 if (restart_syscall && 538 if (restart_syscall &&
@@ -576,16 +556,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
576 /* if there's no signal to deliver, we just put the saved sigmask 556 /* if there's no signal to deliver, we just put the saved sigmask
577 * back 557 * back
578 */ 558 */
579 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 559 restore_saved_sigmask();
580 clear_thread_flag(TIF_RESTORE_SIGMASK);
581 set_current_blocked(&current->saved_sigmask);
582 }
583} 560}
584 561
585void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, 562void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
586 unsigned long thread_info_flags) 563 unsigned long thread_info_flags)
587{ 564{
588 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 565 if (thread_info_flags & _TIF_SIGPENDING)
589 do_signal(regs, orig_i0); 566 do_signal(regs, orig_i0);
590 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 567 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
591 clear_thread_flag(TIF_NOTIFY_RESUME); 568 clear_thread_flag(TIF_NOTIFY_RESUME);
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index c82cf1cc3965..867de2f8189c 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -38,8 +38,6 @@
38#include "systbls.h" 38#include "systbls.h"
39#include "sigutil.h" 39#include "sigutil.h"
40 40
41#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
42
43/* {set, get}context() needed for 64-bit SparcLinux userland. */ 41/* {set, get}context() needed for 64-bit SparcLinux userland. */
44asmlinkage void sparc64_set_context(struct pt_regs *regs) 42asmlinkage void sparc64_set_context(struct pt_regs *regs)
45{ 43{
@@ -71,7 +69,6 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
71 if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(sigset_t))) 69 if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(sigset_t)))
72 goto do_sigsegv; 70 goto do_sigsegv;
73 } 71 }
74 sigdelsetmask(&set, ~_BLOCKABLE);
75 set_current_blocked(&set); 72 set_current_blocked(&set);
76 } 73 }
77 if (test_thread_flag(TIF_32BIT)) { 74 if (test_thread_flag(TIF_32BIT)) {
@@ -315,7 +312,6 @@ void do_rt_sigreturn(struct pt_regs *regs)
315 /* Prevent syscall restart. */ 312 /* Prevent syscall restart. */
316 pt_regs_clear_syscall(regs); 313 pt_regs_clear_syscall(regs);
317 314
318 sigdelsetmask(&set, ~_BLOCKABLE);
319 set_current_blocked(&set); 315 set_current_blocked(&set);
320 return; 316 return;
321segv: 317segv:
@@ -466,7 +462,7 @@ sigsegv:
466 return -EFAULT; 462 return -EFAULT;
467} 463}
468 464
469static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, 465static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
470 siginfo_t *info, 466 siginfo_t *info,
471 sigset_t *oldset, struct pt_regs *regs) 467 sigset_t *oldset, struct pt_regs *regs)
472{ 468{
@@ -475,12 +471,9 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
475 err = setup_rt_frame(ka, regs, signr, oldset, 471 err = setup_rt_frame(ka, regs, signr, oldset,
476 (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); 472 (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
477 if (err) 473 if (err)
478 return err; 474 return;
479
480 block_sigmask(ka, signr);
481 tracehook_signal_handler(signr, info, ka, regs, 0);
482 475
483 return 0; 476 signal_delivered(signr, info, ka, regs, 0);
484} 477}
485 478
486static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, 479static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -512,7 +505,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
512{ 505{
513 struct k_sigaction ka; 506 struct k_sigaction ka;
514 int restart_syscall; 507 int restart_syscall;
515 sigset_t *oldset; 508 sigset_t *oldset = sigmask_to_save();
516 siginfo_t info; 509 siginfo_t info;
517 int signr; 510 int signr;
518 511
@@ -538,11 +531,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
538 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) 531 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
539 regs->u_regs[UREG_G6] = orig_i0; 532 regs->u_regs[UREG_G6] = orig_i0;
540 533
541 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
542 oldset = &current->saved_sigmask;
543 else
544 oldset = &current->blocked;
545
546#ifdef CONFIG_COMPAT 534#ifdef CONFIG_COMPAT
547 if (test_thread_flag(TIF_32BIT)) { 535 if (test_thread_flag(TIF_32BIT)) {
548 extern void do_signal32(sigset_t *, struct pt_regs *); 536 extern void do_signal32(sigset_t *, struct pt_regs *);
@@ -563,14 +551,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
563 if (signr > 0) { 551 if (signr > 0) {
564 if (restart_syscall) 552 if (restart_syscall)
565 syscall_restart(orig_i0, regs, &ka.sa); 553 syscall_restart(orig_i0, regs, &ka.sa);
566 if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { 554 handle_signal(signr, &ka, &info, oldset, regs);
567 /* A signal was successfully delivered; the saved
568 * sigmask will have been stored in the signal frame,
569 * and will be restored by sigreturn, so we can simply
570 * clear the TS_RESTORE_SIGMASK flag.
571 */
572 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
573 }
574 return; 555 return;
575 } 556 }
576 if (restart_syscall && 557 if (restart_syscall &&
@@ -594,10 +575,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
594 /* If there's no signal to deliver, we just put the saved sigmask 575 /* If there's no signal to deliver, we just put the saved sigmask
595 * back 576 * back
596 */ 577 */
597 if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 578 restore_saved_sigmask();
598 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
599 set_current_blocked(&current->saved_sigmask);
600 }
601} 579}
602 580
603void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) 581void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)