summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-26 19:59:16 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-11-28 22:36:46 -0500
commit415bfae9e9dbc2232f1797a3ac78a22049a75e06 (patch)
treed5cd2e445270a1ffc6f1f5a860d458cbf321066b /arch
parent92bbe6cdfdeeaf9ac2a240b1829bab219e7e91d0 (diff)
downloadlinux-415bfae9e9dbc2232f1797a3ac78a22049a75e06.tar.gz
parisc: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/include/asm/unistd.h3
-rw-r--r--arch/parisc/kernel/entry.S38
-rw-r--r--arch/parisc/kernel/process.c49
4 files changed, 22 insertions, 69 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 0aec70c35614..e688a2be30f6 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -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
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index 55512e26b0c2..1efef41659c9 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -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__ */
 
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index c9a9abd4bc58..bfb44247d7a7 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -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 */
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 38db36f64307..9753ecf49a06 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -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;