ARM: Avoid writing to control register on every exception
authorRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 28 Aug 2014 12:08:14 +0000 (13:08 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 26 Sep 2014 13:39:54 +0000 (14:39 +0100)
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>
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/entry-header.S

index 36276cdccfbc71e9e69de18fe21a00ac25ddbd07..3fe61de63e3014f87634c3d05717feae87bf8551 100644 (file)
@@ -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
index e52fe5a2d8439e36dc2e75bc3f5eb1a6df5ec752..6bb09d4abdea6356a575de475e0809765c3ee19e 100644 (file)
@@ -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
index 8db307d0954bb03ee95550471dcc0e6f86ae560f..7b729394e78a30632f059f72aceb82a2660bfe82 100644 (file)
 #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