alpha: simplify fork and friends
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 18 Oct 2012 05:11:58 +0000 (01:11 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 29 Nov 2012 02:49:03 +0000 (21:49 -0500)
* 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>
arch/alpha/kernel/entry.S
arch/alpha/kernel/process.c

index a760783..cc6d34e 100644 (file)
@@ -617,7 +617,6 @@ ret_from_kernel_thread:
        .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 @@ sys_fork:
        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 @@ sys_fork:
        .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 @@ sys_clone:
        .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
index 51987dc..ad86c09 100644 (file)
@@ -246,19 +246,17 @@ release_thread(struct task_struct *dead_task)
 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 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
        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 */