aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 21:11:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 21:11:45 -0400
commitf9369910a6225b8d4892c3f20ae740a711cd5ace (patch)
tree8650ff79d7607bceb35509c028400ecf1c317de0 /arch
parent05f144a0d5c2207a0349348127f996e104ad7404 (diff)
parent415d04d08fec74b226c92c1fb54ad117c9c6bac4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull first series of signal handling cleanups from Al Viro: "This is just the first part of the queue (about a half of it); assorted fixes all over the place in signal handling. This one ends with all sigsuspend() implementations switched to generic one (->saved_sigmask-based). With this, a bunch of assorted old buglets are fixed and most of the missing bits of NOTIFY_RESUME hookup are in place. Two more fixes sit in arm and um trees respectively, and there's a couple of broken ones that need obvious fixes - parisc and avr32 check TIF_NOTIFY_RESUME only on one of two codepaths; fixes for that will happen in the next series" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (55 commits) unicore32: if there's no handler we need to restore sigmask, syscall or no syscall xtensa: add handling of TIF_NOTIFY_RESUME microblaze: drop 'oldset' argument of do_notify_resume() microblaze: handle TIF_NOTIFY_RESUME score: add handling of NOTIFY_RESUME to do_notify_resume() m68k: add TIF_NOTIFY_RESUME and handle it. sparc: kill ancient comment in sparc_sigaction() h8300: missing checks of __get_user()/__put_user() return values frv: missing checks of __get_user()/__put_user() return values cris: missing checks of __get_user()/__put_user() return values powerpc: missing checks of __get_user()/__put_user() return values sh: missing checks of __get_user()/__put_user() return values sparc: missing checks of __get_user()/__put_user() return values avr32: struct old_sigaction is never used m32r: struct old_sigaction is never used xtensa: xtensa_sigaction doesn't exist alpha: tidy signal delivery up score: don't open-code force_sigsegv() cris: don't open-code force_sigsegv() blackfin: don't open-code force_sigsegv() ...
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/signal.c80
-rw-r--r--arch/arm/kernel/signal.c11
-rw-r--r--arch/avr32/include/asm/signal.h7
-rw-r--r--arch/avr32/kernel/signal.c30
-rw-r--r--arch/blackfin/kernel/signal.c21
-rw-r--r--arch/c6x/kernel/signal.c3
-rw-r--r--arch/cris/arch-v10/kernel/signal.c50
-rw-r--r--arch/cris/arch-v32/kernel/signal.c66
-rw-r--r--arch/frv/kernel/signal.c47
-rw-r--r--arch/h8300/include/asm/unistd.h1
-rw-r--r--arch/h8300/kernel/signal.c122
-rw-r--r--arch/h8300/kernel/syscalls.S6
-rw-r--r--arch/hexagon/kernel/signal.c4
-rw-r--r--arch/ia64/kernel/signal.c15
-rw-r--r--arch/m32r/include/asm/signal.h7
-rw-r--r--arch/m32r/kernel/signal.c12
-rw-r--r--arch/m68k/include/asm/thread_info.h1
-rw-r--r--arch/m68k/kernel/entry_mm.S6
-rw-r--r--arch/m68k/kernel/signal.c41
-rw-r--r--arch/m68k/platform/68328/entry.S2
-rw-r--r--arch/m68k/platform/68360/entry.S2
-rw-r--r--arch/m68k/platform/coldfire/entry.S2
-rw-r--r--arch/microblaze/kernel/entry-nommu.S20
-rw-r--r--arch/microblaze/kernel/entry.S30
-rw-r--r--arch/microblaze/kernel/signal.c85
-rw-r--r--arch/mips/kernel/signal.c20
-rw-r--r--arch/mips/kernel/signal32.c20
-rw-r--r--arch/mips/kernel/signal_n32.c10
-rw-r--r--arch/mn10300/kernel/signal.c35
-rw-r--r--arch/parisc/kernel/signal.c15
-rw-r--r--arch/powerpc/kernel/signal_32.c17
-rw-r--r--arch/s390/kernel/signal.c9
-rw-r--r--arch/score/kernel/signal.c29
-rw-r--r--arch/sh/include/asm/syscalls_32.h4
-rw-r--r--arch/sh/include/asm/unistd.h4
-rw-r--r--arch/sh/kernel/signal_32.c53
-rw-r--r--arch/sh/kernel/signal_64.c84
-rw-r--r--arch/sparc/kernel/signal32.c10
-rw-r--r--arch/sparc/kernel/signal_32.c12
-rw-r--r--arch/sparc/kernel/signal_64.c13
-rw-r--r--arch/sparc/kernel/sys_sparc_32.c17
-rw-r--r--arch/um/kernel/signal.c9
-rw-r--r--arch/unicore32/kernel/signal.c18
-rw-r--r--arch/x86/ia32/ia32_signal.c12
-rw-r--r--arch/x86/kernel/signal.c12
-rw-r--r--arch/xtensa/include/asm/signal.h7
-rw-r--r--arch/xtensa/include/asm/syscall.h4
-rw-r--r--arch/xtensa/include/asm/thread_info.h1
-rw-r--r--arch/xtensa/include/asm/unistd.h2
-rw-r--r--arch/xtensa/kernel/entry.S6
-rw-r--r--arch/xtensa/kernel/signal.c73
51 files changed, 368 insertions, 799 deletions
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 35f2ef44de12..10ab2d74ecbb 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -34,9 +34,6 @@
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35 35
36asmlinkage void ret_from_sys_call(void); 36asmlinkage void ret_from_sys_call(void);
37static void do_signal(struct pt_regs *, struct switch_stack *,
38 unsigned long, unsigned long);
39
40 37
41/* 38/*
42 * The OSF/1 sigprocmask calling sequence is different from the 39 * The OSF/1 sigprocmask calling sequence is different from the
@@ -121,17 +118,8 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
121SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask) 118SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
122{ 119{
123 sigset_t blocked; 120 sigset_t blocked;
124
125 current->saved_sigmask = current->blocked;
126
127 mask &= _BLOCKABLE;
128 siginitset(&blocked, mask); 121 siginitset(&blocked, mask);
129 set_current_blocked(&blocked); 122 return sigsuspend(&blocked);
130
131 current->state = TASK_INTERRUPTIBLE;
132 schedule();
133 set_thread_flag(TIF_RESTORE_SIGMASK);
134 return -ERESTARTNOHAND;
135} 123}
136 124
137asmlinkage int 125asmlinkage int
@@ -376,11 +364,11 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
376 oldsp = rdusp(); 364 oldsp = rdusp();
377 frame = get_sigframe(ka, oldsp, sizeof(*frame)); 365 frame = get_sigframe(ka, oldsp, sizeof(*frame));
378 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 366 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
379 goto give_sigsegv; 367 return -EFAULT;
380 368
381 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp); 369 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
382 if (err) 370 if (err)
383 goto give_sigsegv; 371 return -EFAULT;
384 372
385 /* Set up to return from userspace. If provided, use a stub 373 /* Set up to return from userspace. If provided, use a stub
386 already in userspace. */ 374 already in userspace. */
@@ -396,7 +384,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
396 384
397 /* Check that everything was written properly. */ 385 /* Check that everything was written properly. */
398 if (err) 386 if (err)
399 goto give_sigsegv; 387 return err;
400 388
401 /* "Return" to the handler */ 389 /* "Return" to the handler */
402 regs->r26 = r26; 390 regs->r26 = r26;
@@ -410,12 +398,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
410 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 398 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
411 current->comm, current->pid, frame, regs->pc, regs->r26); 399 current->comm, current->pid, frame, regs->pc, regs->r26);
412#endif 400#endif
413
414 return 0; 401 return 0;
415
416give_sigsegv:
417 force_sigsegv(sig, current);
418 return -EFAULT;
419} 402}
420 403
421static int 404static int
@@ -428,7 +411,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
428 oldsp = rdusp(); 411 oldsp = rdusp();
429 frame = get_sigframe(ka, oldsp, sizeof(*frame)); 412 frame = get_sigframe(ka, oldsp, sizeof(*frame));
430 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 413 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
431 goto give_sigsegv; 414 return -EFAULT;
432 415
433 err |= copy_siginfo_to_user(&frame->info, info); 416 err |= copy_siginfo_to_user(&frame->info, info);
434 417
@@ -443,7 +426,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
443 set->sig[0], oldsp); 426 set->sig[0], oldsp);
444 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 427 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
445 if (err) 428 if (err)
446 goto give_sigsegv; 429 return -EFAULT;
447 430
448 /* Set up to return from userspace. If provided, use a stub 431 /* Set up to return from userspace. If provided, use a stub
449 already in userspace. */ 432 already in userspace. */
@@ -459,7 +442,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
459 } 442 }
460 443
461 if (err) 444 if (err)
462 goto give_sigsegv; 445 return -EFAULT;
463 446
464 /* "Return" to the handler */ 447 /* "Return" to the handler */
465 regs->r26 = r26; 448 regs->r26 = r26;
@@ -475,31 +458,37 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
475#endif 458#endif
476 459
477 return 0; 460 return 0;
478
479give_sigsegv:
480 force_sigsegv(sig, current);
481 return -EFAULT;
482} 461}
483 462
484 463
485/* 464/*
486 * OK, we're invoking a handler. 465 * OK, we're invoking a handler.
487 */ 466 */
488static inline int 467static inline void
489handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 468handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
490 sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) 469 struct pt_regs * regs, struct switch_stack *sw)
491{ 470{
471 sigset_t *oldset = &current->blocked;
492 int ret; 472 int ret;
493 473
474 if (test_thread_flag(TIF_RESTORE_SIGMASK))
475 oldset = &current->saved_sigmask;
476
494 if (ka->sa.sa_flags & SA_SIGINFO) 477 if (ka->sa.sa_flags & SA_SIGINFO)
495 ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); 478 ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
496 else 479 else
497 ret = setup_frame(sig, ka, oldset, regs, sw); 480 ret = setup_frame(sig, ka, oldset, regs, sw);
498 481
499 if (ret == 0) 482 if (ret) {
500 block_sigmask(ka, sig); 483 force_sigsegv(sig, current);
501 484 return;
502 return ret; 485 }
486 block_sigmask(ka, sig);
487 /* A signal was successfully delivered, and the
488 saved sigmask was stored on the signal frame,
489 and will be restored by sigreturn. So we can
490 simply clear the restore sigmask flag. */
491 clear_thread_flag(TIF_RESTORE_SIGMASK);
503} 492}
504 493
505static inline void 494static inline void
@@ -547,12 +536,6 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
547 int signr; 536 int signr;
548 unsigned long single_stepping = ptrace_cancel_bpt(current); 537 unsigned long single_stepping = ptrace_cancel_bpt(current);
549 struct k_sigaction ka; 538 struct k_sigaction ka;
550 sigset_t *oldset;
551
552 if (test_thread_flag(TIF_RESTORE_SIGMASK))
553 oldset = &current->saved_sigmask;
554 else
555 oldset = &current->blocked;
556 539
557 /* This lets the debugger run, ... */ 540 /* This lets the debugger run, ... */
558 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 541 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -564,14 +547,7 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
564 /* Whee! Actually deliver the signal. */ 547 /* Whee! Actually deliver the signal. */
565 if (r0) 548 if (r0)
566 syscall_restart(r0, r19, regs, &ka); 549 syscall_restart(r0, r19, regs, &ka);
567 if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) { 550 handle_signal(signr, &ka, &info, regs, sw);
568 /* A signal was successfully delivered, and the
569 saved sigmask was stored on the signal frame,
570 and will be restored by sigreturn. So we can
571 simply clear the restore sigmask flag. */
572 if (test_thread_flag(TIF_RESTORE_SIGMASK))
573 clear_thread_flag(TIF_RESTORE_SIGMASK);
574 }
575 if (single_stepping) 551 if (single_stepping)
576 ptrace_set_bpt(current); /* re-set bpt */ 552 ptrace_set_bpt(current); /* re-set bpt */
577 return; 553 return;
@@ -596,10 +572,8 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
596 } 572 }
597 573
598 /* If there's no signal to deliver, we just restore the saved mask. */ 574 /* If there's no signal to deliver, we just restore the saved mask. */
599 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 575 if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
600 clear_thread_flag(TIF_RESTORE_SIGMASK); 576 set_current_blocked(&current->saved_sigmask);
601 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
602 }
603 577
604 if (single_stepping) 578 if (single_stepping)
605 ptrace_set_bpt(current); /* re-set breakpoint */ 579 ptrace_set_bpt(current); /* re-set breakpoint */
@@ -610,7 +584,7 @@ do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
610 unsigned long thread_info_flags, 584 unsigned long thread_info_flags,
611 unsigned long r0, unsigned long r19) 585 unsigned long r0, unsigned long r19)
612{ 586{
613 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 587 if (thread_info_flags & _TIF_SIGPENDING)
614 do_signal(regs, sw, r0, r19); 588 do_signal(regs, sw, r0, r19);
615 589
616 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 590 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 73d9a420850d..4e5fdd9bd9e3 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -67,17 +67,8 @@ const unsigned long syscall_restart_code[2] = {
67asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) 67asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
68{ 68{
69 sigset_t blocked; 69 sigset_t blocked;
70
71 current->saved_sigmask = current->blocked;
72
73 mask &= _BLOCKABLE;
74 siginitset(&blocked, mask); 70 siginitset(&blocked, mask);
75 set_current_blocked(&blocked); 71 return sigsuspend(&blocked);
76
77 current->state = TASK_INTERRUPTIBLE;
78 schedule();
79 set_restore_sigmask();
80 return -ERESTARTNOHAND;
81} 72}
82 73
83asmlinkage int 74asmlinkage int
diff --git a/arch/avr32/include/asm/signal.h b/arch/avr32/include/asm/signal.h
index 8790dfc10d5b..ae56849fdb2b 100644
--- a/arch/avr32/include/asm/signal.h
+++ b/arch/avr32/include/asm/signal.h
@@ -115,13 +115,6 @@ typedef unsigned long sigset_t;
115#include <asm-generic/signal-defs.h> 115#include <asm-generic/signal-defs.h>
116 116
117#ifdef __KERNEL__ 117#ifdef __KERNEL__
118struct old_sigaction {
119 __sighandler_t sa_handler;
120 old_sigset_t sa_mask;
121 unsigned long sa_flags;
122 __sigrestore_t sa_restorer;
123};
124
125struct sigaction { 118struct sigaction {
126 __sighandler_t sa_handler; 119 __sighandler_t sa_handler;
127 unsigned long sa_flags; 120 unsigned long sa_flags;
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index 64f886fac2ef..ae386c304bee 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -77,6 +77,9 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
77 struct rt_sigframe __user *frame; 77 struct rt_sigframe __user *frame;
78 sigset_t set; 78 sigset_t set;
79 79
80 /* Always make any pending restarted system calls return -EINTR */
81 current_thread_info()->restart_block.fn = do_no_restart_syscall;
82
80 frame = (struct rt_sigframe __user *)regs->sp; 83 frame = (struct rt_sigframe __user *)regs->sp;
81 pr_debug("SIG return: frame = %p\n", frame); 84 pr_debug("SIG return: frame = %p\n", frame);
82 85
@@ -87,10 +90,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
87 goto badframe; 90 goto badframe;
88 91
89 sigdelsetmask(&set, ~_BLOCKABLE); 92 sigdelsetmask(&set, ~_BLOCKABLE);
90 spin_lock_irq(&current->sighand->siglock); 93 set_current_blocked(&set);
91 current->blocked = set;
92 recalc_sigpending();
93 spin_unlock_irq(&current->sighand->siglock);
94 94
95 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 95 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
96 goto badframe; 96 goto badframe;
@@ -238,22 +238,16 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
238 */ 238 */
239 ret |= !valid_user_regs(regs); 239 ret |= !valid_user_regs(regs);
240 240
241 /* 241 if (ret != 0) {
242 * Block the signal if we were unsuccessful. 242 force_sigsegv(sig, current);
243 */
244 if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) {
245 spin_lock_irq(&current->sighand->siglock);
246 sigorsets(&current->blocked, &current->blocked,
247 &ka->sa.sa_mask);
248 sigaddset(&current->blocked, sig);
249 recalc_sigpending();
250 spin_unlock_irq(&current->sighand->siglock);
251 }
252
253 if (ret == 0)
254 return; 243 return;
244 }
255 245
256 force_sigsegv(sig, current); 246 /*
247 * Block the signal if we were successful.
248 */
249 block_sigmask(ka, sig);
250 clear_thread_flag(TIF_RESTORE_SIGMASK);
257} 251}
258 252
259/* 253/*
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index d536f35d1f43..e5bbc1a5edc2 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -99,10 +99,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
99 goto badframe; 99 goto badframe;
100 100
101 sigdelsetmask(&set, ~_BLOCKABLE); 101 sigdelsetmask(&set, ~_BLOCKABLE);
102 spin_lock_irq(&current->sighand->siglock); 102 set_current_blocked(&set);
103 current->blocked = set;
104 recalc_sigpending();
105 spin_unlock_irq(&current->sighand->siglock);
106 103
107 if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) 104 if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
108 goto badframe; 105 goto badframe;
@@ -213,9 +210,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
213 return 0; 210 return 0;
214 211
215 give_sigsegv: 212 give_sigsegv:
216 if (sig == SIGSEGV) 213 force_sigsegv(sig, current);
217 ka->sa.sa_handler = SIG_DFL;
218 force_sig(SIGSEGV, current);
219 return -EFAULT; 214 return -EFAULT;
220} 215}
221 216
@@ -266,15 +261,9 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
266 /* set up the stack frame */ 261 /* set up the stack frame */
267 ret = setup_rt_frame(sig, ka, info, oldset, regs); 262 ret = setup_rt_frame(sig, ka, info, oldset, regs);
268 263
269 if (ret == 0) { 264 if (ret == 0)
270 spin_lock_irq(&current->sighand->siglock); 265 block_sigmask(ka, sig);
271 sigorsets(&current->blocked, &current->blocked, 266
272 &ka->sa.sa_mask);
273 if (!(ka->sa.sa_flags & SA_NODEFER))
274 sigaddset(&current->blocked, sig);
275 recalc_sigpending();
276 spin_unlock_irq(&current->sighand->siglock);
277 }
278 return ret; 267 return ret;
279} 268}
280 269
diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c
index 3b5a05099989..cf37478c1169 100644
--- a/arch/c6x/kernel/signal.c
+++ b/arch/c6x/kernel/signal.c
@@ -69,6 +69,9 @@ asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
69 struct rt_sigframe __user *frame; 69 struct rt_sigframe __user *frame;
70 sigset_t set; 70 sigset_t set;
71 71
72 /* Always make any pending restarted system calls return -EINTR */
73 current_thread_info()->restart_block.fn = do_no_restart_syscall;
74
72 /* 75 /*
73 * Since we stacked the signal on a dword boundary, 76 * Since we stacked the signal on a dword boundary,
74 * 'sp' should be dword aligned here. If it's 77 * 'sp' should be dword aligned here. If it's
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 289c584ba499..e16f8f297f61 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -48,19 +48,11 @@ void do_signal(int canrestart, struct pt_regs *regs);
48 * dummy arguments to be able to reach the regs argument. (Note that this 48 * dummy arguments to be able to reach the regs argument. (Note that this
49 * arrangement relies on old_sigset_t occupying one register.) 49 * arrangement relies on old_sigset_t occupying one register.)
50 */ 50 */
51int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 51int sys_sigsuspend(old_sigset_t mask)
52 long srp, struct pt_regs *regs)
53{ 52{
54 mask &= _BLOCKABLE; 53 sigset_t blocked;
55 spin_lock_irq(&current->sighand->siglock); 54 siginitset(&blocked, mask);
56 current->saved_sigmask = current->blocked; 55 return sigsuspend(&blocked);
57 siginitset(&current->blocked, mask);
58 recalc_sigpending();
59 spin_unlock_irq(&current->sighand->siglock);
60 current->state = TASK_INTERRUPTIBLE;
61 schedule();
62 set_thread_flag(TIF_RESTORE_SIGMASK);
63 return -ERESTARTNOHAND;
64} 56}
65 57
66int sys_sigaction(int sig, const struct old_sigaction __user *act, 58int sys_sigaction(int sig, const struct old_sigaction __user *act,
@@ -73,10 +65,10 @@ int sys_sigaction(int sig, const struct old_sigaction __user *act,
73 old_sigset_t mask; 65 old_sigset_t mask;
74 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 66 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
75 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 67 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
76 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 68 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
69 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
70 __get_user(mask, &act->sa_mask))
77 return -EFAULT; 71 return -EFAULT;
78 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
79 __get_user(mask, &act->sa_mask);
80 siginitset(&new_ka.sa.sa_mask, mask); 72 siginitset(&new_ka.sa.sa_mask, mask);
81 } 73 }
82 74
@@ -85,10 +77,10 @@ int sys_sigaction(int sig, const struct old_sigaction __user *act,
85 if (!ret && oact) { 77 if (!ret && oact) {
86 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 78 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
87 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 79 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
88 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 80 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
81 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
82 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
89 return -EFAULT; 83 return -EFAULT;
90 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
91 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
92 } 84 }
93 85
94 return ret; 86 return ret;
@@ -185,10 +177,7 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
185 goto badframe; 177 goto badframe;
186 178
187 sigdelsetmask(&set, ~_BLOCKABLE); 179 sigdelsetmask(&set, ~_BLOCKABLE);
188 spin_lock_irq(&current->sighand->siglock); 180 set_current_blocked(&set);
189 current->blocked = set;
190 recalc_sigpending();
191 spin_unlock_irq(&current->sighand->siglock);
192 181
193 if (restore_sigcontext(regs, &frame->sc)) 182 if (restore_sigcontext(regs, &frame->sc))
194 goto badframe; 183 goto badframe;
@@ -224,10 +213,7 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
224 goto badframe; 213 goto badframe;
225 214
226 sigdelsetmask(&set, ~_BLOCKABLE); 215 sigdelsetmask(&set, ~_BLOCKABLE);
227 spin_lock_irq(&current->sighand->siglock); 216 set_current_blocked(&set);
228 current->blocked = set;
229 recalc_sigpending();
230 spin_unlock_irq(&current->sighand->siglock);
231 217
232 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 218 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
233 goto badframe; 219 goto badframe;
@@ -469,15 +455,9 @@ static inline int handle_signal(int canrestart, unsigned long sig,
469 else 455 else
470 ret = setup_frame(sig, ka, oldset, regs); 456 ret = setup_frame(sig, ka, oldset, regs);
471 457
472 if (ret == 0) { 458 if (ret == 0)
473 spin_lock_irq(&current->sighand->siglock); 459 block_sigmask(ka, sig);
474 sigorsets(&current->blocked, &current->blocked, 460
475 &ka->sa.sa_mask);
476 if (!(ka->sa.sa_flags & SA_NODEFER))
477 sigaddset(&current->blocked, sig);
478 recalc_sigpending();
479 spin_unlock_irq(&current->sighand->siglock);
480 }
481 return ret; 461 return ret;
482} 462}
483 463
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index ce4ab1a5552c..b338d8fc0c12 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -59,19 +59,11 @@ void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
59 * dummy arguments to be able to reach the regs argument. 59 * dummy arguments to be able to reach the regs argument.
60 */ 60 */
61int 61int
62sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 62sys_sigsuspend(old_sigset_t mask)
63 long srp, struct pt_regs *regs)
64{ 63{
65 mask &= _BLOCKABLE; 64 sigset_t blocked;
66 spin_lock_irq(&current->sighand->siglock); 65 siginitset(&blocked, mask);
67 current->saved_sigmask = current->blocked; 66 return sigsuspend(&blocked);
68 siginitset(&current->blocked, mask);
69 recalc_sigpending();
70 spin_unlock_irq(&current->sighand->siglock);
71 current->state = TASK_INTERRUPTIBLE;
72 schedule();
73 set_thread_flag(TIF_RESTORE_SIGMASK);
74 return -ERESTARTNOHAND;
75} 67}
76 68
77int 69int
@@ -87,11 +79,11 @@ sys_sigaction(int signal, const struct old_sigaction *act,
87 79
88 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 80 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
89 __get_user(newk.sa.sa_handler, &act->sa_handler) || 81 __get_user(newk.sa.sa_handler, &act->sa_handler) ||
90 __get_user(newk.sa.sa_restorer, &act->sa_restorer)) 82 __get_user(newk.sa.sa_restorer, &act->sa_restorer) ||
83 __get_user(newk.sa.sa_flags, &act->sa_flags) ||
84 __get_user(mask, &act->sa_mask))
91 return -EFAULT; 85 return -EFAULT;
92 86
93 __get_user(newk.sa.sa_flags, &act->sa_flags);
94 __get_user(mask, &act->sa_mask);
95 siginitset(&newk.sa.sa_mask, mask); 87 siginitset(&newk.sa.sa_mask, mask);
96 } 88 }
97 89
@@ -100,11 +92,11 @@ sys_sigaction(int signal, const struct old_sigaction *act,
100 if (!retval && oact) { 92 if (!retval && oact) {
101 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 93 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
102 __put_user(oldk.sa.sa_handler, &oact->sa_handler) || 94 __put_user(oldk.sa.sa_handler, &oact->sa_handler) ||
103 __put_user(oldk.sa.sa_restorer, &oact->sa_restorer)) 95 __put_user(oldk.sa.sa_restorer, &oact->sa_restorer) ||
96 __put_user(oldk.sa.sa_flags, &oact->sa_flags) ||
97 __put_user(oldk.sa.sa_mask.sig[0], &oact->sa_mask))
104 return -EFAULT; 98 return -EFAULT;
105 99
106 __put_user(oldk.sa.sa_flags, &oact->sa_flags);
107 __put_user(oldk.sa.sa_mask.sig[0], &oact->sa_mask);
108 } 100 }
109 101
110 return retval; 102 return retval;
@@ -176,12 +168,7 @@ sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
176 goto badframe; 168 goto badframe;
177 169
178 sigdelsetmask(&set, ~_BLOCKABLE); 170 sigdelsetmask(&set, ~_BLOCKABLE);
179 spin_lock_irq(&current->sighand->siglock); 171 set_current_blocked(&set);
180
181 current->blocked = set;
182
183 recalc_sigpending();
184 spin_unlock_irq(&current->sighand->siglock);
185 172
186 if (restore_sigcontext(regs, &frame->sc)) 173 if (restore_sigcontext(regs, &frame->sc))
187 goto badframe; 174 goto badframe;
@@ -222,12 +209,7 @@ sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
222 goto badframe; 209 goto badframe;
223 210
224 sigdelsetmask(&set, ~_BLOCKABLE); 211 sigdelsetmask(&set, ~_BLOCKABLE);
225 spin_lock_irq(&current->sighand->siglock); 212 set_current_blocked(&set);
226
227 current->blocked = set;
228
229 recalc_sigpending();
230 spin_unlock_irq(&current->sighand->siglock);
231 213
232 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 214 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
233 goto badframe; 215 goto badframe;
@@ -363,10 +345,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
363 return 0; 345 return 0;
364 346
365give_sigsegv: 347give_sigsegv:
366 if (sig == SIGSEGV) 348 force_sigsegv(sig, current);
367 ka->sa.sa_handler = SIG_DFL;
368
369 force_sig(SIGSEGV, current);
370 return -EFAULT; 349 return -EFAULT;
371} 350}
372 351
@@ -450,10 +429,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
450 return 0; 429 return 0;
451 430
452give_sigsegv: 431give_sigsegv:
453 if (sig == SIGSEGV) 432 force_sigsegv(sig, current);
454 ka->sa.sa_handler = SIG_DFL;
455
456 force_sig(SIGSEGV, current);
457 return -EFAULT; 433 return -EFAULT;
458} 434}
459 435
@@ -512,18 +488,8 @@ handle_signal(int canrestart, unsigned long sig,
512 else 488 else
513 ret = setup_frame(sig, ka, oldset, regs); 489 ret = setup_frame(sig, ka, oldset, regs);
514 490
515 if (ka->sa.sa_flags & SA_ONESHOT) 491 if (ret == 0)
516 ka->sa.sa_handler = SIG_DFL; 492 block_sigmask(ka, sig);
517
518 if (ret == 0) {
519 spin_lock_irq(&current->sighand->siglock);
520 sigorsets(&current->blocked, &current->blocked,
521 &ka->sa.sa_mask);
522 if (!(ka->sa.sa_flags & SA_NODEFER))
523 sigaddset(&current->blocked, sig);
524 recalc_sigpending();
525 spin_unlock_irq(&current->sighand->siglock);
526 }
527 493
528 return ret; 494 return ret;
529} 495}
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index bab01298b58e..8cf5dca01758 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -40,17 +40,9 @@ struct fdpic_func_descriptor {
40 */ 40 */
41asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask) 41asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
42{ 42{
43 mask &= _BLOCKABLE; 43 sigset_t blocked;
44 spin_lock_irq(&current->sighand->siglock); 44 siginitset(&blocked, mask);
45 current->saved_sigmask = current->blocked; 45 return sigsuspend(&blocked);
46 siginitset(&current->blocked, mask);
47 recalc_sigpending();
48 spin_unlock_irq(&current->sighand->siglock);
49
50 current->state = TASK_INTERRUPTIBLE;
51 schedule();
52 set_thread_flag(TIF_RESTORE_SIGMASK);
53 return -ERESTARTNOHAND;
54} 46}
55 47
56asmlinkage int sys_sigaction(int sig, 48asmlinkage int sys_sigaction(int sig,
@@ -64,10 +56,10 @@ asmlinkage int sys_sigaction(int sig,
64 old_sigset_t mask; 56 old_sigset_t mask;
65 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 57 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
66 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 58 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
67 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 59 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
60 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
61 __get_user(mask, &act->sa_mask))
68 return -EFAULT; 62 return -EFAULT;
69 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
70 __get_user(mask, &act->sa_mask);
71 siginitset(&new_ka.sa.sa_mask, mask); 63 siginitset(&new_ka.sa.sa_mask, mask);
72 } 64 }
73 65
@@ -76,10 +68,10 @@ asmlinkage int sys_sigaction(int sig,
76 if (!ret && oact) { 68 if (!ret && oact) {
77 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 69 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
78 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 70 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
79 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 71 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
72 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
73 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
80 return -EFAULT; 74 return -EFAULT;
81 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
82 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
83 } 75 }
84 76
85 return ret; 77 return ret;
@@ -158,10 +150,7 @@ asmlinkage int sys_sigreturn(void)
158 goto badframe; 150 goto badframe;
159 151
160 sigdelsetmask(&set, ~_BLOCKABLE); 152 sigdelsetmask(&set, ~_BLOCKABLE);
161 spin_lock_irq(&current->sighand->siglock); 153 set_current_blocked(&set);
162 current->blocked = set;
163 recalc_sigpending();
164 spin_unlock_irq(&current->sighand->siglock);
165 154
166 if (restore_sigcontext(&frame->sc, &gr8)) 155 if (restore_sigcontext(&frame->sc, &gr8))
167 goto badframe; 156 goto badframe;
@@ -184,10 +173,7 @@ asmlinkage int sys_rt_sigreturn(void)
184 goto badframe; 173 goto badframe;
185 174
186 sigdelsetmask(&set, ~_BLOCKABLE); 175 sigdelsetmask(&set, ~_BLOCKABLE);
187 spin_lock_irq(&current->sighand->siglock); 176 set_current_blocked(&set);
188 current->blocked = set;
189 recalc_sigpending();
190 spin_unlock_irq(&current->sighand->siglock);
191 177
192 if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8)) 178 if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8))
193 goto badframe; 179 goto badframe;
@@ -474,15 +460,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
474 else 460 else
475 ret = setup_frame(sig, ka, oldset); 461 ret = setup_frame(sig, ka, oldset);
476 462
477 if (ret == 0) { 463 if (ret == 0)
478 spin_lock_irq(&current->sighand->siglock); 464 block_sigmask(ka, sig);
479 sigorsets(&current->blocked, &current->blocked,
480 &ka->sa.sa_mask);
481 if (!(ka->sa.sa_flags & SA_NODEFER))
482 sigaddset(&current->blocked, sig);
483 recalc_sigpending();
484 spin_unlock_irq(&current->sighand->siglock);
485 }
486 465
487 return ret; 466 return ret;
488 467
diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h
index 2c3f8e60b1e0..718511303b4e 100644
--- a/arch/h8300/include/asm/unistd.h
+++ b/arch/h8300/include/asm/unistd.h
@@ -356,6 +356,7 @@
356#define __ARCH_WANT_SYS_SIGPENDING 356#define __ARCH_WANT_SYS_SIGPENDING
357#define __ARCH_WANT_SYS_SIGPROCMASK 357#define __ARCH_WANT_SYS_SIGPROCMASK
358#define __ARCH_WANT_SYS_RT_SIGACTION 358#define __ARCH_WANT_SYS_RT_SIGACTION
359#define __ARCH_WANT_SYS_RT_SIGSUSPEND
359 360
360/* 361/*
361 * "Conditional" syscalls 362 * "Conditional" syscalls
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index af842c369d24..d4b0555d2904 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -49,60 +49,15 @@
49 49
50#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 50#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
51 51
52asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
53
54/* 52/*
55 * Atomically swap in the new signal mask, and wait for a signal. 53 * Atomically swap in the new signal mask, and wait for a signal.
56 */ 54 */
57asmlinkage int do_sigsuspend(struct pt_regs *regs)
58{
59 old_sigset_t mask = regs->er3;
60 sigset_t saveset;
61
62 mask &= _BLOCKABLE;
63 spin_lock_irq(&current->sighand->siglock);
64 saveset = current->blocked;
65 siginitset(&current->blocked, mask);
66 recalc_sigpending();
67 spin_unlock_irq(&current->sighand->siglock);
68
69 regs->er0 = -EINTR;
70 while (1) {
71 current->state = TASK_INTERRUPTIBLE;
72 schedule();
73 if (do_signal(regs, &saveset))
74 return -EINTR;
75 }
76}
77
78asmlinkage int 55asmlinkage int
79do_rt_sigsuspend(struct pt_regs *regs) 56sys_sigsuspend(int unused1, int unused2, old_sigset_t mask)
80{ 57{
81 sigset_t *unewset = (sigset_t *)regs->er1; 58 sigset_t blocked;
82 size_t sigsetsize = (size_t)regs->er2; 59 siginitset(&blocked, mask);
83 sigset_t saveset, newset; 60 return sigsuspend(&blocked);
84
85 /* XXX: Don't preclude handling different sized sigset_t's. */
86 if (sigsetsize != sizeof(sigset_t))
87 return -EINVAL;
88
89 if (copy_from_user(&newset, unewset, sizeof(newset)))
90 return -EFAULT;
91 sigdelsetmask(&newset, ~_BLOCKABLE);
92
93 spin_lock_irq(&current->sighand->siglock);
94 saveset = current->blocked;
95 current->blocked = newset;
96 recalc_sigpending();
97 spin_unlock_irq(&current->sighand->siglock);
98
99 regs->er0 = -EINTR;
100 while (1) {
101 current->state = TASK_INTERRUPTIBLE;
102 schedule();
103 if (do_signal(regs, &saveset))
104 return -EINTR;
105 }
106} 61}
107 62
108asmlinkage int 63asmlinkage int
@@ -116,10 +71,10 @@ sys_sigaction(int sig, const struct old_sigaction *act,
116 old_sigset_t mask; 71 old_sigset_t mask;
117 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 72 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
118 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 73 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
119 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 74 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
75 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
76 __get_user(mask, &act->sa_mask))
120 return -EFAULT; 77 return -EFAULT;
121 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
122 __get_user(mask, &act->sa_mask);
123 siginitset(&new_ka.sa.sa_mask, mask); 78 siginitset(&new_ka.sa.sa_mask, mask);
124 } 79 }
125 80
@@ -128,10 +83,10 @@ sys_sigaction(int sig, const struct old_sigaction *act,
128 if (!ret && oact) { 83 if (!ret && oact) {
129 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 84 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
130 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 85 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
131 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 86 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
87 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
88 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
132 return -EFAULT; 89 return -EFAULT;
133 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
134 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
135 } 90 }
136 91
137 return ret; 92 return ret;
@@ -232,10 +187,7 @@ asmlinkage int do_sigreturn(unsigned long __unused,...)
232 goto badframe; 187 goto badframe;
233 188
234 sigdelsetmask(&set, ~_BLOCKABLE); 189 sigdelsetmask(&set, ~_BLOCKABLE);
235 spin_lock_irq(&current->sighand->siglock); 190 set_current_blocked(&set);
236 current->blocked = set;
237 recalc_sigpending();
238 spin_unlock_irq(&current->sighand->siglock);
239 191
240 if (restore_sigcontext(regs, &frame->sc, &er0)) 192 if (restore_sigcontext(regs, &frame->sc, &er0))
241 goto badframe; 193 goto badframe;
@@ -260,10 +212,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
260 goto badframe; 212 goto badframe;
261 213
262 sigdelsetmask(&set, ~_BLOCKABLE); 214 sigdelsetmask(&set, ~_BLOCKABLE);
263 spin_unlock_irq(&current->sighand->siglock); 215 set_current_blocked(&set);
264 current->blocked = set;
265 recalc_sigpending();
266 spin_lock_irq(&current->sighand->siglock);
267 216
268 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0)) 217 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0))
269 goto badframe; 218 goto badframe;
@@ -314,7 +263,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
314 return (void *)((usp - frame_size) & -8UL); 263 return (void *)((usp - frame_size) & -8UL);
315} 264}
316 265
317static void setup_frame (int sig, struct k_sigaction *ka, 266static int setup_frame (int sig, struct k_sigaction *ka,
318 sigset_t *set, struct pt_regs *regs) 267 sigset_t *set, struct pt_regs *regs)
319{ 268{
320 struct sigframe *frame; 269 struct sigframe *frame;
@@ -375,13 +324,14 @@ static void setup_frame (int sig, struct k_sigaction *ka,
375 regs->er1 = (unsigned long)&(frame->sc); 324 regs->er1 = (unsigned long)&(frame->sc);
376 regs->er5 = current->mm->start_data; /* GOT base */ 325 regs->er5 = current->mm->start_data; /* GOT base */
377 326
378 return; 327 return 0;
379 328
380give_sigsegv: 329give_sigsegv:
381 force_sigsegv(sig, current); 330 force_sigsegv(sig, current);
331 return -EFAULT;
382} 332}
383 333
384static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 334static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
385 sigset_t *set, struct pt_regs *regs) 335 sigset_t *set, struct pt_regs *regs)
386{ 336{
387 struct rt_sigframe *frame; 337 struct rt_sigframe *frame;
@@ -450,10 +400,11 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
450 regs->er2 = (unsigned long)&frame->uc; 400 regs->er2 = (unsigned long)&frame->uc;
451 regs->er5 = current->mm->start_data; /* GOT base */ 401 regs->er5 = current->mm->start_data; /* GOT base */
452 402
453 return; 403 return 0;
454 404
455give_sigsegv: 405give_sigsegv:
456 force_sigsegv(sig, current); 406 force_sigsegv(sig, current);
407 return -EFAULT;
457} 408}
458 409
459/* 410/*
@@ -463,6 +414,7 @@ static void
463handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 414handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
464 sigset_t *oldset, struct pt_regs * regs) 415 sigset_t *oldset, struct pt_regs * regs)
465{ 416{
417 int ret;
466 /* are we from a system call? */ 418 /* are we from a system call? */
467 if (regs->orig_er0 >= 0) { 419 if (regs->orig_er0 >= 0) {
468 switch (regs->er0) { 420 switch (regs->er0) {
@@ -485,16 +437,14 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
485 437
486 /* set up the stack frame */ 438 /* set up the stack frame */
487 if (ka->sa.sa_flags & SA_SIGINFO) 439 if (ka->sa.sa_flags & SA_SIGINFO)
488 setup_rt_frame(sig, ka, info, oldset, regs); 440 ret = setup_rt_frame(sig, ka, info, oldset, regs);
489 else 441 else
490 setup_frame(sig, ka, oldset, regs); 442 ret = setup_frame(sig, ka, oldset, regs);
491 443
492 spin_lock_irq(&current->sighand->siglock); 444 if (!ret) {
493 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 445 block_sigmask(ka, sig);
494 if (!(ka->sa.sa_flags & SA_NODEFER)) 446 clear_thread_flag(TIF_RESTORE_SIGMASK);
495 sigaddset(&current->blocked,sig); 447 }
496 recalc_sigpending();
497 spin_unlock_irq(&current->sighand->siglock);
498} 448}
499 449
500/* 450/*
@@ -502,11 +452,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
502 * want to handle. Thus you cannot kill init even with a SIGKILL even by 452 * want to handle. Thus you cannot kill init even with a SIGKILL even by
503 * mistake. 453 * mistake.
504 */ 454 */
505asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset) 455statis void do_signal(struct pt_regs *regs)
506{ 456{
507 siginfo_t info; 457 siginfo_t info;
508 int signr; 458 int signr;
509 struct k_sigaction ka; 459 struct k_sigaction ka;
460 sigset_t *oldset;
510 461
511 /* 462 /*
512 * We want the common case to go fast, which 463 * We want the common case to go fast, which
@@ -515,21 +466,23 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
515 * if so. 466 * if so.
516 */ 467 */
517 if ((regs->ccr & 0x10)) 468 if ((regs->ccr & 0x10))
518 return 1; 469 return;
519 470
520 if (try_to_freeze()) 471 if (try_to_freeze())
521 goto no_signal; 472 goto no_signal;
522 473
523 current->thread.esp0 = (unsigned long) regs; 474 current->thread.esp0 = (unsigned long) regs;
524 475
525 if (!oldset) 476 if (test_thread_flag(TIF_RESTORE_SIGMASK))
477 oldset = &current->saved_sigmask;
478 else
526 oldset = &current->blocked; 479 oldset = &current->blocked;
527 480
528 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 481 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
529 if (signr > 0) { 482 if (signr > 0) {
530 /* Whee! Actually deliver the signal. */ 483 /* Whee! Actually deliver the signal. */
531 handle_signal(signr, &info, &ka, oldset, regs); 484 handle_signal(signr, &info, &ka, oldset, regs);
532 return 1; 485 return;
533 } 486 }
534 no_signal: 487 no_signal:
535 /* Did we come from a system call? */ 488 /* Did we come from a system call? */
@@ -546,13 +499,16 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
546 regs->pc -= 2; 499 regs->pc -= 2;
547 } 500 }
548 } 501 }
549 return 0; 502
503 /* If there's no signal to deliver, we just restore the saved mask. */
504 if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
505 set_current_blocked(&current->saved_sigmask);
550} 506}
551 507
552asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) 508asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
553{ 509{
554 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 510 if (thread_info_flags & _TIF_SIGPENDING)
555 do_signal(regs, NULL); 511 do_signal(regs);
556 512
557 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 513 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
558 clear_thread_flag(TIF_NOTIFY_RESUME); 514 clear_thread_flag(TIF_NOTIFY_RESUME);
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
index 4be2ea2fbe26..9d77e715a2ed 100644
--- a/arch/h8300/kernel/syscalls.S
+++ b/arch/h8300/kernel/syscalls.S
@@ -343,12 +343,6 @@ SYMBOL_NAME_LABEL(sys_call_table)
343SYMBOL_NAME_LABEL(sys_clone) 343SYMBOL_NAME_LABEL(sys_clone)
344 call_sp h8300_clone 344 call_sp h8300_clone
345 345
346SYMBOL_NAME_LABEL(sys_sigsuspend)
347 call_sp do_sigsuspend
348
349SYMBOL_NAME_LABEL(sys_rt_sigsuspend)
350 call_sp do_rt_sigsuspend
351
352SYMBOL_NAME_LABEL(sys_sigreturn) 346SYMBOL_NAME_LABEL(sys_sigreturn)
353 call_sp do_sigreturn 347 call_sp do_sigreturn
354 348
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index ecbab3457606..434866eb0f1c 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -272,6 +272,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
272 272
273 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 273 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
274 clear_thread_flag(TIF_NOTIFY_RESUME); 274 clear_thread_flag(TIF_NOTIFY_RESUME);
275 tracehook_notify_resume(regs);
275 if (current->replacement_session_keyring) 276 if (current->replacement_session_keyring)
276 key_replace_session_keyring(); 277 key_replace_session_keyring();
277 } 278 }
@@ -293,6 +294,9 @@ asmlinkage int sys_rt_sigreturn(void)
293 struct rt_sigframe __user *frame; 294 struct rt_sigframe __user *frame;
294 sigset_t blocked; 295 sigset_t blocked;
295 296
297 /* Always make any pending restarted system calls return -EINTR */
298 current_thread_info()->restart_block.fn = do_no_restart_syscall;
299
296 frame = (struct rt_sigframe __user *)pt_psp(regs); 300 frame = (struct rt_sigframe __user *)pt_psp(regs);
297 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 301 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
298 goto badframe; 302 goto badframe;
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 7bdafc8788bd..7523501d3bc0 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -201,13 +201,7 @@ ia64_rt_sigreturn (struct sigscratch *scr)
201 goto give_sigsegv; 201 goto give_sigsegv;
202 202
203 sigdelsetmask(&set, ~_BLOCKABLE); 203 sigdelsetmask(&set, ~_BLOCKABLE);
204 204 set_current_blocked(&set);
205 spin_lock_irq(&current->sighand->siglock);
206 {
207 current->blocked = set;
208 recalc_sigpending();
209 }
210 spin_unlock_irq(&current->sighand->siglock);
211 205
212 if (restore_sigcontext(sc, scr)) 206 if (restore_sigcontext(sc, scr))
213 goto give_sigsegv; 207 goto give_sigsegv;
@@ -427,12 +421,7 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse
427 if (!setup_frame(sig, ka, info, oldset, scr)) 421 if (!setup_frame(sig, ka, info, oldset, scr))
428 return 0; 422 return 0;
429 423
430 spin_lock_irq(&current->sighand->siglock); 424 block_sigmask(ka, sig);
431 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
432 if (!(ka->sa.sa_flags & SA_NODEFER))
433 sigaddset(&current->blocked, sig);
434 recalc_sigpending();
435 spin_unlock_irq(&current->sighand->siglock);
436 425
437 /* 426 /*
438 * Let tracing know that we've done the handler setup. 427 * Let tracing know that we've done the handler setup.
diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h
index b2eeb0de1c8d..ea5f95e4079e 100644
--- a/arch/m32r/include/asm/signal.h
+++ b/arch/m32r/include/asm/signal.h
@@ -110,13 +110,6 @@ typedef unsigned long sigset_t;
110#include <asm-generic/signal-defs.h> 110#include <asm-generic/signal-defs.h>
111 111
112#ifdef __KERNEL__ 112#ifdef __KERNEL__
113struct old_sigaction {
114 __sighandler_t sa_handler;
115 old_sigset_t sa_mask;
116 unsigned long sa_flags;
117 __sigrestore_t sa_restorer;
118};
119
120struct sigaction { 113struct sigaction {
121 __sighandler_t sa_handler; 114 __sighandler_t sa_handler;
122 unsigned long sa_flags; 115 unsigned long sa_flags;
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index a08697f0886d..f54d96993ea1 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -112,10 +112,7 @@ sys_rt_sigreturn(unsigned long r0, unsigned long r1,
112 goto badframe; 112 goto badframe;
113 113
114 sigdelsetmask(&set, ~_BLOCKABLE); 114 sigdelsetmask(&set, ~_BLOCKABLE);
115 spin_lock_irq(&current->sighand->siglock); 115 set_current_blocked(&set);
116 current->blocked = set;
117 recalc_sigpending();
118 spin_unlock_irq(&current->sighand->siglock);
119 116
120 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &result)) 117 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &result))
121 goto badframe; 118 goto badframe;
@@ -300,12 +297,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
300 if (setup_rt_frame(sig, ka, info, oldset, regs)) 297 if (setup_rt_frame(sig, ka, info, oldset, regs))
301 return -EFAULT; 298 return -EFAULT;
302 299
303 spin_lock_irq(&current->sighand->siglock); 300 block_sigmask(ka, sig);
304 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
305 if (!(ka->sa.sa_flags & SA_NODEFER))
306 sigaddset(&current->blocked,sig);
307 recalc_sigpending();
308 spin_unlock_irq(&current->sighand->siglock);
309 return 0; 301 return 0;
310} 302}
311 303
diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h
index e8665e6f9464..126131f94a2c 100644
--- a/arch/m68k/include/asm/thread_info.h
+++ b/arch/m68k/include/asm/thread_info.h
@@ -71,6 +71,7 @@ static inline struct thread_info *current_thread_info(void)
71 * bits 0-7 are tested at every exception exit 71 * bits 0-7 are tested at every exception exit
72 * bits 8-15 are also tested at syscall exit 72 * bits 8-15 are also tested at syscall exit
73 */ 73 */
74#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
74#define TIF_SIGPENDING 6 /* signal pending */ 75#define TIF_SIGPENDING 6 /* signal pending */
75#define TIF_NEED_RESCHED 7 /* rescheduling necessary */ 76#define TIF_NEED_RESCHED 7 /* rescheduling necessary */
76#define TIF_DELAYED_TRACE 14 /* single step a syscall */ 77#define TIF_DELAYED_TRACE 14 /* single step a syscall */
diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S
index 675a854966a6..f29e73ca9dbb 100644
--- a/arch/m68k/kernel/entry_mm.S
+++ b/arch/m68k/kernel/entry_mm.S
@@ -148,7 +148,7 @@ syscall_exit_work:
148 jcs do_trace_exit 148 jcs do_trace_exit
149 jmi do_delayed_trace 149 jmi do_delayed_trace
150 lslw #8,%d0 150 lslw #8,%d0
151 jmi do_signal_return 151 jne do_signal_return
152 pea resume_userspace 152 pea resume_userspace
153 jra schedule 153 jra schedule
154 154
@@ -172,7 +172,7 @@ exit_work:
172 | save top of frame 172 | save top of frame
173 movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 173 movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
174 lslb #1,%d0 174 lslb #1,%d0
175 jmi do_signal_return 175 jne do_signal_return
176 pea resume_userspace 176 pea resume_userspace
177 jra schedule 177 jra schedule
178 178
@@ -182,7 +182,7 @@ do_signal_return:
182 subql #4,%sp | dummy return address 182 subql #4,%sp | dummy return address
183 SAVE_SWITCH_STACK 183 SAVE_SWITCH_STACK
184 pea %sp@(SWITCH_STACK_SIZE) 184 pea %sp@(SWITCH_STACK_SIZE)
185 bsrl do_signal 185 bsrl do_notify_resume
186 addql #4,%sp 186 addql #4,%sp
187 RESTORE_SWITCH_STACK 187 RESTORE_SWITCH_STACK
188 addql #4,%sp 188 addql #4,%sp
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index 1747c7030a33..d9f3d1900eed 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -43,6 +43,7 @@
43#include <linux/tty.h> 43#include <linux/tty.h>
44#include <linux/binfmts.h> 44#include <linux/binfmts.h>
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/tracehook.h>
46 47
47#include <asm/setup.h> 48#include <asm/setup.h>
48#include <asm/uaccess.h> 49#include <asm/uaccess.h>
@@ -230,18 +231,9 @@ static inline void push_cache(unsigned long vaddr)
230asmlinkage int 231asmlinkage int
231sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) 232sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
232{ 233{
233 mask &= _BLOCKABLE; 234 sigset_t blocked;
234 spin_lock_irq(&current->sighand->siglock); 235 siginitset(&blocked, mask);
235 current->saved_sigmask = current->blocked; 236 return sigsuspend(&blocked);
236 siginitset(&current->blocked, mask);
237 recalc_sigpending();
238 spin_unlock_irq(&current->sighand->siglock);
239
240 current->state = TASK_INTERRUPTIBLE;
241 schedule();
242 set_restore_sigmask();
243
244 return -ERESTARTNOHAND;
245} 237}
246 238
247asmlinkage int 239asmlinkage int
@@ -804,8 +796,7 @@ asmlinkage int do_sigreturn(unsigned long __unused)
804 goto badframe; 796 goto badframe;
805 797
806 sigdelsetmask(&set, ~_BLOCKABLE); 798 sigdelsetmask(&set, ~_BLOCKABLE);
807 current->blocked = set; 799 set_current_blocked(&set);
808 recalc_sigpending();
809 800
810 if (restore_sigcontext(regs, &frame->sc, frame + 1)) 801 if (restore_sigcontext(regs, &frame->sc, frame + 1))
811 goto badframe; 802 goto badframe;
@@ -830,8 +821,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
830 goto badframe; 821 goto badframe;
831 822
832 sigdelsetmask(&set, ~_BLOCKABLE); 823 sigdelsetmask(&set, ~_BLOCKABLE);
833 current->blocked = set; 824 set_current_blocked(&set);
834 recalc_sigpending();
835 825
836 if (rt_restore_ucontext(regs, sw, &frame->uc)) 826 if (rt_restore_ucontext(regs, sw, &frame->uc))
837 goto badframe; 827 goto badframe;
@@ -1150,10 +1140,7 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
1150 if (err) 1140 if (err)
1151 return; 1141 return;
1152 1142
1153 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 1143 block_sigmask(ka, sig);
1154 if (!(ka->sa.sa_flags & SA_NODEFER))
1155 sigaddset(&current->blocked,sig);
1156 recalc_sigpending();
1157 1144
1158 if (test_thread_flag(TIF_DELAYED_TRACE)) { 1145 if (test_thread_flag(TIF_DELAYED_TRACE)) {
1159 regs->sr &= ~0x8000; 1146 regs->sr &= ~0x8000;
@@ -1168,7 +1155,7 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
1168 * want to handle. Thus you cannot kill init even with a SIGKILL even by 1155 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1169 * mistake. 1156 * mistake.
1170 */ 1157 */
1171asmlinkage void do_signal(struct pt_regs *regs) 1158static void do_signal(struct pt_regs *regs)
1172{ 1159{
1173 siginfo_t info; 1160 siginfo_t info;
1174 struct k_sigaction ka; 1161 struct k_sigaction ka;
@@ -1200,3 +1187,15 @@ asmlinkage void do_signal(struct pt_regs *regs)
1200 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 1187 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1201 } 1188 }
1202} 1189}
1190
1191void do_notify_resume(struct pt_regs *regs)
1192{
1193 if (test_thread_flag(TIF_SIGPENDING))
1194 do_signal(regs);
1195
1196 if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
1197 tracehook_notify_resume(regs);
1198 if (current->replacement_session_keyring)
1199 key_replace_session_keyring();
1200 }
1201}
diff --git a/arch/m68k/platform/68328/entry.S b/arch/m68k/platform/68328/entry.S
index 5c39b80ed7de..7f91c2fde509 100644
--- a/arch/m68k/platform/68328/entry.S
+++ b/arch/m68k/platform/68328/entry.S
@@ -119,7 +119,7 @@ Lsignal_return:
119 subql #4,%sp /* dummy return address*/ 119 subql #4,%sp /* dummy return address*/
120 SAVE_SWITCH_STACK 120 SAVE_SWITCH_STACK
121 pea %sp@(SWITCH_STACK_SIZE) 121 pea %sp@(SWITCH_STACK_SIZE)
122 bsrw do_signal 122 bsrw do_notify_resume
123 addql #4,%sp 123 addql #4,%sp
124 RESTORE_SWITCH_STACK 124 RESTORE_SWITCH_STACK
125 addql #4,%sp 125 addql #4,%sp
diff --git a/arch/m68k/platform/68360/entry.S b/arch/m68k/platform/68360/entry.S
index aa47d1d49929..904fd9a4af4e 100644
--- a/arch/m68k/platform/68360/entry.S
+++ b/arch/m68k/platform/68360/entry.S
@@ -115,7 +115,7 @@ Lsignal_return:
115 subql #4,%sp /* dummy return address*/ 115 subql #4,%sp /* dummy return address*/
116 SAVE_SWITCH_STACK 116 SAVE_SWITCH_STACK
117 pea %sp@(SWITCH_STACK_SIZE) 117 pea %sp@(SWITCH_STACK_SIZE)
118 bsrw do_signal 118 bsrw do_notify_resume
119 addql #4,%sp 119 addql #4,%sp
120 RESTORE_SWITCH_STACK 120 RESTORE_SWITCH_STACK
121 addql #4,%sp 121 addql #4,%sp
diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S
index 281e38c2b6c7..881ab8e379d4 100644
--- a/arch/m68k/platform/coldfire/entry.S
+++ b/arch/m68k/platform/coldfire/entry.S
@@ -152,7 +152,7 @@ Lsignal_return:
152 subql #4,%sp /* dummy return address */ 152 subql #4,%sp /* dummy return address */
153 SAVE_SWITCH_STACK 153 SAVE_SWITCH_STACK
154 pea %sp@(SWITCH_STACK_SIZE) 154 pea %sp@(SWITCH_STACK_SIZE)
155 jsr do_signal 155 jsr do_notify_resume
156 addql #4,%sp 156 addql #4,%sp
157 RESTORE_SWITCH_STACK 157 RESTORE_SWITCH_STACK
158 addql #4,%sp 158 addql #4,%sp
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index 34b526f59b43..75c3ea1f48a1 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -132,11 +132,10 @@ ret_from_intr:
132 beqi r11, 1f 132 beqi r11, 1f
133 bralid r15, schedule 133 bralid r15, schedule
134 nop 134 nop
1351: andi r11, r19, _TIF_SIGPENDING 1351: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
136 beqid r11, no_intr_resched 136 beqid r11, no_intr_resched
137 addk r5, r1, r0 137 addk r5, r1, r0
138 addk r7, r0, r0 138 bralid r15, do_notify_resume
139 bralid r15, do_signal
140 addk r6, r0, r0 139 addk r6, r0, r0
141 140
142no_intr_resched: 141no_intr_resched:
@@ -292,8 +291,8 @@ ENTRY(_user_exception)
292 291
293/* 292/*
294 * Debug traps are like a system call, but entered via brki r14, 0x60 293 * Debug traps are like a system call, but entered via brki r14, 0x60
295 * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal 294 * All we need to do is send the SIGTRAP signal to current, ptrace and
296 * will handle the rest 295 * do_notify_resume will handle the rest
297 */ 296 */
298ENTRY(_debug_exception) 297ENTRY(_debug_exception)
299 swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ 298 swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
@@ -482,12 +481,11 @@ work_pending:
482 beqi r11, 1f 481 beqi r11, 1f
483 bralid r15, schedule 482 bralid r15, schedule
484 nop 483 nop
4851: andi r11, r19, _TIF_SIGPENDING 4841: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
486 beqi r11, no_work_pending 485 beqi r11, no_work_pending
487 addk r5, r1, r0 486 addk r5, r1, r0
488 addik r7, r0, 1 487 bralid r15, do_notify_resume
489 bralid r15, do_signal 488 addik r6, r0, 1
490 addk r6, r0, r0
491 bri no_work_pending 489 bri no_work_pending
492 490
493ENTRY(ret_to_user) 491ENTRY(ret_to_user)
@@ -569,10 +567,6 @@ sys_rt_sigreturn_wrapper:
569 brid sys_rt_sigreturn 567 brid sys_rt_sigreturn
570 addk r5, r1, r0 568 addk r5, r1, r0
571 569
572sys_rt_sigsuspend_wrapper:
573 brid sys_rt_sigsuspend
574 addk r7, r1, r0
575
576 /* Interrupt vector table */ 570 /* Interrupt vector table */
577 .section .init.ivt, "ax" 571 .section .init.ivt, "ax"
578 .org 0x0 572 .org 0x0
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 66e34a3bfe1b..daff9e5e4a1f 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -430,13 +430,12 @@ C_ENTRY(ret_from_trap):
4305: /* get thread info from current task*/ 4305: /* get thread info from current task*/
431 lwi r11, CURRENT_TASK, TS_THREAD_INFO; 431 lwi r11, CURRENT_TASK, TS_THREAD_INFO;
432 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 432 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
433 andi r11, r11, _TIF_SIGPENDING; 433 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
434 beqi r11, 1f; /* Signals to handle, handle them */ 434 beqi r11, 1f; /* Signals to handle, handle them */
435 435
436 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 436 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
437 addi r7, r0, 1; /* Arg 3: int in_syscall */ 437 bralid r15, do_notify_resume; /* Handle any signals */
438 bralid r15, do_signal; /* Handle any signals */ 438 addi r6, r0, 1; /* Arg 2: int in_syscall */
439 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
440 439
441/* Finally, return to user state. */ 440/* Finally, return to user state. */
4421: set_bip; /* Ints masked for state restore */ 4411: set_bip; /* Ints masked for state restore */
@@ -622,7 +621,7 @@ C_ENTRY(ret_from_exc):
622 /* Maybe handle a signal */ 621 /* Maybe handle a signal */
6235: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 6225: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
624 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 623 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
625 andi r11, r11, _TIF_SIGPENDING; 624 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
626 beqi r11, 1f; /* Signals to handle, handle them */ 625 beqi r11, 1f; /* Signals to handle, handle them */
627 626
628 /* 627 /*
@@ -635,11 +634,10 @@ C_ENTRY(ret_from_exc):
635 * traps), but signal handlers may want to examine or change the 634 * traps), but signal handlers may want to examine or change the
636 * complete register state. Here we save anything not saved by 635 * complete register state. Here we save anything not saved by
637 * the normal entry sequence, so that it may be safely restored 636 * the normal entry sequence, so that it may be safely restored
638 * (in a possibly modified form) after do_signal returns. */ 637 * (in a possibly modified form) after do_notify_resume returns. */
639 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 638 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
640 addi r7, r0, 0; /* Arg 3: int in_syscall */ 639 bralid r15, do_notify_resume; /* Handle any signals */
641 bralid r15, do_signal; /* Handle any signals */ 640 addi r6, r0, 0; /* Arg 2: int in_syscall */
642 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
643 641
644/* Finally, return to user state. */ 642/* Finally, return to user state. */
6451: set_bip; /* Ints masked for state restore */ 6431: set_bip; /* Ints masked for state restore */
@@ -732,13 +730,12 @@ ret_from_irq:
732 /* Maybe handle a signal */ 730 /* Maybe handle a signal */
7335: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */ 7315: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */
734 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 732 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
735 andi r11, r11, _TIF_SIGPENDING; 733 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
736 beqid r11, no_intr_resched 734 beqid r11, no_intr_resched
737/* Handle a signal return; Pending signals should be in r18. */ 735/* Handle a signal return; Pending signals should be in r18. */
738 addi r7, r0, 0; /* Arg 3: int in_syscall */
739 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 736 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
740 bralid r15, do_signal; /* Handle any signals */ 737 bralid r15, do_notify_resume; /* Handle any signals */
741 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 738 addi r6, r0, 0; /* Arg 2: int in_syscall */
742 739
743/* Finally, return to user state. */ 740/* Finally, return to user state. */
744no_intr_resched: 741no_intr_resched:
@@ -869,13 +866,12 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
869 /* Maybe handle a signal */ 866 /* Maybe handle a signal */
8705: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ 8675: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
871 lwi r11, r11, TI_FLAGS; /* get flags in thread info */ 868 lwi r11, r11, TI_FLAGS; /* get flags in thread info */
872 andi r11, r11, _TIF_SIGPENDING; 869 andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
873 beqi r11, 1f; /* Signals to handle, handle them */ 870 beqi r11, 1f; /* Signals to handle, handle them */
874 871
875 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */ 872 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
876 addi r7, r0, 0; /* Arg 3: int in_syscall */ 873 bralid r15, do_notify_resume; /* Handle any signals */
877 bralid r15, do_signal; /* Handle any signals */ 874 addi r6, r0, 0; /* Arg 2: int in_syscall */
878 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
879 875
880/* Finally, return to user state. */ 876/* Finally, return to user state. */
8811: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ 8771: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 599671168980..7f4c7bef1642 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -31,6 +31,7 @@
31#include <linux/personality.h> 31#include <linux/personality.h>
32#include <linux/percpu.h> 32#include <linux/percpu.h>
33#include <linux/linkage.h> 33#include <linux/linkage.h>
34#include <linux/tracehook.h>
34#include <asm/entry.h> 35#include <asm/entry.h>
35#include <asm/ucontext.h> 36#include <asm/ucontext.h>
36#include <linux/uaccess.h> 37#include <linux/uaccess.h>
@@ -42,8 +43,6 @@
42 43
43#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
44 45
45asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
46
47asmlinkage long 46asmlinkage long
48sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 47sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
49 struct pt_regs *regs) 48 struct pt_regs *regs)
@@ -98,6 +97,9 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
98 sigset_t set; 97 sigset_t set;
99 int rval; 98 int rval;
100 99
100 /* Always make any pending restarted system calls return -EINTR */
101 current_thread_info()->restart_block.fn = do_no_restart_syscall;
102
101 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 103 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
102 goto badframe; 104 goto badframe;
103 105
@@ -105,10 +107,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
105 goto badframe; 107 goto badframe;
106 108
107 sigdelsetmask(&set, ~_BLOCKABLE); 109 sigdelsetmask(&set, ~_BLOCKABLE);
108 spin_lock_irq(&current->sighand->siglock); 110 set_current_blocked(&set);
109 current->blocked = set;
110 recalc_sigpending();
111 spin_unlock_irq(&current->sighand->siglock);
112 111
113 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval)) 112 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
114 goto badframe; 113 goto badframe;
@@ -169,7 +168,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
169 return (void __user *)((sp - frame_size) & -8UL); 168 return (void __user *)((sp - frame_size) & -8UL);
170} 169}
171 170
172static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 171static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
173 sigset_t *set, struct pt_regs *regs) 172 sigset_t *set, struct pt_regs *regs)
174{ 173{
175 struct rt_sigframe __user *frame; 174 struct rt_sigframe __user *frame;
@@ -267,12 +266,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
267 current->comm, current->pid, frame, regs->pc); 266 current->comm, current->pid, frame, regs->pc);
268#endif 267#endif
269 268
270 return; 269 return 0;
271 270
272give_sigsegv: 271give_sigsegv:
273 if (sig == SIGSEGV) 272 force_sigsegv(sig, current);
274 ka->sa.sa_handler = SIG_DFL; 273 return -EFAULT;
275 force_sig(SIGSEGV, current);
276} 274}
277 275
278/* Handle restarting system calls */ 276/* Handle restarting system calls */
@@ -316,24 +314,20 @@ static int
316handle_signal(unsigned long sig, struct k_sigaction *ka, 314handle_signal(unsigned long sig, struct k_sigaction *ka,
317 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) 315 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
318{ 316{
317 int ret;
318
319 /* Set up the stack frame */ 319 /* Set up the stack frame */
320 if (ka->sa.sa_flags & SA_SIGINFO) 320 if (ka->sa.sa_flags & SA_SIGINFO)
321 setup_rt_frame(sig, ka, info, oldset, regs); 321 ret = setup_rt_frame(sig, ka, info, oldset, regs);
322 else 322 else
323 setup_rt_frame(sig, ka, NULL, oldset, regs); 323 ret = setup_rt_frame(sig, ka, NULL, oldset, regs);
324 324
325 if (ka->sa.sa_flags & SA_ONESHOT) 325 if (ret)
326 ka->sa.sa_handler = SIG_DFL; 326 return ret;
327 327
328 if (!(ka->sa.sa_flags & SA_NODEFER)) { 328 block_sigmask(ka, sig);
329 spin_lock_irq(&current->sighand->siglock); 329
330 sigorsets(&current->blocked, 330 return 0;
331 &current->blocked, &ka->sa.sa_mask);
332 sigaddset(&current->blocked, sig);
333 recalc_sigpending();
334 spin_unlock_irq(&current->sighand->siglock);
335 }
336 return 1;
337} 331}
338 332
339/* 333/*
@@ -345,24 +339,17 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
345 * the kernel can handle, and then we build all the user-level signal handling 339 * the kernel can handle, and then we build all the user-level signal handling
346 * stack-frames in one go after that. 340 * stack-frames in one go after that.
347 */ 341 */
348int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) 342static void do_signal(struct pt_regs *regs, int in_syscall)
349{ 343{
350 siginfo_t info; 344 siginfo_t info;
351 int signr; 345 int signr;
352 struct k_sigaction ka; 346 struct k_sigaction ka;
347 sigset_t *oldset;
353#ifdef DEBUG_SIG 348#ifdef DEBUG_SIG
354 printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall); 349 printk(KERN_INFO "do signal: %p %d\n", regs, in_syscall);
355 printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1, 350 printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
356 regs->r12, current_thread_info()->flags); 351 regs->r12, current_thread_info()->flags);
357#endif 352#endif
358 /*
359 * We want the common case to go fast, which
360 * is why we may in certain cases get here from
361 * kernel mode. Just return without doing anything
362 * if so.
363 */
364 if (kernel_mode(regs))
365 return 1;
366 353
367 if (current_thread_info()->status & TS_RESTORE_SIGMASK) 354 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
368 oldset = &current->saved_sigmask; 355 oldset = &current->saved_sigmask;
@@ -374,7 +361,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
374 /* Whee! Actually deliver the signal. */ 361 /* Whee! Actually deliver the signal. */
375 if (in_syscall) 362 if (in_syscall)
376 handle_restart(regs, &ka, 1); 363 handle_restart(regs, &ka, 1);
377 if (handle_signal(signr, &ka, &info, oldset, regs)) { 364 if (!handle_signal(signr, &ka, &info, oldset, regs)) {
378 /* 365 /*
379 * A signal was successfully delivered; the saved 366 * A signal was successfully delivered; the saved
380 * sigmask will have been stored in the signal frame, 367 * sigmask will have been stored in the signal frame,
@@ -384,7 +371,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
384 current_thread_info()->status &= 371 current_thread_info()->status &=
385 ~TS_RESTORE_SIGMASK; 372 ~TS_RESTORE_SIGMASK;
386 } 373 }
387 return 1; 374 return;
388 } 375 }
389 376
390 if (in_syscall) 377 if (in_syscall)
@@ -398,7 +385,25 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
398 current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 385 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
399 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 386 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
400 } 387 }
388}
401 389
402 /* Did we come from a system call? */ 390void do_notify_resume(struct pt_regs *regs, int in_syscall)
403 return 0; 391{
392 /*
393 * We want the common case to go fast, which
394 * is why we may in certain cases get here from
395 * kernel mode. Just return without doing anything
396 * if so.
397 */
398 if (kernel_mode(regs))
399 return;
400
401 if (test_thread_flag(TIF_SIGPENDING))
402 do_signal(regs, in_syscall);
403
404 if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
405 tracehook_notify_resume(regs);
406 if (current->replacement_session_keyring)
407 key_replace_session_keyring();
408 }
404} 409}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index d5a338a1739c..17f6ee30ad0d 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -255,15 +255,7 @@ asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
255 uset = (sigset_t __user *) regs.regs[4]; 255 uset = (sigset_t __user *) regs.regs[4];
256 if (copy_from_user(&newset, uset, sizeof(sigset_t))) 256 if (copy_from_user(&newset, uset, sizeof(sigset_t)))
257 return -EFAULT; 257 return -EFAULT;
258 sigdelsetmask(&newset, ~_BLOCKABLE); 258 return sigsuspend(&newset);
259
260 current->saved_sigmask = current->blocked;
261 set_current_blocked(&newset);
262
263 current->state = TASK_INTERRUPTIBLE;
264 schedule();
265 set_thread_flag(TIF_RESTORE_SIGMASK);
266 return -ERESTARTNOHAND;
267} 259}
268#endif 260#endif
269 261
@@ -281,15 +273,7 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
281 unewset = (sigset_t __user *) regs.regs[4]; 273 unewset = (sigset_t __user *) regs.regs[4];
282 if (copy_from_user(&newset, unewset, sizeof(newset))) 274 if (copy_from_user(&newset, unewset, sizeof(newset)))
283 return -EFAULT; 275 return -EFAULT;
284 sigdelsetmask(&newset, ~_BLOCKABLE); 276 return sigsuspend(&newset);
285
286 current->saved_sigmask = current->blocked;
287 set_current_blocked(&newset);
288
289 current->state = TASK_INTERRUPTIBLE;
290 schedule();
291 set_thread_flag(TIF_RESTORE_SIGMASK);
292 return -ERESTARTNOHAND;
293} 277}
294 278
295#ifdef CONFIG_TRAD_SIGNALS 279#ifdef CONFIG_TRAD_SIGNALS
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index ac3b8d89aae5..b4fe2eacbd5d 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -288,15 +288,7 @@ asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
288 uset = (compat_sigset_t __user *) regs.regs[4]; 288 uset = (compat_sigset_t __user *) regs.regs[4];
289 if (get_sigset(&newset, uset)) 289 if (get_sigset(&newset, uset))
290 return -EFAULT; 290 return -EFAULT;
291 sigdelsetmask(&newset, ~_BLOCKABLE); 291 return sigsuspend(&newset);
292
293 current->saved_sigmask = current->blocked;
294 set_current_blocked(&newset);
295
296 current->state = TASK_INTERRUPTIBLE;
297 schedule();
298 set_thread_flag(TIF_RESTORE_SIGMASK);
299 return -ERESTARTNOHAND;
300} 292}
301 293
302asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) 294asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -313,15 +305,7 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
313 uset = (compat_sigset_t __user *) regs.regs[4]; 305 uset = (compat_sigset_t __user *) regs.regs[4];
314 if (get_sigset(&newset, uset)) 306 if (get_sigset(&newset, uset))
315 return -EFAULT; 307 return -EFAULT;
316 sigdelsetmask(&newset, ~_BLOCKABLE); 308 return sigsuspend(&newset);
317
318 current->saved_sigmask = current->blocked;
319 set_current_blocked(&newset);
320
321 current->state = TASK_INTERRUPTIBLE;
322 schedule();
323 set_thread_flag(TIF_RESTORE_SIGMASK);
324 return -ERESTARTNOHAND;
325} 309}
326 310
327SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act, 311SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 86eb4b04631c..63ffac9af7c5 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -91,15 +91,7 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
91 if (copy_from_user(&uset, unewset, sizeof(uset))) 91 if (copy_from_user(&uset, unewset, sizeof(uset)))
92 return -EFAULT; 92 return -EFAULT;
93 sigset_from_compat(&newset, &uset); 93 sigset_from_compat(&newset, &uset);
94 sigdelsetmask(&newset, ~_BLOCKABLE); 94 return sigsuspend(&newset);
95
96 current->saved_sigmask = current->blocked;
97 set_current_blocked(&newset);
98
99 current->state = TASK_INTERRUPTIBLE;
100 schedule();
101 set_thread_flag(TIF_RESTORE_SIGMASK);
102 return -ERESTARTNOHAND;
103} 95}
104 96
105asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) 97asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 690f4e9507d7..890cf91767cc 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -38,17 +38,9 @@
38 */ 38 */
39asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask) 39asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
40{ 40{
41 mask &= _BLOCKABLE; 41 sigset_t blocked;
42 spin_lock_irq(&current->sighand->siglock); 42 siginitset(&blocked, mask);
43 current->saved_sigmask = current->blocked; 43 return sigsuspend(&blocked);
44 siginitset(&current->blocked, mask);
45 recalc_sigpending();
46 spin_unlock_irq(&current->sighand->siglock);
47
48 current->state = TASK_INTERRUPTIBLE;
49 schedule();
50 set_thread_flag(TIF_RESTORE_SIGMASK);
51 return -ERESTARTNOHAND;
52} 44}
53 45
54/* 46/*
@@ -172,10 +164,7 @@ asmlinkage long sys_sigreturn(void)
172 goto badframe; 164 goto badframe;
173 165
174 sigdelsetmask(&set, ~_BLOCKABLE); 166 sigdelsetmask(&set, ~_BLOCKABLE);
175 spin_lock_irq(&current->sighand->siglock); 167 set_current_blocked(&set);
176 current->blocked = set;
177 recalc_sigpending();
178 spin_unlock_irq(&current->sighand->siglock);
179 168
180 if (restore_sigcontext(current_frame(), &frame->sc, &d0)) 169 if (restore_sigcontext(current_frame(), &frame->sc, &d0))
181 goto badframe; 170 goto badframe;
@@ -203,10 +192,7 @@ asmlinkage long sys_rt_sigreturn(void)
203 goto badframe; 192 goto badframe;
204 193
205 sigdelsetmask(&set, ~_BLOCKABLE); 194 sigdelsetmask(&set, ~_BLOCKABLE);
206 spin_lock_irq(&current->sighand->siglock); 195 set_current_blocked(&set);
207 current->blocked = set;
208 recalc_sigpending();
209 spin_unlock_irq(&current->sighand->siglock);
210 196
211 if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0)) 197 if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0))
212 goto badframe; 198 goto badframe;
@@ -476,15 +462,8 @@ static int handle_signal(int sig,
476 else 462 else
477 ret = setup_frame(sig, ka, oldset, regs); 463 ret = setup_frame(sig, ka, oldset, regs);
478 464
479 if (ret == 0) { 465 if (ret == 0)
480 spin_lock_irq(&current->sighand->siglock); 466 block_sigmask(ka, sig);
481 sigorsets(&current->blocked, &current->blocked,
482 &ka->sa.sa_mask);
483 if (!(ka->sa.sa_flags & SA_NODEFER))
484 sigaddset(&current->blocked, sig);
485 recalc_sigpending();
486 spin_unlock_irq(&current->sighand->siglock);
487 }
488 467
489 return ret; 468 return ret;
490} 469}
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 12c1ed33dc18..4b9cb0d546d1 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -109,6 +109,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
109 sigframe_size = PARISC_RT_SIGFRAME_SIZE32; 109 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
110#endif 110#endif
111 111
112 current_thread_info()->restart_block.fn = do_no_restart_syscall;
112 113
113 /* Unwind the user stack to get the rt_sigframe structure. */ 114 /* Unwind the user stack to get the rt_sigframe structure. */
114 frame = (struct rt_sigframe __user *) 115 frame = (struct rt_sigframe __user *)
@@ -131,10 +132,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
131 } 132 }
132 133
133 sigdelsetmask(&set, ~_BLOCKABLE); 134 sigdelsetmask(&set, ~_BLOCKABLE);
134 spin_lock_irq(&current->sighand->siglock); 135 set_current_blocked(&set);
135 current->blocked = set;
136 recalc_sigpending();
137 spin_unlock_irq(&current->sighand->siglock);
138 136
139 /* Good thing we saved the old gr[30], eh? */ 137 /* Good thing we saved the old gr[30], eh? */
140#ifdef CONFIG_64BIT 138#ifdef CONFIG_64BIT
@@ -454,12 +452,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
454 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) 452 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
455 return 0; 453 return 0;
456 454
457 spin_lock_irq(&current->sighand->siglock); 455 block_sigmask(ka, sig);
458 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
459 if (!(ka->sa.sa_flags & SA_NODEFER))
460 sigaddset(&current->blocked,sig);
461 recalc_sigpending();
462 spin_unlock_irq(&current->sighand->siglock);
463 456
464 tracehook_signal_handler(sig, info, ka, regs, 457 tracehook_signal_handler(sig, info, ka, regs,
465 test_thread_flag(TIF_SINGLESTEP) || 458 test_thread_flag(TIF_SINGLESTEP) ||
@@ -474,8 +467,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
474 /* Check the return code */ 467 /* Check the return code */
475 switch (regs->gr[28]) { 468 switch (regs->gr[28]) {
476 case -ERESTART_RESTARTBLOCK: 469 case -ERESTART_RESTARTBLOCK:
477 current_thread_info()->restart_block.fn =
478 do_no_restart_syscall;
479 case -ERESTARTNOHAND: 470 case -ERESTARTNOHAND:
480 DBG(1,"ERESTARTNOHAND: returning -EINTR\n"); 471 DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
481 regs->gr[28] = -EINTR; 472 regs->gr[28] = -EINTR;
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 45eb998557f8..61f6aff25edc 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -204,10 +204,10 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka,
204 204
205 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 205 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
206 __get_user(new_ka->sa.sa_handler, &act->sa_handler) || 206 __get_user(new_ka->sa.sa_handler, &act->sa_handler) ||
207 __get_user(new_ka->sa.sa_restorer, &act->sa_restorer)) 207 __get_user(new_ka->sa.sa_restorer, &act->sa_restorer) ||
208 __get_user(new_ka->sa.sa_flags, &act->sa_flags) ||
209 __get_user(mask, &act->sa_mask))
208 return -EFAULT; 210 return -EFAULT;
209 __get_user(new_ka->sa.sa_flags, &act->sa_flags);
210 __get_user(mask, &act->sa_mask);
211 siginitset(&new_ka->sa.sa_mask, mask); 211 siginitset(&new_ka->sa.sa_mask, mask);
212 return 0; 212 return 0;
213} 213}
@@ -244,17 +244,8 @@ static inline int restore_general_regs(struct pt_regs *regs,
244long sys_sigsuspend(old_sigset_t mask) 244long sys_sigsuspend(old_sigset_t mask)
245{ 245{
246 sigset_t blocked; 246 sigset_t blocked;
247
248 current->saved_sigmask = current->blocked;
249
250 mask &= _BLOCKABLE;
251 siginitset(&blocked, mask); 247 siginitset(&blocked, mask);
252 set_current_blocked(&blocked); 248 return sigsuspend(&blocked);
253
254 current->state = TASK_INTERRUPTIBLE;
255 schedule();
256 set_restore_sigmask();
257 return -ERESTARTNOHAND;
258} 249}
259 250
260long sys_sigaction(int sig, struct old_sigaction __user *act, 251long sys_sigaction(int sig, struct old_sigaction __user *act,
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 8a4e2b760d56..f626232e216c 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -59,15 +59,8 @@ typedef struct
59SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask) 59SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask)
60{ 60{
61 sigset_t blocked; 61 sigset_t blocked;
62
63 current->saved_sigmask = current->blocked;
64 mask &= _BLOCKABLE;
65 siginitset(&blocked, mask); 62 siginitset(&blocked, mask);
66 set_current_blocked(&blocked); 63 return sigsuspend(&blocked);
67 set_current_state(TASK_INTERRUPTIBLE);
68 schedule();
69 set_restore_sigmask();
70 return -ERESTARTNOHAND;
71} 64}
72 65
73SYSCALL_DEFINE3(sigaction, int, sig, const struct old_sigaction __user *, act, 66SYSCALL_DEFINE3(sigaction, int, sig, const struct old_sigaction __user *, act,
diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c
index aa57440e4973..d4a49011c48a 100644
--- a/arch/score/kernel/signal.c
+++ b/arch/score/kernel/signal.c
@@ -28,6 +28,7 @@
28#include <linux/ptrace.h> 28#include <linux/ptrace.h>
29#include <linux/unistd.h> 29#include <linux/unistd.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/tracehook.h>
31 32
32#include <asm/cacheflush.h> 33#include <asm/cacheflush.h>
33#include <asm/syscalls.h> 34#include <asm/syscalls.h>
@@ -152,6 +153,9 @@ score_rt_sigreturn(struct pt_regs *regs)
152 stack_t st; 153 stack_t st;
153 int sig; 154 int sig;
154 155
156 /* Always make any pending restarted system calls return -EINTR */
157 current_thread_info()->restart_block.fn = do_no_restart_syscall;
158
155 frame = (struct rt_sigframe __user *) regs->regs[0]; 159 frame = (struct rt_sigframe __user *) regs->regs[0];
156 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 160 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
157 goto badframe; 161 goto badframe;
@@ -159,10 +163,7 @@ score_rt_sigreturn(struct pt_regs *regs)
159 goto badframe; 163 goto badframe;
160 164
161 sigdelsetmask(&set, ~_BLOCKABLE); 165 sigdelsetmask(&set, ~_BLOCKABLE);
162 spin_lock_irq(&current->sighand->siglock); 166 set_current_blocked(&set);
163 current->blocked = set;
164 recalc_sigpending();
165 spin_unlock_irq(&current->sighand->siglock);
166 167
167 sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext); 168 sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext);
168 if (sig < 0) 169 if (sig < 0)
@@ -236,9 +237,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
236 return 0; 237 return 0;
237 238
238give_sigsegv: 239give_sigsegv:
239 if (signr == SIGSEGV) 240 force_sigsegv(signr, current);
240 ka->sa.sa_handler = SIG_DFL;
241 force_sig(SIGSEGV, current);
242 return -EFAULT; 241 return -EFAULT;
243} 242}
244 243
@@ -272,12 +271,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
272 */ 271 */
273 ret = setup_rt_frame(ka, regs, sig, oldset, info); 272 ret = setup_rt_frame(ka, regs, sig, oldset, info);
274 273
275 spin_lock_irq(&current->sighand->siglock); 274 if (ret == 0)
276 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask); 275 block_sigmask(ka, sig);
277 if (!(ka->sa.sa_flags & SA_NODEFER))
278 sigaddset(&current->blocked, sig);
279 recalc_sigpending();
280 spin_unlock_irq(&current->sighand->siglock);
281 276
282 return ret; 277 return ret;
283} 278}
@@ -356,6 +351,12 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
356 __u32 thread_info_flags) 351 __u32 thread_info_flags)
357{ 352{
358 /* deal with pending signal delivery */ 353 /* deal with pending signal delivery */
359 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 354 if (thread_info_flags & _TIF_SIGPENDING)
360 do_signal(regs); 355 do_signal(regs);
356 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
357 clear_thread_flag(TIF_NOTIFY_RESUME);
358 tracehook_notify_resume(regs);
359 if (current->replacement_session_keyring)
360 key_replace_session_keyring();
361 }
361} 362}
diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h
index ae717e3c26d6..6c1fa559753c 100644
--- a/arch/sh/include/asm/syscalls_32.h
+++ b/arch/sh/include/asm/syscalls_32.h
@@ -23,9 +23,7 @@ asmlinkage int sys_execve(const char __user *ufilename,
23 const char __user *const __user *uargv, 23 const char __user *const __user *uargv,
24 const char __user *const __user *uenvp, 24 const char __user *const __user *uenvp,
25 unsigned long r7, struct pt_regs __regs); 25 unsigned long r7, struct pt_regs __regs);
26asmlinkage int sys_sigsuspend(old_sigset_t mask, unsigned long r5, 26asmlinkage int sys_sigsuspend(old_sigset_t mask);
27 unsigned long r6, unsigned long r7,
28 struct pt_regs __regs);
29asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act, 27asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act,
30 struct old_sigaction __user *oact); 28 struct old_sigaction __user *oact);
31asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 29asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
diff --git a/arch/sh/include/asm/unistd.h b/arch/sh/include/asm/unistd.h
index a42a5610a36a..e800a38c9f8d 100644
--- a/arch/sh/include/asm/unistd.h
+++ b/arch/sh/include/asm/unistd.h
@@ -1,13 +1,11 @@
1#ifdef __KERNEL__ 1#ifdef __KERNEL__
2# ifdef CONFIG_SUPERH32 2# ifdef CONFIG_SUPERH32
3
4# include "unistd_32.h" 3# include "unistd_32.h"
5# define __ARCH_WANT_SYS_RT_SIGSUSPEND
6
7# else 4# else
8# include "unistd_64.h" 5# include "unistd_64.h"
9# endif 6# endif
10 7
8# define __ARCH_WANT_SYS_RT_SIGSUSPEND
11# define __ARCH_WANT_IPC_PARSE_VERSION 9# define __ARCH_WANT_IPC_PARSE_VERSION
12# define __ARCH_WANT_OLD_READDIR 10# define __ARCH_WANT_OLD_READDIR
13# define __ARCH_WANT_OLD_STAT 11# define __ARCH_WANT_OLD_STAT
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 5901fba3176e..cb4172c8af7d 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -53,23 +53,11 @@ struct fdpic_func_descriptor {
53 * Atomically swap in the new signal mask, and wait for a signal. 53 * Atomically swap in the new signal mask, and wait for a signal.
54 */ 54 */
55asmlinkage int 55asmlinkage int
56sys_sigsuspend(old_sigset_t mask, 56sys_sigsuspend(old_sigset_t mask)
57 unsigned long r5, unsigned long r6, unsigned long r7,
58 struct pt_regs __regs)
59{ 57{
60 sigset_t blocked; 58 sigset_t blocked;
61
62 current->saved_sigmask = current->blocked;
63
64 mask &= _BLOCKABLE;
65 siginitset(&blocked, mask); 59 siginitset(&blocked, mask);
66 set_current_blocked(&blocked); 60 return sigsuspend(&blocked);
67
68 current->state = TASK_INTERRUPTIBLE;
69 schedule();
70 set_restore_sigmask();
71
72 return -ERESTARTNOHAND;
73} 61}
74 62
75asmlinkage int 63asmlinkage int
@@ -83,10 +71,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
83 old_sigset_t mask; 71 old_sigset_t mask;
84 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 72 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
85 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 73 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
86 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 74 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
75 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
76 __get_user(mask, &act->sa_mask))
87 return -EFAULT; 77 return -EFAULT;
88 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
89 __get_user(mask, &act->sa_mask);
90 siginitset(&new_ka.sa.sa_mask, mask); 78 siginitset(&new_ka.sa.sa_mask, mask);
91 } 79 }
92 80
@@ -95,10 +83,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
95 if (!ret && oact) { 83 if (!ret && oact) {
96 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 84 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
97 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 85 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
98 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 86 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
87 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
88 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
99 return -EFAULT; 89 return -EFAULT;
100 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
101 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
102 } 90 }
103 91
104 return ret; 92 return ret;
@@ -162,12 +150,11 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
162 if (!(boot_cpu_data.flags & CPU_HAS_FPU)) 150 if (!(boot_cpu_data.flags & CPU_HAS_FPU))
163 return 0; 151 return 0;
164 152
165 if (!used_math()) { 153 if (!used_math())
166 __put_user(0, &sc->sc_ownedfp); 154 return __put_user(0, &sc->sc_ownedfp);
167 return 0;
168 }
169 155
170 __put_user(1, &sc->sc_ownedfp); 156 if (__put_user(1, &sc->sc_ownedfp))
157 return -EFAULT;
171 158
172 /* This will cause a "finit" to be triggered by the next 159 /* This will cause a "finit" to be triggered by the next
173 attempted FPU operation by the 'current' process. 160 attempted FPU operation by the 'current' process.
@@ -207,7 +194,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
207 regs->sr |= SR_FD; /* Release FPU */ 194 regs->sr |= SR_FD; /* Release FPU */
208 clear_fpu(tsk, regs); 195 clear_fpu(tsk, regs);
209 clear_used_math(); 196 clear_used_math();
210 __get_user (owned_fp, &sc->sc_ownedfp); 197 err |= __get_user (owned_fp, &sc->sc_ownedfp);
211 if (owned_fp) 198 if (owned_fp)
212 err |= restore_sigcontext_fpu(sc); 199 err |= restore_sigcontext_fpu(sc);
213 } 200 }
@@ -398,11 +385,14 @@ static int setup_frame(int sig, struct k_sigaction *ka,
398 struct fdpic_func_descriptor __user *funcptr = 385 struct fdpic_func_descriptor __user *funcptr =
399 (struct fdpic_func_descriptor __user *)ka->sa.sa_handler; 386 (struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
400 387
401 __get_user(regs->pc, &funcptr->text); 388 err |= __get_user(regs->pc, &funcptr->text);
402 __get_user(regs->regs[12], &funcptr->GOT); 389 err |= __get_user(regs->regs[12], &funcptr->GOT);
403 } else 390 } else
404 regs->pc = (unsigned long)ka->sa.sa_handler; 391 regs->pc = (unsigned long)ka->sa.sa_handler;
405 392
393 if (err)
394 goto give_sigsegv;
395
406 set_fs(USER_DS); 396 set_fs(USER_DS);
407 397
408 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", 398 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
@@ -482,11 +472,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
482 struct fdpic_func_descriptor __user *funcptr = 472 struct fdpic_func_descriptor __user *funcptr =
483 (struct fdpic_func_descriptor __user *)ka->sa.sa_handler; 473 (struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
484 474
485 __get_user(regs->pc, &funcptr->text); 475 err |= __get_user(regs->pc, &funcptr->text);
486 __get_user(regs->regs[12], &funcptr->GOT); 476 err |= __get_user(regs->regs[12], &funcptr->GOT);
487 } else 477 } else
488 regs->pc = (unsigned long)ka->sa.sa_handler; 478 regs->pc = (unsigned long)ka->sa.sa_handler;
489 479
480 if (err)
481 goto give_sigsegv;
482
490 set_fs(USER_DS); 483 set_fs(USER_DS);
491 484
492 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", 485 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 3c9a6f7dcdce..b589a354c069 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -83,11 +83,12 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
83 * the kernel can handle, and then we build all the user-level signal handling 83 * the kernel can handle, and then we build all the user-level signal handling
84 * stack-frames in one go after that. 84 * stack-frames in one go after that.
85 */ 85 */
86static int do_signal(struct pt_regs *regs, sigset_t *oldset) 86static void do_signal(struct pt_regs *regs)
87{ 87{
88 siginfo_t info; 88 siginfo_t info;
89 int signr; 89 int signr;
90 struct k_sigaction ka; 90 struct k_sigaction ka;
91 sigset_t *oldset;
91 92
92 /* 93 /*
93 * We want the common case to go fast, which 94 * We want the common case to go fast, which
@@ -96,11 +97,11 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
96 * if so. 97 * if so.
97 */ 98 */
98 if (!user_mode(regs)) 99 if (!user_mode(regs))
99 return 1; 100 return;
100 101
101 if (current_thread_info()->status & TS_RESTORE_SIGMASK) 102 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
102 oldset = &current->saved_sigmask; 103 oldset = &current->saved_sigmask;
103 else if (!oldset) 104 else
104 oldset = &current->blocked; 105 oldset = &current->blocked;
105 106
106 signr = get_signal_to_deliver(&info, &ka, regs, 0); 107 signr = get_signal_to_deliver(&info, &ka, regs, 0);
@@ -118,7 +119,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
118 119
119 tracehook_signal_handler(signr, &info, &ka, regs, 120 tracehook_signal_handler(signr, &info, &ka, regs,
120 test_thread_flag(TIF_SINGLESTEP)); 121 test_thread_flag(TIF_SINGLESTEP));
121 return 1; 122 return;
122 } 123 }
123 } 124 }
124 125
@@ -147,71 +148,18 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
147 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 148 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
148 } 149 }
149 150
150 return 0; 151 return;
151} 152}
152 153
153/* 154/*
154 * Atomically swap in the new signal mask, and wait for a signal. 155 * Atomically swap in the new signal mask, and wait for a signal.
155 */ 156 */
156asmlinkage int 157asmlinkage int
157sys_sigsuspend(old_sigset_t mask, 158sys_sigsuspend(old_sigset_t mask)
158 unsigned long r3, unsigned long r4, unsigned long r5,
159 unsigned long r6, unsigned long r7,
160 struct pt_regs * regs)
161{ 159{
162 sigset_t saveset, blocked; 160 sigset_t blocked;
163
164 saveset = current->blocked;
165
166 mask &= _BLOCKABLE;
167 siginitset(&blocked, mask); 161 siginitset(&blocked, mask);
168 set_current_blocked(&blocked); 162 return sigsuspend(&blocked);
169
170 REF_REG_RET = -EINTR;
171 while (1) {
172 current->state = TASK_INTERRUPTIBLE;
173 schedule();
174 set_restore_sigmask();
175 regs->pc += 4; /* because sys_sigreturn decrements the pc */
176 if (do_signal(regs, &saveset)) {
177 /* pc now points at signal handler. Need to decrement
178 it because entry.S will increment it. */
179 regs->pc -= 4;
180 return -EINTR;
181 }
182 }
183}
184
185asmlinkage int
186sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
187 unsigned long r4, unsigned long r5, unsigned long r6,
188 unsigned long r7,
189 struct pt_regs * regs)
190{
191 sigset_t saveset, newset;
192
193 /* XXX: Don't preclude handling different sized sigset_t's. */
194 if (sigsetsize != sizeof(sigset_t))
195 return -EINVAL;
196
197 if (copy_from_user(&newset, unewset, sizeof(newset)))
198 return -EFAULT;
199 sigdelsetmask(&newset, ~_BLOCKABLE);
200 saveset = current->blocked;
201 set_current_blocked(&newset);
202
203 REF_REG_RET = -EINTR;
204 while (1) {
205 current->state = TASK_INTERRUPTIBLE;
206 schedule();
207 regs->pc += 4; /* because sys_sigreturn decrements the pc */
208 if (do_signal(regs, &saveset)) {
209 /* pc now points at signal handler. Need to decrement
210 it because entry.S will increment it. */
211 regs->pc -= 4;
212 return -EINTR;
213 }
214 }
215} 163}
216 164
217asmlinkage int 165asmlinkage int
@@ -225,10 +173,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
225 old_sigset_t mask; 173 old_sigset_t mask;
226 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 174 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
227 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 175 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
228 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 176 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
177 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
178 __get_user(mask, &act->sa_mask))
229 return -EFAULT; 179 return -EFAULT;
230 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
231 __get_user(mask, &act->sa_mask);
232 siginitset(&new_ka.sa.sa_mask, mask); 180 siginitset(&new_ka.sa.sa_mask, mask);
233 } 181 }
234 182
@@ -237,10 +185,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
237 if (!ret && oact) { 185 if (!ret && oact) {
238 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 186 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
239 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 187 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
240 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 188 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
189 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
190 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
241 return -EFAULT; 191 return -EFAULT;
242 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
243 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
244 } 192 }
245 193
246 return ret; 194 return ret;
@@ -732,7 +680,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
732asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) 680asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
733{ 681{
734 if (thread_info_flags & _TIF_SIGPENDING) 682 if (thread_info_flags & _TIF_SIGPENDING)
735 do_signal(regs, 0); 683 do_signal(regs);
736 684
737 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 685 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
738 clear_thread_flag(TIF_NOTIFY_RESUME); 686 clear_thread_flag(TIF_NOTIFY_RESUME);
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 948700fb9036..bb1513e45f1a 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -215,8 +215,9 @@ void do_sigreturn32(struct pt_regs *regs)
215 (((unsigned long) sf) & 3)) 215 (((unsigned long) sf) & 3))
216 goto segv; 216 goto segv;
217 217
218 get_user(pc, &sf->info.si_regs.pc); 218 if (get_user(pc, &sf->info.si_regs.pc) ||
219 __get_user(npc, &sf->info.si_regs.npc); 219 __get_user(npc, &sf->info.si_regs.npc))
220 goto segv;
220 221
221 if ((pc | npc) & 3) 222 if ((pc | npc) & 3)
222 goto segv; 223 goto segv;
@@ -305,8 +306,9 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
305 (((unsigned long) sf) & 3)) 306 (((unsigned long) sf) & 3))
306 goto segv; 307 goto segv;
307 308
308 get_user(pc, &sf->regs.pc); 309 if (get_user(pc, &sf->regs.pc) ||
309 __get_user(npc, &sf->regs.npc); 310 __get_user(npc, &sf->regs.npc))
311 goto segv;
310 312
311 if ((pc | npc) & 3) 313 if ((pc | npc) & 3)
312 goto segv; 314 goto segv;
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index ac8e66b50f07..2b7e849f7c65 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -64,18 +64,8 @@ struct rt_signal_frame {
64static int _sigpause_common(old_sigset_t set) 64static int _sigpause_common(old_sigset_t set)
65{ 65{
66 sigset_t blocked; 66 sigset_t blocked;
67
68 current->saved_sigmask = current->blocked;
69
70 set &= _BLOCKABLE;
71 siginitset(&blocked, set); 67 siginitset(&blocked, set);
72 set_current_blocked(&blocked); 68 return sigsuspend(&blocked);
73
74 current->state = TASK_INTERRUPTIBLE;
75 schedule();
76 set_thread_flag(TIF_RESTORE_SIGMASK);
77
78 return -ERESTARTNOHAND;
79} 69}
80 70
81asmlinkage int sys_sigsuspend(old_sigset_t set) 71asmlinkage int sys_sigsuspend(old_sigset_t set)
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 48b0f57b65f7..eafaab486b2d 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -242,19 +242,8 @@ struct rt_signal_frame {
242static long _sigpause_common(old_sigset_t set) 242static long _sigpause_common(old_sigset_t set)
243{ 243{
244 sigset_t blocked; 244 sigset_t blocked;
245
246 current->saved_sigmask = current->blocked;
247
248 set &= _BLOCKABLE;
249 siginitset(&blocked, set); 245 siginitset(&blocked, set);
250 set_current_blocked(&blocked); 246 return sigsuspend(&blocked);
251
252 current->state = TASK_INTERRUPTIBLE;
253 schedule();
254
255 set_restore_sigmask();
256
257 return -ERESTARTNOHAND;
258} 247}
259 248
260asmlinkage long sys_sigpause(unsigned int set) 249asmlinkage long sys_sigpause(unsigned int set)
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 627e89af1d71..0c9b31b22e07 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -184,10 +184,10 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
184 184
185 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 185 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
186 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 186 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
187 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 187 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
188 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
189 __get_user(mask, &act->sa_mask))
188 return -EFAULT; 190 return -EFAULT;
189 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
190 __get_user(mask, &act->sa_mask);
191 siginitset(&new_ka.sa.sa_mask, mask); 191 siginitset(&new_ka.sa.sa_mask, mask);
192 new_ka.ka_restorer = NULL; 192 new_ka.ka_restorer = NULL;
193 } 193 }
@@ -195,17 +195,12 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
195 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 195 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
196 196
197 if (!ret && oact) { 197 if (!ret && oact) {
198 /* In the clone() case we could copy half consistent
199 * state to the user, however this could sleep and
200 * deadlock us if we held the signal lock on SMP. So for
201 * now I take the easy way out and do no locking.
202 */
203 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 198 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
204 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 199 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
205 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 200 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
201 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
202 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
206 return -EFAULT; 203 return -EFAULT;
207 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
208 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
209 } 204 }
210 205
211 return ret; 206 return ret;
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index 187118fbe1bc..292e706016c5 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -148,15 +148,8 @@ int do_signal(void)
148long sys_sigsuspend(int history0, int history1, old_sigset_t mask) 148long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
149{ 149{
150 sigset_t blocked; 150 sigset_t blocked;
151
152 mask &= _BLOCKABLE;
153 siginitset(&blocked, mask); 151 siginitset(&blocked, mask);
154 set_current_blocked(&blocked); 152 return sigsuspend(&blocked);
155
156 current->state = TASK_INTERRUPTIBLE;
157 schedule();
158 set_thread_flag(TIF_RESTORE_SIGMASK);
159 return -ERESTARTNOHAND;
160} 153}
161 154
162long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) 155long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c
index 911b549a6df5..7754df6ef7d4 100644
--- a/arch/unicore32/kernel/signal.c
+++ b/arch/unicore32/kernel/signal.c
@@ -370,10 +370,7 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
370 /* 370 /*
371 * Block the signal if we were successful. 371 * Block the signal if we were successful.
372 */ 372 */
373 sigorsets(&blocked, &tsk->blocked, &ka->sa.sa_mask); 373 block_sigmask(ka, sig);
374 if (!(ka->sa.sa_flags & SA_NODEFER))
375 sigaddset(&blocked, sig);
376 set_current_blocked(&blocked);
377 374
378 return 0; 375 return 0;
379} 376}
@@ -450,15 +447,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
450 regs->UCreg_00 == -ERESTARTNOINTR) { 447 regs->UCreg_00 == -ERESTARTNOINTR) {
451 setup_syscall_restart(regs); 448 setup_syscall_restart(regs);
452 } 449 }
453
454 /* If there's no signal to deliver, we just put the saved
455 * sigmask back.
456 */
457 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
458 clear_thread_flag(TIF_RESTORE_SIGMASK);
459 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
460 }
461 } 450 }
451 /* If there's no signal to deliver, we just put the saved
452 * sigmask back.
453 */
454 if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
455 set_current_blocked(&current->saved_sigmask);
462} 456}
463 457
464asmlinkage void do_notify_resume(struct pt_regs *regs, 458asmlinkage void do_notify_resume(struct pt_regs *regs,
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 0b3f2354f6aa..98bd70faccc5 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -131,18 +131,8 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
131asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask) 131asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
132{ 132{
133 sigset_t blocked; 133 sigset_t blocked;
134
135 current->saved_sigmask = current->blocked;
136
137 mask &= _BLOCKABLE;
138 siginitset(&blocked, mask); 134 siginitset(&blocked, mask);
139 set_current_blocked(&blocked); 135 return sigsuspend(&blocked);
140
141 current->state = TASK_INTERRUPTIBLE;
142 schedule();
143
144 set_restore_sigmask();
145 return -ERESTARTNOHAND;
146} 136}
147 137
148asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, 138asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 115eac431483..b68ccadd2ff4 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -478,18 +478,8 @@ asmlinkage int
478sys_sigsuspend(int history0, int history1, old_sigset_t mask) 478sys_sigsuspend(int history0, int history1, old_sigset_t mask)
479{ 479{
480 sigset_t blocked; 480 sigset_t blocked;
481
482 current->saved_sigmask = current->blocked;
483
484 mask &= _BLOCKABLE;
485 siginitset(&blocked, mask); 481 siginitset(&blocked, mask);
486 set_current_blocked(&blocked); 482 return sigsuspend(&blocked);
487
488 current->state = TASK_INTERRUPTIBLE;
489 schedule();
490
491 set_restore_sigmask();
492 return -ERESTARTNOHAND;
493} 483}
494 484
495asmlinkage int 485asmlinkage int
diff --git a/arch/xtensa/include/asm/signal.h b/arch/xtensa/include/asm/signal.h
index 633ba73bc4d2..7f201b9d4195 100644
--- a/arch/xtensa/include/asm/signal.h
+++ b/arch/xtensa/include/asm/signal.h
@@ -120,13 +120,6 @@ typedef void (*__sighandler_t)(int);
120#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ 120#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
121 121
122#ifdef __KERNEL__ 122#ifdef __KERNEL__
123struct old_sigaction {
124 __sighandler_t sa_handler;
125 old_sigset_t sa_mask;
126 unsigned long sa_flags;
127 void (*sa_restorer)(void);
128};
129
130struct sigaction { 123struct sigaction {
131 __sighandler_t sa_handler; 124 __sighandler_t sa_handler;
132 unsigned long sa_flags; 125 unsigned long sa_flags;
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h
index efcf33b92e4c..0b9f2e13c781 100644
--- a/arch/xtensa/include/asm/syscall.h
+++ b/arch/xtensa/include/asm/syscall.h
@@ -15,10 +15,6 @@ asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*);
15asmlinkage long xtensa_ptrace(long, long, long, long); 15asmlinkage long xtensa_ptrace(long, long, long, long);
16asmlinkage long xtensa_sigreturn(struct pt_regs*); 16asmlinkage long xtensa_sigreturn(struct pt_regs*);
17asmlinkage long xtensa_rt_sigreturn(struct pt_regs*); 17asmlinkage long xtensa_rt_sigreturn(struct pt_regs*);
18asmlinkage long xtensa_sigsuspend(struct pt_regs*);
19asmlinkage long xtensa_rt_sigsuspend(struct pt_regs*);
20asmlinkage long xtensa_sigaction(int, const struct old_sigaction*,
21 struct old_sigaction*);
22asmlinkage long xtensa_sigaltstack(struct pt_regs *regs); 18asmlinkage long xtensa_sigaltstack(struct pt_regs *regs);
23asmlinkage long sys_rt_sigaction(int, 19asmlinkage long sys_rt_sigaction(int,
24 const struct sigaction __user *, 20 const struct sigaction __user *,
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index 6abbedd09d85..81abfd5d01ac 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/arch/xtensa/include/asm/thread_info.h
@@ -131,6 +131,7 @@ static inline struct thread_info *current_thread_info(void)
131#define TIF_IRET 4 /* return with iret */ 131#define TIF_IRET 4 /* return with iret */
132#define TIF_MEMDIE 5 /* is terminating due to OOM killer */ 132#define TIF_MEMDIE 5 /* is terminating due to OOM killer */
133#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */ 133#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
134#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
134#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ 135#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
135 136
136#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 137#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h
index 798ee6d285a1..bc7e005faa60 100644
--- a/arch/xtensa/include/asm/unistd.h
+++ b/arch/xtensa/include/asm/unistd.h
@@ -507,7 +507,7 @@ __SYSCALL(229, sys_rt_sigtimedwait, 4)
507#define __NR_rt_sigqueueinfo 230 507#define __NR_rt_sigqueueinfo 230
508__SYSCALL(230, sys_rt_sigqueueinfo, 3) 508__SYSCALL(230, sys_rt_sigqueueinfo, 3)
509#define __NR_rt_sigsuspend 231 509#define __NR_rt_sigsuspend 231
510__SYSCALL(231, xtensa_rt_sigsuspend, 2) 510__SYSCALL(231, sys_rt_sigsuspend, 2)
511 511
512/* Message */ 512/* Message */
513 513
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 6223f3346b5c..7e6236073397 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -409,16 +409,16 @@ common_exception_return:
409 l32i a4, a2, TI_FLAGS 409 l32i a4, a2, TI_FLAGS
410 410
411 _bbsi.l a4, TIF_NEED_RESCHED, 3f 411 _bbsi.l a4, TIF_NEED_RESCHED, 3f
412 _bbsi.l a4, TIF_NOTIFY_RESUME, 2f
412 _bbci.l a4, TIF_SIGPENDING, 4f 413 _bbci.l a4, TIF_SIGPENDING, 4f
413 414
414 l32i a4, a1, PT_DEPC 4152: l32i a4, a1, PT_DEPC
415 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f 416 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
416 417
417 /* Call do_signal() */ 418 /* Call do_signal() */
418 419
419 movi a4, do_signal # int do_signal(struct pt_regs*, sigset_t*) 420 movi a4, do_notify_resume # int do_notify_resume(struct pt_regs*)
420 mov a6, a1 421 mov a6, a1
421 movi a7, 0
422 callx4 a4 422 callx4 a4
423 j 1b 423 j 1b
424 424
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index d78869a00b11..c5e4ec0598d2 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -20,6 +20,7 @@
20#include <linux/ptrace.h> 20#include <linux/ptrace.h>
21#include <linux/personality.h> 21#include <linux/personality.h>
22#include <linux/freezer.h> 22#include <linux/freezer.h>
23#include <linux/tracehook.h>
23 24
24#include <asm/ucontext.h> 25#include <asm/ucontext.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
@@ -31,8 +32,6 @@
31 32
32#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
33 34
34asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
35
36extern struct task_struct *coproc_owners[]; 35extern struct task_struct *coproc_owners[];
37 36
38struct rt_sigframe 37struct rt_sigframe
@@ -248,6 +247,9 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,
248 sigset_t set; 247 sigset_t set;
249 int ret; 248 int ret;
250 249
250 /* Always make any pending restarted system calls return -EINTR */
251 current_thread_info()->restart_block.fn = do_no_restart_syscall;
252
251 if (regs->depc > 64) 253 if (regs->depc > 64)
252 panic("rt_sigreturn in double exception!\n"); 254 panic("rt_sigreturn in double exception!\n");
253 255
@@ -426,37 +428,6 @@ give_sigsegv:
426 return -EFAULT; 428 return -EFAULT;
427} 429}
428 430
429/*
430 * Atomically swap in the new signal mask, and wait for a signal.
431 */
432
433asmlinkage long xtensa_rt_sigsuspend(sigset_t __user *unewset,
434 size_t sigsetsize,
435 long a2, long a3, long a4, long a5,
436 struct pt_regs *regs)
437{
438 sigset_t saveset, newset;
439
440 /* XXX: Don't preclude handling different sized sigset_t's. */
441 if (sigsetsize != sizeof(sigset_t))
442 return -EINVAL;
443
444 if (copy_from_user(&newset, unewset, sizeof(newset)))
445 return -EFAULT;
446
447 sigdelsetmask(&newset, ~_BLOCKABLE);
448 saveset = current->blocked;
449 set_current_blocked(&newset);
450
451 regs->areg[2] = -EINTR;
452 while (1) {
453 current->state = TASK_INTERRUPTIBLE;
454 schedule();
455 if (do_signal(regs, &saveset))
456 return -EINTR;
457 }
458}
459
460asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, 431asmlinkage long xtensa_sigaltstack(const stack_t __user *uss,
461 stack_t __user *uoss, 432 stack_t __user *uoss,
462 long a2, long a3, long a4, long a5, 433 long a2, long a3, long a4, long a5,
@@ -476,19 +447,19 @@ asmlinkage long xtensa_sigaltstack(const stack_t __user *uss,
476 * the kernel can handle, and then we build all the user-level signal handling 447 * the kernel can handle, and then we build all the user-level signal handling
477 * stack-frames in one go after that. 448 * stack-frames in one go after that.
478 */ 449 */
479int do_signal(struct pt_regs *regs, sigset_t *oldset) 450static void do_signal(struct pt_regs *regs)
480{ 451{
481 siginfo_t info; 452 siginfo_t info;
482 int signr; 453 int signr;
483 struct k_sigaction ka; 454 struct k_sigaction ka;
484 455 sigset_t oldset;
485 if (!user_mode(regs))
486 return 0;
487 456
488 if (try_to_freeze()) 457 if (try_to_freeze())
489 goto no_signal; 458 goto no_signal;
490 459
491 if (!oldset) 460 if (test_thread_flag(TIF_RESTORE_SIGMASK))
461 oldset = &current->saved_sigmask;
462 else
492 oldset = &current->blocked; 463 oldset = &current->blocked;
493 464
494 task_pt_regs(current)->icountlevel = 0; 465 task_pt_regs(current)->icountlevel = 0;
@@ -532,13 +503,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
532 /* Set up the stack frame */ 503 /* Set up the stack frame */
533 ret = setup_frame(signr, &ka, &info, oldset, regs); 504 ret = setup_frame(signr, &ka, &info, oldset, regs);
534 if (ret) 505 if (ret)
535 return ret; 506 return;
536 507
508 clear_thread_flag(TIF_RESTORE_SIGMASK);
537 block_sigmask(&ka, signr); 509 block_sigmask(&ka, signr);
538 if (current->ptrace & PT_SINGLESTEP) 510 if (current->ptrace & PT_SINGLESTEP)
539 task_pt_regs(current)->icountlevel = 1; 511 task_pt_regs(current)->icountlevel = 1;
540 512
541 return 1; 513 return;
542 } 514 }
543 515
544no_signal: 516no_signal:
@@ -558,8 +530,27 @@ no_signal:
558 break; 530 break;
559 } 531 }
560 } 532 }
533
534 /* If there's no signal to deliver, we just restore the saved mask. */
535 if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
536 set_current_blocked(&current->saved_sigmask);
537
561 if (current->ptrace & PT_SINGLESTEP) 538 if (current->ptrace & PT_SINGLESTEP)
562 task_pt_regs(current)->icountlevel = 1; 539 task_pt_regs(current)->icountlevel = 1;
563 return 0; 540 return;
564} 541}
565 542
543void do_notify_resume(struct pt_regs *regs)
544{
545 if (!user_mode(regs))
546 return;
547
548 if (test_thread_flag(TIF_SIGPENDING))
549 do_signal(regs);
550
551 if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
552 tracehook_notify_resume(regs);
553 if (current->replacement_session_keyring)
554 key_replace_session_keyring();
555 }
556}