From: Andi Kleen <ak@muc.de>

Add the signal race changes to x86-64 to make it compile again.

Didn't merge the more pointless changes from i386.

Also remove the special SA_ONESHOT handling, doesn't seem to be needed
anymore.


---

 25-akpm/arch/x86_64/ia32/ia32_signal.c |   35 ++++++++++++-----------
 25-akpm/arch/x86_64/kernel/signal.c    |   49 ++++++++++++++++-----------------
 2 files changed, 42 insertions(+), 42 deletions(-)

diff -puN arch/x86_64/ia32/ia32_signal.c~signal-race-fix-x86_64 arch/x86_64/ia32/ia32_signal.c
--- 25/arch/x86_64/ia32/ia32_signal.c~signal-race-fix-x86_64	2004-03-28 15:47:53.678746672 -0800
+++ 25-akpm/arch/x86_64/ia32/ia32_signal.c	2004-03-28 15:47:53.684745760 -0800
@@ -391,7 +391,8 @@ ia32_setup_sigcontext(struct sigcontext_
  * Determine which stack to use..
  */
 static void *
-get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
+get_sigframe(struct k_sigaction *ka_copy, struct pt_regs * regs,
+	     size_t frame_size)
 {
 	unsigned long rsp;
 
@@ -399,28 +400,28 @@ get_sigframe(struct k_sigaction *ka, str
 	rsp = regs->rsp;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
-	if (ka->sa.sa_flags & SA_ONSTACK) {
+	if (ka_copy->sa.sa_flags & SA_ONSTACK) {
 		if (sas_ss_flags(rsp) == 0)
 			rsp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
 	/* This is the legacy signal stack switching. */
 	else if ((regs->ss & 0xffff) != __USER_DS &&
-		!(ka->sa.sa_flags & SA_RESTORER) &&
-		 ka->sa.sa_restorer) {
-		rsp = (unsigned long) ka->sa.sa_restorer;
+		!(ka_copy->sa.sa_flags & SA_RESTORER) &&
+		 ka_copy->sa.sa_restorer) {
+		rsp = (unsigned long) ka_copy->sa.sa_restorer;
 	}
 
 	return (void *)((rsp - frame_size) & -8UL);
 }
 
-void ia32_setup_frame(int sig, struct k_sigaction *ka,
+void ia32_setup_frame(int sig, struct k_sigaction *ka_copy,
 			compat_sigset_t *set, struct pt_regs * regs)
 {
 	struct sigframe *frame;
 	int err = 0;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka_copy, regs, sizeof(*frame));
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
@@ -451,8 +452,8 @@ void ia32_setup_frame(int sig, struct k_
 	/* Return stub is in 32bit vsyscall page */
 	{ 
 		void *restorer = VSYSCALL32_SIGRETURN; 
-		if (ka->sa.sa_flags & SA_RESTORER)
-			restorer = ka->sa.sa_restorer;       
+		if (ka_copy->sa.sa_flags & SA_RESTORER)
+			restorer = ka_copy->sa.sa_restorer;
 		err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
 	}
 	/* These are actually not used anymore, but left because some 
@@ -477,7 +478,7 @@ void ia32_setup_frame(int sig, struct k_
 
 	/* Set up registers for signal handler */
 	regs->rsp = (unsigned long) frame;
-	regs->rip = (unsigned long) ka->sa.sa_handler;
+	regs->rip = (unsigned long) ka_copy->sa.sa_handler;
 
 	asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 
 	asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 
@@ -497,17 +498,17 @@ void ia32_setup_frame(int sig, struct k_
 
 give_sigsegv:
 	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
+		current->sighand->action[SIGSEGV-1].sa.sa_handler = SIG_DFL;
 	signal_fault(regs,frame,"32bit signal deliver");
 }
 
-void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+void ia32_setup_rt_frame(int sig, struct k_sigaction *ka_copy, siginfo_t *info,
 			   compat_sigset_t *set, struct pt_regs * regs)
 {
 	struct rt_sigframe *frame;
 	int err = 0;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka_copy, regs, sizeof(*frame));
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
@@ -544,8 +545,8 @@ void ia32_setup_rt_frame(int sig, struct
 	
 	{ 
 		void *restorer = VSYSCALL32_RTSIGRETURN; 
-		if (ka->sa.sa_flags & SA_RESTORER)
-			restorer = ka->sa.sa_restorer;       
+		if (ka_copy->sa.sa_flags & SA_RESTORER)
+			restorer = ka_copy->sa.sa_restorer;
 		err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
 	}
 
@@ -573,7 +574,7 @@ void ia32_setup_rt_frame(int sig, struct
 
 	/* Set up registers for signal handler */
 	regs->rsp = (unsigned long) frame;
-	regs->rip = (unsigned long) ka->sa.sa_handler;
+	regs->rip = (unsigned long) ka_copy->sa.sa_handler;
 
 	asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 
 	asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 
@@ -593,7 +594,7 @@ void ia32_setup_rt_frame(int sig, struct
 
 give_sigsegv:
 	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
+		current->sighand->action[SIGSEGV-1].sa.sa_handler = SIG_DFL;
 	signal_fault(regs, frame, "32bit rt signal setup"); 
 }
 
diff -puN arch/x86_64/kernel/signal.c~signal-race-fix-x86_64 arch/x86_64/kernel/signal.c
--- 25/arch/x86_64/kernel/signal.c~signal-race-fix-x86_64	2004-03-28 15:47:53.679746520 -0800
+++ 25-akpm/arch/x86_64/kernel/signal.c	2004-03-28 15:47:53.683745912 -0800
@@ -236,7 +236,8 @@ get_stack(struct k_sigaction *ka, struct
 	return (void *)round_down(rsp - size, 16); 
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+static void setup_rt_frame(int sig, struct k_sigaction *ka_copy,
+			   siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
 	struct rt_sigframe *frame;
@@ -245,7 +246,7 @@ static void setup_rt_frame(int sig, stru
 	struct task_struct *me = current;
 
 	if (me->used_math) {
-		fp = get_stack(ka, regs, sizeof(struct _fpstate)); 
+		fp = get_stack(ka_copy, regs, sizeof(struct _fpstate));
 		frame = (void *)round_down((u64)fp - sizeof(struct rt_sigframe), 16) - 8;
 
 		if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) { 
@@ -255,14 +256,14 @@ static void setup_rt_frame(int sig, stru
 		if (save_i387(fp) < 0) 
 			err |= -1; 
 	} else {
-		frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
+		frame = get_stack(ka_copy, regs, sizeof(struct rt_sigframe)) - 8;
 	}
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
 		goto give_sigsegv;
 	}
 
-	if (ka->sa.sa_flags & SA_SIGINFO) { 
+	if (ka_copy->sa.sa_flags & SA_SIGINFO) {
 		err |= copy_siginfo_to_user(&frame->info, info);
 		if (err) { 
 			goto give_sigsegv;
@@ -288,10 +289,10 @@ static void setup_rt_frame(int sig, stru
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
 	/* x86-64 should always use SA_RESTORER. */
-	if (ka->sa.sa_flags & SA_RESTORER) {
-		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
+	if (ka_copy->sa.sa_flags & SA_RESTORER) {
+		err |= __put_user(ka_copy->sa.sa_restorer, &frame->pretcode);
 	} else {
-		printk("%s forgot to set SA_RESTORER for signal %d.\n", me->comm, sig); 
+		/* could use a vstub here */
 		goto give_sigsegv; 
 	}
 
@@ -317,7 +318,7 @@ static void setup_rt_frame(int sig, stru
 	   next argument after the signal number on the stack. */
 	regs->rsi = (unsigned long)&frame->info; 
 	regs->rdx = (unsigned long)&frame->uc; 
-	regs->rip = (unsigned long) ka->sa.sa_handler;
+	regs->rip = (unsigned long) ka_copy->sa.sa_handler;
 
 	regs->rsp = (unsigned long)frame;
 
@@ -333,7 +334,7 @@ static void setup_rt_frame(int sig, stru
 
 give_sigsegv:
 	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
+		current->sighand->action[SIGSEGV-1].sa.sa_handler = SIG_DFL;
 	signal_fault(regs,frame,"signal deliver");
 }
 
@@ -342,11 +343,10 @@ give_sigsegv:
  */	
 
 static void
-handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
-	struct pt_regs * regs)
+handle_signal(unsigned long sig, siginfo_t *info,
+	      struct k_sigaction *ka_copy, sigset_t *oldset,
+	      struct pt_regs * regs)
 {
-	struct k_sigaction *ka = &current->sighand->action[sig-1];
-
 #if DEBUG_SIG
 	printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", current->pid, sig, 
 		regs->rip, regs->rsp, regs);
@@ -362,7 +362,7 @@ handle_signal(unsigned long sig, siginfo
 				break;
 
 			case -ERESTARTSYS:
-				if (!(ka->sa.sa_flags & SA_RESTART)) {
+				if (!(ka_copy->sa.sa_flags & SA_RESTART)) {
 					regs->rax = -EINTR;
 					break;
 				}
@@ -375,20 +375,18 @@ handle_signal(unsigned long sig, siginfo
 
 #ifdef CONFIG_IA32_EMULATION
 	if (test_thread_flag(TIF_IA32)) {
-		if (ka->sa.sa_flags & SA_SIGINFO)
-			ia32_setup_rt_frame(sig, ka, info, oldset, regs);
+		if (ka_copy->sa.sa_flags & SA_SIGINFO)
+			ia32_setup_rt_frame(sig, ka_copy, info, oldset, regs);
 		else
-			ia32_setup_frame(sig, ka, oldset, regs);
+			ia32_setup_frame(sig, ka_copy, oldset, regs);
 	} else 
 #endif
-	setup_rt_frame(sig, ka, info, oldset, regs);
-
-	if (ka->sa.sa_flags & SA_ONESHOT)
-		ka->sa.sa_handler = SIG_DFL;
+	setup_rt_frame(sig, ka_copy, info, oldset, regs);
 
-	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+	if (!(ka_copy->sa.sa_flags & SA_NODEFER)) {
 		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigorsets(&current->blocked,&current->blocked,
+			  &ka_copy->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
@@ -402,6 +400,7 @@ handle_signal(unsigned long sig, siginfo
  */
 int do_signal(struct pt_regs *regs, sigset_t *oldset)
 {
+	struct k_sigaction ka_copy;
 	siginfo_t info;
 	int signr;
 
@@ -423,7 +422,7 @@ int do_signal(struct pt_regs *regs, sigs
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs, NULL);
+	signr = get_signal_to_deliver(&info, &ka_copy, regs, NULL);
 	if (signr > 0) {
 		/* Reenable any watchpoints before delivering the
 		 * signal to user space. The processor register will
@@ -434,7 +433,7 @@ int do_signal(struct pt_regs *regs, sigs
 			asm volatile("movq %0,%%db7"	: : "r" (current->thread.debugreg7));
 
 		/* Whee!  Actually deliver the signal.  */
-		handle_signal(signr, &info, oldset, regs);
+		handle_signal(signr, &info, &ka_copy, oldset, regs);
 		return 1;
 	}
 

_