sh: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
415bfae9e9
Коммит
0ad9513d0f
|
@ -9,16 +9,6 @@
|
|||
|
||||
struct pt_regs;
|
||||
|
||||
asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs);
|
||||
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
unsigned long parent_tidptr,
|
||||
unsigned long child_tidptr,
|
||||
struct pt_regs __regs);
|
||||
asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs);
|
||||
asmlinkage int sys_sigsuspend(old_sigset_t mask);
|
||||
asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act,
|
||||
struct old_sigaction __user *oact);
|
||||
|
|
|
@ -9,19 +9,6 @@
|
|||
|
||||
struct pt_regs;
|
||||
|
||||
asmlinkage int sys_fork(unsigned long r2, unsigned long r3,
|
||||
unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs *pregs);
|
||||
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs *pregs);
|
||||
asmlinkage int sys_vfork(unsigned long r2, unsigned long r3,
|
||||
unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs *pregs);
|
||||
|
||||
/* Misc syscall related bits */
|
||||
asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs);
|
||||
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
# define __ARCH_WANT_SYS_SIGPROCMASK
|
||||
# define __ARCH_WANT_SYS_RT_SIGACTION
|
||||
# define __ARCH_WANT_SYS_EXECVE
|
||||
# define __ARCH_WANT_SYS_FORK
|
||||
# define __ARCH_WANT_SYS_VFORK
|
||||
# define __ARCH_WANT_SYS_CLONE
|
||||
|
||||
/*
|
||||
* "Conditional" syscalls
|
||||
|
|
|
@ -129,7 +129,7 @@ asmlinkage void ret_from_kernel_thread(void);
|
|||
|
||||
int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
unsigned long arg,
|
||||
struct task_struct *p, struct pt_regs *regs)
|
||||
struct task_struct *p, struct pt_regs *unused)
|
||||
{
|
||||
struct thread_info *ti = task_thread_info(p);
|
||||
struct pt_regs *childregs;
|
||||
|
@ -164,9 +164,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||
p->fpu_counter = 0;
|
||||
return 0;
|
||||
}
|
||||
*childregs = *regs;
|
||||
*childregs = *current_pt_regs();
|
||||
|
||||
childregs->regs[15] = usp;
|
||||
if (usp)
|
||||
childregs->regs[15] = usp;
|
||||
ti->addr_limit = USER_DS;
|
||||
|
||||
if (clone_flags & CLONE_SETTLS)
|
||||
|
@ -217,51 +218,6 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
|
|||
return prev;
|
||||
}
|
||||
|
||||
asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
#ifdef CONFIG_MMU
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL);
|
||||
#else
|
||||
/* fork almost works, enough to trick you into looking elsewhere :-( */
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
unsigned long parent_tidptr,
|
||||
unsigned long child_tidptr,
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
if (!newsp)
|
||||
newsp = regs->regs[15];
|
||||
return do_fork(clone_flags, newsp, regs, 0,
|
||||
(int __user *)parent_tidptr,
|
||||
(int __user *)child_tidptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is trivial, and on the face of it looks like it
|
||||
* could equally well be done in user mode.
|
||||
*
|
||||
* Not so, for quite unobvious reasons - register pressure.
|
||||
* In user mode vfork() cannot have a stack frame, and if
|
||||
* done by calling the "clone()" system call directly, you
|
||||
* do not have enough call-clobbered registers to hold all
|
||||
* the information you need.
|
||||
*/
|
||||
asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs,
|
||||
0, NULL, NULL);
|
||||
}
|
||||
|
||||
unsigned long get_wchan(struct task_struct *p)
|
||||
{
|
||||
unsigned long pc;
|
||||
|
|
|
@ -383,7 +383,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||
save_fpu(current);
|
||||
disable_fpu();
|
||||
last_task_used_math = NULL;
|
||||
regs->sr |= SR_FD;
|
||||
current_pt_regs()->sr |= SR_FD;
|
||||
}
|
||||
#endif
|
||||
/* Copy from sh version */
|
||||
|
@ -399,7 +399,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||
p->thread.pc = (unsigned long) ret_from_kernel_thread;
|
||||
return 0;
|
||||
}
|
||||
*childregs = *regs;
|
||||
*childregs = *current_pt_regs();
|
||||
|
||||
/*
|
||||
* Sign extend the edited stack.
|
||||
|
@ -407,7 +407,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||
* 32-bit wide and context switch must take care
|
||||
* of NEFF sign extension.
|
||||
*/
|
||||
childregs->regs[15] = neff_sign_extend(usp);
|
||||
if (usp)
|
||||
childregs->regs[15] = neff_sign_extend(usp);
|
||||
p->thread.uregs = childregs;
|
||||
|
||||
childregs->regs[9] = 0; /* Set return value for child */
|
||||
|
@ -418,42 +419,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage int sys_fork(unsigned long r2, unsigned long r3,
|
||||
unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs *pregs)
|
||||
{
|
||||
return do_fork(SIGCHLD, pregs->regs[15], pregs, 0, 0, 0);
|
||||
}
|
||||
|
||||
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
|
||||
unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs *pregs)
|
||||
{
|
||||
if (!newsp)
|
||||
newsp = pregs->regs[15];
|
||||
return do_fork(clone_flags, newsp, pregs, 0, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is trivial, and on the face of it looks like it
|
||||
* could equally well be done in user mode.
|
||||
*
|
||||
* Not so, for quite unobvious reasons - register pressure.
|
||||
* In user mode vfork() cannot have a stack frame, and if
|
||||
* done by calling the "clone()" system call directly, you
|
||||
* do not have enough call-clobbered registers to hold all
|
||||
* the information you need.
|
||||
*/
|
||||
asmlinkage int sys_vfork(unsigned long r2, unsigned long r3,
|
||||
unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs *pregs)
|
||||
{
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, pregs->regs[15], pregs, 0, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
static int in_sh64_switch_to(unsigned long pc)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче