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/kernel | |
| 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/kernel')
| -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 | ||
