diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-27 06:13:51 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-29 04:36:47 +0100 |
commit | 0ad9513d0f81584c25f3fc7ff582c382cc1a93f7 (patch) | |
tree | 1bf616181ff9fb07d413d5e949e9ea0527fc1915 /arch/sh/kernel/process_32.c | |
parent | parisc: switch to generic fork/vfork/clone (diff) | |
download | linux-0ad9513d0f81584c25f3fc7ff582c382cc1a93f7.tar.xz linux-0ad9513d0f81584c25f3fc7ff582c382cc1a93f7.zip |
sh: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/sh/kernel/process_32.c')
-rw-r--r-- | arch/sh/kernel/process_32.c | 52 |
1 files changed, 4 insertions, 48 deletions
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index fce8029de922..1786d16b6c64 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -129,7 +129,7 @@ asmlinkage void ret_from_kernel_thread(void); int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg, - struct task_struct *p, struct pt_regs *regs) + struct task_struct *p, struct pt_regs *unused) { struct thread_info *ti = task_thread_info(p); struct pt_regs *childregs; @@ -164,9 +164,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->fpu_counter = 0; return 0; } - *childregs = *regs; + *childregs = *current_pt_regs(); - childregs->regs[15] = usp; + if (usp) + childregs->regs[15] = usp; ti->addr_limit = USER_DS; if (clone_flags & CLONE_SETTLS) @@ -217,51 +218,6 @@ __switch_to(struct task_struct *prev, struct task_struct *next) return prev; } -asmlinkage int sys_fork(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) -{ -#ifdef CONFIG_MMU - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL); -#else - /* fork almost works, enough to trick you into looking elsewhere :-( */ - return -EINVAL; -#endif -} - -asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, - unsigned long parent_tidptr, - unsigned long child_tidptr, - struct pt_regs __regs) -{ - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - if (!newsp) - newsp = regs->regs[15]; - 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(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) -{ - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs, - 0, NULL, NULL); -} - unsigned long get_wchan(struct task_struct *p) { unsigned long pc; |