aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2005-08-29 11:44:09 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-08-29 13:03:11 -0400
commit69be8f189653cd81aae5a74e26615b12871bb72e (patch)
tree89c7d7b5b68ae47818b9dbc9015f1e4452ec2075 /arch
parent02b3e4e2d71b6058ec11cc01c72ac651eb3ded2b (diff)
[PATCH] convert signal handling of NODEFER to act like other Unix boxes.
It has been reported that the way Linux handles NODEFER for signals is not consistent with the way other Unix boxes handle it. I've written a program to test the behavior of how this flag affects signals and had several reports from people who ran this on various Unix boxes, confirming that Linux seems to be unique on the way this is handled. The way NODEFER affects signals on other Unix boxes is as follows: 1) If NODEFER is set, other signals in sa_mask are still blocked. 2) If NODEFER is set and the signal is in sa_mask, then the signal is still blocked. (Note: this is the behavior of all tested but Linux _and_ NetBSD 2.0 *). The way NODEFER affects signals on Linux: 1) If NODEFER is set, other signals are _not_ blocked regardless of sa_mask (Even NetBSD doesn't do this). 2) If NODEFER is set and the signal is in sa_mask, then the signal being handled is not blocked. The patch converts signal handling in all current Linux architectures to the way most Unix boxes work. Unix boxes that were tested: DU4, AIX 5.2, Irix 6.5, NetBSD 2.0, SFU 3.5 on WinXP, AIX 5.3, Mac OSX, and of course Linux 2.6.13-rcX. * NetBSD was the only other Unix to behave like Linux on point #2. The main concern was brought up by point #1 which even NetBSD isn't like Linux. So with this patch, we leave NetBSD as the lonely one that behaves differently here with #2. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/signal.c11
-rw-r--r--arch/arm/kernel/signal.c5
-rw-r--r--arch/arm26/kernel/signal.c13
-rw-r--r--arch/cris/arch-v10/kernel/signal.c11
-rw-r--r--arch/cris/arch-v32/kernel/signal.c11
-rw-r--r--arch/frv/kernel/signal.c11
-rw-r--r--arch/h8300/kernel/signal.c11
-rw-r--r--arch/i386/kernel/signal.c5
-rw-r--r--arch/ia64/kernel/signal.c15
-rw-r--r--arch/m32r/kernel/signal.c11
-rw-r--r--arch/m68knommu/kernel/signal.c11
-rw-r--r--arch/mips/kernel/irixsig.c11
-rw-r--r--arch/mips/kernel/signal.c11
-rw-r--r--arch/mips/kernel/signal32.c11
-rw-r--r--arch/parisc/kernel/signal.c11
-rw-r--r--arch/ppc/kernel/signal.c11
-rw-r--r--arch/ppc64/kernel/signal.c5
-rw-r--r--arch/ppc64/kernel/signal32.c5
-rw-r--r--arch/s390/kernel/compat_signal.c11
-rw-r--r--arch/s390/kernel/signal.c11
-rw-r--r--arch/sh/kernel/signal.c11
-rw-r--r--arch/sh64/kernel/signal.c11
-rw-r--r--arch/sparc/kernel/signal.c11
-rw-r--r--arch/sparc64/kernel/signal.c11
-rw-r--r--arch/sparc64/kernel/signal32.c11
-rw-r--r--arch/um/kernel/signal_kern.c6
-rw-r--r--arch/v850/kernel/signal.c11
-rw-r--r--arch/x86_64/kernel/signal.c5
-rw-r--r--arch/xtensa/kernel/signal.c11
29 files changed, 135 insertions, 155 deletions
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 08fe8071a7f8..2e45e8604e32 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -566,13 +566,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
566 if (ka->sa.sa_flags & SA_RESETHAND) 566 if (ka->sa.sa_flags & SA_RESETHAND)
567 ka->sa.sa_handler = SIG_DFL; 567 ka->sa.sa_handler = SIG_DFL;
568 568
569 if (!(ka->sa.sa_flags & SA_NODEFER)) { 569 spin_lock_irq(&current->sighand->siglock);
570 spin_lock_irq(&current->sighand->siglock); 570 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
571 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 571 if (!(ka->sa.sa_flags & SA_NODEFER))
572 sigaddset(&current->blocked,sig); 572 sigaddset(&current->blocked,sig);
573 recalc_sigpending(); 573 recalc_sigpending();
574 spin_unlock_irq(&current->sighand->siglock); 574 spin_unlock_irq(&current->sighand->siglock);
575 }
576} 575}
577 576
578static inline void 577static inline void
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 5e435e42dacd..a94d75fef598 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -658,11 +658,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
658 /* 658 /*
659 * Block the signal if we were unsuccessful. 659 * Block the signal if we were unsuccessful.
660 */ 660 */
661 if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) { 661 if (ret != 0) {
662 spin_lock_irq(&tsk->sighand->siglock); 662 spin_lock_irq(&tsk->sighand->siglock);
663 sigorsets(&tsk->blocked, &tsk->blocked, 663 sigorsets(&tsk->blocked, &tsk->blocked,
664 &ka->sa.sa_mask); 664 &ka->sa.sa_mask);
665 sigaddset(&tsk->blocked, sig); 665 if (!(ka->sa.sa_flags & SA_NODEFER))
666 sigaddset(&tsk->blocked, sig);
666 recalc_sigpending(); 667 recalc_sigpending();
667 spin_unlock_irq(&tsk->sighand->siglock); 668 spin_unlock_irq(&tsk->sighand->siglock);
668 } 669 }
diff --git a/arch/arm26/kernel/signal.c b/arch/arm26/kernel/signal.c
index 356d9809cc0b..ce2055bdc9ee 100644
--- a/arch/arm26/kernel/signal.c
+++ b/arch/arm26/kernel/signal.c
@@ -454,14 +454,13 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
454 if (ka->sa.sa_flags & SA_ONESHOT) 454 if (ka->sa.sa_flags & SA_ONESHOT)
455 ka->sa.sa_handler = SIG_DFL; 455 ka->sa.sa_handler = SIG_DFL;
456 456
457 if (!(ka->sa.sa_flags & SA_NODEFER)) { 457 spin_lock_irq(&tsk->sighand->siglock);
458 spin_lock_irq(&tsk->sighand->siglock); 458 sigorsets(&tsk->blocked, &tsk->blocked,
459 sigorsets(&tsk->blocked, &tsk->blocked, 459 &ka->sa.sa_mask);
460 &ka->sa.sa_mask); 460 if (!(ka->sa.sa_flags & SA_NODEFER))
461 sigaddset(&tsk->blocked, sig); 461 sigaddset(&tsk->blocked, sig);
462 recalc_sigpending(); 462 recalc_sigpending();
463 spin_unlock_irq(&tsk->sighand->siglock); 463 spin_unlock_irq(&tsk->sighand->siglock);
464 }
465 return; 464 return;
466 } 465 }
467 466
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 85e0032e664f..693771961f85 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -517,13 +517,12 @@ handle_signal(int canrestart, unsigned long sig,
517 if (ka->sa.sa_flags & SA_ONESHOT) 517 if (ka->sa.sa_flags & SA_ONESHOT)
518 ka->sa.sa_handler = SIG_DFL; 518 ka->sa.sa_handler = SIG_DFL;
519 519
520 if (!(ka->sa.sa_flags & SA_NODEFER)) { 520 spin_lock_irq(&current->sighand->siglock);
521 spin_lock_irq(&current->sighand->siglock); 521 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
522 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 522 if (!(ka->sa.sa_flags & SA_NODEFER))
523 sigaddset(&current->blocked,sig); 523 sigaddset(&current->blocked,sig);
524 recalc_sigpending(); 524 recalc_sigpending();
525 spin_unlock_irq(&current->sighand->siglock); 525 spin_unlock_irq(&current->sighand->siglock);
526 }
527} 526}
528 527
529/* 528/*
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index fb4c79d5b76b..0a3614dab887 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -568,13 +568,12 @@ handle_signal(int canrestart, unsigned long sig,
568 if (ka->sa.sa_flags & SA_ONESHOT) 568 if (ka->sa.sa_flags & SA_ONESHOT)
569 ka->sa.sa_handler = SIG_DFL; 569 ka->sa.sa_handler = SIG_DFL;
570 570
571 if (!(ka->sa.sa_flags & SA_NODEFER)) { 571 spin_lock_irq(&current->sighand->siglock);
572 spin_lock_irq(&current->sighand->siglock); 572 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
573 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 573 if (!(ka->sa.sa_flags & SA_NODEFER))
574 sigaddset(&current->blocked,sig); 574 sigaddset(&current->blocked,sig);
575 recalc_sigpending(); 575 recalc_sigpending();
576 spin_unlock_irq(&current->sighand->siglock); 576 spin_unlock_irq(&current->sighand->siglock);
577 }
578} 577}
579 578
580/* 579/*
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 36a2dffc8ebd..d4ccc0728dfe 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -506,13 +506,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
506 else 506 else
507 setup_frame(sig, ka, oldset, regs); 507 setup_frame(sig, ka, oldset, regs);
508 508
509 if (!(ka->sa.sa_flags & SA_NODEFER)) { 509 spin_lock_irq(&current->sighand->siglock);
510 spin_lock_irq(&current->sighand->siglock); 510 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
511 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask); 511 if (!(ka->sa.sa_flags & SA_NODEFER))
512 sigaddset(&current->blocked, sig); 512 sigaddset(&current->blocked, sig);
513 recalc_sigpending(); 513 recalc_sigpending();
514 spin_unlock_irq(&current->sighand->siglock); 514 spin_unlock_irq(&current->sighand->siglock);
515 }
516} /* end handle_signal() */ 515} /* end handle_signal() */
517 516
518/*****************************************************************************/ 517/*****************************************************************************/
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index 5aab87eae1f9..f13d5e82d4b9 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -488,13 +488,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
488 else 488 else
489 setup_frame(sig, ka, oldset, regs); 489 setup_frame(sig, ka, oldset, regs);
490 490
491 if (!(ka->sa.sa_flags & SA_NODEFER)) { 491 spin_lock_irq(&current->sighand->siglock);
492 spin_lock_irq(&current->sighand->siglock); 492 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
493 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 493 if (!(ka->sa.sa_flags & SA_NODEFER))
494 sigaddset(&current->blocked,sig); 494 sigaddset(&current->blocked,sig);
495 recalc_sigpending(); 495 recalc_sigpending();
496 spin_unlock_irq(&current->sighand->siglock); 496 spin_unlock_irq(&current->sighand->siglock);
497 }
498} 497}
499 498
500/* 499/*
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 89ef7adc63a4..140e340569c6 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -577,10 +577,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
577 else 577 else
578 ret = setup_frame(sig, ka, oldset, regs); 578 ret = setup_frame(sig, ka, oldset, regs);
579 579
580 if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { 580 if (ret) {
581 spin_lock_irq(&current->sighand->siglock); 581 spin_lock_irq(&current->sighand->siglock);
582 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 582 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
583 sigaddset(&current->blocked,sig); 583 if (!(ka->sa.sa_flags & SA_NODEFER))
584 sigaddset(&current->blocked,sig);
584 recalc_sigpending(); 585 recalc_sigpending();
585 spin_unlock_irq(&current->sighand->siglock); 586 spin_unlock_irq(&current->sighand->siglock);
586 } 587 }
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index b8a0a7d257a9..774f34b675cf 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -467,15 +467,12 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse
467 if (!setup_frame(sig, ka, info, oldset, scr)) 467 if (!setup_frame(sig, ka, info, oldset, scr))
468 return 0; 468 return 0;
469 469
470 if (!(ka->sa.sa_flags & SA_NODEFER)) { 470 spin_lock_irq(&current->sighand->siglock);
471 spin_lock_irq(&current->sighand->siglock); 471 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
472 { 472 if (!(ka->sa.sa_flags & SA_NODEFER))
473 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask); 473 sigaddset(&current->blocked, sig);
474 sigaddset(&current->blocked, sig); 474 recalc_sigpending();
475 recalc_sigpending(); 475 spin_unlock_irq(&current->sighand->siglock);
476 }
477 spin_unlock_irq(&current->sighand->siglock);
478 }
479 return 1; 476 return 1;
480} 477}
481 478
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 5aef7e406ef5..71763f7a1d19 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -341,13 +341,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
341 /* Set up the stack frame */ 341 /* Set up the stack frame */
342 setup_rt_frame(sig, ka, info, oldset, regs); 342 setup_rt_frame(sig, ka, info, oldset, regs);
343 343
344 if (!(ka->sa.sa_flags & SA_NODEFER)) { 344 spin_lock_irq(&current->sighand->siglock);
345 spin_lock_irq(&current->sighand->siglock); 345 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
346 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 346 if (!(ka->sa.sa_flags & SA_NODEFER))
347 sigaddset(&current->blocked,sig); 347 sigaddset(&current->blocked,sig);
348 recalc_sigpending(); 348 recalc_sigpending();
349 spin_unlock_irq(&current->sighand->siglock); 349 spin_unlock_irq(&current->sighand->siglock);
350 }
351} 350}
352 351
353/* 352/*
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
index 30dceb59a462..43a2726c0d0a 100644
--- a/arch/m68knommu/kernel/signal.c
+++ b/arch/m68knommu/kernel/signal.c
@@ -732,13 +732,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
732 if (ka->sa.sa_flags & SA_ONESHOT) 732 if (ka->sa.sa_flags & SA_ONESHOT)
733 ka->sa.sa_handler = SIG_DFL; 733 ka->sa.sa_handler = SIG_DFL;
734 734
735 if (!(ka->sa.sa_flags & SA_NODEFER)) { 735 spin_lock_irq(&current->sighand->siglock);
736 spin_lock_irq(&current->sighand->siglock); 736 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
737 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 737 if (!(ka->sa.sa_flags & SA_NODEFER))
738 sigaddset(&current->blocked,sig); 738 sigaddset(&current->blocked,sig);
739 recalc_sigpending(); 739 recalc_sigpending();
740 spin_unlock_irq(&current->sighand->siglock); 740 spin_unlock_irq(&current->sighand->siglock);
741 }
742} 741}
743 742
744/* 743/*
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 40244782a8e5..4c114ae21793 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -155,13 +155,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
155 else 155 else
156 setup_irix_frame(ka, regs, sig, oldset); 156 setup_irix_frame(ka, regs, sig, oldset);
157 157
158 if (!(ka->sa.sa_flags & SA_NODEFER)) { 158 spin_lock_irq(&current->sighand->siglock);
159 spin_lock_irq(&current->sighand->siglock); 159 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
160 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 160 if (!(ka->sa.sa_flags & SA_NODEFER))
161 sigaddset(&current->blocked,sig); 161 sigaddset(&current->blocked,sig);
162 recalc_sigpending(); 162 recalc_sigpending();
163 spin_unlock_irq(&current->sighand->siglock); 163 spin_unlock_irq(&current->sighand->siglock);
164 }
165} 164}
166 165
167asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) 166asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 65ee15396ffd..0209c1dd1429 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -425,13 +425,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
425 setup_frame(ka, regs, sig, oldset); 425 setup_frame(ka, regs, sig, oldset);
426#endif 426#endif
427 427
428 if (!(ka->sa.sa_flags & SA_NODEFER)) { 428 spin_lock_irq(&current->sighand->siglock);
429 spin_lock_irq(&current->sighand->siglock); 429 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
430 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 430 if (!(ka->sa.sa_flags & SA_NODEFER))
431 sigaddset(&current->blocked,sig); 431 sigaddset(&current->blocked,sig);
432 recalc_sigpending(); 432 recalc_sigpending();
433 spin_unlock_irq(&current->sighand->siglock); 433 spin_unlock_irq(&current->sighand->siglock);
434 }
435} 434}
436 435
437extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); 436extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index c1a69cf232f9..f6875f023a29 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -751,13 +751,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
751 else 751 else
752 setup_frame(ka, regs, sig, oldset); 752 setup_frame(ka, regs, sig, oldset);
753 753
754 if (!(ka->sa.sa_flags & SA_NODEFER)) { 754 spin_lock_irq(&current->sighand->siglock);
755 spin_lock_irq(&current->sighand->siglock); 755 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
756 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 756 if (!(ka->sa.sa_flags & SA_NODEFER))
757 sigaddset(&current->blocked,sig); 757 sigaddset(&current->blocked,sig);
758 recalc_sigpending(); 758 recalc_sigpending();
759 spin_unlock_irq(&current->sighand->siglock); 759 spin_unlock_irq(&current->sighand->siglock);
760 }
761} 760}
762 761
763int do_signal32(sigset_t *oldset, struct pt_regs *regs) 762int do_signal32(sigset_t *oldset, struct pt_regs *regs)
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 9421bb98ea63..55d71c15e1f7 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -517,13 +517,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
517 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) 517 if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
518 return 0; 518 return 0;
519 519
520 if (!(ka->sa.sa_flags & SA_NODEFER)) { 520 spin_lock_irq(&current->sighand->siglock);
521 spin_lock_irq(&current->sighand->siglock); 521 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
522 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 522 if (!(ka->sa.sa_flags & SA_NODEFER))
523 sigaddset(&current->blocked,sig); 523 sigaddset(&current->blocked,sig);
524 recalc_sigpending(); 524 recalc_sigpending();
525 spin_unlock_irq(&current->sighand->siglock); 525 spin_unlock_irq(&current->sighand->siglock);
526 }
527 return 1; 526 return 1;
528} 527}
529 528
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
index 8aaeb6f4e750..2244bf91e593 100644
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -759,13 +759,12 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
759 else 759 else
760 handle_signal(signr, &ka, &info, oldset, regs, newsp); 760 handle_signal(signr, &ka, &info, oldset, regs, newsp);
761 761
762 if (!(ka.sa.sa_flags & SA_NODEFER)) { 762 spin_lock_irq(&current->sighand->siglock);
763 spin_lock_irq(&current->sighand->siglock); 763 sigorsets(&current->blocked,&current->blocked,&ka.sa.sa_mask);
764 sigorsets(&current->blocked,&current->blocked,&ka.sa.sa_mask); 764 if (!(ka.sa.sa_flags & SA_NODEFER))
765 sigaddset(&current->blocked, signr); 765 sigaddset(&current->blocked, signr);
766 recalc_sigpending(); 766 recalc_sigpending();
767 spin_unlock_irq(&current->sighand->siglock); 767 spin_unlock_irq(&current->sighand->siglock);
768 }
769 768
770 return 1; 769 return 1;
771} 770}
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
index bf782276984c..49a79a55c32d 100644
--- a/arch/ppc64/kernel/signal.c
+++ b/arch/ppc64/kernel/signal.c
@@ -481,10 +481,11 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
481 /* Set up Signal Frame */ 481 /* Set up Signal Frame */
482 ret = setup_rt_frame(sig, ka, info, oldset, regs); 482 ret = setup_rt_frame(sig, ka, info, oldset, regs);
483 483
484 if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { 484 if (ret) {
485 spin_lock_irq(&current->sighand->siglock); 485 spin_lock_irq(&current->sighand->siglock);
486 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask); 486 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
487 sigaddset(&current->blocked,sig); 487 if (!(ka->sa.sa_flags & SA_NODEFER))
488 sigaddset(&current->blocked,sig);
488 recalc_sigpending(); 489 recalc_sigpending();
489 spin_unlock_irq(&current->sighand->siglock); 490 spin_unlock_irq(&current->sighand->siglock);
490 } 491 }
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
index 3c2fa5c284c0..46f4d6cc7fc9 100644
--- a/arch/ppc64/kernel/signal32.c
+++ b/arch/ppc64/kernel/signal32.c
@@ -976,11 +976,12 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
976 else 976 else
977 ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp); 977 ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp);
978 978
979 if (ret && !(ka.sa.sa_flags & SA_NODEFER)) { 979 if (ret) {
980 spin_lock_irq(&current->sighand->siglock); 980 spin_lock_irq(&current->sighand->siglock);
981 sigorsets(&current->blocked, &current->blocked, 981 sigorsets(&current->blocked, &current->blocked,
982 &ka.sa.sa_mask); 982 &ka.sa.sa_mask);
983 sigaddset(&current->blocked, signr); 983 if (!(ka.sa.sa_flags & SA_NODEFER))
984 sigaddset(&current->blocked, signr);
984 recalc_sigpending(); 985 recalc_sigpending();
985 spin_unlock_irq(&current->sighand->siglock); 986 spin_unlock_irq(&current->sighand->siglock);
986 } 987 }
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index d05d65ac9694..7358cdb8441f 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -637,12 +637,11 @@ handle_signal32(unsigned long sig, struct k_sigaction *ka,
637 else 637 else
638 setup_frame32(sig, ka, oldset, regs); 638 setup_frame32(sig, ka, oldset, regs);
639 639
640 if (!(ka->sa.sa_flags & SA_NODEFER)) { 640 spin_lock_irq(&current->sighand->siglock);
641 spin_lock_irq(&current->sighand->siglock); 641 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
642 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 642 if (!(ka->sa.sa_flags & SA_NODEFER))
643 sigaddset(&current->blocked,sig); 643 sigaddset(&current->blocked,sig);
644 recalc_sigpending(); 644 recalc_sigpending();
645 spin_unlock_irq(&current->sighand->siglock); 645 spin_unlock_irq(&current->sighand->siglock);
646 }
647} 646}
648 647
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 610c1d03e975..6a3f5b7473a9 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -429,13 +429,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
429 else 429 else
430 setup_frame(sig, ka, oldset, regs); 430 setup_frame(sig, ka, oldset, regs);
431 431
432 if (!(ka->sa.sa_flags & SA_NODEFER)) { 432 spin_lock_irq(&current->sighand->siglock);
433 spin_lock_irq(&current->sighand->siglock); 433 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
434 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 434 if (!(ka->sa.sa_flags & SA_NODEFER))
435 sigaddset(&current->blocked,sig); 435 sigaddset(&current->blocked,sig);
436 recalc_sigpending(); 436 recalc_sigpending();
437 spin_unlock_irq(&current->sighand->siglock); 437 spin_unlock_irq(&current->sighand->siglock);
438 }
439} 438}
440 439
441/* 440/*
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 8022243f0178..b475c4d2405f 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -546,13 +546,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
546 if (ka->sa.sa_flags & SA_ONESHOT) 546 if (ka->sa.sa_flags & SA_ONESHOT)
547 ka->sa.sa_handler = SIG_DFL; 547 ka->sa.sa_handler = SIG_DFL;
548 548
549 if (!(ka->sa.sa_flags & SA_NODEFER)) { 549 spin_lock_irq(&current->sighand->siglock);
550 spin_lock_irq(&current->sighand->siglock); 550 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
551 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 551 if (!(ka->sa.sa_flags & SA_NODEFER))
552 sigaddset(&current->blocked,sig); 552 sigaddset(&current->blocked,sig);
553 recalc_sigpending(); 553 recalc_sigpending();
554 spin_unlock_irq(&current->sighand->siglock); 554 spin_unlock_irq(&current->sighand->siglock);
555 }
556} 555}
557 556
558/* 557/*
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c
index c6a14a87c59b..3ea8929e483b 100644
--- a/arch/sh64/kernel/signal.c
+++ b/arch/sh64/kernel/signal.c
@@ -664,13 +664,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
664 else 664 else
665 setup_frame(sig, ka, oldset, regs); 665 setup_frame(sig, ka, oldset, regs);
666 666
667 if (!(ka->sa.sa_flags & SA_NODEFER)) { 667 spin_lock_irq(&current->sighand->siglock);
668 spin_lock_irq(&current->sighand->siglock); 668 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
669 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 669 if (!(ka->sa.sa_flags & SA_NODEFER))
670 sigaddset(&current->blocked,sig); 670 sigaddset(&current->blocked,sig);
671 recalc_sigpending(); 671 recalc_sigpending();
672 spin_unlock_irq(&current->sighand->siglock); 672 spin_unlock_irq(&current->sighand->siglock);
673 }
674} 673}
675 674
676/* 675/*
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 011ff35057a5..5f34d7dc2b89 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1034,13 +1034,12 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
1034 else 1034 else
1035 setup_frame(&ka->sa, regs, signr, oldset, info); 1035 setup_frame(&ka->sa, regs, signr, oldset, info);
1036 } 1036 }
1037 if (!(ka->sa.sa_flags & SA_NOMASK)) { 1037 spin_lock_irq(&current->sighand->siglock);
1038 spin_lock_irq(&current->sighand->siglock); 1038 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1039 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 1039 if (!(ka->sa.sa_flags & SA_NOMASK))
1040 sigaddset(&current->blocked, signr); 1040 sigaddset(&current->blocked, signr);
1041 recalc_sigpending(); 1041 recalc_sigpending();
1042 spin_unlock_irq(&current->sighand->siglock); 1042 spin_unlock_irq(&current->sighand->siglock);
1043 }
1044} 1043}
1045 1044
1046static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, 1045static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index b27934671c35..60f5dfabb1e1 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -574,13 +574,12 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
574{ 574{
575 setup_rt_frame(ka, regs, signr, oldset, 575 setup_rt_frame(ka, regs, signr, oldset,
576 (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); 576 (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
577 if (!(ka->sa.sa_flags & SA_NOMASK)) { 577 spin_lock_irq(&current->sighand->siglock);
578 spin_lock_irq(&current->sighand->siglock); 578 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
579 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 579 if (!(ka->sa.sa_flags & SA_NOMASK))
580 sigaddset(&current->blocked,signr); 580 sigaddset(&current->blocked,signr);
581 recalc_sigpending(); 581 recalc_sigpending();
582 spin_unlock_irq(&current->sighand->siglock); 582 spin_unlock_irq(&current->sighand->siglock);
583 }
584} 583}
585 584
586static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, 585static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index f28428f4170e..b1ed23091fbb 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1325,13 +1325,12 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
1325 else 1325 else
1326 setup_frame32(&ka->sa, regs, signr, oldset, info); 1326 setup_frame32(&ka->sa, regs, signr, oldset, info);
1327 } 1327 }
1328 if (!(ka->sa.sa_flags & SA_NOMASK)) { 1328 spin_lock_irq(&current->sighand->siglock);
1329 spin_lock_irq(&current->sighand->siglock); 1329 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1330 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 1330 if (!(ka->sa.sa_flags & SA_NOMASK))
1331 sigaddset(&current->blocked,signr); 1331 sigaddset(&current->blocked,signr);
1332 recalc_sigpending(); 1332 recalc_sigpending();
1333 spin_unlock_irq(&current->sighand->siglock); 1333 spin_unlock_irq(&current->sighand->siglock);
1334 }
1335} 1334}
1336 1335
1337static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, 1336static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
index 7807a3e8c426..03618bd13d55 100644
--- a/arch/um/kernel/signal_kern.c
+++ b/arch/um/kernel/signal_kern.c
@@ -87,12 +87,12 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
87 recalc_sigpending(); 87 recalc_sigpending();
88 spin_unlock_irq(&current->sighand->siglock); 88 spin_unlock_irq(&current->sighand->siglock);
89 force_sigsegv(signr, current); 89 force_sigsegv(signr, current);
90 } 90 } else {
91 else if(!(ka->sa.sa_flags & SA_NODEFER)){
92 spin_lock_irq(&current->sighand->siglock); 91 spin_lock_irq(&current->sighand->siglock);
93 sigorsets(&current->blocked, &current->blocked, 92 sigorsets(&current->blocked, &current->blocked,
94 &ka->sa.sa_mask); 93 &ka->sa.sa_mask);
95 sigaddset(&current->blocked, signr); 94 if(!(ka->sa.sa_flags & SA_NODEFER))
95 sigaddset(&current->blocked, signr);
96 recalc_sigpending(); 96 recalc_sigpending();
97 spin_unlock_irq(&current->sighand->siglock); 97 spin_unlock_irq(&current->sighand->siglock);
98 } 98 }
diff --git a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c
index 37061e32e1a4..633e4e1b825f 100644
--- a/arch/v850/kernel/signal.c
+++ b/arch/v850/kernel/signal.c
@@ -462,13 +462,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
462 else 462 else
463 setup_frame(sig, ka, oldset, regs); 463 setup_frame(sig, ka, oldset, regs);
464 464
465 if (!(ka->sa.sa_flags & SA_NODEFER)) { 465 spin_lock_irq(&current->sighand->siglock);
466 spin_lock_irq(&current->sighand->siglock); 466 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
467 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 467 if (!(ka->sa.sa_flags & SA_NODEFER))
468 sigaddset(&current->blocked,sig); 468 sigaddset(&current->blocked,sig);
469 recalc_sigpending(); 469 recalc_sigpending();
470 spin_unlock_irq(&current->sighand->siglock); 470 spin_unlock_irq(&current->sighand->siglock);
471 }
472} 471}
473 472
474/* 473/*
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index 98590a989f3d..d642fbf3da29 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -394,10 +394,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
394#endif 394#endif
395 ret = setup_rt_frame(sig, ka, info, oldset, regs); 395 ret = setup_rt_frame(sig, ka, info, oldset, regs);
396 396
397 if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { 397 if (ret) {
398 spin_lock_irq(&current->sighand->siglock); 398 spin_lock_irq(&current->sighand->siglock);
399 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 399 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
400 sigaddset(&current->blocked,sig); 400 if (!(ka->sa.sa_flags & SA_NODEFER))
401 sigaddset(&current->blocked,sig);
401 recalc_sigpending(); 402 recalc_sigpending();
402 spin_unlock_irq(&current->sighand->siglock); 403 spin_unlock_irq(&current->sighand->siglock);
403 } 404 }
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index df6e1e17b096..dc42cede9394 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -702,12 +702,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
702 if (ka.sa.sa_flags & SA_ONESHOT) 702 if (ka.sa.sa_flags & SA_ONESHOT)
703 ka.sa.sa_handler = SIG_DFL; 703 ka.sa.sa_handler = SIG_DFL;
704 704
705 if (!(ka.sa.sa_flags & SA_NODEFER)) { 705 spin_lock_irq(&current->sighand->siglock);
706 spin_lock_irq(&current->sighand->siglock); 706 sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
707 sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask); 707 if (!(ka.sa.sa_flags & SA_NODEFER))
708 sigaddset(&current->blocked, signr); 708 sigaddset(&current->blocked, signr);
709 recalc_sigpending(); 709 recalc_sigpending();
710 spin_unlock_irq(&current->sighand->siglock); 710 spin_unlock_irq(&current->sighand->siglock);
711 }
712 return 1; 711 return 1;
713} 712}