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

Commit 7cedd601 authored by Anton Blanchard's avatar Anton Blanchard
Browse files

powerpc: Fix kernel thread creation on ABIv2



Change how we setup registers for ret_from_kernel_thread. In
ABIv1, instead of passing a function descriptor in, dereference
it and pass the target in directly.

Use ppc_global_function_entry to get it right on both ABIv1 and ABIv2.

Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
parent b86206e4
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -378,9 +378,11 @@ _GLOBAL(ret_from_fork)
_GLOBAL(ret_from_kernel_thread)
	bl	schedule_tail
	REST_NVGPRS(r1)
	ld	r14, 0(r14)
	mtlr	r14
	mr	r3,r15
#if defined(_CALL_ELF) && _CALL_ELF == 2
	mr	r12,r14
#endif
	blrl
	li	r3,0
	b	syscall_exit
+5 −12
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@
#ifdef CONFIG_PPC64
#include <asm/firmware.h>
#endif
#include <asm/code-patching.h>
#include <linux/kprobes.h>
#include <linux/kdebug.h>

@@ -1108,7 +1109,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
		struct thread_info *ti = (void *)task_stack_page(p);
		memset(childregs, 0, sizeof(struct pt_regs));
		childregs->gpr[1] = sp + sizeof(struct pt_regs);
		childregs->gpr[14] = usp;	/* function */
		/* function */
		if (usp)
			childregs->gpr[14] = ppc_function_entry((void *)usp);
#ifdef CONFIG_PPC64
		clear_tsk_thread_flag(p, TIF_32BIT);
		childregs->softe = 1;
@@ -1187,17 +1190,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
	if (cpu_has_feature(CPU_FTR_HAS_PPR))
		p->thread.ppr = INIT_PPR;
#endif
	/*
	 * The PPC64 ABI makes use of a TOC to contain function 
	 * pointers.  The function (ret_from_except) is actually a pointer
	 * to the TOC entry.  The first entry is a pointer to the actual
	 * function.
	 */
#ifdef CONFIG_PPC64
	kregs->nip = *((unsigned long *)f);
#else
	kregs->nip = (unsigned long)f;
#endif
	kregs->nip = ppc_function_entry(f);
	return 0;
}