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

Commit 415bfae9 authored by Al Viro's avatar Al Viro
Browse files

parisc: switch to generic fork/vfork/clone



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 92bbe6cd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ config PARISC
	select MODULES_USE_ELF_RELA
	select GENERIC_KERNEL_THREAD
	select GENERIC_KERNEL_EXECVE
	select CLONE_BACKWARDS

	help
	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
+3 −0
Original line number Diff line number Diff line
@@ -164,6 +164,9 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE

#endif /* __ASSEMBLY__ */

+8 −30
Original line number Diff line number Diff line
@@ -1688,18 +1688,20 @@ dtlb_fault:
	LDREG   PT_GR18(\regs),%r18
	.endm

ENTRY(sys_fork_wrapper)
	.macro	fork_like name
ENTRY(sys_\name\()_wrapper)
	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
	ldo	TASK_REGS(%r1),%r1
	reg_save %r1
	mfctl	%cr27, %r28
	b	sys_\name
	STREG	%r28, PT_CR27(%r1)
ENDPROC(sys_\name\()_wrapper)
	.endm

	LDREG	PT_GR30(%r1),%r25
	copy	%r1,%r24
	b	sys_clone
	ldi	SIGCHLD,%r26
ENDPROC(sys_fork_wrapper)
fork_like clone
fork_like fork
fork_like vfork

	/* Set the return value for the child */
ENTRY(child_return)
@@ -1716,30 +1718,6 @@ finish_child_return:
	copy	%r0,%r28
ENDPROC(child_return)


ENTRY(sys_clone_wrapper)
	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
	reg_save %r1
	mfctl	%cr27, %r28
	STREG	%r28, PT_CR27(%r1)
	b	sys_clone
	copy	%r1,%r24
ENDPROC(sys_clone_wrapper)


ENTRY(sys_vfork_wrapper)
	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
	reg_save %r1
	mfctl	%cr27, %r28
	STREG	%r28, PT_CR27(%r1)

	b	sys_vfork
	copy	%r1,%r26
ENDPROC(sys_vfork_wrapper)

	
ENTRY(sys_rt_sigreturn_wrapper)
	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
	ldo	TASK_REGS(%r26),%r26	/* get pt regs */
+10 −39
Original line number Diff line number Diff line
@@ -202,46 +202,10 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
	return 1;
}

/* Note that "fork()" is implemented in terms of clone, with
   parameters (SIGCHLD, regs->gr[30], regs). */
int
sys_clone(unsigned long clone_flags, unsigned long usp,
	  struct pt_regs *regs)
{
  	/* Arugments from userspace are:
	   r26 = Clone flags.
	   r25 = Child stack.
	   r24 = parent_tidptr.
	   r23 = Is the TLS storage descriptor 
	   r22 = child_tidptr 
	   
	   However, these last 3 args are only examined
	   if the proper flags are set. */
	int __user *parent_tidptr = (int __user *)regs->gr[24];
	int __user *child_tidptr  = (int __user *)regs->gr[22];

	/* usp must be word aligned.  This also prevents users from
	 * passing in the value 1 (which is the signal for a special
	 * return for a kernel thread) */
	usp = ALIGN(usp, 4);

	/* A zero value for usp means use the current stack */
	if (usp == 0)
	  usp = regs->gr[30];

	return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
}

int
sys_vfork(struct pt_regs *regs)
{
	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
}

int
copy_thread(unsigned long clone_flags, unsigned long usp,
	    unsigned long arg,
	    struct task_struct *p, struct pt_regs *pregs)
	    struct task_struct *p, struct pt_regs *unused)
{
	struct pt_regs * cregs = &(p->thread.regs);
	void *stack = task_stack_page(p);
@@ -278,7 +242,14 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
		cregs->gr[25] = arg;
	} else {
		/* user thread */
		/* usp must be word aligned.  This also prevents users from
		 * passing in the value 1 (which is the signal for a special
		 * return for a kernel thread) */
		if (usp) {
			usp = ALIGN(usp, 4);
			if (likely(usp))
				cregs->gr[30] = usp;
		}
		cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
		if (personality(p->personality) == PER_HPUX) {
#ifdef CONFIG_HPUX
@@ -291,7 +262,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
		}
		/* Setup thread TLS area from the 4th parameter in clone */
		if (clone_flags & CLONE_SETTLS)
			cregs->cr27 = pregs->gr[23];
			cregs->cr27 = cregs->gr[23];
	}

	return 0;