diff options
Diffstat (limited to 'arch/m32r/kernel/process.c')
-rw-r--r-- | arch/m32r/kernel/process.c | 106 |
1 files changed, 26 insertions, 80 deletions
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index e7366276ef3..62c713f5694 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -165,41 +165,6 @@ void show_regs(struct pt_regs * regs) } /* - * Create a kernel thread - */ - -/* - * This is the mechanism for creating a new kernel thread. - * - * NOTE! Only a kernel-only process(ie the swapper or direct descendants - * who haven't done an "execve()") should use this: it will work within - * a system call from a "real" process, but the process memory space will - * not be free'd until both the parent and the child have exited. - */ -static void kernel_thread_helper(void *nouse, int (*fn)(void *), void *arg) -{ - fn(arg); - do_exit(-1); -} - -int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof (regs)); - regs.r1 = (unsigned long)fn; - regs.r2 = (unsigned long)arg; - - regs.bpc = (unsigned long)kernel_thread_helper; - - regs.psw = M32R_PSW_BIE; - - /* Ok, create the new process. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, - NULL); -} - -/* * Free current thread data structures etc.. */ void exit_thread(void) @@ -227,29 +192,35 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) } int copy_thread(unsigned long clone_flags, unsigned long spu, - unsigned long unused, struct task_struct *tsk, struct pt_regs *regs) + unsigned long arg, struct task_struct *tsk, struct pt_regs *regs) { struct pt_regs *childregs = task_pt_regs(tsk); extern void ret_from_fork(void); - - /* Copy registers */ - *childregs = *regs; - - childregs->spu = spu; - childregs->r0 = 0; /* Child gets zero as return value */ - regs->r0 = tsk->pid; + extern void ret_from_kernel_thread(void); + + if (unlikely(tsk->flags & PF_KTHREAD)) { + memset(childregs, 0, sizeof(struct pt_regs)); + childregs->psw = M32R_PSW_BIE; + childregs->r1 = spu; /* fn */ + childregs->r0 = arg; + tsk->thread.lr = (unsigned long)ret_from_kernel_thread; + } else { + /* Copy registers */ + *childregs = *regs; + childregs->spu = spu; + childregs->r0 = 0; /* Child gets zero as return value */ + tsk->thread.lr = (unsigned long)ret_from_fork; + } tsk->thread.sp = (unsigned long)childregs; - tsk->thread.lr = (unsigned long)ret_from_fork; return 0; } -asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2, - unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, - struct pt_regs regs) +asmlinkage int sys_fork(void) { #ifdef CONFIG_MMU - return do_fork(SIGCHLD, regs.spu, ®s, 0, NULL, NULL); + struct pt_regs *regs = current_pt_regs(); + return do_fork(SIGCHLD, regs->spu, regs, 0, NULL, NULL); #else return -EINVAL; #endif /* CONFIG_MMU */ @@ -257,14 +228,13 @@ asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2, asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, unsigned long parent_tidptr, - unsigned long child_tidptr, - unsigned long r4, unsigned long r5, unsigned long r6, - struct pt_regs regs) + unsigned long child_tidptr) { + struct pt_regs *regs = current_pt_regs(); if (!newsp) - newsp = regs.spu; + newsp = regs->spu; - return do_fork(clone_flags, newsp, ®s, 0, + return do_fork(clone_flags, newsp, regs, 0, (int __user *)parent_tidptr, (int __user *)child_tidptr); } @@ -278,38 +248,14 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, * do not have enough call-clobbered registers to hold all * the information you need. */ -asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2, - unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, - struct pt_regs regs) +asmlinkage int sys_vfork(void) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.spu, ®s, 0, + struct pt_regs *regs = current_pt_regs(); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->spu, regs, 0, NULL, NULL); } /* - * sys_execve() executes a new program. - */ -asmlinkage int sys_execve(const char __user *ufilename, - const char __user *const __user *uargv, - const char __user *const __user *uenvp, - unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, struct pt_regs regs) -{ - int error; - struct filename *filename; - - filename = getname(ufilename); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - - error = do_execve(filename->name, uargv, uenvp, ®s); - putname(filename); -out: - return error; -} - -/* * These bracket the sleeping functions.. */ #define first_sched ((unsigned long) scheduling_functions_start_here) |