sparc: convert to ksignal

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 9d9eb91..cd5dc4d 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -323,7 +323,7 @@
 	return 0;
 }
 
-static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
+static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 {
 	unsigned long sp;
 	
@@ -338,12 +338,7 @@
 		return (void __user *) -1L;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
-	if (sa->sa_flags & SA_ONSTACK) {
-		if (sas_ss_flags(sp) == 0)
-			sp = current->sas_ss_sp + current->sas_ss_size;
-	}
-
-	sp -= framesize;
+	sp = sigsp(sp, ksig) - framesize;
 
 	/* Always align the stack frame.  This handles two cases.  First,
 	 * sigaltstack need not be mindful of platform specific stack
@@ -414,8 +409,8 @@
 
 }
 
-static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
-			 int signo, sigset_t *oldset)
+static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
+			 sigset_t *oldset)
 {
 	struct signal_frame32 __user *sf;
 	int i, err, wsaved;
@@ -437,10 +432,12 @@
 		sigframe_size += sizeof(__siginfo_rwin_t);
 
 	sf = (struct signal_frame32 __user *)
-		get_sigframe(&ka->sa, regs, sigframe_size);
+		get_sigframe(ksig, regs, sigframe_size);
 	
-	if (invalid_frame_pointer(sf, sigframe_size))
-		goto sigill;
+	if (invalid_frame_pointer(sf, sigframe_size)) {
+		do_exit(SIGILL);
+		return -EINVAL;
+	}
 
 	tail = (sf + 1);
 
@@ -514,16 +511,16 @@
 		err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
 	}	
 	if (err)
-		goto sigsegv;
+		return err;
 
 	/* 3. signal handler back-trampoline and parameters */
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
-	regs->u_regs[UREG_I0] = signo;
+	regs->u_regs[UREG_I0] = ksig->sig;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 	regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
 
 	/* 4. signal handler */
-	regs->tpc = (unsigned long) ka->sa.sa_handler;
+	regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
 	regs->tnpc = (regs->tpc + 4);
 	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
@@ -531,8 +528,8 @@
 	}
 
 	/* 5. return to kernel instructions */
-	if (ka->ka_restorer) {
-		regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
+	if (ksig->ka.ka_restorer) {
+		regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
 	} else {
 		unsigned long address = ((unsigned long)&(sf->insns[0]));
 
@@ -541,23 +538,14 @@
 		err  = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
 		err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
 		if (err)
-			goto sigsegv;
+			return err;
 		flush_signal_insns(address);
 	}
 	return 0;
-
-sigill:
-	do_exit(SIGILL);
-	return -EINVAL;
-
-sigsegv:
-	force_sigsegv(signo, current);
-	return -EFAULT;
 }
 
-static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
-			    unsigned long signr, sigset_t *oldset,
-			    siginfo_t *info)
+static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
+			    sigset_t *oldset)
 {
 	struct rt_signal_frame32 __user *sf;
 	int i, err, wsaved;
@@ -579,10 +567,12 @@
 		sigframe_size += sizeof(__siginfo_rwin_t);
 
 	sf = (struct rt_signal_frame32 __user *)
-		get_sigframe(&ka->sa, regs, sigframe_size);
+		get_sigframe(ksig, regs, sigframe_size);
 	
-	if (invalid_frame_pointer(sf, sigframe_size))
-		goto sigill;
+	if (invalid_frame_pointer(sf, sigframe_size)) {
+		do_exit(SIGILL);
+		return -EINVAL;
+	}
 
 	tail = (sf + 1);
 
@@ -627,7 +617,7 @@
 	}
 
 	/* Update the siginfo structure.  */
-	err |= copy_siginfo_to_user32(&sf->info, info);
+	err |= copy_siginfo_to_user32(&sf->info, &ksig->info);
 	
 	/* Setup sigaltstack */
 	err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
@@ -660,16 +650,16 @@
 		err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
 	}
 	if (err)
-		goto sigsegv;
+		return err;
 	
 	/* 3. signal handler back-trampoline and parameters */
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
-	regs->u_regs[UREG_I0] = signr;
+	regs->u_regs[UREG_I0] = ksig->sig;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 	regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
 
 	/* 4. signal handler */
-	regs->tpc = (unsigned long) ka->sa.sa_handler;
+	regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
 	regs->tnpc = (regs->tpc + 4);
 	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
@@ -677,8 +667,8 @@
 	}
 
 	/* 5. return to kernel instructions */
-	if (ka->ka_restorer)
-		regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
+	if (ksig->ka.ka_restorer)
+		regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
 	else {
 		unsigned long address = ((unsigned long)&(sf->insns[0]));
 
@@ -690,36 +680,25 @@
 		/* t 0x10 */
 		err |= __put_user(0x91d02010, &sf->insns[1]);
 		if (err)
-			goto sigsegv;
+			return err;
 
 		flush_signal_insns(address);
 	}
 	return 0;
-
-sigill:
-	do_exit(SIGILL);
-	return -EINVAL;
-
-sigsegv:
-	force_sigsegv(signr, current);
-	return -EFAULT;
 }
 
-static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
-				  siginfo_t *info,
-				  sigset_t *oldset, struct pt_regs *regs)
+static inline void handle_signal32(struct ksignal *ksig, 
+				  struct pt_regs *regs)
 {
+	sigset_t *oldset = sigmask_to_save();
 	int err;
 
-	if (ka->sa.sa_flags & SA_SIGINFO)
-		err = setup_rt_frame32(ka, regs, signr, oldset, info);
+	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+		err = setup_rt_frame32(ksig, regs, oldset);
 	else
-		err = setup_frame32(ka, regs, signr, oldset);
+		err = setup_frame32(ksig, regs, oldset);
 
-	if (err)
-		return;
-
-	signal_delivered(signr, info, ka, regs, 0);
+	signal_setup_done(err, ksig, 0);
 }
 
 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -749,50 +728,41 @@
  */
 void do_signal32(sigset_t *oldset, struct pt_regs * regs)
 {
-	struct k_sigaction ka;
-	unsigned long orig_i0;
-	int restart_syscall;
-	siginfo_t info;
-	int signr;
-	
-	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	struct ksignal ksig;
+	unsigned long orig_i0 = 0;
+	int restart_syscall = 0;
+	bool has_handler = get_signal(&ksig);
 
-	restart_syscall = 0;
-	orig_i0 = 0;
 	if (pt_regs_is_syscall(regs) &&
 	    (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
 		restart_syscall = 1;
 		orig_i0 = regs->u_regs[UREG_G6];
 	}
 
-	if (signr > 0) {
+	if (has_handler) {
 		if (restart_syscall)
-			syscall_restart32(orig_i0, regs, &ka.sa);
-		handle_signal32(signr, &ka, &info, oldset, regs);
-		return;
+			syscall_restart32(orig_i0, regs, &ksig.ka.sa);
+		handle_signal32(&ksig, regs);
+	} else {
+		if (restart_syscall) {
+			switch (regs->u_regs[UREG_I0]) {
+			case ERESTARTNOHAND:
+	     		case ERESTARTSYS:
+			case ERESTARTNOINTR:
+				/* replay the system call when we are done */
+				regs->u_regs[UREG_I0] = orig_i0;
+				regs->tpc -= 4;
+				regs->tnpc -= 4;
+				pt_regs_clear_syscall(regs);
+			case ERESTART_RESTARTBLOCK:
+				regs->u_regs[UREG_G1] = __NR_restart_syscall;
+				regs->tpc -= 4;
+				regs->tnpc -= 4;
+				pt_regs_clear_syscall(regs);
+			}
+		}
+		restore_saved_sigmask();
 	}
-	if (restart_syscall &&
-	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
-		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = orig_i0;
-		regs->tpc -= 4;
-		regs->tnpc -= 4;
-		pt_regs_clear_syscall(regs);
-	}
-	if (restart_syscall &&
-	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
-		regs->u_regs[UREG_G1] = __NR_restart_syscall;
-		regs->tpc -= 4;
-		regs->tnpc -= 4;
-		pt_regs_clear_syscall(regs);
-	}
-
-	/* If there's no signal to deliver, we just put the saved sigmask
-	 * back
-	 */
-	restore_saved_sigmask();
 }
 
 struct sigstack32 {