Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ad9513d authored by Al Viro's avatar Al Viro
Browse files

sh: switch to generic fork/vfork/clone



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 415bfae9
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -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);
+0 −13
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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
+4 −48
Original line number Diff line number Diff line
@@ -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,8 +164,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
		p->fpu_counter = 0;
		return 0;
	}
	*childregs = *regs;
	*childregs = *current_pt_regs();

	if (usp)
		childregs->regs[15] = usp;
	ti->addr_limit = USER_DS;

@@ -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;
+4 −39
Original line number Diff line number Diff line
@@ -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,6 +407,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
	 * 32-bit wide and context switch must take care
	 * of NEFF sign extension.
	 */
	if (usp)
		childregs->regs[15] = neff_sign_extend(usp);
	p->thread.uregs = childregs;

@@ -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)
{