alpha: simplify fork and friends

* no need to restore everything from switch_stack when we only need $26
* no need to pass current_pt_regs() manually, we can just as easily
calculate it in alpha_clone/alpha_vfork ($8 + constant)
* interpretation of zero usp as "use the parent's" is simpler in copy_thread();
let fork and vfork just pass 0.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index a760783..cc6d34e 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -617,7 +617,6 @@
 	.ent	sys_fork
 sys_fork:
 	.prologue 0
-	mov	$sp, $21
 	bsr	$1, do_switch_stack
 	bis	$31, SIGCHLD, $16
 	mov	$31, $17
@@ -625,7 +624,9 @@
 	mov	$31, $19
 	mov	$31, $20
 	jsr	$26, alpha_clone
-	bsr	$1, undo_switch_stack
+fork_out:
+	ldq	$26, 56($sp)
+	lda	$sp, SWITCH_STACK_SIZE($sp)
 	ret
 .end sys_fork
 
@@ -634,12 +635,10 @@
 	.ent	sys_clone
 sys_clone:
 	.prologue 0
-	mov	$sp, $21
 	bsr	$1, do_switch_stack
 	/* $16, $17, $18, $19, $20 come from the user.  */
-	jsr	$26, alpha_clone
-	bsr	$1, undo_switch_stack
-	ret
+	lda	$26, fork_out
+	jsr	$31, alpha_clone
 .end sys_clone
 
 	.align	4
@@ -647,11 +646,9 @@
 	.ent	sys_vfork
 sys_vfork:
 	.prologue 0
-	mov	$sp, $16
 	bsr	$1, do_switch_stack
-	jsr	$26, alpha_vfork
-	bsr	$1, undo_switch_stack
-	ret
+	lda	$26, fork_out
+	jsr	$31, alpha_vfork
 .end sys_vfork
 
 	.align	4
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 51987dc..ad86c09 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -246,19 +246,17 @@
 int
 alpha_clone(unsigned long clone_flags, unsigned long usp,
 	    int __user *parent_tid, int __user *child_tid,
-	    unsigned long tls_value, struct pt_regs *regs)
+	    unsigned long tls_value)
 {
-	if (!usp)
-		usp = rdusp();
-
-	return do_fork(clone_flags, usp, regs, 0, parent_tid, child_tid);
+	return do_fork(clone_flags, usp, current_pt_regs(), 0,
+			parent_tid, child_tid);
 }
 
 int
-alpha_vfork(struct pt_regs *regs)
+alpha_vfork(void)
 {
-	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
-		       regs, 0, NULL, NULL);
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
+		       current_pt_regs(), 0, NULL, NULL);
 }
 
 /*
@@ -301,7 +299,7 @@
 	stack = ((struct switch_stack *) regs) - 1;
 	*childstack = *stack;
 	childstack->r26 = (unsigned long) ret_from_fork;
-	childti->pcb.usp = usp;
+	childti->pcb.usp = usp ?: rdusp();
 	childti->pcb.ksp = (unsigned long) childstack;
 	childti->pcb.flags = 1;	/* set FEN, clear everything else */