Skip to content

Commit 5080746

Browse files
ardbiesheuvelRussell King (Oracle)
authored andcommitted
ARM: 9195/1: entry: avoid explicit literal loads
ARMv7 has MOVW/MOVT instruction pairs to load symbol addresses into registers without having to rely on literal loads that go via the D-cache. For older cores, we now support a similar arrangement, based on PC-relative group relocations. This means we can elide most literal loads entirely from the entry path, by switching to the ldr_va macro to emit the appropriate sequence depending on the target architecture revision. While at it, switch to the bl_r macro for invoking the right PABT/DABT helpers instead of setting the LR register explicitly, which does not play well with cores that speculate across function returns. Signed-off-by: Ard Biesheuvel <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Signed-off-by: Russell King (Oracle) <[email protected]>
1 parent 952f033 commit 5080746

File tree

4 files changed

+18
-50
lines changed

4 files changed

+18
-50
lines changed

arch/arm/include/asm/assembler.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -666,12 +666,11 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
666666
__adldst_l str, \src, \sym, \tmp, \cond
667667
.endm
668668

669-
.macro __ldst_va, op, reg, tmp, sym, cond
669+
.macro __ldst_va, op, reg, tmp, sym, cond, offset
670670
#if __LINUX_ARM_ARCH__ >= 7 || \
671671
!defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
672672
(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
673673
mov_l \tmp, \sym, \cond
674-
\op\cond \reg, [\tmp]
675674
#else
676675
/*
677676
* Avoid a literal load, by emitting a sequence of ADD/LDR instructions
@@ -683,28 +682,29 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
683682
.reloc .L0_\@, R_ARM_ALU_PC_G0_NC, \sym
684683
.reloc .L1_\@, R_ARM_ALU_PC_G1_NC, \sym
685684
.reloc .L2_\@, R_ARM_LDR_PC_G2, \sym
686-
.L0_\@: sub\cond \tmp, pc, #8
687-
.L1_\@: sub\cond \tmp, \tmp, #4
688-
.L2_\@: \op\cond \reg, [\tmp, #0]
685+
.L0_\@: sub\cond \tmp, pc, #8 - \offset
686+
.L1_\@: sub\cond \tmp, \tmp, #4 - \offset
687+
.L2_\@:
689688
#endif
689+
\op\cond \reg, [\tmp, #\offset]
690690
.endm
691691

692692
/*
693693
* ldr_va - load a 32-bit word from the virtual address of \sym
694694
*/
695-
.macro ldr_va, rd:req, sym:req, cond, tmp
695+
.macro ldr_va, rd:req, sym:req, cond, tmp, offset=0
696696
.ifnb \tmp
697-
__ldst_va ldr, \rd, \tmp, \sym, \cond
697+
__ldst_va ldr, \rd, \tmp, \sym, \cond, \offset
698698
.else
699-
__ldst_va ldr, \rd, \rd, \sym, \cond
699+
__ldst_va ldr, \rd, \rd, \sym, \cond, \offset
700700
.endif
701701
.endm
702702

703703
/*
704704
* str_va - store a 32-bit word to the virtual address of \sym
705705
*/
706706
.macro str_va, rn:req, sym:req, tmp:req, cond
707-
__ldst_va str, \rn, \tmp, \sym, \cond
707+
__ldst_va str, \rn, \tmp, \sym, \cond, 0
708708
.endm
709709

710710
/*

arch/arm/kernel/entry-armv.S

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@
6161
.macro pabt_helper
6262
@ PABORT handler takes pt_regs in r2, fault address in r4 and psr in r5
6363
#ifdef MULTI_PABORT
64-
ldr ip, .LCprocfns
65-
mov lr, pc
66-
ldr pc, [ip, #PROCESSOR_PABT_FUNC]
64+
ldr_va ip, processor, offset=PROCESSOR_PABT_FUNC
65+
bl_r ip
6766
#else
6867
bl CPU_PABORT_HANDLER
6968
#endif
@@ -82,9 +81,8 @@
8281
@ the fault status register in r1. r9 must be preserved.
8382
@
8483
#ifdef MULTI_DABORT
85-
ldr ip, .LCprocfns
86-
mov lr, pc
87-
ldr pc, [ip, #PROCESSOR_DABT_FUNC]
84+
ldr_va ip, processor, offset=PROCESSOR_DABT_FUNC
85+
bl_r ip
8886
#else
8987
bl CPU_DABORT_HANDLER
9088
#endif
@@ -302,16 +300,6 @@ __fiq_svc:
302300
UNWIND(.fnend )
303301
ENDPROC(__fiq_svc)
304302

305-
.align 5
306-
.LCcralign:
307-
.word cr_alignment
308-
#ifdef MULTI_DABORT
309-
.LCprocfns:
310-
.word processor
311-
#endif
312-
.LCfp:
313-
.word fp_enter
314-
315303
/*
316304
* Abort mode handlers
317305
*/
@@ -370,7 +358,7 @@ ENDPROC(__fiq_abt)
370358
THUMB( stmia sp, {r0 - r12} )
371359

372360
ATRAP( mrc p15, 0, r7, c1, c0, 0)
373-
ATRAP( ldr r8, .LCcralign)
361+
ATRAP( ldr_va r8, cr_alignment)
374362

375363
ldmia r0, {r3 - r5}
376364
add r0, sp, #S_PC @ here for interlock avoidance
@@ -379,8 +367,6 @@ ENDPROC(__fiq_abt)
379367
str r3, [sp] @ save the "real" r0 copied
380368
@ from the exception stack
381369

382-
ATRAP( ldr r8, [r8, #0])
383-
384370
@
385371
@ We are now ready to fill in the remaining blanks on the stack:
386372
@
@@ -505,9 +491,7 @@ __und_usr_thumb:
505491
*/
506492
#if __LINUX_ARM_ARCH__ < 7
507493
/* If the target CPU may not be Thumb-2-capable, a run-time check is needed: */
508-
#define NEED_CPU_ARCHITECTURE
509-
ldr r5, .LCcpu_architecture
510-
ldr r5, [r5]
494+
ldr_va r5, cpu_architecture
511495
cmp r5, #CPU_ARCH_ARMv7
512496
blo __und_usr_fault_16 @ 16bit undefined instruction
513497
/*
@@ -654,12 +638,6 @@ call_fpe:
654638
ret.w lr @ CP#14 (Debug)
655639
ret.w lr @ CP#15 (Control)
656640

657-
#ifdef NEED_CPU_ARCHITECTURE
658-
.align 2
659-
.LCcpu_architecture:
660-
.word __cpu_architecture
661-
#endif
662-
663641
#ifdef CONFIG_NEON
664642
.align 6
665643

@@ -685,9 +663,8 @@ call_fpe:
685663
#endif
686664

687665
do_fpe:
688-
ldr r4, .LCfp
689666
add r10, r10, #TI_FPSTATE @ r10 = workspace
690-
ldr pc, [r4] @ Call FP module USR entry point
667+
ldr_va pc, fp_enter, tmp=r4 @ Call FP module USR entry point
691668

692669
/*
693670
* The FP module is called with these registers set:

arch/arm/kernel/entry-common.S

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ ENTRY(vector_swi)
198198
#endif
199199
reload_current r10, ip
200200
zero_fp
201-
alignment_trap r10, ip, __cr_alignment
201+
alignment_trap r10, ip, cr_alignment
202202
asm_trace_hardirqs_on save=0
203203
enable_irq_notrace
204204
ct_user_exit save=0
@@ -328,14 +328,6 @@ __sys_trace_return:
328328
bl syscall_trace_exit
329329
b ret_slow_syscall
330330

331-
.align 5
332-
#ifdef CONFIG_ALIGNMENT_TRAP
333-
.type __cr_alignment, #object
334-
__cr_alignment:
335-
.word cr_alignment
336-
#endif
337-
.ltorg
338-
339331
.macro syscall_table_start, sym
340332
.equ __sys_nr, 0
341333
.type \sym, #object

arch/arm/kernel/entry-header.S

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@
4848
.macro alignment_trap, rtmp1, rtmp2, label
4949
#ifdef CONFIG_ALIGNMENT_TRAP
5050
mrc p15, 0, \rtmp2, c1, c0, 0
51-
ldr \rtmp1, \label
52-
ldr \rtmp1, [\rtmp1]
51+
ldr_va \rtmp1, \label
5352
teq \rtmp1, \rtmp2
5453
mcrne p15, 0, \rtmp1, c1, c0, 0
5554
#endif

0 commit comments

Comments
 (0)