diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 15:22:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 15:22:13 -0500 |
commit | 9977d9b379cb77e0f67bd6f4563618106e58e11d (patch) | |
tree | 0191accfddf578edb52c69c933d64521e3dce297 /arch/arm | |
parent | cf4af01221579a4e895f43dbfc47598fbfc5a731 (diff) | |
parent | 541880d9a2c7871f6370071d55aa6662d329c51e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull big execve/kernel_thread/fork unification series from Al Viro:
"All architectures are converted to new model. Quite a bit of that
stuff is actually shared with architecture trees; in such cases it's
literally shared branch pulled by both, not a cherry-pick.
A lot of ugliness and black magic is gone (-3KLoC total in this one):
- kernel_thread()/kernel_execve()/sys_execve() redesign.
We don't do syscalls from kernel anymore for either kernel_thread()
or kernel_execve():
kernel_thread() is essentially clone(2) with callback run before we
return to userland, the callbacks either never return or do
successful do_execve() before returning.
kernel_execve() is a wrapper for do_execve() - it doesn't need to
do transition to user mode anymore.
As a result kernel_thread() and kernel_execve() are
arch-independent now - they live in kernel/fork.c and fs/exec.c
resp. sys_execve() is also in fs/exec.c and it's completely
architecture-independent.
- daemonize() is gone, along with its parts in fs/*.c
- struct pt_regs * is no longer passed to do_fork/copy_process/
copy_thread/do_execve/search_binary_handler/->load_binary/do_coredump.
- sys_fork()/sys_vfork()/sys_clone() unified; some architectures
still need wrappers (ones with callee-saved registers not saved in
pt_regs on syscall entry), but the main part of those suckers is in
kernel/fork.c now."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (113 commits)
do_coredump(): get rid of pt_regs argument
print_fatal_signal(): get rid of pt_regs argument
ptrace_signal(): get rid of unused arguments
get rid of ptrace_signal_deliver() arguments
new helper: signal_pt_regs()
unify default ptrace_signal_deliver
flagday: kill pt_regs argument of do_fork()
death to idle_regs()
don't pass regs to copy_process()
flagday: don't pass regs to copy_thread()
bfin: switch to generic vfork, get rid of pointless wrappers
xtensa: switch to generic clone()
openrisc: switch to use of generic fork and clone
unicore32: switch to generic clone(2)
score: switch to generic fork/vfork/clone
c6x: sanitize copy_thread(), get rid of clone(2) wrapper, switch to generic clone()
take sys_fork/sys_vfork/sys_clone prototypes to linux/syscalls.h
mn10300: switch to generic fork/vfork/clone
h8300: switch to generic fork/vfork/clone
tile: switch to generic clone()
...
Conflicts:
arch/microblaze/include/asm/Kbuild
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/signal.h | 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 |
7 files changed, 13 insertions, 56 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d7d7c2fc5388..08330d9e6a9c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -57,6 +57,7 @@ config ARM | |||
57 | select SYS_SUPPORTS_APM_EMULATION | 57 | select SYS_SUPPORTS_APM_EMULATION |
58 | select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND | 58 | select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND |
59 | select MODULES_USE_ELF_REL | 59 | select MODULES_USE_ELF_REL |
60 | select CLONE_BACKWARDS | ||
60 | help | 61 | help |
61 | The ARM series is a line of low-power-consumption RISC chip designs | 62 | The ARM series is a line of low-power-consumption RISC chip designs |
62 | licensed by ARM Ltd and targeted at embedded applications and | 63 | licensed by ARM Ltd and targeted at embedded applications and |
diff --git a/arch/arm/include/asm/signal.h b/arch/arm/include/asm/signal.h index 5a7963dbd3fb..9a0ea6ab988f 100644 --- a/arch/arm/include/asm/signal.h +++ b/arch/arm/include/asm/signal.h | |||
@@ -35,5 +35,4 @@ struct k_sigaction { | |||
35 | }; | 35 | }; |
36 | 36 | ||
37 | #include <asm/sigcontext.h> | 37 | #include <asm/sigcontext.h> |
38 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
39 | #endif | 38 | #endif |
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 804153c0a9cf..a6c301e90a3b 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -502,22 +502,6 @@ sys_syscall: | |||
502 | b sys_ni_syscall | 502 | b sys_ni_syscall |
503 | ENDPROC(sys_syscall) | 503 | ENDPROC(sys_syscall) |
504 | 504 | ||
505 | sys_fork_wrapper: | ||
506 | add r0, sp, #S_OFF | ||
507 | b sys_fork | ||
508 | ENDPROC(sys_fork_wrapper) | ||
509 | |||
510 | sys_vfork_wrapper: | ||
511 | add r0, sp, #S_OFF | ||
512 | b sys_vfork | ||
513 | ENDPROC(sys_vfork_wrapper) | ||
514 | |||
515 | sys_clone_wrapper: | ||
516 | add ip, sp, #S_OFF | ||
517 | str ip, [sp, #4] | ||
518 | b sys_clone | ||
519 | ENDPROC(sys_clone_wrapper) | ||
520 | |||
521 | sys_sigreturn_wrapper: | 505 | sys_sigreturn_wrapper: |
522 | add r0, sp, #S_OFF | 506 | add r0, sp, #S_OFF |
523 | mov why, #0 @ prevent syscall restart handling | 507 | mov why, #0 @ prevent syscall restart handling |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 44bc0b327e2b..c6dec5fc20aa 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) |
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. |