diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-18 01:11:58 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-28 21:49:03 -0500 |
commit | e0e431aa45416982eb3fddf34cedc72f1c3b3ce3 (patch) | |
tree | 10f3e3009387881a3c4a209b9d72c453aae865a1 /arch/alpha | |
parent | 2b067fc9dd143be5e0ee94bae0fbd28ea0a407f8 (diff) |
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>
Diffstat (limited to 'arch/alpha')
-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: | |||
617 | .ent sys_fork | 617 | .ent sys_fork |
618 | sys_fork: | 618 | sys_fork: |
619 | .prologue 0 | 619 | .prologue 0 |
620 | mov $sp, $21 | ||
621 | bsr $1, do_switch_stack | 620 | bsr $1, do_switch_stack |
622 | bis $31, SIGCHLD, $16 | 621 | bis $31, SIGCHLD, $16 |
623 | mov $31, $17 | 622 | mov $31, $17 |
@@ -625,7 +624,9 @@ sys_fork: | |||
625 | mov $31, $19 | 624 | mov $31, $19 |
626 | mov $31, $20 | 625 | mov $31, $20 |
627 | jsr $26, alpha_clone | 626 | jsr $26, alpha_clone |
628 | bsr $1, undo_switch_stack | 627 | fork_out: |
628 | ldq $26, 56($sp) | ||
629 | lda $sp, SWITCH_STACK_SIZE($sp) | ||
629 | ret | 630 | ret |
630 | .end sys_fork | 631 | .end sys_fork |
631 | 632 | ||
@@ -634,12 +635,10 @@ sys_fork: | |||
634 | .ent sys_clone | 635 | .ent sys_clone |
635 | sys_clone: | 636 | sys_clone: |
636 | .prologue 0 | 637 | .prologue 0 |
637 | mov $sp, $21 | ||
638 | bsr $1, do_switch_stack | 638 | bsr $1, do_switch_stack |
639 | /* $16, $17, $18, $19, $20 come from the user. */ | 639 | /* $16, $17, $18, $19, $20 come from the user. */ |
640 | jsr $26, alpha_clone | 640 | lda $26, fork_out |
641 | bsr $1, undo_switch_stack | 641 | jsr $31, alpha_clone |
642 | ret | ||
643 | .end sys_clone | 642 | .end sys_clone |
644 | 643 | ||
645 | .align 4 | 644 | .align 4 |
@@ -647,11 +646,9 @@ sys_clone: | |||
647 | .ent sys_vfork | 646 | .ent sys_vfork |
648 | sys_vfork: | 647 | sys_vfork: |
649 | .prologue 0 | 648 | .prologue 0 |
650 | mov $sp, $16 | ||
651 | bsr $1, do_switch_stack | 649 | bsr $1, do_switch_stack |
652 | jsr $26, alpha_vfork | 650 | lda $26, fork_out |
653 | bsr $1, undo_switch_stack | 651 | jsr $31, alpha_vfork |
654 | ret | ||
655 | .end sys_vfork | 652 | .end sys_vfork |
656 | 653 | ||
657 | .align 4 | 654 | .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) | |||
246 | int | 246 | int |
247 | alpha_clone(unsigned long clone_flags, unsigned long usp, | 247 | alpha_clone(unsigned long clone_flags, unsigned long usp, |
248 | int __user *parent_tid, int __user *child_tid, | 248 | int __user *parent_tid, int __user *child_tid, |
249 | unsigned long tls_value, struct pt_regs *regs) | 249 | unsigned long tls_value) |
250 | { | 250 | { |
251 | if (!usp) | 251 | return do_fork(clone_flags, usp, current_pt_regs(), 0, |
252 | usp = rdusp(); | 252 | parent_tid, child_tid); |
253 | |||
254 | return do_fork(clone_flags, usp, regs, 0, parent_tid, child_tid); | ||
255 | } | 253 | } |
256 | 254 | ||
257 | int | 255 | int |
258 | alpha_vfork(struct pt_regs *regs) | 256 | alpha_vfork(void) |
259 | { | 257 | { |
260 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), | 258 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, |
261 | regs, 0, NULL, NULL); | 259 | current_pt_regs(), 0, NULL, NULL); |
262 | } | 260 | } |
263 | 261 | ||
264 | /* | 262 | /* |
@@ -301,7 +299,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, | |||
301 | stack = ((struct switch_stack *) regs) - 1; | 299 | stack = ((struct switch_stack *) regs) - 1; |
302 | *childstack = *stack; | 300 | *childstack = *stack; |
303 | childstack->r26 = (unsigned long) ret_from_fork; | 301 | childstack->r26 = (unsigned long) ret_from_fork; |
304 | childti->pcb.usp = usp; | 302 | childti->pcb.usp = usp ?: rdusp(); |
305 | childti->pcb.ksp = (unsigned long) childstack; | 303 | childti->pcb.ksp = (unsigned long) childstack; |
306 | childti->pcb.flags = 1; /* set FEN, clear everything else */ | 304 | childti->pcb.flags = 1; /* set FEN, clear everything else */ |
307 | 305 | ||