parisc: switch to generic fork/vfork/clone
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 26 Oct 2012 23:59:16 +0000 (19:59 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 29 Nov 2012 03:36:46 +0000 (22:36 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/parisc/Kconfig
arch/parisc/include/asm/unistd.h
arch/parisc/kernel/entry.S
arch/parisc/kernel/process.c

index 0aec70c3561403d15a046ea4212f41259dd4f67b..e688a2be30f6a78659da7a2067c82a6c1808eb52 100644 (file)
@@ -24,6 +24,7 @@ config PARISC
        select MODULES_USE_ELF_RELA
        select GENERIC_KERNEL_THREAD
        select GENERIC_KERNEL_EXECVE
+       select CLONE_BACKWARDS
 
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
index 55512e26b0c20a9921c6165e387b6f988afdd6c9..1efef41659c9a570ee15e5b2bea1313f2b2b2991 100644 (file)
@@ -164,6 +164,9 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)       \
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_SYS_FORK
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_CLONE
 
 #endif /* __ASSEMBLY__ */
 
index c9a9abd4bc587df2e4d1e3fba13057d8be3b9489..bfb44247d7a7b023d1953d5983a110fc69966995 100644 (file)
@@ -1688,18 +1688,20 @@ dtlb_fault:
        LDREG   PT_GR18(\regs),%r18
        .endm
 
-ENTRY(sys_fork_wrapper)
+       .macro  fork_like name
+ENTRY(sys_\name\()_wrapper)
        LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
        ldo     TASK_REGS(%r1),%r1
        reg_save %r1
        mfctl   %cr27, %r28
+       b       sys_\name
        STREG   %r28, PT_CR27(%r1)
+ENDPROC(sys_\name\()_wrapper)
+       .endm
 
-       LDREG   PT_GR30(%r1),%r25
-       copy    %r1,%r24
-       b       sys_clone
-       ldi     SIGCHLD,%r26
-ENDPROC(sys_fork_wrapper)
+fork_like clone
+fork_like fork
+fork_like vfork
 
        /* Set the return value for the child */
 ENTRY(child_return)
@@ -1716,30 +1718,6 @@ finish_child_return:
        copy    %r0,%r28
 ENDPROC(child_return)
 
-
-ENTRY(sys_clone_wrapper)
-       LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
-       ldo     TASK_REGS(%r1),%r1      /* get pt regs */
-       reg_save %r1
-       mfctl   %cr27, %r28
-       STREG   %r28, PT_CR27(%r1)
-       b       sys_clone
-       copy    %r1,%r24
-ENDPROC(sys_clone_wrapper)
-
-
-ENTRY(sys_vfork_wrapper)
-       LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
-       ldo     TASK_REGS(%r1),%r1      /* get pt regs */
-       reg_save %r1
-       mfctl   %cr27, %r28
-       STREG   %r28, PT_CR27(%r1)
-
-       b       sys_vfork
-       copy    %r1,%r26
-ENDPROC(sys_vfork_wrapper)
-
-       
 ENTRY(sys_rt_sigreturn_wrapper)
        LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
        ldo     TASK_REGS(%r26),%r26    /* get pt regs */
index 38db36f64307a9bafa8db66db12e8403fc873f97..9753ecf49a06364ab2efa8e6fc32784461c4d52b 100644 (file)
@@ -202,46 +202,10 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
        return 1;
 }
 
-/* Note that "fork()" is implemented in terms of clone, with
-   parameters (SIGCHLD, regs->gr[30], regs). */
-int
-sys_clone(unsigned long clone_flags, unsigned long usp,
-         struct pt_regs *regs)
-{
-       /* Arugments from userspace are:
-          r26 = Clone flags.
-          r25 = Child stack.
-          r24 = parent_tidptr.
-          r23 = Is the TLS storage descriptor 
-          r22 = child_tidptr 
-          
-          However, these last 3 args are only examined
-          if the proper flags are set. */
-       int __user *parent_tidptr = (int __user *)regs->gr[24];
-       int __user *child_tidptr  = (int __user *)regs->gr[22];
-
-       /* usp must be word aligned.  This also prevents users from
-        * passing in the value 1 (which is the signal for a special
-        * return for a kernel thread) */
-       usp = ALIGN(usp, 4);
-
-       /* A zero value for usp means use the current stack */
-       if (usp == 0)
-         usp = regs->gr[30];
-
-       return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
-}
-
-int
-sys_vfork(struct pt_regs *regs)
-{
-       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
-}
-
 int
 copy_thread(unsigned long clone_flags, unsigned long usp,
            unsigned long arg,
-           struct task_struct *p, struct pt_regs *pregs)
+           struct task_struct *p, struct pt_regs *unused)
 {
        struct pt_regs * cregs = &(p->thread.regs);
        void *stack = task_stack_page(p);
@@ -278,7 +242,14 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
                cregs->gr[25] = arg;
        } else {
                /* user thread */
-               cregs->gr[30] = usp;
+               /* usp must be word aligned.  This also prevents users from
+                * passing in the value 1 (which is the signal for a special
+                * return for a kernel thread) */
+               if (usp) {
+                       usp = ALIGN(usp, 4);
+                       if (likely(usp))
+                               cregs->gr[30] = usp;
+               }
                cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
                if (personality(p->personality) == PER_HPUX) {
 #ifdef CONFIG_HPUX
@@ -291,7 +262,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
                }
                /* Setup thread TLS area from the 4th parameter in clone */
                if (clone_flags & CLONE_SETTLS)
-                       cregs->cr27 = pregs->gr[23];
+                       cregs->cr27 = cregs->gr[23];
        }
 
        return 0;