Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+20 -8
+7 -3
arch/arm/kernel/entry-armv.S
··· 321 321 ARM( stmib sp, {r1 - r12} ) 322 322 THUMB( stmia sp, {r0 - r12} ) 323 323 324 + ATRAP( mrc p15, 0, r7, c1, c0, 0) 325 + ATRAP( ldr r8, .LCcralign) 326 + 324 327 ldmia r0, {r3 - r5} 325 328 add r0, sp, #S_PC @ here for interlock avoidance 326 329 mov r6, #-1 @ "" "" "" "" 327 330 328 331 str r3, [sp] @ save the "real" r0 copied 329 332 @ from the exception stack 333 + 334 + ATRAP( ldr r8, [r8, #0]) 330 335 331 336 @ 332 337 @ We are now ready to fill in the remaining blanks on the stack: ··· 346 341 ARM( stmdb r0, {sp, lr}^ ) 347 342 THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) 348 343 349 - @ 350 344 @ Enable the alignment trap while in kernel mode 351 - @ 352 - alignment_trap r0, .LCcralign 345 + ATRAP( teq r8, r7) 346 + ATRAP( mcrne p15, 0, r8, c1, c0, 0) 353 347 354 348 @ 355 349 @ Clear FP to mark the first stack frame
+1 -1
arch/arm/kernel/entry-common.S
··· 366 366 str r0, [sp, #S_OLD_R0] @ Save OLD_R0 367 367 #endif 368 368 zero_fp 369 - alignment_trap ip, __cr_alignment 369 + alignment_trap r10, ip, __cr_alignment 370 370 enable_irq 371 371 ct_user_exit 372 372 get_thread_info tsk
+12 -4
arch/arm/kernel/entry-header.S
··· 37 37 #endif 38 38 .endm 39 39 40 - .macro alignment_trap, rtemp, label 41 40 #ifdef CONFIG_ALIGNMENT_TRAP 42 - ldr \rtemp, \label 43 - ldr \rtemp, [\rtemp] 44 - mcr p15, 0, \rtemp, c1, c0 41 + #define ATRAP(x...) x 42 + #else 43 + #define ATRAP(x...) 44 + #endif 45 + 46 + .macro alignment_trap, rtmp1, rtmp2, label 47 + #ifdef CONFIG_ALIGNMENT_TRAP 48 + mrc p15, 0, \rtmp2, c1, c0, 0 49 + ldr \rtmp1, \label 50 + ldr \rtmp1, [\rtmp1] 51 + teq \rtmp1, \rtmp2 52 + mcrne p15, 0, \rtmp1, c1, c0, 0 45 53 #endif 46 54 .endm 47 55