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/c6x/kernel | |
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/c6x/kernel')
-rw-r--r-- | arch/c6x/kernel/entry.S | 24 | ||||
-rw-r--r-- | arch/c6x/kernel/process.c | 25 |
2 files changed, 6 insertions, 43 deletions
diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S index 0ed6157dd256..5239057de4c4 100644 --- a/arch/c6x/kernel/entry.S +++ b/arch/c6x/kernel/entry.S | |||
@@ -415,19 +415,9 @@ ENTRY(ret_from_kernel_thread) | |||
415 | 0: | 415 | 0: |
416 | B .S2 B10 /* call fn */ | 416 | B .S2 B10 /* call fn */ |
417 | LDW .D2T1 *+SP(REGS_A1+8),A4 /* get arg */ | 417 | LDW .D2T1 *+SP(REGS_A1+8),A4 /* get arg */ |
418 | MVKL .S2 sys_exit,B11 | 418 | ADDKPC .S2 ret_from_fork_2,B3,3 |
419 | MVKH .S2 sys_exit,B11 | ||
420 | ADDKPC .S2 0f,B3,1 | ||
421 | 0: | ||
422 | BNOP .S2 B11,5 /* jump to sys_exit */ | ||
423 | ENDPROC(ret_from_kernel_thread) | 419 | ENDPROC(ret_from_kernel_thread) |
424 | 420 | ||
425 | ENTRY(ret_from_kernel_execve) | ||
426 | GET_THREAD_INFO A12 | ||
427 | BNOP .S2 syscall_exit,4 | ||
428 | ADD .D2X A4,-8,SP | ||
429 | ENDPROC(ret_from_kernel_execve) | ||
430 | |||
431 | ;; | 421 | ;; |
432 | ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ() | 422 | ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ() |
433 | ;; | 423 | ;; |
@@ -624,18 +614,6 @@ ENDPROC(sys_sigaltstack) | |||
624 | ;; Special system calls | 614 | ;; Special system calls |
625 | ;; return address is in B3 | 615 | ;; return address is in B3 |
626 | ;; | 616 | ;; |
627 | ENTRY(sys_clone) | ||
628 | ADD .D1X SP,8,A4 | ||
629 | #ifdef CONFIG_C6X_BIG_KERNEL | ||
630 | || MVKL .S1 sys_c6x_clone,A0 | ||
631 | MVKH .S1 sys_c6x_clone,A0 | ||
632 | BNOP .S2X A0,5 | ||
633 | #else | ||
634 | || B .S2 sys_c6x_clone | ||
635 | NOP 5 | ||
636 | #endif | ||
637 | ENDPROC(sys_clone) | ||
638 | |||
639 | ENTRY(sys_rt_sigreturn) | 617 | ENTRY(sys_rt_sigreturn) |
640 | ADD .D1X SP,8,A4 | 618 | ADD .D1X SP,8,A4 |
641 | #ifdef CONFIG_C6X_BIG_KERNEL | 619 | #ifdef CONFIG_C6X_BIG_KERNEL |
diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c index 2770d9a9a84e..6434df476f77 100644 --- a/arch/c6x/kernel/process.c +++ b/arch/c6x/kernel/process.c | |||
@@ -112,22 +112,6 @@ void exit_thread(void) | |||
112 | { | 112 | { |
113 | } | 113 | } |
114 | 114 | ||
115 | SYSCALL_DEFINE1(c6x_clone, struct pt_regs *, regs) | ||
116 | { | ||
117 | unsigned long clone_flags; | ||
118 | unsigned long newsp; | ||
119 | |||
120 | /* syscall puts clone_flags in A4 and usp in B4 */ | ||
121 | clone_flags = regs->orig_a4; | ||
122 | if (regs->b4) | ||
123 | newsp = regs->b4; | ||
124 | else | ||
125 | newsp = regs->sp; | ||
126 | |||
127 | return do_fork(clone_flags, newsp, regs, 0, (int __user *)regs->a6, | ||
128 | (int __user *)regs->b6); | ||
129 | } | ||
130 | |||
131 | /* | 115 | /* |
132 | * Do necessary setup to start up a newly executed thread. | 116 | * Do necessary setup to start up a newly executed thread. |
133 | */ | 117 | */ |
@@ -155,13 +139,13 @@ void start_thread(struct pt_regs *regs, unsigned int pc, unsigned long usp) | |||
155 | */ | 139 | */ |
156 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 140 | int copy_thread(unsigned long clone_flags, unsigned long usp, |
157 | unsigned long ustk_size, | 141 | unsigned long ustk_size, |
158 | struct task_struct *p, struct pt_regs *regs) | 142 | struct task_struct *p) |
159 | { | 143 | { |
160 | struct pt_regs *childregs; | 144 | struct pt_regs *childregs; |
161 | 145 | ||
162 | childregs = task_pt_regs(p); | 146 | childregs = task_pt_regs(p); |
163 | 147 | ||
164 | if (!regs) { | 148 | if (unlikely(p->flags & PF_KTHREAD)) { |
165 | /* case of __kernel_thread: we return to supervisor space */ | 149 | /* case of __kernel_thread: we return to supervisor space */ |
166 | memset(childregs, 0, sizeof(struct pt_regs)); | 150 | memset(childregs, 0, sizeof(struct pt_regs)); |
167 | childregs->sp = (unsigned long)(childregs + 1); | 151 | childregs->sp = (unsigned long)(childregs + 1); |
@@ -170,8 +154,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
170 | childregs->a1 = ustk_size; /* argument */ | 154 | childregs->a1 = ustk_size; /* argument */ |
171 | } else { | 155 | } else { |
172 | /* Otherwise use the given stack */ | 156 | /* Otherwise use the given stack */ |
173 | *childregs = *regs; | 157 | *childregs = *current_pt_regs(); |
174 | childregs->sp = usp; | 158 | if (usp) |
159 | childregs->sp = usp; | ||
175 | p->thread.pc = (unsigned long) ret_from_fork; | 160 | p->thread.pc = (unsigned long) ret_from_fork; |
176 | } | 161 | } |
177 | 162 | ||