diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-18 07:11:58 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-29 03:49:03 +0100 |
commit | e0e431aa45416982eb3fddf34cedc72f1c3b3ce3 (patch) | |
tree | 10f3e3009387881a3c4a209b9d72c453aae865a1 | |
parent | um: don't bother looking at regs in copy_thread() - current_pt_regs() is what... (diff) | |
download | linux-e0e431aa45416982eb3fddf34cedc72f1c3b3ce3.tar.xz linux-e0e431aa45416982eb3fddf34cedc72f1c3b3ce3.zip |
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>
-rw-r--r-- | arch/alpha/kernel/entry.S | 17 | ||||
-rw-r--r-- | arch/alpha/kernel/process.c | 16 |
2 files changed, 14 insertions, 19 deletions
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index a7607832dd4f..cc6d34e9e2ea 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -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 diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 51987dcf79b8..ad86c099b6f5 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -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 */ |