diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-03 23:28:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-14 19:36:30 -0400 |
commit | a44e060fc523c379341e35a981c09c3953cf4ba4 (patch) | |
tree | f32db182b2f746acd95cd7dbb8794352a8f98eb4 /arch/parisc/kernel/process.c | |
parent | ddffeb8c4d0331609ef2581d84de4d763607bd37 (diff) |
parisc: switch to generic kernel_thread()
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.c | 53 |
1 files changed, 16 insertions, 37 deletions
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index cbc37216bf90..b7b4126774e0 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -165,23 +165,6 @@ void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL(pm_power_off); /* - * Create a kernel thread - */ - -extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - - /* - * FIXME: Once we are sure we don't need any debug here, - * kernel_thread can become a #define. - */ - - return __kernel_thread(fn, arg, flags); -} -EXPORT_SYMBOL(kernel_thread); - -/* * Free current thread data structures etc.. */ void exit_thread(void) @@ -256,8 +239,8 @@ sys_vfork(struct pt_regs *regs) int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long unused, /* in ia64 this is "user_stack_size" */ - struct task_struct * p, struct pt_regs * pregs) + unsigned long arg, + struct task_struct *p, struct pt_regs *pregs) { struct pt_regs * cregs = &(p->thread.regs); void *stack = task_stack_page(p); @@ -271,21 +254,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp, extern void * const hpux_child_return; #endif - *cregs = *pregs; - - /* Set the return value for the child. Note that this is not - actually restored by the syscall exit path, but we put it - here for consistency in case of signals. */ - cregs->gr[28] = 0; /* child */ - - /* - * We need to differentiate between a user fork and a - * kernel fork. We can't use user_mode, because the - * the syscall path doesn't save iaoq. Right now - * We rely on the fact that kernel_thread passes - * in zero for usp. - */ - if (usp == 1) { + if (unlikely((p->flags & PF_KTHREAD) && usp != 0)) { + memset(cregs, 0, sizeof(struct pt_regs)); /* kernel thread */ cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN; /* Must exit via ret_from_kernel_thread in order @@ -297,10 +267,12 @@ copy_thread(unsigned long clone_flags, unsigned long usp, * ret_from_kernel_thread. */ #ifdef CONFIG_64BIT - cregs->gr[27] = pregs->gr[27]; + cregs->gr[27] = ((unsigned long *)usp)[3]; + cregs->gr[26] = ((unsigned long *)usp)[2]; +#else + cregs->gr[26] = usp; #endif - cregs->gr[26] = pregs->gr[26]; - cregs->gr[25] = pregs->gr[25]; + cregs->gr[25] = arg; } else { /* user thread */ /* @@ -308,6 +280,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp, * for setting gr[21]. */ + *cregs = *pregs; + + /* Set the return value for the child. Note that this is not + actually restored by the syscall exit path, but we put it + here for consistency in case of signals. */ + cregs->gr[28] = 0; /* child */ + /* Use same stack depth as parent */ cregs->ksp = (unsigned long)stack + (pregs->gr[21] & (THREAD_SIZE - 1)); |