diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-27 00:13:51 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-28 22:36:47 -0500 |
commit | 0ad9513d0f81584c25f3fc7ff582c382cc1a93f7 (patch) | |
tree | 1bf616181ff9fb07d413d5e949e9ea0527fc1915 /arch | |
parent | 415bfae9e9dbc2232f1797a3ac78a22049a75e06 (diff) |
sh: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sh/include/asm/syscalls_32.h | 10 | ||||
-rw-r--r-- | arch/sh/include/asm/syscalls_64.h | 13 | ||||
-rw-r--r-- | arch/sh/include/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/sh/kernel/process_32.c | 52 | ||||
-rw-r--r-- | arch/sh/kernel/process_64.c | 43 |
5 files changed, 11 insertions, 110 deletions
diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h index d2f89f1741f4..cc25485996bb 100644 --- a/arch/sh/include/asm/syscalls_32.h +++ b/arch/sh/include/asm/syscalls_32.h | |||
@@ -9,16 +9,6 @@ | |||
9 | 9 | ||
10 | struct pt_regs; | 10 | struct pt_regs; |
11 | 11 | ||
12 | asmlinkage int sys_fork(unsigned long r4, unsigned long r5, | ||
13 | unsigned long r6, unsigned long r7, | ||
14 | struct pt_regs __regs); | ||
15 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
16 | unsigned long parent_tidptr, | ||
17 | unsigned long child_tidptr, | ||
18 | struct pt_regs __regs); | ||
19 | asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, | ||
20 | unsigned long r6, unsigned long r7, | ||
21 | struct pt_regs __regs); | ||
22 | asmlinkage int sys_sigsuspend(old_sigset_t mask); | 12 | asmlinkage int sys_sigsuspend(old_sigset_t mask); |
23 | asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act, | 13 | asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act, |
24 | struct old_sigaction __user *oact); | 14 | struct old_sigaction __user *oact); |
diff --git a/arch/sh/include/asm/syscalls_64.h b/arch/sh/include/asm/syscalls_64.h index 3fedd9f1fab5..d62e8eb22f74 100644 --- a/arch/sh/include/asm/syscalls_64.h +++ b/arch/sh/include/asm/syscalls_64.h | |||
@@ -9,19 +9,6 @@ | |||
9 | 9 | ||
10 | struct pt_regs; | 10 | struct pt_regs; |
11 | 11 | ||
12 | asmlinkage int sys_fork(unsigned long r2, unsigned long r3, | ||
13 | unsigned long r4, unsigned long r5, | ||
14 | unsigned long r6, unsigned long r7, | ||
15 | struct pt_regs *pregs); | ||
16 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
17 | unsigned long r4, unsigned long r5, | ||
18 | unsigned long r6, unsigned long r7, | ||
19 | struct pt_regs *pregs); | ||
20 | asmlinkage int sys_vfork(unsigned long r2, unsigned long r3, | ||
21 | unsigned long r4, unsigned long r5, | ||
22 | unsigned long r6, unsigned long r7, | ||
23 | struct pt_regs *pregs); | ||
24 | |||
25 | /* Misc syscall related bits */ | 12 | /* Misc syscall related bits */ |
26 | asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs); | 13 | asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs); |
27 | asmlinkage void do_syscall_trace_leave(struct pt_regs *regs); | 14 | asmlinkage void do_syscall_trace_leave(struct pt_regs *regs); |
diff --git a/arch/sh/include/asm/unistd.h b/arch/sh/include/asm/unistd.h index f1f4775766a6..43d3f26b2eab 100644 --- a/arch/sh/include/asm/unistd.h +++ b/arch/sh/include/asm/unistd.h | |||
@@ -29,6 +29,9 @@ | |||
29 | # define __ARCH_WANT_SYS_SIGPROCMASK | 29 | # define __ARCH_WANT_SYS_SIGPROCMASK |
30 | # define __ARCH_WANT_SYS_RT_SIGACTION | 30 | # define __ARCH_WANT_SYS_RT_SIGACTION |
31 | # define __ARCH_WANT_SYS_EXECVE | 31 | # define __ARCH_WANT_SYS_EXECVE |
32 | # define __ARCH_WANT_SYS_FORK | ||
33 | # define __ARCH_WANT_SYS_VFORK | ||
34 | # define __ARCH_WANT_SYS_CLONE | ||
32 | 35 | ||
33 | /* | 36 | /* |
34 | * "Conditional" syscalls | 37 | * "Conditional" syscalls |
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index fce8029de922..1786d16b6c64 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c | |||
@@ -129,7 +129,7 @@ asmlinkage void ret_from_kernel_thread(void); | |||
129 | 129 | ||
130 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 130 | int copy_thread(unsigned long clone_flags, unsigned long usp, |
131 | unsigned long arg, | 131 | unsigned long arg, |
132 | struct task_struct *p, struct pt_regs *regs) | 132 | struct task_struct *p, struct pt_regs *unused) |
133 | { | 133 | { |
134 | struct thread_info *ti = task_thread_info(p); | 134 | struct thread_info *ti = task_thread_info(p); |
135 | struct pt_regs *childregs; | 135 | struct pt_regs *childregs; |
@@ -164,9 +164,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
164 | p->fpu_counter = 0; | 164 | p->fpu_counter = 0; |
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | *childregs = *regs; | 167 | *childregs = *current_pt_regs(); |
168 | 168 | ||
169 | childregs->regs[15] = usp; | 169 | if (usp) |
170 | childregs->regs[15] = usp; | ||
170 | ti->addr_limit = USER_DS; | 171 | ti->addr_limit = USER_DS; |
171 | 172 | ||
172 | if (clone_flags & CLONE_SETTLS) | 173 | if (clone_flags & CLONE_SETTLS) |
@@ -217,51 +218,6 @@ __switch_to(struct task_struct *prev, struct task_struct *next) | |||
217 | return prev; | 218 | return prev; |
218 | } | 219 | } |
219 | 220 | ||
220 | asmlinkage int sys_fork(unsigned long r4, unsigned long r5, | ||
221 | unsigned long r6, unsigned long r7, | ||
222 | struct pt_regs __regs) | ||
223 | { | ||
224 | #ifdef CONFIG_MMU | ||
225 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
226 | return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL); | ||
227 | #else | ||
228 | /* fork almost works, enough to trick you into looking elsewhere :-( */ | ||
229 | return -EINVAL; | ||
230 | #endif | ||
231 | } | ||
232 | |||
233 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
234 | unsigned long parent_tidptr, | ||
235 | unsigned long child_tidptr, | ||
236 | struct pt_regs __regs) | ||
237 | { | ||
238 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
239 | if (!newsp) | ||
240 | newsp = regs->regs[15]; | ||
241 | return do_fork(clone_flags, newsp, regs, 0, | ||
242 | (int __user *)parent_tidptr, | ||
243 | (int __user *)child_tidptr); | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * This is trivial, and on the face of it looks like it | ||
248 | * could equally well be done in user mode. | ||
249 | * | ||
250 | * Not so, for quite unobvious reasons - register pressure. | ||
251 | * In user mode vfork() cannot have a stack frame, and if | ||
252 | * done by calling the "clone()" system call directly, you | ||
253 | * do not have enough call-clobbered registers to hold all | ||
254 | * the information you need. | ||
255 | */ | ||
256 | asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, | ||
257 | unsigned long r6, unsigned long r7, | ||
258 | struct pt_regs __regs) | ||
259 | { | ||
260 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
261 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs, | ||
262 | 0, NULL, NULL); | ||
263 | } | ||
264 | |||
265 | unsigned long get_wchan(struct task_struct *p) | 221 | unsigned long get_wchan(struct task_struct *p) |
266 | { | 222 | { |
267 | unsigned long pc; | 223 | unsigned long pc; |
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 3a0f3fd3bb58..d5c86a8a3849 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c | |||
@@ -383,7 +383,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
383 | save_fpu(current); | 383 | save_fpu(current); |
384 | disable_fpu(); | 384 | disable_fpu(); |
385 | last_task_used_math = NULL; | 385 | last_task_used_math = NULL; |
386 | regs->sr |= SR_FD; | 386 | current_pt_regs()->sr |= SR_FD; |
387 | } | 387 | } |
388 | #endif | 388 | #endif |
389 | /* Copy from sh version */ | 389 | /* Copy from sh version */ |
@@ -399,7 +399,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
399 | p->thread.pc = (unsigned long) ret_from_kernel_thread; | 399 | p->thread.pc = (unsigned long) ret_from_kernel_thread; |
400 | return 0; | 400 | return 0; |
401 | } | 401 | } |
402 | *childregs = *regs; | 402 | *childregs = *current_pt_regs(); |
403 | 403 | ||
404 | /* | 404 | /* |
405 | * Sign extend the edited stack. | 405 | * Sign extend the edited stack. |
@@ -407,7 +407,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
407 | * 32-bit wide and context switch must take care | 407 | * 32-bit wide and context switch must take care |
408 | * of NEFF sign extension. | 408 | * of NEFF sign extension. |
409 | */ | 409 | */ |
410 | childregs->regs[15] = neff_sign_extend(usp); | 410 | if (usp) |
411 | childregs->regs[15] = neff_sign_extend(usp); | ||
411 | p->thread.uregs = childregs; | 412 | p->thread.uregs = childregs; |
412 | 413 | ||
413 | childregs->regs[9] = 0; /* Set return value for child */ | 414 | childregs->regs[9] = 0; /* Set return value for child */ |
@@ -418,42 +419,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
418 | return 0; | 419 | return 0; |
419 | } | 420 | } |
420 | 421 | ||
421 | asmlinkage int sys_fork(unsigned long r2, unsigned long r3, | ||
422 | unsigned long r4, unsigned long r5, | ||
423 | unsigned long r6, unsigned long r7, | ||
424 | struct pt_regs *pregs) | ||
425 | { | ||
426 | return do_fork(SIGCHLD, pregs->regs[15], pregs, 0, 0, 0); | ||
427 | } | ||
428 | |||
429 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
430 | unsigned long r4, unsigned long r5, | ||
431 | unsigned long r6, unsigned long r7, | ||
432 | struct pt_regs *pregs) | ||
433 | { | ||
434 | if (!newsp) | ||
435 | newsp = pregs->regs[15]; | ||
436 | return do_fork(clone_flags, newsp, pregs, 0, 0, 0); | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * This is trivial, and on the face of it looks like it | ||
441 | * could equally well be done in user mode. | ||
442 | * | ||
443 | * Not so, for quite unobvious reasons - register pressure. | ||
444 | * In user mode vfork() cannot have a stack frame, and if | ||
445 | * done by calling the "clone()" system call directly, you | ||
446 | * do not have enough call-clobbered registers to hold all | ||
447 | * the information you need. | ||
448 | */ | ||
449 | asmlinkage int sys_vfork(unsigned long r2, unsigned long r3, | ||
450 | unsigned long r4, unsigned long r5, | ||
451 | unsigned long r6, unsigned long r7, | ||
452 | struct pt_regs *pregs) | ||
453 | { | ||
454 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, pregs->regs[15], pregs, 0, 0, 0); | ||
455 | } | ||
456 | |||
457 | #ifdef CONFIG_FRAME_POINTER | 422 | #ifdef CONFIG_FRAME_POINTER |
458 | static int in_sh64_switch_to(unsigned long pc) | 423 | static int in_sh64_switch_to(unsigned long pc) |
459 | { | 424 | { |