浏览代码

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>
Al Viro 13 年之前
父节点
当前提交
f3268edbe6

+ 1 - 0
arch/microblaze/Kconfig

@@ -28,6 +28,7 @@ config MICROBLAZE
 	select MODULES_USE_ELF_RELA
 	select MODULES_USE_ELF_RELA
 	select GENERIC_KERNEL_THREAD
 	select GENERIC_KERNEL_THREAD
 	select GENERIC_KERNEL_EXECVE
 	select GENERIC_KERNEL_EXECVE
+	select CLONE_BACKWARDS
 
 
 config SWAP
 config SWAP
 	def_bool n
 	def_bool n

+ 5 - 0
arch/microblaze/include/asm/unistd.h

@@ -423,6 +423,11 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_SYS_EXECVE
 #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
  * "Conditional" syscalls

+ 0 - 8
arch/microblaze/kernel/entry-nommu.S

@@ -559,14 +559,6 @@ no_work_pending:
 	rtid	r14, 0
 	rtid	r14, 0
 	nop
 	nop
 
 
-sys_vfork:
-	brid	microblaze_vfork
-	addk	r5, r1, r0
-
-sys_clone:
-	brid	microblaze_clone
-	addk	r7, r1, r0
-
 sys_rt_sigreturn_wrapper:
 sys_rt_sigreturn_wrapper:
 	brid	sys_rt_sigreturn
 	brid	sys_rt_sigreturn
 	addk	r5, r1, r0
 	addk	r5, r1, r0

+ 0 - 26
arch/microblaze/kernel/entry.S

@@ -442,18 +442,6 @@ TRAP_return:		/* Make global symbol for debugging */
 	nop;
 	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
 /* 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
    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
    syscall.  This function is actually `returned to' from switch_thread
@@ -475,20 +463,6 @@ C_ENTRY(ret_from_kernel_thread):
 	brid	ret_from_trap
 	brid	ret_from_trap
 	add	r3, r0, r0
 	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):
 C_ENTRY(sys_rt_sigreturn_wrapper):
 	brid	sys_rt_sigreturn	/* Do real work */
 	brid	sys_rt_sigreturn	/* Do real work */
 	addik	r5, r1, 0;		/* add user context as 1st arg */
 	addik	r5, r1, 0;		/* add user context as 1st arg */

+ 5 - 3
arch/microblaze/kernel/process.c

@@ -13,6 +13,7 @@
 #include <linux/pm.h>
 #include <linux/pm.h>
 #include <linux/tick.h>
 #include <linux/tick.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
+#include <linux/ptrace.h>
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h> /* for USER_DS macros */
 #include <asm/uaccess.h> /* for USER_DS macros */
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
@@ -120,7 +121,7 @@ void flush_thread(void)
 
 
 int copy_thread(unsigned long clone_flags, unsigned long usp,
 int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long arg,
 		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 pt_regs *childregs = task_pt_regs(p);
 	struct thread_info *ti = task_thread_info(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;
 		ti->cpu_context.r15 = (unsigned long)ret_from_kernel_thread - 8;
 		return 0;
 		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));
 	memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
 	ti->cpu_context.r1 = (unsigned long)childregs;
 	ti->cpu_context.r1 = (unsigned long)childregs;

+ 0 - 14
arch/microblaze/kernel/sys_microblaze.c

@@ -34,20 +34,6 @@
 
 
 #include <asm/syscalls.h>
 #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,
 asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 			unsigned long prot, unsigned long flags,
 			unsigned long prot, unsigned long flags,
 			unsigned long fd, off_t pgoff)
 			unsigned long fd, off_t pgoff)

+ 1 - 5
arch/microblaze/kernel/syscall_table.S

@@ -2,11 +2,7 @@ ENTRY(sys_call_table)
 	.long sys_restart_syscall	/* 0 - old "setup()" system call,
 	.long sys_restart_syscall	/* 0 - old "setup()" system call,
 					 * used for restarting */
 					 * used for restarting */
 	.long sys_exit
 	.long sys_exit
-#ifdef CONFIG_MMU
-	.long sys_fork_wrapper
-#else
-	.long sys_ni_syscall
-#endif
+	.long sys_fork
 	.long sys_read
 	.long sys_read
 	.long sys_write
 	.long sys_write
 	.long sys_open			/* 5 */
 	.long sys_open			/* 5 */