diff options
Diffstat (limited to 'arch/arm/kernel/process.c')
| -rw-r--r-- | arch/arm/kernel/process.c | 23 | 
1 files changed, 14 insertions, 9 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index acf5e6fdb6d..a4a9cc88bec 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -351,17 +351,21 @@ EXPORT_SYMBOL(dump_fpu);  /*   * Shuffle the argument into the correct register before calling the - * thread function.  r1 is the thread argument, r2 is the pointer to - * the thread function, and r3 points to the exit function. + * thread function.  r4 is the thread argument, r5 is the pointer to + * the thread function, and r6 points to the exit function.   */  extern void kernel_thread_helper(void);  asm(	".pushsection .text\n"  "	.align\n"  "	.type	kernel_thread_helper, #function\n"  "kernel_thread_helper:\n" -"	mov	r0, r1\n" -"	mov	lr, r3\n" -"	mov	pc, r2\n" +#ifdef CONFIG_TRACE_IRQFLAGS +"	bl	trace_hardirqs_on\n" +#endif +"	msr	cpsr_c, r7\n" +"	mov	r0, r4\n" +"	mov	lr, r6\n" +"	mov	pc, r5\n"  "	.size	kernel_thread_helper, . - kernel_thread_helper\n"  "	.popsection"); @@ -391,11 +395,12 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)  	memset(®s, 0, sizeof(regs)); -	regs.ARM_r1 = (unsigned long)arg; -	regs.ARM_r2 = (unsigned long)fn; -	regs.ARM_r3 = (unsigned long)kernel_thread_exit; +	regs.ARM_r4 = (unsigned long)arg; +	regs.ARM_r5 = (unsigned long)fn; +	regs.ARM_r6 = (unsigned long)kernel_thread_exit; +	regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;  	regs.ARM_pc = (unsigned long)kernel_thread_helper; -	regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE; +	regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;  	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);  }  |