From f3268edbe6fe0ce56e62c6d6b14640aeb04864b7 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Sat, 27 Oct 2012 00:03:41 -0400
Subject: microblaze: switch to generic fork/vfork/clone

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
 arch/microblaze/Kconfig                 |  1 +
 arch/microblaze/include/asm/unistd.h    |  5 +++++
 arch/microblaze/kernel/entry-nommu.S    |  8 --------
 arch/microblaze/kernel/entry.S          | 26 --------------------------
 arch/microblaze/kernel/process.c        |  8 +++++---
 arch/microblaze/kernel/sys_microblaze.c | 14 --------------
 arch/microblaze/kernel/syscall_table.S  |  6 +-----
 7 files changed, 12 insertions(+), 56 deletions(-)

(limited to 'arch/microblaze')

diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 198abf6d41c..4bcf89148f3 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -28,6 +28,7 @@ config MICROBLAZE
 	select MODULES_USE_ELF_RELA
 	select GENERIC_KERNEL_THREAD
 	select GENERIC_KERNEL_EXECVE
+	select CLONE_BACKWARDS
 
 config SWAP
 	def_bool n
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index ea744283429..94d978986b7 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -423,6 +423,11 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_SYS_VFORK
+#ifdef CONFIG_MMU
+#define __ARCH_WANT_SYS_FORK
+#endif
 
 /*
  * "Conditional" syscalls
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index 673a49c04a0..cb0327f204a 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -559,14 +559,6 @@ no_work_pending:
 	rtid	r14, 0
 	nop
 
-sys_vfork:
-	brid	microblaze_vfork
-	addk	r5, r1, r0
-
-sys_clone:
-	brid	microblaze_clone
-	addk	r7, r1, r0
-
 sys_rt_sigreturn_wrapper:
 	brid	sys_rt_sigreturn
 	addk	r5, r1, r0
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 10f360ed82b..c217367dfc7 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -442,18 +442,6 @@ TRAP_return:		/* Make global symbol for debugging */
 	nop;
 
 
-/* These syscalls need access to the struct pt_regs on the stack, so we
-   implement them in assembly (they're basically all wrappers anyway).  */
-
-C_ENTRY(sys_fork_wrapper):
-	addi	r5, r0, SIGCHLD			/* Arg 0: flags */
-	lwi	r6, r1, PT_R1	/* Arg 1: child SP (use parent's) */
-	addik	r7, r1, 0			/* Arg 2: parent context */
-	add	r8, r0, r0			/* Arg 3: (unused) */
-	add	r9, r0, r0;			/* Arg 4: (unused) */
-	brid	do_fork		/* Do real work (tail-call) */
-	add	r10, r0, r0;			/* Arg 5: (unused) */
-
 /* This the initial entry point for a new child thread, with an appropriate
    stack in place that makes it look the the child is in the middle of an
    syscall.  This function is actually `returned to' from switch_thread
@@ -475,20 +463,6 @@ C_ENTRY(ret_from_kernel_thread):
 	brid	ret_from_trap
 	add	r3, r0, r0
 
-C_ENTRY(sys_vfork):
-	brid	microblaze_vfork	/* Do real work (tail-call) */
-	addik	r5, r1, 0
-
-C_ENTRY(sys_clone):
-	bnei	r6, 1f;			/* See if child SP arg (arg 1) is 0. */
-	lwi	r6, r1, PT_R1;	/* If so, use paret's stack ptr */
-1:	addik	r7, r1, 0;			/* Arg 2: parent context */
-	lwi     r9, r1, PT_R8;          /* parent tid.  */
-	lwi     r10, r1, PT_R9;         /* child tid.  */
-	/* do_fork will pick up TLS from regs->r10.  */
-	brid	do_fork		/* Do real work (tail-call) */
-	add     r8, r0, r0;             /* Arg 3: (unused) */
-
 C_ENTRY(sys_rt_sigreturn_wrapper):
 	brid	sys_rt_sigreturn	/* Do real work */
 	addik	r5, r1, 0;		/* add user context as 1st arg */
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 29768c3dc35..a5fed8db726 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -13,6 +13,7 @@
 #include <linux/pm.h>
 #include <linux/tick.h>
 #include <linux/bitops.h>
+#include <linux/ptrace.h>
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h> /* for USER_DS macros */
 #include <asm/cacheflush.h>
@@ -120,7 +121,7 @@ void flush_thread(void)
 
 int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long arg,
-		struct task_struct *p, struct pt_regs *regs)
+		struct task_struct *p, struct pt_regs *unused)
 {
 	struct pt_regs *childregs = task_pt_regs(p);
 	struct thread_info *ti = task_thread_info(p);
@@ -141,8 +142,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 		ti->cpu_context.r15 = (unsigned long)ret_from_kernel_thread - 8;
 		return 0;
 	}
-	*childregs = *regs;
-	childregs->r1 = usp;
+	*childregs = *current_pt_regs();
+	if (usp)
+		childregs->r1 = usp;
 
 	memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
 	ti->cpu_context.r1 = (unsigned long)childregs;
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index a6a7bae9f5c..63647c586b4 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -34,20 +34,6 @@
 
 #include <asm/syscalls.h>
 
-asmlinkage long microblaze_vfork(struct pt_regs *regs)
-{
-	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
-						regs, 0, NULL, NULL);
-}
-
-asmlinkage long microblaze_clone(int flags, unsigned long stack,
-							struct pt_regs *regs)
-{
-	if (!stack)
-		stack = regs->r1;
-	return do_fork(flags, stack, regs, 0, NULL, NULL);
-}
-
 asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 			unsigned long prot, unsigned long flags,
 			unsigned long fd, off_t pgoff)
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 6a2b294ef6d..ff6431e5468 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -2,11 +2,7 @@ ENTRY(sys_call_table)
 	.long sys_restart_syscall	/* 0 - old "setup()" system call,
 					 * used for restarting */
 	.long sys_exit
-#ifdef CONFIG_MMU
-	.long sys_fork_wrapper
-#else
-	.long sys_ni_syscall
-#endif
+	.long sys_fork
 	.long sys_read
 	.long sys_write
 	.long sys_open			/* 5 */
-- 
cgit v1.2.3-70-g09d2