aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/entry.S
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-05 18:55:57 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-10-14 19:36:37 -0400
commitff0ab8af9c3f36e7b6f716c3b9e8811a4202eec6 (patch)
tree78f5dba557a1f91b868fa0118516562b6cd28244 /arch/parisc/kernel/entry.S
parent7f1f311ac7b7b9c779fd207a20369f7fa3a61ba6 (diff)
downloadlinux-ff0ab8af9c3f36e7b6f716c3b9e8811a4202eec6.tar.gz
parisc: optimizations in copy_thread() and friends
* in user thread case the registers had been copied as part of task_struct already; no need to do it in copy_thread(). * no need to store kernel stack pointer into regs->r21; we know its offset anyway. * no need to clobber r3 in sys_fork_wrapper and friends - r28 will do just as well and *it* will be overwritten anyway. * no need to mess with storing the return address for child - it should just use syscall_exit. * no need to bother with separate stack frame for sys_clone() - just branch there and be done with that. * no need to bother with wrapper_exit - we need it only on the child_return, so let's just do it there. * use the same ksp for kernel threads and userland ones, while we are at it, and let ret_from_kernel_execve() go through the normal syscall_exit. More straightforward is better here... [fixes from jejb folded] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/parisc/kernel/entry.S')
-rw-r--r--arch/parisc/kernel/entry.S86
1 files changed, 19 insertions, 67 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 7d22e97347b7e..47fb6ddcf12e6 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -719,7 +719,7 @@ ENTRY(ret_from_kernel_thread)
BL schedule_tail, %r2
nop
- LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1
+ LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
LDREG TASK_PT_GR25(%r1), %r26
#ifdef CONFIG_64BIT
LDREG TASK_PT_GR27(%r1), %r27
@@ -743,9 +743,8 @@ ENDPROC(ret_from_kernel_thread)
ENTRY(ret_from_kernel_execve)
mfctl %cr30, %r1
- ldo THREAD_SZ_ALGN(%r1), %r30
- b intr_return /* forward */
- copy %r26,%r16 /* pt_regs into r16 */
+ b syscall_exit /* forward */
+ ldo THREAD_SZ_ALGN+FRAME_SIZE(%r1), %r30
ENDPROC(ret_from_kernel_execve)
@@ -1709,39 +1708,13 @@ ENTRY(sys_fork_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
ldo TASK_REGS(%r1),%r1
reg_save %r1
- mfctl %cr27, %r3
- STREG %r3, PT_CR27(%r1)
-
- STREG %r2,-RP_OFFSET(%r30)
- ldo FRAME_SIZE(%r30),%r30
-#ifdef CONFIG_64BIT
- ldo -16(%r30),%r29 /* Reference param save area */
-#endif
-
- /* These are call-clobbered registers and therefore
- also syscall-clobbered (we hope). */
- STREG %r2,PT_GR19(%r1) /* save for child */
- STREG %r30,PT_GR21(%r1)
+ mfctl %cr27, %r28
+ STREG %r28, PT_CR27(%r1)
LDREG PT_GR30(%r1),%r25
copy %r1,%r24
- BL sys_clone,%r2
+ b sys_clone
ldi SIGCHLD,%r26
-
- LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
-wrapper_exit:
- ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */
- LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
- ldo TASK_REGS(%r1),%r1 /* get pt regs */
-
- LDREG PT_CR27(%r1), %r3
- mtctl %r3, %cr27
- reg_restore %r1
-
- /* strace expects syscall # to be preserved in r20 */
- ldi __NR_fork,%r20
- bv %r0(%r2)
- STREG %r20,PT_GR20(%r1)
ENDPROC(sys_fork_wrapper)
/* Set the return value for the child */
@@ -1749,9 +1722,13 @@ ENTRY(child_return)
BL schedule_tail, %r2
nop
- LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1
- LDREG TASK_PT_GR19(%r1),%r2
- b wrapper_exit
+ LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
+ ldo TASK_REGS(%r1),%r1 /* get pt regs */
+
+ LDREG PT_CR27(%r1), %r3
+ mtctl %r3, %cr27
+ reg_restore %r1
+ b syscall_exit
copy %r0,%r28
ENDPROC(child_return)
@@ -1760,23 +1737,10 @@ ENTRY(sys_clone_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
reg_save %r1
- mfctl %cr27, %r3
- STREG %r3, PT_CR27(%r1)
-
- STREG %r2,-RP_OFFSET(%r30)
- ldo FRAME_SIZE(%r30),%r30
-#ifdef CONFIG_64BIT
- ldo -16(%r30),%r29 /* Reference param save area */
-#endif
-
- /* WARNING - Clobbers r19 and r21, userspace must save these! */
- STREG %r2,PT_GR19(%r1) /* save for child */
- STREG %r30,PT_GR21(%r1)
- BL sys_clone,%r2
+ mfctl %cr27, %r28
+ STREG %r28, PT_CR27(%r1)
+ b sys_clone
copy %r1,%r24
-
- b wrapper_exit
- LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
ENDPROC(sys_clone_wrapper)
@@ -1784,23 +1748,11 @@ ENTRY(sys_vfork_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
reg_save %r1
- mfctl %cr27, %r3
- STREG %r3, PT_CR27(%r1)
-
- STREG %r2,-RP_OFFSET(%r30)
- ldo FRAME_SIZE(%r30),%r30
-#ifdef CONFIG_64BIT
- ldo -16(%r30),%r29 /* Reference param save area */
-#endif
+ mfctl %cr27, %r28
+ STREG %r28, PT_CR27(%r1)
- STREG %r2,PT_GR19(%r1) /* save for child */
- STREG %r30,PT_GR21(%r1)
-
- BL sys_vfork,%r2
+ b sys_vfork
copy %r1,%r26
-
- b wrapper_exit
- LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
ENDPROC(sys_vfork_wrapper)