diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-21 15:54:27 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-28 22:13:54 -0500 |
commit | 38a61b6b4a45ec8c82c75403848e1c579113c3c5 (patch) | |
tree | 140ebeb63daf0a526a0a3ba91cd53991681e0ffe | |
parent | 1d4b4b2994b5fc208963c0b795291f8c1f18becf (diff) |
arm: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/arm/kernel/calls.S | 6 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 16 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 11 | ||||
-rw-r--r-- | arch/arm/kernel/sys_arm.c | 31 |
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 |
511 | ENDPROC(sys_syscall) | 511 | ENDPROC(sys_syscall) |
512 | 512 | ||
513 | sys_fork_wrapper: | ||
514 | add r0, sp, #S_OFF | ||
515 | b sys_fork | ||
516 | ENDPROC(sys_fork_wrapper) | ||
517 | |||
518 | sys_vfork_wrapper: | ||
519 | add r0, sp, #S_OFF | ||
520 | b sys_vfork | ||
521 | ENDPROC(sys_vfork_wrapper) | ||
522 | |||
523 | sys_clone_wrapper: | ||
524 | add ip, sp, #S_OFF | ||
525 | str ip, [sp, #4] | ||
526 | b sys_clone | ||
527 | ENDPROC(sys_clone_wrapper) | ||
528 | |||
529 | sys_sigreturn_wrapper: | 513 | sys_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 | ||
377 | int | 377 | int |
378 | copy_thread(unsigned long clone_flags, unsigned long stack_start, | 378 | copy_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 | */ | ||
34 | asmlinkage 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 | */ | ||
47 | asmlinkage 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 | |||
57 | asmlinkage 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. |