aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-03-28 18:16:32 -0400
committerPaul Mundt <lethal@linux-sh.org>2012-03-28 20:11:26 -0400
commit5e047fa159cf40733c627002d0443fddff3183c7 (patch)
tree0e2044faec870879572a2df0cdf67456f23eb7aa /arch/sh
parent8368b0e0ca5f38f605066fa0c9ea33bbc191e267 (diff)
sh: use set_current_blocked() and block_sigmask()
As described in e6fa16ab ("signal: sigprocmask() should do retarget_shared_pending()") the modification of current->blocked is incorrect as we need to check whether the signal we're about to block is pending in the shared queue. Also, use the new helper function introduced in commit 5e6292c0f28f ("signal: add block_sigmask() for adding sigmask to current->blocked") which centralises the code for updating current->blocked after successfully delivering a signal and reduces the amount of duplicate code across architectures. In the past some architectures got this code wrong, so using this helper function should stop that from happening again. Acked-by: Oleg Nesterov <oleg@redhat.com> Cc: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Matt Fleming <matt.fleming@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/kernel/signal_32.c32
-rw-r--r--arch/sh/kernel/signal_64.c37
2 files changed, 20 insertions, 49 deletions
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 1055146a20eb..883d711bb4bb 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -58,12 +58,13 @@ sys_sigsuspend(old_sigset_t mask,
58 unsigned long r5, unsigned long r6, unsigned long r7, 58 unsigned long r5, unsigned long r6, unsigned long r7,
59 struct pt_regs __regs) 59 struct pt_regs __regs)
60{ 60{
61 mask &= _BLOCKABLE; 61 sigset_t blocked;
62 spin_lock_irq(&current->sighand->siglock); 62
63 current->saved_sigmask = current->blocked; 63 current->saved_sigmask = current->blocked;
64 siginitset(&current->blocked, mask); 64
65 recalc_sigpending(); 65 mask &= _BLOCKABLE;
66 spin_unlock_irq(&current->sighand->siglock); 66 siginitset(&blocked, mask);
67 set_current_blocked(&blocked);
67 68
68 current->state = TASK_INTERRUPTIBLE; 69 current->state = TASK_INTERRUPTIBLE;
69 schedule(); 70 schedule();
@@ -240,11 +241,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
240 goto badframe; 241 goto badframe;
241 242
242 sigdelsetmask(&set, ~_BLOCKABLE); 243 sigdelsetmask(&set, ~_BLOCKABLE);
243 244 set_current_blocked(&set);
244 spin_lock_irq(&current->sighand->siglock);
245 current->blocked = set;
246 recalc_sigpending();
247 spin_unlock_irq(&current->sighand->siglock);
248 245
249 if (restore_sigcontext(regs, &frame->sc, &r0)) 246 if (restore_sigcontext(regs, &frame->sc, &r0))
250 goto badframe; 247 goto badframe;
@@ -274,10 +271,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
274 goto badframe; 271 goto badframe;
275 272
276 sigdelsetmask(&set, ~_BLOCKABLE); 273 sigdelsetmask(&set, ~_BLOCKABLE);
277 spin_lock_irq(&current->sighand->siglock); 274 set_current_blocked(&set);
278 current->blocked = set;
279 recalc_sigpending();
280 spin_unlock_irq(&current->sighand->siglock);
281 275
282 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) 276 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
283 goto badframe; 277 goto badframe;
@@ -548,14 +542,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
548 else 542 else
549 ret = setup_frame(sig, ka, oldset, regs); 543 ret = setup_frame(sig, ka, oldset, regs);
550 544
551 if (ret == 0) { 545 if (ret == 0)
552 spin_lock_irq(&current->sighand->siglock); 546 block_sigmask(ka, sig);
553 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
554 if (!(ka->sa.sa_flags & SA_NODEFER))
555 sigaddset(&current->blocked,sig);
556 recalc_sigpending();
557 spin_unlock_irq(&current->sighand->siglock);
558 }
559 547
560 return ret; 548 return ret;
561} 549}
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 7b9278d29102..3c9a6f7dcdce 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -159,14 +159,13 @@ sys_sigsuspend(old_sigset_t mask,
159 unsigned long r6, unsigned long r7, 159 unsigned long r6, unsigned long r7,
160 struct pt_regs * regs) 160 struct pt_regs * regs)
161{ 161{
162 sigset_t saveset; 162 sigset_t saveset, blocked;
163 163
164 mask &= _BLOCKABLE;
165 spin_lock_irq(&current->sighand->siglock);
166 saveset = current->blocked; 164 saveset = current->blocked;
167 siginitset(&current->blocked, mask); 165
168 recalc_sigpending(); 166 mask &= _BLOCKABLE;
169 spin_unlock_irq(&current->sighand->siglock); 167 siginitset(&blocked, mask);
168 set_current_blocked(&blocked);
170 169
171 REF_REG_RET = -EINTR; 170 REF_REG_RET = -EINTR;
172 while (1) { 171 while (1) {
@@ -198,11 +197,8 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
198 if (copy_from_user(&newset, unewset, sizeof(newset))) 197 if (copy_from_user(&newset, unewset, sizeof(newset)))
199 return -EFAULT; 198 return -EFAULT;
200 sigdelsetmask(&newset, ~_BLOCKABLE); 199 sigdelsetmask(&newset, ~_BLOCKABLE);
201 spin_lock_irq(&current->sighand->siglock);
202 saveset = current->blocked; 200 saveset = current->blocked;
203 current->blocked = newset; 201 set_current_blocked(&newset);
204 recalc_sigpending();
205 spin_unlock_irq(&current->sighand->siglock);
206 202
207 REF_REG_RET = -EINTR; 203 REF_REG_RET = -EINTR;
208 while (1) { 204 while (1) {
@@ -408,11 +404,7 @@ asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
408 goto badframe; 404 goto badframe;
409 405
410 sigdelsetmask(&set, ~_BLOCKABLE); 406 sigdelsetmask(&set, ~_BLOCKABLE);
411 407 set_current_blocked(&set);
412 spin_lock_irq(&current->sighand->siglock);
413 current->blocked = set;
414 recalc_sigpending();
415 spin_unlock_irq(&current->sighand->siglock);
416 408
417 if (restore_sigcontext(regs, &frame->sc, &ret)) 409 if (restore_sigcontext(regs, &frame->sc, &ret))
418 goto badframe; 410 goto badframe;
@@ -445,10 +437,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
445 goto badframe; 437 goto badframe;
446 438
447 sigdelsetmask(&set, ~_BLOCKABLE); 439 sigdelsetmask(&set, ~_BLOCKABLE);
448 spin_lock_irq(&current->sighand->siglock); 440 set_current_blocked(&set);
449 current->blocked = set;
450 recalc_sigpending();
451 spin_unlock_irq(&current->sighand->siglock);
452 441
453 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret)) 442 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
454 goto badframe; 443 goto badframe;
@@ -734,14 +723,8 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
734 else 723 else
735 ret = setup_frame(sig, ka, oldset, regs); 724 ret = setup_frame(sig, ka, oldset, regs);
736 725
737 if (ret == 0) { 726 if (ret == 0)
738 spin_lock_irq(&current->sighand->siglock); 727 block_sigmask(ka, sig);
739 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
740 if (!(ka->sa.sa_flags & SA_NODEFER))
741 sigaddset(&current->blocked,sig);
742 recalc_sigpending();
743 spin_unlock_irq(&current->sighand->siglock);
744 }
745 728
746 return ret; 729 return ret;
747} 730}