diff options
-rw-r--r-- | arch/frv/Kconfig | 1 | ||||
-rw-r--r-- | arch/frv/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/frv/kernel/process.c | 41 |
3 files changed, 20 insertions, 23 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 971c0a19facb..a27a1c6f8457 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -10,6 +10,7 @@ config FRV select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CPU_DEVICES select ARCH_WANT_IPC_PARSE_VERSION + select GENERIC_KERNEL_THREAD config ZONE_DMA bool diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index cc86e07a4119..a34f309e5801 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h @@ -105,7 +105,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); extern asmlinkage void save_user_regs(struct user_context *target); extern asmlinkage void *restore_user_regs(const struct user_context *target, ...); diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index 7ff4dbef0567..014f855362b9 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c @@ -170,7 +170,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, * set up the kernel stack and exception frames for a new process */ int copy_thread(unsigned long clone_flags, - unsigned long usp, unsigned long topstk, + unsigned long usp, unsigned long arg, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; @@ -178,17 +178,6 @@ int copy_thread(unsigned long clone_flags, childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); - /* set up the userspace frame (the only place that the USP is stored) */ - *childregs = *regs; - - childregs->sp = usp; - childregs->next_frame = NULL; - - if (unlikely(!user_mode(regs))) - p->thread.pc = (unsigned long) ret_from_kernel_thread; - else - p->thread.pc = (unsigned long) ret_from_fork; - p->set_child_tid = p->clear_child_tid = NULL; p->thread.frame = childregs; @@ -198,6 +187,24 @@ int copy_thread(unsigned long clone_flags, p->thread.lr = 0; p->thread.frame0 = childregs; + if (unlikely(!regs)) { + memset(childregs, 0, sizeof(struct pt_regs)); + childregs->gr9 = usp; /* function */ + childregs->gr8 = arg; + chilregs->psr = PSR_S; + p->thread.pc = (unsigned long) ret_from_kernel_thread; + save_user_regs(p->thread.user); + return 0; + } + + /* set up the userspace frame (the only place that the USP is stored) */ + *childregs = *regs; + + childregs->sp = usp; + childregs->next_frame = NULL; + + p->thread.pc = (unsigned long) ret_from_fork; + /* the new TLS pointer is passed in as arg #5 to sys_clone() */ if (clone_flags & CLONE_SETTLS) childregs->gr29 = childregs->gr12; @@ -320,13 +327,3 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs) sizeof(current->thread.user->f)); return 1; } - -int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs = { - .gr8 = (unsigned long)arg; - .gr9 = (unsigned long)fn; - .psr = PSR_S; - }; - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} |