aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/entry-armv.S16
-rw-r--r--arch/arm/kernel/process.c23
2 files changed, 20 insertions, 19 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7ee48e7f8f3..3fd7861de4d 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -162,8 +162,6 @@ ENDPROC(__und_invalid)
@ r4 - orig_r0 (see pt_regs definition in ptrace.h)
@
stmia r5, {r0 - r4}
-
- asm_trace_hardirqs_off
.endm
.align 5
@@ -204,7 +202,7 @@ __dabt_svc:
@
@ IRQs off again before pulling preserved data off the stack
@
- disable_irq
+ disable_irq_notrace
@
@ restore SPSR and restart the instruction
@@ -218,6 +216,9 @@ ENDPROC(__dabt_svc)
__irq_svc:
svc_entry
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl trace_hardirqs_off
+#endif
#ifdef CONFIG_PREEMPT
get_thread_info tsk
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -291,7 +292,7 @@ __und_svc:
@
@ IRQs off again before pulling preserved data off the stack
@
-1: disable_irq
+1: disable_irq_notrace
@
@ restore SPSR and restart the instruction
@@ -327,7 +328,7 @@ __pabt_svc:
@
@ IRQs off again before pulling preserved data off the stack
@
- disable_irq
+ disable_irq_notrace
@
@ restore SPSR and restart the instruction
@@ -393,8 +394,6 @@ ENDPROC(__pabt_svc)
@ Clear FP to mark the first stack frame
@
zero_fp
-
- asm_trace_hardirqs_off
.endm
.macro kuser_cmpxchg_check
@@ -465,9 +464,6 @@ __irq_usr:
THUMB( movne r0, #0 )
THUMB( strne r0, [r0] )
#endif
-#ifdef CONFIG_TRACE_IRQFLAGS
- bl trace_hardirqs_on
-#endif
mov why, #0
b ret_to_user
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(&regs, 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, &regs, 0, NULL, NULL);
}