diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-21 19:54:27 (GMT) |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-29 03:13:54 (GMT) |
commit | 38a61b6b4a45ec8c82c75403848e1c579113c3c5 (patch) | |
tree | 140ebeb63daf0a526a0a3ba91cd53991681e0ffe /arch | |
parent | 1d4b4b2994b5fc208963c0b795291f8c1f18becf (diff) | |
download | linux-38a61b6b4a45ec8c82c75403848e1c579113c3c5.tar.xz |
arm: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/arm/kernel/calls.S | 6 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 16 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 11 | ||||
-rw-r--r-- | arch/arm/kernel/sys_arm.c | 31 |
6 files changed, 13 insertions, 55 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ade7e92..8918a2d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -55,6 +55,7 @@ config ARM select SYS_SUPPORTS_APM_EMULATION select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select MODULES_USE_ELF_REL + select CLONE_BACKWARDS help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 8f60b6e..7cd13cc 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -42,6 +42,9 @@ #define __ARCH_WANT_SYS_SOCKETCALL #endif #define __ARCH_WANT_SYS_EXECVE +#define __ARCH_WANT_SYS_FORK +#define __ARCH_WANT_SYS_VFORK +#define __ARCH_WANT_SYS_CLONE /* * "Conditional" syscalls diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 831cd38..5935b6a 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -11,7 +11,7 @@ */ /* 0 */ CALL(sys_restart_syscall) CALL(sys_exit) - CALL(sys_fork_wrapper) + CALL(sys_fork) CALL(sys_read) CALL(sys_write) /* 5 */ CALL(sys_open) @@ -129,7 +129,7 @@ CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc))) CALL(sys_fsync) CALL(sys_sigreturn_wrapper) -/* 120 */ CALL(sys_clone_wrapper) +/* 120 */ CALL(sys_clone) CALL(sys_setdomainname) CALL(sys_newuname) CALL(sys_ni_syscall) /* modify_ldt */ @@ -199,7 +199,7 @@ CALL(sys_sendfile) CALL(sys_ni_syscall) /* getpmsg */ CALL(sys_ni_syscall) /* putpmsg */ -/* 190 */ CALL(sys_vfork_wrapper) +/* 190 */ CALL(sys_vfork) CALL(sys_getrlimit) CALL(sys_mmap2) CALL(ABI(sys_truncate64, sys_oabi_truncate64)) diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 3471175..88a07fe 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -510,22 +510,6 @@ sys_syscall: b sys_ni_syscall ENDPROC(sys_syscall) -sys_fork_wrapper: - add r0, sp, #S_OFF - b sys_fork -ENDPROC(sys_fork_wrapper) - -sys_vfork_wrapper: - add r0, sp, #S_OFF - b sys_vfork -ENDPROC(sys_vfork_wrapper) - -sys_clone_wrapper: - add ip, sp, #S_OFF - str ip, [sp, #4] - b sys_clone -ENDPROC(sys_clone_wrapper) - sys_sigreturn_wrapper: add r0, sp, #S_OFF mov why, #0 @ prevent syscall restart handling diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 90084a6..4ab80bb 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -376,17 +376,18 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); int copy_thread(unsigned long clone_flags, unsigned long stack_start, - unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs) + unsigned long stk_sz, struct task_struct *p, struct pt_regs *unused) { struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); - if (likely(regs)) { - *childregs = *regs; + if (likely(!(p->flags & PF_KTHREAD))) { + *childregs = *current_pt_regs(); childregs->ARM_r0 = 0; - childregs->ARM_sp = stack_start; + if (stack_start) + childregs->ARM_sp = stack_start; } else { memset(childregs, 0, sizeof(struct pt_regs)); thread->cpu_context.r4 = stk_sz; @@ -399,7 +400,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, clear_ptrace_hw_breakpoint(p); if (clone_flags & CLONE_SETTLS) - thread->tp_value = regs->ARM_r3; + thread->tp_value = childregs->ARM_r3; thread_notify(THREAD_NOTIFY_COPY, thread); diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index c2a898a..3151f56 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -28,37 +28,6 @@ #include <linux/uaccess.h> #include <linux/slab.h> -/* Fork a new task - this creates a new program thread. - * This is called indirectly via a small wrapper - */ -asmlinkage int sys_fork(struct pt_regs *regs) -{ -#ifdef CONFIG_MMU - return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL); -#else - /* can not support in nommu mode */ - return(-EINVAL); -#endif -} - -/* Clone a task - this clones the calling program thread. - * This is called indirectly via a small wrapper - */ -asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, - int __user *parent_tidptr, int tls_val, - int __user *child_tidptr, struct pt_regs *regs) -{ - if (!newsp) - newsp = regs->ARM_sp; - - return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); -} - -asmlinkage int sys_vfork(struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL); -} - /* * Since loff_t is a 64 bit type we avoid a lot of ABI hassle * with a different argument ordering. |