aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
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/parisc
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/parisc')
-rw-r--r--arch/parisc/include/asm/thread_info.h2
-rw-r--r--arch/parisc/kernel/entry.S4
-rw-r--r--arch/parisc/kernel/signal.c47
-rw-r--r--arch/parisc/kernel/signal32.c2
4 files changed, 14 insertions, 41 deletions
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 83ae7dd4d99e..22b4726dee49 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -74,7 +74,7 @@ struct thread_info {
74#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP) 74#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)
75 75
76#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \ 76#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
77 _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) 77 _TIF_NEED_RESCHED)
78 78
79#endif /* __KERNEL__ */ 79#endif /* __KERNEL__ */
80 80
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index c7fbc96472f3..18670a078849 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -924,7 +924,7 @@ intr_check_sig:
924 /* As above */ 924 /* As above */
925 mfctl %cr30,%r1 925 mfctl %cr30,%r1
926 LDREG TI_FLAGS(%r1),%r19 926 LDREG TI_FLAGS(%r1),%r19
927 ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20 927 ldi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r20
928 and,COND(<>) %r19, %r20, %r0 928 and,COND(<>) %r19, %r20, %r0
929 b,n intr_restore /* skip past if we've nothing to do */ 929 b,n intr_restore /* skip past if we've nothing to do */
930 930
@@ -2032,7 +2032,7 @@ syscall_check_resched:
2032 .import do_signal,code 2032 .import do_signal,code
2033syscall_check_sig: 2033syscall_check_sig:
2034 LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 2034 LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
2035 ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r26 2035 ldi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r26
2036 and,COND(<>) %r19, %r26, %r0 2036 and,COND(<>) %r19, %r26, %r0
2037 b,n syscall_restore /* skip past if we've nothing to do */ 2037 b,n syscall_restore /* skip past if we've nothing to do */
2038 2038
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index e7a7cd3e1120..594459bde14e 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -48,9 +48,6 @@
48#define DBG(LEVEL, ...) 48#define DBG(LEVEL, ...)
49#endif 49#endif
50 50
51
52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
53
54/* gcc will complain if a pointer is cast to an integer of different 51/* gcc will complain if a pointer is cast to an integer of different
55 * size. If you really need to do this (and we do for an ELF32 user 52 * size. If you really need to do this (and we do for an ELF32 user
56 * application in an ELF64 kernel) then you have to do a cast to an 53 * application in an ELF64 kernel) then you have to do a cast to an
@@ -131,7 +128,6 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
131 goto give_sigsegv; 128 goto give_sigsegv;
132 } 129 }
133 130
134 sigdelsetmask(&set, ~_BLOCKABLE);
135 set_current_blocked(&set); 131 set_current_blocked(&set);
136 132
137 /* Good thing we saved the old gr[30], eh? */ 133 /* Good thing we saved the old gr[30], eh? */
@@ -443,8 +439,9 @@ give_sigsegv:
443 439
444static long 440static long
445handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 441handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
446 sigset_t *oldset, struct pt_regs *regs, int in_syscall) 442 struct pt_regs *regs, int in_syscall)
447{ 443{
444 sigset_t *oldset = sigmask_to_save();
448 DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n", 445 DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
449 sig, ka, info, oldset, regs); 446 sig, ka, info, oldset, regs);
450 447
@@ -452,12 +449,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
452 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) 449 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
453 return 0; 450 return 0;
454 451
455 block_sigmask(ka, sig); 452 signal_delivered(sig, info, ka, regs,
456
457 tracehook_signal_handler(sig, info, ka, regs,
458 test_thread_flag(TIF_SINGLESTEP) || 453 test_thread_flag(TIF_SINGLESTEP) ||
459 test_thread_flag(TIF_BLOCKSTEP)); 454 test_thread_flag(TIF_BLOCKSTEP));
460 455
456 DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
457 regs->gr[28]);
458
461 return 1; 459 return 1;
462} 460}
463 461
@@ -568,28 +566,17 @@ do_signal(struct pt_regs *regs, long in_syscall)
568 siginfo_t info; 566 siginfo_t info;
569 struct k_sigaction ka; 567 struct k_sigaction ka;
570 int signr; 568 int signr;
571 sigset_t *oldset;
572 569
573 DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n", 570 DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
574 oldset, regs, regs->sr[7], in_syscall); 571 regs, regs->sr[7], in_syscall);
575 572
576 /* Everyone else checks to see if they are in kernel mode at 573 /* Everyone else checks to see if they are in kernel mode at
577 this point and exits if that's the case. I'm not sure why 574 this point and exits if that's the case. I'm not sure why
578 we would be called in that case, but for some reason we 575 we would be called in that case, but for some reason we
579 are. */ 576 are. */
580 577
581 if (test_thread_flag(TIF_RESTORE_SIGMASK))
582 oldset = &current->saved_sigmask;
583 else
584 oldset = &current->blocked;
585
586 DBG(1,"do_signal: oldset %08lx / %08lx\n",
587 oldset->sig[0], oldset->sig[1]);
588
589
590 /* May need to force signal if handle_signal failed to deliver */ 578 /* May need to force signal if handle_signal failed to deliver */
591 while (1) { 579 while (1) {
592
593 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 580 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
594 DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 581 DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
595 582
@@ -603,14 +590,8 @@ do_signal(struct pt_regs *regs, long in_syscall)
603 /* Whee! Actually deliver the signal. If the 590 /* Whee! Actually deliver the signal. If the
604 delivery failed, we need to continue to iterate in 591 delivery failed, we need to continue to iterate in
605 this loop so we can deliver the SIGSEGV... */ 592 this loop so we can deliver the SIGSEGV... */
606 if (handle_signal(signr, &info, &ka, oldset, 593 if (handle_signal(signr, &info, &ka, regs, in_syscall))
607 regs, in_syscall)) {
608 DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
609 regs->gr[28]);
610 if (test_thread_flag(TIF_RESTORE_SIGMASK))
611 clear_thread_flag(TIF_RESTORE_SIGMASK);
612 return; 594 return;
613 }
614 } 595 }
615 /* end of while(1) looping forever if we can't force a signal */ 596 /* end of while(1) looping forever if we can't force a signal */
616 597
@@ -621,18 +602,12 @@ do_signal(struct pt_regs *regs, long in_syscall)
621 DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 602 DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n",
622 regs->gr[28]); 603 regs->gr[28]);
623 604
624 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 605 restore_saved_sigmask();
625 clear_thread_flag(TIF_RESTORE_SIGMASK);
626 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
627 }
628
629 return;
630} 606}
631 607
632void do_notify_resume(struct pt_regs *regs, long in_syscall) 608void do_notify_resume(struct pt_regs *regs, long in_syscall)
633{ 609{
634 if (test_thread_flag(TIF_SIGPENDING) || 610 if (test_thread_flag(TIF_SIGPENDING))
635 test_thread_flag(TIF_RESTORE_SIGMASK))
636 do_signal(regs, in_syscall); 611 do_signal(regs, in_syscall);
637 612
638 if (test_thread_flag(TIF_NOTIFY_RESUME)) { 613 if (test_thread_flag(TIF_NOTIFY_RESUME)) {
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index e14132430762..fd49aeda9eb8 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -47,8 +47,6 @@
47#define DBG(LEVEL, ...) 47#define DBG(LEVEL, ...)
48#endif 48#endif
49 49
50#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
51
52inline void 50inline void
53sigset_32to64(sigset_t *s64, compat_sigset_t *s32) 51sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
54{ 52{