<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Mikael Pettersson &lt;mikpe@csd.uu.se&gt;

2.6.8-rc2-mm1 reintroduced the signal-race-fixes patch for i386, x86_64,
s390, and ia64, breaking all other archs.

The patch below updates ppc, following the pattern of i386.  Compiled &amp;
runtime tested.  No observable breakage.

Signed-off-by: Mikael Pettersson &lt;mikpe@csd.uu.se&gt;
Signed-off-by: Andrew Morton &lt;akpm@osdl.org&gt;
---

 25-akpm/arch/ppc/kernel/signal.c |   37 ++++++++++++++++---------------------
 1 files changed, 16 insertions(+), 21 deletions(-)

diff -puN arch/ppc/kernel/signal.c~ppc-signal-handling-fixes arch/ppc/kernel/signal.c
--- 25/arch/ppc/kernel/signal.c~ppc-signal-handling-fixes	Wed Jul 28 15:47:31 2004
+++ 25-akpm/arch/ppc/kernel/signal.c	Wed Jul 28 15:47:31 2004
@@ -350,7 +350,7 @@ restore_sigmask(sigset_t *set)
  * (one which gets siginfo).
  */
 static void
-handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
+handle_rt_signal(unsigned long sig, struct k_sigaction *ka_copy,
 		 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
 		 unsigned long newsp)
 {
@@ -393,7 +393,7 @@ handle_rt_signal(unsigned long sig, stru
 	regs-&gt;gpr[4] = (unsigned long) &amp;rt_sf-&gt;info;
 	regs-&gt;gpr[5] = (unsigned long) &amp;rt_sf-&gt;uc;
 	regs-&gt;gpr[6] = (unsigned long) rt_sf;
-	regs-&gt;nip = (unsigned long) ka-&gt;sa.sa_handler;
+	regs-&gt;nip = (unsigned long) ka_copy-&gt;sa.sa_handler;
 	regs-&gt;link = (unsigned long) frame-&gt;tramp;
 	regs-&gt;trap = 0;
 
@@ -405,7 +405,7 @@ badframe:
 	       regs, frame, newsp);
 #endif
 	if (sig == SIGSEGV)
-		ka-&gt;sa.sa_handler = SIG_DFL;
+		current-&gt;sighand-&gt;action[sig-1].sa.sa_handler = SIG_DFL;
 	force_sig(SIGSEGV, current);
 }
 
@@ -505,7 +505,7 @@ int sys_rt_sigreturn(int r3, int r4, int
  * OK, we're invoking a handler
  */
 static void
-handle_signal(unsigned long sig, struct k_sigaction *ka,
+handle_signal(unsigned long sig, struct k_sigaction *ka_copy,
 	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
 	      unsigned long newsp)
 {
@@ -530,7 +530,7 @@ handle_signal(unsigned long sig, struct 
 #if _NSIG != 64
 #error "Please adjust handle_signal()"
 #endif
-	if (__put_user((unsigned long) ka-&gt;sa.sa_handler, &amp;sc-&gt;handler)
+	if (__put_user((unsigned long) ka_copy-&gt;sa.sa_handler, &amp;sc-&gt;handler)
 	    || __put_user(oldset-&gt;sig[0], &amp;sc-&gt;oldmask)
 	    || __put_user(oldset-&gt;sig[1], &amp;sc-&gt;_unused[3])
 	    || __put_user((struct pt_regs *)frame, &amp;sc-&gt;regs)
@@ -545,7 +545,7 @@ handle_signal(unsigned long sig, struct 
 	regs-&gt;gpr[1] = newsp;
 	regs-&gt;gpr[3] = sig;
 	regs-&gt;gpr[4] = (unsigned long) sc;
-	regs-&gt;nip = (unsigned long) ka-&gt;sa.sa_handler;
+	regs-&gt;nip = (unsigned long) ka_copy-&gt;sa.sa_handler;
 	regs-&gt;link = (unsigned long) frame-&gt;mctx.tramp;
 	regs-&gt;trap = 0;
 
@@ -557,7 +557,7 @@ badframe:
 	       regs, frame, newsp);
 #endif
 	if (sig == SIGSEGV)
-		ka-&gt;sa.sa_handler = SIG_DFL;
+		current-&gt;sighand-&gt;action[sig-1].sa.sa_handler = SIG_DFL;
 	force_sig(SIGSEGV, current);
 }
 
@@ -604,7 +604,7 @@ badframe:
 int do_signal(sigset_t *oldset, struct pt_regs *regs)
 {
 	siginfo_t info;
-	struct k_sigaction *ka;
+	struct k_sigaction ka_copy;
 	unsigned long frame, newsp;
 	int signr, ret;
 
@@ -613,9 +613,7 @@ int do_signal(sigset_t *oldset, struct p
 
 	newsp = frame = 0;
 
-	signr = get_signal_to_deliver(&amp;info, regs, NULL);
-
-	ka = (signr == 0)? NULL: &amp;current-&gt;sighand-&gt;action[signr-1];
+	signr = get_signal_to_deliver(&amp;info, &amp;ka_copy, regs, NULL);
 
 	if (TRAP(regs) == 0x0C00		/* System Call! */
 	    &amp;&amp; regs-&gt;ccr &amp; 0x10000000		/* error signalled */
@@ -626,7 +624,7 @@ int do_signal(sigset_t *oldset, struct p
 		if (signr &gt; 0
 		    &amp;&amp; (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
 			|| (ret == ERESTARTSYS
-			    &amp;&amp; !(ka-&gt;sa.sa_flags &amp; SA_RESTART)))) {
+			    &amp;&amp; !(ka_copy.sa.sa_flags &amp; SA_RESTART)))) {
 			/* make the system call return an EINTR error */
 			regs-&gt;result = -EINTR;
 			regs-&gt;gpr[3] = EINTR;
@@ -645,7 +643,7 @@ int do_signal(sigset_t *oldset, struct p
 	if (signr == 0)
 		return 0;		/* no signals delivered */
 
-	if ((ka-&gt;sa.sa_flags &amp; SA_ONSTACK) &amp;&amp; current-&gt;sas_ss_size
+	if ((ka_copy.sa.sa_flags &amp; SA_ONSTACK) &amp;&amp; current-&gt;sas_ss_size
 	    &amp;&amp; !on_sig_stack(regs-&gt;gpr[1]))
 		newsp = current-&gt;sas_ss_sp + current-&gt;sas_ss_size;
 	else
@@ -653,17 +651,14 @@ int do_signal(sigset_t *oldset, struct p
 	newsp &amp;= ~0xfUL;
 
 	/* Whee!  Actually deliver the signal.  */
-	if (ka-&gt;sa.sa_flags &amp; SA_SIGINFO)
-		handle_rt_signal(signr, ka, &amp;info, oldset, regs, newsp);
+	if (ka_copy.sa.sa_flags &amp; SA_SIGINFO)
+		handle_rt_signal(signr, &amp;ka_copy, &amp;info, oldset, regs, newsp);
 	else
-		handle_signal(signr, ka, &amp;info, oldset, regs, newsp);
-
-	if (ka-&gt;sa.sa_flags &amp; SA_ONESHOT)
-		ka-&gt;sa.sa_handler = SIG_DFL;
+		handle_signal(signr, &amp;ka_copy, &amp;info, oldset, regs, newsp);
 
-	if (!(ka-&gt;sa.sa_flags &amp; SA_NODEFER)) {
+	if (!(ka_copy.sa.sa_flags &amp; SA_NODEFER)) {
 		spin_lock_irq(&amp;current-&gt;sighand-&gt;siglock);
-		sigorsets(&amp;current-&gt;blocked,&amp;current-&gt;blocked,&amp;ka-&gt;sa.sa_mask);
+		sigorsets(&amp;current-&gt;blocked,&amp;current-&gt;blocked,&amp;ka_copy.sa.sa_mask);
 		sigaddset(&amp;current-&gt;blocked, signr);
 		recalc_sigpending();
 		spin_unlock_irq(&amp;current-&gt;sighand-&gt;siglock);
_
</pre></body></html>