Commit e0e431aa authored by Al Viro's avatar Al Viro

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2b067fc9
...@@ -617,7 +617,6 @@ ret_from_kernel_thread: ...@@ -617,7 +617,6 @@ ret_from_kernel_thread:
.ent sys_fork .ent sys_fork
sys_fork: sys_fork:
.prologue 0 .prologue 0
mov $sp, $21
bsr $1, do_switch_stack bsr $1, do_switch_stack
bis $31, SIGCHLD, $16 bis $31, SIGCHLD, $16
mov $31, $17 mov $31, $17
...@@ -625,7 +624,9 @@ sys_fork: ...@@ -625,7 +624,9 @@ sys_fork:
mov $31, $19 mov $31, $19
mov $31, $20 mov $31, $20
jsr $26, alpha_clone jsr $26, alpha_clone
bsr $1, undo_switch_stack fork_out:
ldq $26, 56($sp)
lda $sp, SWITCH_STACK_SIZE($sp)
ret ret
.end sys_fork .end sys_fork
...@@ -634,12 +635,10 @@ sys_fork: ...@@ -634,12 +635,10 @@ sys_fork:
.ent sys_clone .ent sys_clone
sys_clone: sys_clone:
.prologue 0 .prologue 0
mov $sp, $21
bsr $1, do_switch_stack bsr $1, do_switch_stack
/* $16, $17, $18, $19, $20 come from the user. */ /* $16, $17, $18, $19, $20 come from the user. */
jsr $26, alpha_clone lda $26, fork_out
bsr $1, undo_switch_stack jsr $31, alpha_clone
ret
.end sys_clone .end sys_clone
.align 4 .align 4
...@@ -647,11 +646,9 @@ sys_clone: ...@@ -647,11 +646,9 @@ sys_clone:
.ent sys_vfork .ent sys_vfork
sys_vfork: sys_vfork:
.prologue 0 .prologue 0
mov $sp, $16
bsr $1, do_switch_stack bsr $1, do_switch_stack
jsr $26, alpha_vfork lda $26, fork_out
bsr $1, undo_switch_stack jsr $31, alpha_vfork
ret
.end sys_vfork .end sys_vfork
.align 4 .align 4
......
...@@ -246,19 +246,17 @@ release_thread(struct task_struct *dead_task) ...@@ -246,19 +246,17 @@ release_thread(struct task_struct *dead_task)
int int
alpha_clone(unsigned long clone_flags, unsigned long usp, alpha_clone(unsigned long clone_flags, unsigned long usp,
int __user *parent_tid, int __user *child_tid, int __user *parent_tid, int __user *child_tid,
unsigned long tls_value, struct pt_regs *regs) unsigned long tls_value)
{ {
if (!usp) return do_fork(clone_flags, usp, current_pt_regs(), 0,
usp = rdusp(); parent_tid, child_tid);
return do_fork(clone_flags, usp, regs, 0, parent_tid, child_tid);
} }
int int
alpha_vfork(struct pt_regs *regs) alpha_vfork(void)
{ {
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
regs, 0, NULL, NULL); current_pt_regs(), 0, NULL, NULL);
} }
/* /*
...@@ -301,7 +299,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -301,7 +299,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
stack = ((struct switch_stack *) regs) - 1; stack = ((struct switch_stack *) regs) - 1;
*childstack = *stack; *childstack = *stack;
childstack->r26 = (unsigned long) ret_from_fork; childstack->r26 = (unsigned long) ret_from_fork;
childti->pcb.usp = usp; childti->pcb.usp = usp ?: rdusp();
childti->pcb.ksp = (unsigned long) childstack; childti->pcb.ksp = (unsigned long) childstack;
childti->pcb.flags = 1; /* set FEN, clear everything else */ childti->pcb.flags = 1; /* set FEN, clear everything else */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment