Commit 0ad9513d0f81584c25f3fc7ff582c382cc1a93f7
1 parent
415bfae9e9
Exists in
master
and in
20 other branches
sh: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 5 changed files with 11 additions and 110 deletions Side-by-side Diff
arch/sh/include/asm/syscalls_32.h
... | ... | @@ -9,16 +9,6 @@ |
9 | 9 | |
10 | 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 | 12 | asmlinkage int sys_sigsuspend(old_sigset_t mask); |
23 | 13 | asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act, |
24 | 14 | struct old_sigaction __user *oact); |
arch/sh/include/asm/syscalls_64.h
... | ... | @@ -9,19 +9,6 @@ |
9 | 9 | |
10 | 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 | 12 | /* Misc syscall related bits */ |
26 | 13 | asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs); |
27 | 14 | asmlinkage void do_syscall_trace_leave(struct pt_regs *regs); |
arch/sh/include/asm/unistd.h
... | ... | @@ -29,6 +29,9 @@ |
29 | 29 | # define __ARCH_WANT_SYS_SIGPROCMASK |
30 | 30 | # define __ARCH_WANT_SYS_RT_SIGACTION |
31 | 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 | 37 | * "Conditional" syscalls |
arch/sh/kernel/process_32.c
... | ... | @@ -129,7 +129,7 @@ |
129 | 129 | |
130 | 130 | int copy_thread(unsigned long clone_flags, unsigned long usp, |
131 | 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 | 134 | struct thread_info *ti = task_thread_info(p); |
135 | 135 | struct pt_regs *childregs; |
136 | 136 | |
... | ... | @@ -164,9 +164,10 @@ |
164 | 164 | p->fpu_counter = 0; |
165 | 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 | 171 | ti->addr_limit = USER_DS; |
171 | 172 | |
172 | 173 | if (clone_flags & CLONE_SETTLS) |
... | ... | @@ -215,51 +216,6 @@ |
215 | 216 | __fpu_state_restore(); |
216 | 217 | |
217 | 218 | return prev; |
218 | -} | |
219 | - | |
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 | 219 | } |
264 | 220 | |
265 | 221 | unsigned long get_wchan(struct task_struct *p) |
arch/sh/kernel/process_64.c
... | ... | @@ -383,7 +383,7 @@ |
383 | 383 | save_fpu(current); |
384 | 384 | disable_fpu(); |
385 | 385 | last_task_used_math = NULL; |
386 | - regs->sr |= SR_FD; | |
386 | + current_pt_regs()->sr |= SR_FD; | |
387 | 387 | } |
388 | 388 | #endif |
389 | 389 | /* Copy from sh version */ |
... | ... | @@ -399,7 +399,7 @@ |
399 | 399 | p->thread.pc = (unsigned long) ret_from_kernel_thread; |
400 | 400 | return 0; |
401 | 401 | } |
402 | - *childregs = *regs; | |
402 | + *childregs = *current_pt_regs(); | |
403 | 403 | |
404 | 404 | /* |
405 | 405 | * Sign extend the edited stack. |
... | ... | @@ -407,7 +407,8 @@ |
407 | 407 | * 32-bit wide and context switch must take care |
408 | 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 | 412 | p->thread.uregs = childregs; |
412 | 413 | |
413 | 414 | childregs->regs[9] = 0; /* Set return value for child */ |
... | ... | @@ -416,42 +417,6 @@ |
416 | 417 | p->thread.pc = (unsigned long) ret_from_fork; |
417 | 418 | |
418 | 419 | return 0; |
419 | -} | |
420 | - | |
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 | 420 | } |
456 | 421 | |
457 | 422 | #ifdef CONFIG_FRAME_POINTER |