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

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

parisc: switch to generic kernel_thread()



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent ddffeb8c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ config PARISC
	select GENERIC_STRNCPY_FROM_USER
	select HAVE_MOD_ARCH_SPECIFIC
	select MODULES_USE_ELF_RELA
	select GENERIC_KERNEL_THREAD

	help
	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
+1 −52
Original line number Diff line number Diff line
@@ -707,60 +707,10 @@ ENTRY(end_fault_vector)
	.import		handle_interruption,code
	.import		do_cpu_irq_mask,code

	/*
	 * r26 = function to be called
	 * r25 = argument to pass in
	 * r24 = flags for do_fork()
	 *
	 * Kernel threads don't ever return, so they don't need
	 * a true register context. We just save away the arguments
	 * for copy_thread/ret_ to properly set up the child.
	 */

#define CLONE_VM 0x100	/* Must agree with <linux/sched.h> */
#define CLONE_UNTRACED 0x00800000

	.import do_fork
ENTRY(__kernel_thread)
	STREG	%r2, -RP_OFFSET(%r30)

	copy	%r30, %r1
	ldo	PT_SZ_ALGN(%r30),%r30
#ifdef CONFIG_64BIT
	/* Yo, function pointers in wide mode are little structs... -PB */
	ldd	24(%r26), %r2
	STREG	%r2, PT_GR27(%r1)	/* Store childs %dp */
	ldd	16(%r26), %r26

	STREG	%r22, PT_GR22(%r1)	/* save r22 (arg5) */
	copy	%r0, %r22		/* user_tid */
#endif
	STREG	%r26, PT_GR26(%r1)  /* Store function & argument for child */
	STREG	%r25, PT_GR25(%r1)
	ldil	L%CLONE_UNTRACED, %r26
	ldo	CLONE_VM(%r26), %r26   /* Force CLONE_VM since only init_mm */
	or	%r26, %r24, %r26      /* will have kernel mappings.	 */
	ldi	1, %r25			/* stack_start, signals kernel thread */
	stw	%r0, -52(%r30)	     	/* user_tid */
#ifdef CONFIG_64BIT
	ldo	-16(%r30),%r29		/* Reference param save area */
#endif
	BL	do_fork, %r2
	copy	%r1, %r24		/* pt_regs */

	/* Parent Returns here */

	LDREG	-PT_SZ_ALGN-RP_OFFSET(%r30), %r2
	ldo	-PT_SZ_ALGN(%r30), %r30
	bv	%r0(%r2)
	nop
ENDPROC(__kernel_thread)

	/*
	 * Child Returns here
	 *
	 * copy_thread moved args from temp save area set up above
	 * into task save area.
	 * copy_thread moved args into task save area.
	 */

ENTRY(ret_from_kernel_thread)
@@ -773,7 +723,6 @@ ENTRY(ret_from_kernel_thread)
	LDREG	TASK_PT_GR25(%r1), %r26
#ifdef CONFIG_64BIT
	LDREG	TASK_PT_GR27(%r1), %r27
	LDREG	TASK_PT_GR22(%r1), %r22
#endif
	LDREG	TASK_PT_GR26(%r1), %r1
	ble	0(%sr7, %r1)
+16 −37
Original line number Diff line number Diff line
@@ -164,23 +164,6 @@ void machine_power_off(void)
void (*pm_power_off)(void) = machine_power_off;
EXPORT_SYMBOL(pm_power_off);

/*
 * Create a kernel thread
 */

extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{

	/*
	 * FIXME: Once we are sure we don't need any debug here,
	 *	  kernel_thread can become a #define.
	 */

	return __kernel_thread(fn, arg, flags);
}
EXPORT_SYMBOL(kernel_thread);

/*
 * Free current thread data structures etc..
 */
@@ -256,7 +239,7 @@ sys_vfork(struct pt_regs *regs)

int
copy_thread(unsigned long clone_flags, unsigned long usp,
	    unsigned long unused,	/* in ia64 this is "user_stack_size" */
	    unsigned long arg,
	    struct task_struct *p, struct pt_regs *pregs)
{
	struct pt_regs * cregs = &(p->thread.regs);
@@ -271,21 +254,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
	extern void * const hpux_child_return;
#endif

	*cregs = *pregs;

	/* Set the return value for the child.  Note that this is not
           actually restored by the syscall exit path, but we put it
           here for consistency in case of signals. */
	cregs->gr[28] = 0; /* child */

	/*
	 * We need to differentiate between a user fork and a
	 * kernel fork. We can't use user_mode, because the
	 * the syscall path doesn't save iaoq. Right now
	 * We rely on the fact that kernel_thread passes
	 * in zero for usp.
	 */
	if (usp == 1) {
	if (unlikely((p->flags & PF_KTHREAD) && usp != 0)) {
		memset(cregs, 0, sizeof(struct pt_regs));
		/* kernel thread */
		cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN;
		/* Must exit via ret_from_kernel_thread in order
@@ -297,10 +267,12 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
		 * ret_from_kernel_thread.
		 */
#ifdef CONFIG_64BIT
		cregs->gr[27] = pregs->gr[27];
		cregs->gr[27] = ((unsigned long *)usp)[3];
		cregs->gr[26] = ((unsigned long *)usp)[2];
#else
		cregs->gr[26] = usp;
#endif
		cregs->gr[26] = pregs->gr[26];
		cregs->gr[25] = pregs->gr[25];
		cregs->gr[25] = arg;
	} else {
		/* user thread */
		/*
@@ -308,6 +280,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
		 * for setting gr[21].
		 */

		*cregs = *pregs;

		/* Set the return value for the child.  Note that this is not
		   actually restored by the syscall exit path, but we put it
		   here for consistency in case of signals. */
		cregs->gr[28] = 0; /* child */

		/* Use same stack depth as parent */
		cregs->ksp = (unsigned long)stack
			+ (pregs->gr[21] & (THREAD_SIZE - 1));