arm: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
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 @@
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..5935b6a02 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 @@
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 @@
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 @@
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.