aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/process.c
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2014-02-04 00:08:51 -0500
committerAnton Blanchard <anton@samba.org>2014-04-22 20:05:23 -0400
commit7cedd6014bfe353d4b552ed8d54d63f6e06e26ba (patch)
treee65291b54d3de8d90c370581d776dbb4d2aafe05 /arch/powerpc/kernel/process.c
parentb86206e4c32cbe6ac3de1c6dc52c2d64bcf461cb (diff)
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: Anton Blanchard <anton@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r--arch/powerpc/kernel/process.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 31d021506d21..2ae1b99166c6 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -54,6 +54,7 @@
54#ifdef CONFIG_PPC64 54#ifdef CONFIG_PPC64
55#include <asm/firmware.h> 55#include <asm/firmware.h>
56#endif 56#endif
57#include <asm/code-patching.h>
57#include <linux/kprobes.h> 58#include <linux/kprobes.h>
58#include <linux/kdebug.h> 59#include <linux/kdebug.h>
59 60
@@ -1108,7 +1109,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
1108 struct thread_info *ti = (void *)task_stack_page(p); 1109 struct thread_info *ti = (void *)task_stack_page(p);
1109 memset(childregs, 0, sizeof(struct pt_regs)); 1110 memset(childregs, 0, sizeof(struct pt_regs));
1110 childregs->gpr[1] = sp + sizeof(struct pt_regs); 1111 childregs->gpr[1] = sp + sizeof(struct pt_regs);
1111 childregs->gpr[14] = usp; /* function */ 1112 /* function */
1113 if (usp)
1114 childregs->gpr[14] = ppc_function_entry((void *)usp);
1112#ifdef CONFIG_PPC64 1115#ifdef CONFIG_PPC64
1113 clear_tsk_thread_flag(p, TIF_32BIT); 1116 clear_tsk_thread_flag(p, TIF_32BIT);
1114 childregs->softe = 1; 1117 childregs->softe = 1;
@@ -1187,17 +1190,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
1187 if (cpu_has_feature(CPU_FTR_HAS_PPR)) 1190 if (cpu_has_feature(CPU_FTR_HAS_PPR))
1188 p->thread.ppr = INIT_PPR; 1191 p->thread.ppr = INIT_PPR;
1189#endif 1192#endif
1190 /* 1193 kregs->nip = ppc_function_entry(f);
1191 * The PPC64 ABI makes use of a TOC to contain function
1192 * pointers. The function (ret_from_except) is actually a pointer
1193 * to the TOC entry. The first entry is a pointer to the actual
1194 * function.
1195 */
1196#ifdef CONFIG_PPC64
1197 kregs->nip = *((unsigned long *)f);
1198#else
1199 kregs->nip = (unsigned long)f;
1200#endif
1201 return 0; 1194 return 0;
1202} 1195}
1203 1196