summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-08-28 13:08:14 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-09-26 14:39:54 +0100
commit195b58add463f697fb802ed55e26759094d40a54 (patch)
treed3523c21a3bb610a87672356770a83c1e3c0ca8d
parent8b521cb2947d8811b4cf7fc6a7a6ebde35218243 (diff)
downloadop-kernel-dev-195b58add463f697fb802ed55e26759094d40a54.zip
op-kernel-dev-195b58add463f697fb802ed55e26759094d40a54.tar.gz
ARM: Avoid writing to control register on every exception
If we are not changing the control register value, avoid writing to it. Writes to the control register can be very expensive, taking around a hundred cycles or so. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/entry-armv.S10
-rw-r--r--arch/arm/kernel/entry-common.S2
-rw-r--r--arch/arm/kernel/entry-header.S16
3 files changed, 20 insertions, 8 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 36276cd..3fe61de 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -321,6 +321,9 @@ ENDPROC(__pabt_svc)
ARM( stmib sp, {r1 - r12} )
THUMB( stmia sp, {r0 - r12} )
+ ATRAP( mrc p15, 0, r7, c1, c0, 0)
+ ATRAP( ldr r8, .LCcralign)
+
ldmia r0, {r3 - r5}
add r0, sp, #S_PC @ here for interlock avoidance
mov r6, #-1 @ "" "" "" ""
@@ -328,6 +331,8 @@ ENDPROC(__pabt_svc)
str r3, [sp] @ save the "real" r0 copied
@ from the exception stack
+ ATRAP( ldr r8, [r8, #0])
+
@
@ We are now ready to fill in the remaining blanks on the stack:
@
@@ -341,10 +346,9 @@ ENDPROC(__pabt_svc)
ARM( stmdb r0, {sp, lr}^ )
THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )
- @
@ Enable the alignment trap while in kernel mode
- @
- alignment_trap r0, .LCcralign
+ ATRAP( teq r8, r7)
+ ATRAP( mcrne p15, 0, r8, c1, c0, 0)
@
@ Clear FP to mark the first stack frame
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index e52fe5a..6bb09d4 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -366,7 +366,7 @@ ENTRY(vector_swi)
str r0, [sp, #S_OLD_R0] @ Save OLD_R0
#endif
zero_fp
- alignment_trap ip, __cr_alignment
+ alignment_trap r10, ip, __cr_alignment
enable_irq
ct_user_exit
get_thread_info tsk
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 8db307d..7b72939 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -37,11 +37,19 @@
#endif
.endm
- .macro alignment_trap, rtemp, label
#ifdef CONFIG_ALIGNMENT_TRAP
- ldr \rtemp, \label
- ldr \rtemp, [\rtemp]
- mcr p15, 0, \rtemp, c1, c0
+#define ATRAP(x...) x
+#else
+#define ATRAP(x...)
+#endif
+
+ .macro alignment_trap, rtmp1, rtmp2, label
+#ifdef CONFIG_ALIGNMENT_TRAP
+ mrc p15, 0, \rtmp2, c1, c0, 0
+ ldr \rtmp1, \label
+ ldr \rtmp1, [\rtmp1]
+ teq \rtmp1, \rtmp2
+ mcrne p15, 0, \rtmp1, c1, c0, 0
#endif
.endm
OpenPOWER on IntegriCloud