aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/process.c
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/process.c
parent7f1f311ac7b7b9c779fd207a20369f7fa3a61ba6 (diff)
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/process.c')
-rw-r--r--arch/parisc/kernel/process.c28
1 files changed, 8 insertions, 20 deletions
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 44e8534c52e..38db36f6430 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -52,6 +52,7 @@
52 52
53#include <asm/io.h> 53#include <asm/io.h>
54#include <asm/asm-offsets.h> 54#include <asm/asm-offsets.h>
55#include <asm/assembly.h>
55#include <asm/pdc.h> 56#include <asm/pdc.h>
56#include <asm/pdc_chassis.h> 57#include <asm/pdc_chassis.h>
57#include <asm/pgalloc.h> 58#include <asm/pgalloc.h>
@@ -253,14 +254,16 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
253#ifdef CONFIG_HPUX 254#ifdef CONFIG_HPUX
254 extern void * const hpux_child_return; 255 extern void * const hpux_child_return;
255#endif 256#endif
256 257 if (unlikely(p->flags & PF_KTHREAD)) {
257 if (unlikely((p->flags & PF_KTHREAD) && usp != 0)) {
258 memset(cregs, 0, sizeof(struct pt_regs)); 258 memset(cregs, 0, sizeof(struct pt_regs));
259 if (!usp) /* idle thread */
260 return 0;
261
259 /* kernel thread */ 262 /* kernel thread */
260 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN;
261 /* Must exit via ret_from_kernel_thread in order 263 /* Must exit via ret_from_kernel_thread in order
262 * to call schedule_tail() 264 * to call schedule_tail()
263 */ 265 */
266 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
264 cregs->kpc = (unsigned long) &ret_from_kernel_thread; 267 cregs->kpc = (unsigned long) &ret_from_kernel_thread;
265 /* 268 /*
266 * Copy function and argument to be called from 269 * Copy function and argument to be called from
@@ -275,22 +278,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
275 cregs->gr[25] = arg; 278 cregs->gr[25] = arg;
276 } else { 279 } else {
277 /* user thread */ 280 /* user thread */
278 /*
279 * Note that the fork wrappers are responsible
280 * for setting gr[21].
281 */
282
283 *cregs = *pregs;
284
285 /* Set the return value for the child. Note that this is not
286 actually restored by the syscall exit path, but we put it
287 here for consistency in case of signals. */
288 cregs->gr[28] = 0; /* child */
289
290 /* Use same stack depth as parent */
291 cregs->ksp = (unsigned long)stack
292 + (pregs->gr[21] & (THREAD_SIZE - 1));
293 cregs->gr[30] = usp; 281 cregs->gr[30] = usp;
282 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
294 if (personality(p->personality) == PER_HPUX) { 283 if (personality(p->personality) == PER_HPUX) {
295#ifdef CONFIG_HPUX 284#ifdef CONFIG_HPUX
296 cregs->kpc = (unsigned long) &hpux_child_return; 285 cregs->kpc = (unsigned long) &hpux_child_return;
@@ -302,8 +291,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
302 } 291 }
303 /* Setup thread TLS area from the 4th parameter in clone */ 292 /* Setup thread TLS area from the 4th parameter in clone */
304 if (clone_flags & CLONE_SETTLS) 293 if (clone_flags & CLONE_SETTLS)
305 cregs->cr27 = pregs->gr[23]; 294 cregs->cr27 = pregs->gr[23];
306
307 } 295 }
308 296
309 return 0; 297 return 0;