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

Commit b9763ce3 authored by Al Viro's avatar Al Viro
Browse files

frv: switch to generic fork/vfork/clone



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 0bcfe540
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,9 @@
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#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
+5 −40
Original line number Original line Diff line number Diff line
@@ -139,42 +139,12 @@ inline unsigned long user_stack(const struct pt_regs *regs)
	return user_mode(regs) ? regs->sp : 0;
	return user_mode(regs) ? regs->sp : 0;
}
}


asmlinkage int sys_fork(void)
{
#ifndef CONFIG_MMU
	/* fork almost works, enough to trick you into looking elsewhere:-( */
	return -EINVAL;
#else
	return do_fork(SIGCHLD, user_stack(__frame), __frame, 0, NULL, NULL);
#endif
}

asmlinkage int sys_vfork(void)
{
	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, user_stack(__frame), __frame, 0,
		       NULL, NULL);
}

/*****************************************************************************/
/*
 * clone a process
 * - tlsptr is retrieved by copy_thread()
 */
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
			 int __user *parent_tidptr, int __user *child_tidptr,
			 int __user *tlsptr)
{
	if (!newsp)
		newsp = user_stack(__frame);
	return do_fork(clone_flags, newsp, __frame, 0, parent_tidptr, child_tidptr);
} /* end sys_clone() */

/*
/*
 * set up the kernel stack and exception frames for a new process
 * set up the kernel stack and exception frames for a new process
 */
 */
int copy_thread(unsigned long clone_flags,
int copy_thread(unsigned long clone_flags,
		unsigned long usp, unsigned long arg,
		unsigned long usp, unsigned long arg,
		struct task_struct *p, struct pt_regs *regs)
		struct task_struct *p, struct pt_regs *unused)
{
{
	struct pt_regs *childregs;
	struct pt_regs *childregs;


@@ -182,9 +152,7 @@ int copy_thread(unsigned long clone_flags,
		(task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
		(task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);


	/* set up the userspace frame (the only place that the USP is stored) */
	/* set up the userspace frame (the only place that the USP is stored) */
	*childregs = *__kernel_frame0_ptr;
	*childregs = *current_pt_regs();

	p->set_child_tid = p->clear_child_tid = NULL;


	p->thread.frame	 = childregs;
	p->thread.frame	 = childregs;
	p->thread.curr	 = p;
	p->thread.curr	 = p;
@@ -193,17 +161,14 @@ int copy_thread(unsigned long clone_flags,
	p->thread.lr	 = 0;
	p->thread.lr	 = 0;
	p->thread.frame0 = childregs;
	p->thread.frame0 = childregs;


	if (unlikely(!regs)) {
	if (unlikely(p->flags & PF_KTHREAD)) {
		childregs->gr9 = usp; /* function */
		childregs->gr9 = usp; /* function */
		childregs->gr8 = arg;
		childregs->gr8 = arg;
		p->thread.pc = (unsigned long) ret_from_kernel_thread;
		p->thread.pc = (unsigned long) ret_from_kernel_thread;
		save_user_regs(p->thread.user);
		save_user_regs(p->thread.user);
		return 0;
		return 0;
	}
	}

	if (usp)
	/* set up the userspace frame (the only place that the USP is stored) */
	*childregs = *regs;

		childregs->sp = usp;
		childregs->sp = usp;
	childregs->next_frame	= NULL;
	childregs->next_frame	= NULL;