aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-27 00:13:51 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-11-28 22:36:47 -0500
commit0ad9513d0f81584c25f3fc7ff582c382cc1a93f7 (patch)
tree1bf616181ff9fb07d413d5e949e9ea0527fc1915 /arch
parent415bfae9e9dbc2232f1797a3ac78a22049a75e06 (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.h10
-rw-r--r--arch/sh/include/asm/syscalls_64.h13
-rw-r--r--arch/sh/include/asm/unistd.h3
-rw-r--r--arch/sh/kernel/process_32.c52
-rw-r--r--arch/sh/kernel/process_64.c43
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
10struct pt_regs; 10struct pt_regs;
11 11
12asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
13 unsigned long r6, unsigned long r7,
14 struct pt_regs __regs);
15asmlinkage 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);
19asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
20 unsigned long r6, unsigned long r7,
21 struct pt_regs __regs);
22asmlinkage int sys_sigsuspend(old_sigset_t mask); 12asmlinkage int sys_sigsuspend(old_sigset_t mask);
23asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act, 13asmlinkage 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
10struct pt_regs; 10struct pt_regs;
11 11
12asmlinkage 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);
16asmlinkage 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);
20asmlinkage 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 */
26asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs); 13asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs);
27asmlinkage void do_syscall_trace_leave(struct pt_regs *regs); 14asmlinkage 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
130int copy_thread(unsigned long clone_flags, unsigned long usp, 130int 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
220asmlinkage 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
233asmlinkage 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 */
256asmlinkage 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
265unsigned long get_wchan(struct task_struct *p) 221unsigned 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
421asmlinkage 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
429asmlinkage 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 */
449asmlinkage 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
458static int in_sh64_switch_to(unsigned long pc) 423static int in_sh64_switch_to(unsigned long pc)
459{ 424{