frv: switch to generic kernel_thread()
Al Viro [Sat, 22 Sep 2012 22:10:15 +0000 (18:10 -0400)]
arch/frv/Kconfig
arch/frv/include/asm/processor.h
arch/frv/kernel/process.c

index 971c0a1..a27a1c6 100644 (file)
@@ -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
index cc86e07..a34f309 100644 (file)
@@ -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, ...);
 
index 7ff4dbe..014f855 100644 (file)
@@ -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, &regs, 0, NULL, NULL);
-}