mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 20:48:49 +08:00
sh: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
415bfae9e9
commit
0ad9513d0f
@ -9,16 +9,6 @@
|
|||||||
|
|
||||||
struct pt_regs;
|
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_sigsuspend(old_sigset_t mask);
|
||||||
asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act,
|
asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act,
|
||||||
struct old_sigaction __user *oact);
|
struct old_sigaction __user *oact);
|
||||||
|
@ -9,19 +9,6 @@
|
|||||||
|
|
||||||
struct pt_regs;
|
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 */
|
/* Misc syscall related bits */
|
||||||
asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs);
|
asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs);
|
||||||
asmlinkage void do_syscall_trace_leave(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_SIGPROCMASK
|
||||||
# define __ARCH_WANT_SYS_RT_SIGACTION
|
# define __ARCH_WANT_SYS_RT_SIGACTION
|
||||||
# define __ARCH_WANT_SYS_EXECVE
|
# define __ARCH_WANT_SYS_EXECVE
|
||||||
|
# define __ARCH_WANT_SYS_FORK
|
||||||
|
# define __ARCH_WANT_SYS_VFORK
|
||||||
|
# define __ARCH_WANT_SYS_CLONE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Conditional" syscalls
|
* "Conditional" syscalls
|
||||||
|
@ -129,7 +129,7 @@ asmlinkage void ret_from_kernel_thread(void);
|
|||||||
|
|
||||||
int copy_thread(unsigned long clone_flags, unsigned long usp,
|
int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||||
unsigned long arg,
|
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 thread_info *ti = task_thread_info(p);
|
||||||
struct pt_regs *childregs;
|
struct pt_regs *childregs;
|
||||||
@ -164,9 +164,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||||||
p->fpu_counter = 0;
|
p->fpu_counter = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*childregs = *regs;
|
*childregs = *current_pt_regs();
|
||||||
|
|
||||||
childregs->regs[15] = usp;
|
if (usp)
|
||||||
|
childregs->regs[15] = usp;
|
||||||
ti->addr_limit = USER_DS;
|
ti->addr_limit = USER_DS;
|
||||||
|
|
||||||
if (clone_flags & CLONE_SETTLS)
|
if (clone_flags & CLONE_SETTLS)
|
||||||
@ -217,51 +218,6 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
|
|||||||
return prev;
|
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 get_wchan(struct task_struct *p)
|
||||||
{
|
{
|
||||||
unsigned long pc;
|
unsigned long pc;
|
||||||
|
@ -383,7 +383,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||||||
save_fpu(current);
|
save_fpu(current);
|
||||||
disable_fpu();
|
disable_fpu();
|
||||||
last_task_used_math = NULL;
|
last_task_used_math = NULL;
|
||||||
regs->sr |= SR_FD;
|
current_pt_regs()->sr |= SR_FD;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Copy from sh version */
|
/* 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;
|
p->thread.pc = (unsigned long) ret_from_kernel_thread;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*childregs = *regs;
|
*childregs = *current_pt_regs();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sign extend the edited stack.
|
* 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
|
* 32-bit wide and context switch must take care
|
||||||
* of NEFF sign extension.
|
* of NEFF sign extension.
|
||||||
*/
|
*/
|
||||||
childregs->regs[15] = neff_sign_extend(usp);
|
if (usp)
|
||||||
|
childregs->regs[15] = neff_sign_extend(usp);
|
||||||
p->thread.uregs = childregs;
|
p->thread.uregs = childregs;
|
||||||
|
|
||||||
childregs->regs[9] = 0; /* Set return value for child */
|
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;
|
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
|
#ifdef CONFIG_FRAME_POINTER
|
||||||
static int in_sh64_switch_to(unsigned long pc)
|
static int in_sh64_switch_to(unsigned long pc)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user