summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/frv/Kconfig1
-rw-r--r--arch/frv/include/asm/processor.h1
-rw-r--r--arch/frv/kernel/process.c41
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, &regs, 0, NULL, NULL);
-}