From 51a7b448d4134e3e8eec633435e3e8faee14a828 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 21 May 2012 23:33:55 -0400 Subject: new helper: restore_saved_sigmask() first fruits of ..._restore_sigmask() helpers: now we can take boilerplate "signal didn't have a handler, clear RESTORE_SIGMASK and restore the blocked mask from ->saved_mask" into a common helper. Open-coded instances switched... Signed-off-by: Al Viro --- arch/blackfin/kernel/signal.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index fc9ecce..9d692a1 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -319,10 +319,7 @@ asmlinkage void do_signal(struct pt_regs *regs) /* if there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } + restore_saved_sigmask(); } /* -- cgit v1.1 From b7f9a11a6cf1ea9ee6be3eb2b90d91327a09ad14 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 May 2012 09:59:21 -0400 Subject: new helper: sigmask_to_save() replace boilerplate "should we use ->saved_sigmask or ->blocked?" with calls of obvious inlined helper... Signed-off-by: Al Viro --- arch/blackfin/kernel/signal.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index 9d692a1..7f4205d 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -249,7 +249,7 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) */ static int handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, - sigset_t *oldset, struct pt_regs *regs) + struct pt_regs *regs) { int ret; @@ -259,7 +259,7 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, handle_restart(regs, ka, 1); /* set up the stack frame */ - ret = setup_rt_frame(sig, ka, info, oldset, regs); + ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); if (ret == 0) block_sigmask(ka, sig); @@ -281,22 +281,16 @@ asmlinkage void do_signal(struct pt_regs *regs) siginfo_t info; int signr; struct k_sigaction ka; - sigset_t *oldset; current->thread.esp0 = (unsigned long)regs; if (try_to_freeze()) goto no_signal; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { + if (handle_signal(signr, &info, &ka, regs) == 0) { /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply -- cgit v1.1 From a610d6e672d6d3723e8da257ad4a8a288a8f2f89 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 21 May 2012 23:42:15 -0400 Subject: pull clearing RESTORE_SIGMASK into block_sigmask() Signed-off-by: Al Viro --- arch/blackfin/kernel/signal.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index 7f4205d..b25cbfe 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -247,7 +247,7 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) /* * OK, we're invoking a handler */ -static int +static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs) { @@ -260,11 +260,12 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, /* set up the stack frame */ ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); + if (ret) + return; - if (ret == 0) - block_sigmask(ka, sig); - - return ret; + block_sigmask(ka, sig); + tracehook_signal_handler(sig, info, ka, regs, + test_thread_flag(TIF_SINGLESTEP)); } /* @@ -290,18 +291,7 @@ asmlinkage void do_signal(struct pt_regs *regs) signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - - tracehook_signal_handler(signr, &info, &ka, regs, - test_thread_flag(TIF_SINGLESTEP)); - } - + handle_signal(signr, &info, &ka, regs); return; } -- cgit v1.1 From bf343dfd877ebf16cfbc31ba121606c5b6cef01f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 27 Apr 2012 01:18:52 -0400 Subject: don't call try_to_freeze() from do_signal() get_signal_to_deliver() will handle it itself Signed-off-by: Al Viro --- arch/blackfin/kernel/signal.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index b25cbfe..93d1ecd 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -285,9 +285,6 @@ asmlinkage void do_signal(struct pt_regs *regs) current->thread.esp0 = (unsigned long)regs; - if (try_to_freeze()) - goto no_signal; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ @@ -295,7 +292,6 @@ asmlinkage void do_signal(struct pt_regs *regs) return; } - no_signal: /* Did we come from a system call? */ if (regs->orig_p0 >= 0) /* Restart the system call - no handlers present */ -- cgit v1.1 From 6fd84c0831ec78d98736b76dc5e9b849f1dbfc9e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 23 May 2012 15:28:58 -0400 Subject: TIF_RESTORE_SIGMASK can be set only when TIF_SIGPENDING is set Signed-off-by: Al Viro --- arch/blackfin/kernel/signal.c | 2 +- arch/blackfin/mach-common/entry.S | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index 93d1ecd..b20d435 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -307,7 +307,7 @@ asmlinkage void do_signal(struct pt_regs *regs) */ asmlinkage void do_notify_resume(struct pt_regs *regs) { - if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_RESTORE_SIGMASK)) + if (test_thread_flag(TIF_SIGPENDING)) do_signal(regs); if (test_thread_flag(TIF_NOTIFY_RESUME)) { diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 80aa253..04c2fbe 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -711,8 +711,6 @@ ENTRY(_system_call) jump .Lresume_userspace_1; .Lsyscall_sigpending: - cc = BITTST(r7, TIF_RESTORE_SIGMASK); - if cc jump .Lsyscall_do_signals; cc = BITTST(r7, TIF_SIGPENDING); if cc jump .Lsyscall_do_signals; cc = BITTST(r7, TIF_NOTIFY_RESUME); -- cgit v1.1 From 77097ae503b170120ab66dd1d547f8577193f91f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 27 Apr 2012 13:58:59 -0400 Subject: most of set_current_blocked() callers want SIGKILL/SIGSTOP removed from set Only 3 out of 63 do not. Renamed the current variant to __set_current_blocked(), added set_current_blocked() that will exclude unblockable signals, switched open-coded instances to it. Signed-off-by: Al Viro --- arch/blackfin/kernel/signal.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index b20d435..4636126 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -19,8 +19,6 @@ #include #include -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* Location of the trace bit in SYSCFG. */ #define TRACE_BITS 0x0001 @@ -98,7 +96,6 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused) if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) -- cgit v1.1 From efee984c27b67e3ebef40410f35671997441b57c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 28 Apr 2012 02:04:15 -0400 Subject: new helper: signal_delivered() Does block_sigmask() + tracehook_signal_handler(); called when sigframe has been successfully built. All architectures converted to it; block_sigmask() itself is gone now (merged into this one). I'm still not too happy with the signature, but that's a separate story (IMO we need a structure that would contain signal number + siginfo + k_sigaction, so that get_signal_to_deliver() would fill one, signal_delivered(), handle_signal() and probably setup...frame() - take one). Signed-off-by: Al Viro --- arch/blackfin/kernel/signal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index 4636126..35459e6 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -260,8 +260,7 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, if (ret) return; - block_sigmask(ka, sig); - tracehook_signal_handler(sig, info, ka, regs, + signal_delivered(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); } -- cgit v1.1 From 35d51807577d4ab10f321ef22e4dcea30bee1caa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 1 Jun 2012 13:00:49 -0400 Subject: whack-a-mole with TIF_FREEZE blackfin has reintroduced it, completely unused. Signed-off-by: Al Viro --- arch/blackfin/include/asm/thread_info.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h index 02560fd8..53ad100 100644 --- a/arch/blackfin/include/asm/thread_info.h +++ b/arch/blackfin/include/asm/thread_info.h @@ -100,7 +100,6 @@ static inline struct thread_info *current_thread_info(void) TIF_NEED_RESCHED */ #define TIF_MEMDIE 4 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ -#define TIF_FREEZE 6 /* is freezing for suspend */ #define TIF_IRQ_SYNC 7 /* sync pipeline stage */ #define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ #define TIF_SINGLESTEP 9 @@ -111,7 +110,6 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_NEED_RESCHED (1< Date: Wed, 2 May 2012 21:14:30 -0400 Subject: blackfin: check __get_user() return value Signed-off-by: Al Viro --- arch/blackfin/kernel/signal.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'arch/blackfin') diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index 35459e6..6682b73 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -187,17 +187,22 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); if (err) - goto give_sigsegv; + return -EFAULT; /* Set up registers for signal handler */ - wrusp((unsigned long)frame); if (current->personality & FDPIC_FUNCPTRS) { struct fdpic_func_descriptor __user *funcptr = (struct fdpic_func_descriptor *) ka->sa.sa_handler; - __get_user(regs->pc, &funcptr->text); - __get_user(regs->p3, &funcptr->GOT); + u32 pc, p3; + err |= __get_user(pc, &funcptr->text); + err |= __get_user(p3, &funcptr->GOT); + if (err) + return -EFAULT; + regs->pc = pc; + regs->p3 = p3; } else regs->pc = (unsigned long)ka->sa.sa_handler; + wrusp((unsigned long)frame); regs->rets = SIGRETURN_STUB; regs->r0 = frame->sig; @@ -205,10 +210,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, regs->r2 = (unsigned long)(&frame->uc); return 0; - - give_sigsegv: - force_sigsegv(sig, current); - return -EFAULT; } static inline void @@ -248,20 +249,17 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs) { - int ret; - /* are we from a system call? to see pt_regs->orig_p0 */ if (regs->orig_p0 >= 0) /* If so, check system call restarting.. */ handle_restart(regs, ka, 1); /* set up the stack frame */ - ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); - if (ret) - return; - - signal_delivered(sig, info, ka, regs, - test_thread_flag(TIF_SINGLESTEP)); + if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) + force_sigsegv(sig, current); + else + signal_delivered(sig, info, ka, regs, + test_thread_flag(TIF_SINGLESTEP)); } /* -- cgit v1.1