From ea4a1da9b2e6f419526b5fde15cd5563096368eb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 15 Oct 2012 16:26:03 -0400 Subject: m32r: switch to generic kernel_thread()/kernel_execve() Signed-off-by: Al Viro --- arch/m32r/kernel/process.c | 60 +++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 44 deletions(-) (limited to 'arch/m32r/kernel/process.c') diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index e7366276ef30..fa89f027c04a 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -164,41 +164,6 @@ void show_regs(struct pt_regs * regs) #endif } -/* - * 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.. */ @@ -227,19 +192,26 @@ 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; } -- cgit v1.2.1 From 8eae10e86c57b6be5e4842b34ea541efbca28bf8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 15 Oct 2012 16:37:12 -0400 Subject: m32r: switch to generic sys_execve() ... and get rid of the horrors in fork()/vfork()/clone() prototypes. It's fscking faster to calculate pt_regs in question than to fetch the pointer from stack... Signed-off-by: Al Viro --- arch/m32r/kernel/process.c | 46 ++++++++++------------------------------------ 1 file changed, 10 insertions(+), 36 deletions(-) (limited to 'arch/m32r/kernel/process.c') diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index fa89f027c04a..62c713f5694a 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -216,12 +216,11 @@ int copy_thread(unsigned long clone_flags, unsigned long spu, 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 */ @@ -229,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); } @@ -250,37 +248,13 @@ 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.. */ -- cgit v1.2.1 From 92bbe6cdfdeeaf9ac2a240b1829bab219e7e91d0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 21 Oct 2012 16:52:56 -0400 Subject: m32r: switch to generic fork/vfork/clone Signed-off-by: Al Viro --- arch/m32r/kernel/process.c | 46 ++++------------------------------------------ 1 file changed, 4 insertions(+), 42 deletions(-) (limited to 'arch/m32r/kernel/process.c') diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 62c713f5694a..c37e9a9a8f27 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -192,7 +192,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) } int copy_thread(unsigned long clone_flags, unsigned long spu, - unsigned long arg, struct task_struct *tsk, struct pt_regs *regs) + unsigned long arg, struct task_struct *tsk, struct pt_regs *unused) { struct pt_regs *childregs = task_pt_regs(tsk); extern void ret_from_fork(void); @@ -206,8 +206,9 @@ int copy_thread(unsigned long clone_flags, unsigned long spu, tsk->thread.lr = (unsigned long)ret_from_kernel_thread; } else { /* Copy registers */ - *childregs = *regs; - childregs->spu = spu; + *childregs = *current_pt_regs(); + if (spu) + childregs->spu = spu; childregs->r0 = 0; /* Child gets zero as return value */ tsk->thread.lr = (unsigned long)ret_from_fork; } @@ -216,45 +217,6 @@ int copy_thread(unsigned long clone_flags, unsigned long spu, return 0; } -asmlinkage int sys_fork(void) -{ -#ifdef CONFIG_MMU - struct pt_regs *regs = current_pt_regs(); - return do_fork(SIGCHLD, regs->spu, regs, 0, NULL, NULL); -#else - return -EINVAL; -#endif /* CONFIG_MMU */ -} - -asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, - unsigned long parent_tidptr, - unsigned long child_tidptr) -{ - struct pt_regs *regs = current_pt_regs(); - if (!newsp) - newsp = regs->spu; - - return do_fork(clone_flags, newsp, regs, 0, - (int __user *)parent_tidptr, (int __user *)child_tidptr); -} - -/* - * This is trivial, and on the face of it looks like it - * could equally well be done in user mode. - * - * Not so, for quite unobvious reasons - register pressure. - * In user mode vfork() cannot have a stack frame, and if - * done by calling the "clone()" system call directly, you - * do not have enough call-clobbered registers to hold all - * the information you need. - */ -asmlinkage int sys_vfork(void) -{ - struct pt_regs *regs = current_pt_regs(); - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->spu, regs, 0, - NULL, NULL); -} - /* * These bracket the sleeping functions.. */ -- cgit v1.2.1 From afa86fc426ff7e7f5477f15da9c405d08d5cf790 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 22 Oct 2012 22:51:14 -0400 Subject: flagday: don't pass regs to copy_thread() Signed-off-by: Al Viro --- arch/m32r/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/m32r/kernel/process.c') diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index c37e9a9a8f27..765d0f57c787 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -192,7 +192,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) } int copy_thread(unsigned long clone_flags, unsigned long spu, - unsigned long arg, struct task_struct *tsk, struct pt_regs *unused) + unsigned long arg, struct task_struct *tsk) { struct pt_regs *childregs = task_pt_regs(tsk); extern void ret_from_fork(void); -- cgit v1.2.1