arm: switch to generic fork/vfork/clone
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 21 Oct 2012 19:54:27 +0000 (15:54 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 29 Nov 2012 03:13:54 +0000 (22:13 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/arm/Kconfig
arch/arm/include/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/process.c
arch/arm/kernel/sys_arm.c

index ade7e924bef5faaf00de76c0354e025ed4371b35..8918a2dd89b40fffcae39bcd5376163774a978ba 100644 (file)
@@ -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
index 8f60b6e6bd41c632ccfe4e90250fcc4cb3bff46a..7cd13cc62624b223873d654b4c8acf40ddd9f4f2 100644 (file)
@@ -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
index 831cd38c8d997b32f895fa077f3745c08879d99d..5935b6a02e6e2e0af99db6bda596574eadb35199 100644 (file)
@@ -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)
                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 */
                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))
index 34711757ba59a958592d31ea527170c1356c282c..88a07feaa05fb3283d1f8e765bed0dd9fd16566f 100644 (file)
@@ -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
index 90084a6de35a75ede68e451a4f521e3a4174fc92..4ab80bbb6d9572ff7dadeb6b2669d04caee576c8 100644 (file)
@@ -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);
 
index c2a898aa57aada4b16cff08ea6da84d797f88ab9..3151f5623d0e88ded30150fb47b8696366108111 100644 (file)
 #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.