sparc: switch to generic sigaltstack

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 21fd1a8..e2a0300 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -820,14 +820,6 @@
 	 mov	%l5, %o7
 
 	.align	4
-	.globl	sys_sigaltstack
-sys_sigaltstack:
-	mov	%o7, %l5
-	mov	%fp, %o2
-	call	do_sigaltstack
-	 mov	%l5, %o7
-
-	.align	4
 	.globl	sys_sigstack
 sys_sigstack:
 	mov	%o7, %l5
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 53e48f7..9d9eb91 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -61,7 +61,7 @@
 	compat_sigset_t		mask;
 	/* __siginfo_fpu_t * */ u32 fpu_save;
 	unsigned int		insns[2];
-	stack_t32		stack;
+	compat_stack_t		stack;
 	unsigned int		extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
 	/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
 	siginfo_extra_v8plus_t	v8plus;
@@ -230,13 +230,11 @@
 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 {
 	struct rt_signal_frame32 __user *sf;
-	unsigned int psr, pc, npc, u_ss_sp;
+	unsigned int psr, pc, npc;
 	compat_uptr_t fpu_save;
 	compat_uptr_t rwin_save;
-	mm_segment_t old_fs;
 	sigset_t set;
 	compat_sigset_t seta;
-	stack_t st;
 	int err, i;
 	
 	/* Always make any pending restarted system calls return -EINTR */
@@ -295,20 +293,10 @@
 	if (!err && fpu_save)
 		err |= restore_fpu_state(regs, compat_ptr(fpu_save));
 	err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
-	err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
-	st.ss_sp = compat_ptr(u_ss_sp);
-	err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
-	err |= __get_user(st.ss_size, &sf->stack.ss_size);
+	err |= compat_restore_altstack(&sf->stack);
 	if (err)
 		goto segv;
 		
-	/* It is more difficult to avoid calling this function than to
-	   call it and ignore errors.  */
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
-	set_fs(old_fs);
-	
 	err |= __get_user(rwin_save, &sf->rwin_save);
 	if (!err && rwin_save) {
 		if (restore_rwin_state(compat_ptr(rwin_save)))
@@ -642,9 +630,7 @@
 	err |= copy_siginfo_to_user32(&sf->info, info);
 	
 	/* Setup sigaltstack */
-	err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
-	err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
-	err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
+	err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
 
 	switch (_NSIG_WORDS) {
 	case 4: seta.sig[7] = (oldset->sig[3] >> 32);
@@ -856,29 +842,3 @@
 out:
 	return ret;
 }
-
-asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
-{
-	stack_t uss, uoss;
-	u32 u_ss_sp = 0;
-	int ret;
-	mm_segment_t old_fs;
-	stack_t32 __user *uss32 = compat_ptr(ussa);
-	stack_t32 __user *uoss32 = compat_ptr(uossa);
-	
-	if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
-		    __get_user(uss.ss_flags, &uss32->ss_flags) ||
-		    __get_user(uss.ss_size, &uss32->ss_size)))
-		return -EFAULT;
-	uss.ss_sp = compat_ptr(u_ss_sp);
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
-			     uossa ? (stack_t __user *) &uoss : NULL, sp);
-	set_fs(old_fs);
-	if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
-		    __put_user(uoss.ss_flags, &uoss32->ss_flags) ||
-		    __put_user(uoss.ss_size, &uoss32->ss_size)))
-		return -EFAULT;
-	return ret;
-}
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 68f9c86..7391fa8 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -141,9 +141,7 @@
 	unsigned int psr, pc, npc;
 	__siginfo_fpu_t __user *fpu_save;
 	__siginfo_rwin_t __user *rwin_save;
-	mm_segment_t old_fs;
 	sigset_t set;
-	stack_t st;
 	int err;
 
 	synchronize_user_stack();
@@ -171,8 +169,7 @@
 	if (!err && fpu_save)
 		err |= restore_fpu_state(regs, fpu_save);
 	err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
-	
-	err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t));
+	err |= restore_altstack(&sf->stack);
 	
 	if (err)
 		goto segv;
@@ -180,14 +177,6 @@
 	regs->pc = pc;
 	regs->npc = npc;
 	
-	/* It is more difficult to avoid calling this function than to
-	 * call it and ignore errors.
-	 */
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
-	set_fs(old_fs);
-
 	err |= __get_user(rwin_save, &sf->rwin_save);
 	if (!err && rwin_save) {
 		if (restore_rwin_state(rwin_save))
@@ -391,9 +380,7 @@
 	err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
 	
 	/* Setup sigaltstack */
-	err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
-	err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
-	err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
+	err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
 	
 	if (!wsaved) {
 		err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 689e1ba..176e0e7 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -295,7 +295,8 @@
 		err |= restore_fpu_state(regs, fpu_save);
 
 	err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
-	if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT)
+	err |= restore_altstack(&sf->stack);
+	if (err)
 		goto segv;
 
 	err |= __get_user(rwin_save, &sf->rwin_save);
@@ -403,9 +404,7 @@
 	}
 	
 	/* Setup sigaltstack */
-	err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
-	err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
-	err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
+	err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
 
 	err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
 
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index e0fed77..22a1098 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -25,16 +25,10 @@
 sys_memory_ordering:
 	ba,pt	%xcc, sparc_memory_ordering
 	 add	%sp, PTREGS_OFF, %o1
-sys_sigaltstack:
-	ba,pt	%xcc, do_sigaltstack
-	 add	%i6, STACK_BIAS, %o2
 #ifdef CONFIG_COMPAT
 sys32_sigstack:
 	ba,pt	%xcc, do_sys32_sigstack
 	 mov	%i6, %o2
-sys32_sigaltstack:
-	ba,pt	%xcc, do_sys32_sigaltstack
-	 mov	%i6, %o2
 #endif
 	.align	32
 #ifdef CONFIG_COMPAT
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 1009ecb..83ec8d46 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -23,7 +23,7 @@
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
 /*15*/	.word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
-/*25*/	.word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause
+/*25*/	.word sys32_vmsplice, compat_sys_ptrace, sys_alarm, compat_sys_sigaltstack, sys_pause
 /*30*/	.word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
 	.word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile
 /*40*/	.word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid