aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-21 15:54:27 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-11-28 22:13:54 -0500
commit38a61b6b4a45ec8c82c75403848e1c579113c3c5 (patch)
tree140ebeb63daf0a526a0a3ba91cd53991681e0ffe
parent1d4b4b2994b5fc208963c0b795291f8c1f18becf (diff)
arm: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/include/asm/unistd.h3
-rw-r--r--arch/arm/kernel/calls.S6
-rw-r--r--arch/arm/kernel/entry-common.S16
-rw-r--r--arch/arm/kernel/process.c11
-rw-r--r--arch/arm/kernel/sys_arm.c31
6 files changed, 13 insertions, 55 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ade7e924bef5..8918a2dd89b4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -55,6 +55,7 @@ config ARM
55 select SYS_SUPPORTS_APM_EMULATION 55 select SYS_SUPPORTS_APM_EMULATION
56 select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND 56 select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
57 select MODULES_USE_ELF_REL 57 select MODULES_USE_ELF_REL
58 select CLONE_BACKWARDS
58 help 59 help
59 The ARM series is a line of low-power-consumption RISC chip designs 60 The ARM series is a line of low-power-consumption RISC chip designs
60 licensed by ARM Ltd and targeted at embedded applications and 61 licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 8f60b6e6bd41..7cd13cc62624 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -42,6 +42,9 @@
42#define __ARCH_WANT_SYS_SOCKETCALL 42#define __ARCH_WANT_SYS_SOCKETCALL
43#endif 43#endif
44#define __ARCH_WANT_SYS_EXECVE 44#define __ARCH_WANT_SYS_EXECVE
45#define __ARCH_WANT_SYS_FORK
46#define __ARCH_WANT_SYS_VFORK
47#define __ARCH_WANT_SYS_CLONE
45 48
46/* 49/*
47 * "Conditional" syscalls 50 * "Conditional" syscalls
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 831cd38c8d99..5935b6a02e6e 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -11,7 +11,7 @@
11 */ 11 */
12/* 0 */ CALL(sys_restart_syscall) 12/* 0 */ CALL(sys_restart_syscall)
13 CALL(sys_exit) 13 CALL(sys_exit)
14 CALL(sys_fork_wrapper) 14 CALL(sys_fork)
15 CALL(sys_read) 15 CALL(sys_read)
16 CALL(sys_write) 16 CALL(sys_write)
17/* 5 */ CALL(sys_open) 17/* 5 */ CALL(sys_open)
@@ -129,7 +129,7 @@
129 CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc))) 129 CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
130 CALL(sys_fsync) 130 CALL(sys_fsync)
131 CALL(sys_sigreturn_wrapper) 131 CALL(sys_sigreturn_wrapper)
132/* 120 */ CALL(sys_clone_wrapper) 132/* 120 */ CALL(sys_clone)
133 CALL(sys_setdomainname) 133 CALL(sys_setdomainname)
134 CALL(sys_newuname) 134 CALL(sys_newuname)
135 CALL(sys_ni_syscall) /* modify_ldt */ 135 CALL(sys_ni_syscall) /* modify_ldt */
@@ -199,7 +199,7 @@
199 CALL(sys_sendfile) 199 CALL(sys_sendfile)
200 CALL(sys_ni_syscall) /* getpmsg */ 200 CALL(sys_ni_syscall) /* getpmsg */
201 CALL(sys_ni_syscall) /* putpmsg */ 201 CALL(sys_ni_syscall) /* putpmsg */
202/* 190 */ CALL(sys_vfork_wrapper) 202/* 190 */ CALL(sys_vfork)
203 CALL(sys_getrlimit) 203 CALL(sys_getrlimit)
204 CALL(sys_mmap2) 204 CALL(sys_mmap2)
205 CALL(ABI(sys_truncate64, sys_oabi_truncate64)) 205 CALL(ABI(sys_truncate64, sys_oabi_truncate64))
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 34711757ba59..88a07feaa05f 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -510,22 +510,6 @@ sys_syscall:
510 b sys_ni_syscall 510 b sys_ni_syscall
511ENDPROC(sys_syscall) 511ENDPROC(sys_syscall)
512 512
513sys_fork_wrapper:
514 add r0, sp, #S_OFF
515 b sys_fork
516ENDPROC(sys_fork_wrapper)
517
518sys_vfork_wrapper:
519 add r0, sp, #S_OFF
520 b sys_vfork
521ENDPROC(sys_vfork_wrapper)
522
523sys_clone_wrapper:
524 add ip, sp, #S_OFF
525 str ip, [sp, #4]
526 b sys_clone
527ENDPROC(sys_clone_wrapper)
528
529sys_sigreturn_wrapper: 513sys_sigreturn_wrapper:
530 add r0, sp, #S_OFF 514 add r0, sp, #S_OFF
531 mov why, #0 @ prevent syscall restart handling 515 mov why, #0 @ prevent syscall restart handling
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 90084a6de35a..4ab80bbb6d95 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -376,17 +376,18 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
376 376
377int 377int
378copy_thread(unsigned long clone_flags, unsigned long stack_start, 378copy_thread(unsigned long clone_flags, unsigned long stack_start,
379 unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs) 379 unsigned long stk_sz, struct task_struct *p, struct pt_regs *unused)
380{ 380{
381 struct thread_info *thread = task_thread_info(p); 381 struct thread_info *thread = task_thread_info(p);
382 struct pt_regs *childregs = task_pt_regs(p); 382 struct pt_regs *childregs = task_pt_regs(p);
383 383
384 memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); 384 memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
385 385
386 if (likely(regs)) { 386 if (likely(!(p->flags & PF_KTHREAD))) {
387 *childregs = *regs; 387 *childregs = *current_pt_regs();
388 childregs->ARM_r0 = 0; 388 childregs->ARM_r0 = 0;
389 childregs->ARM_sp = stack_start; 389 if (stack_start)
390 childregs->ARM_sp = stack_start;
390 } else { 391 } else {
391 memset(childregs, 0, sizeof(struct pt_regs)); 392 memset(childregs, 0, sizeof(struct pt_regs));
392 thread->cpu_context.r4 = stk_sz; 393 thread->cpu_context.r4 = stk_sz;
@@ -399,7 +400,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
399 clear_ptrace_hw_breakpoint(p); 400 clear_ptrace_hw_breakpoint(p);
400 401
401 if (clone_flags & CLONE_SETTLS) 402 if (clone_flags & CLONE_SETTLS)
402 thread->tp_value = regs->ARM_r3; 403 thread->tp_value = childregs->ARM_r3;
403 404
404 thread_notify(THREAD_NOTIFY_COPY, thread); 405 thread_notify(THREAD_NOTIFY_COPY, thread);
405 406
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index c2a898aa57aa..3151f5623d0e 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -28,37 +28,6 @@
28#include <linux/uaccess.h> 28#include <linux/uaccess.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30 30
31/* Fork a new task - this creates a new program thread.
32 * This is called indirectly via a small wrapper
33 */
34asmlinkage int sys_fork(struct pt_regs *regs)
35{
36#ifdef CONFIG_MMU
37 return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
38#else
39 /* can not support in nommu mode */
40 return(-EINVAL);
41#endif
42}
43
44/* Clone a task - this clones the calling program thread.
45 * This is called indirectly via a small wrapper
46 */
47asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
48 int __user *parent_tidptr, int tls_val,
49 int __user *child_tidptr, struct pt_regs *regs)
50{
51 if (!newsp)
52 newsp = regs->ARM_sp;
53
54 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
55}
56
57asmlinkage int sys_vfork(struct pt_regs *regs)
58{
59 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
60}
61
62/* 31/*
63 * Since loff_t is a 64 bit type we avoid a lot of ABI hassle 32 * Since loff_t is a 64 bit type we avoid a lot of ABI hassle
64 * with a different argument ordering. 33 * with a different argument ordering.