Skip to content

Commit 6ebbf2c

Browse files
author
Russell King
committed
ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+
ARMv6 and greater introduced a new instruction ("bx") which can be used to return from function calls. Recent CPUs perform better when the "bx lr" instruction is used rather than the "mov pc, lr" instruction, and this sequence is strongly recommended to be used by the ARM architecture manual (section A.4.1.1). We provide a new macro "ret" with all its variants for the condition code which will resolve to the appropriate instruction. Rather than doing this piecemeal, and miss some instances, change all the "mov pc" instances to use the new macro, with the exception of the "movs" instruction and the kprobes code. This allows us to detect the "mov pc, lr" case and fix it up - and also gives us the possibility of deploying this for other registers depending on the CPU selection. Reported-by: Will Deacon <will.deacon@arm.com> Tested-by: Stephen Warren <swarren@nvidia.com> # Tegra Jetson TK1 Tested-by: Robert Jarzmik <robert.jarzmik@free.fr> # mioa701_bootresume.S Tested-by: Andrew Lunn <andrew@lunn.ch> # Kirkwood Tested-by: Shawn Guo <shawn.guo@freescale.com> Tested-by: Tony Lindgren <tony@atomide.com> # OMAPs Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com> # Armada XP, 375, 385 Acked-by: Sekhar Nori <nsekhar@ti.com> # DaVinci Acked-by: Christoffer Dall <christoffer.dall@linaro.org> # kvm/hyp Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com> # PXA3xx Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> # Xen Tested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> # ARMv7M Tested-by: Simon Horman <horms+renesas@verge.net.au> # Shmobile Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
1 parent af040ff commit 6ebbf2c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+644
-607
lines changed

arch/arm/crypto/aes-armv4.S

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
@ that is being targetted.
3636

3737
#include <linux/linkage.h>
38+
#include <asm/assembler.h>
3839

3940
.text
4041

@@ -648,7 +649,7 @@ _armv4_AES_set_encrypt_key:
648649

649650
.Ldone: mov r0,#0
650651
ldmia sp!,{r4-r12,lr}
651-
.Labrt: mov pc,lr
652+
.Labrt: ret lr
652653
ENDPROC(private_AES_set_encrypt_key)
653654

654655
.align 5

arch/arm/include/asm/assembler.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,25 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
427427
#endif
428428
.endm
429429

430+
.irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
431+
.macro ret\c, reg
432+
#if __LINUX_ARM_ARCH__ < 6
433+
mov\c pc, \reg
434+
#else
435+
.ifeqs "\reg", "lr"
436+
bx\c \reg
437+
.else
438+
mov\c pc, \reg
439+
.endif
440+
#endif
441+
.endm
442+
.endr
443+
444+
.macro ret.w, reg
445+
ret \reg
446+
#ifdef CONFIG_THUMB2_KERNEL
447+
nop
448+
#endif
449+
.endm
450+
430451
#endif /* __ASM_ASSEMBLER_H__ */

arch/arm/include/asm/entry-macro-multi.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@
3535
\symbol_name:
3636
mov r8, lr
3737
arch_irq_handler_default
38-
mov pc, r8
38+
ret r8
3939
.endm

arch/arm/kernel/debug.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ ENTRY(printascii)
9090
ldrneb r1, [r0], #1
9191
teqne r1, #0
9292
bne 1b
93-
mov pc, lr
93+
ret lr
9494
ENDPROC(printascii)
9595

9696
ENTRY(printch)
@@ -105,7 +105,7 @@ ENTRY(debug_ll_addr)
105105
addruart r2, r3, ip
106106
str r2, [r0]
107107
str r3, [r1]
108-
mov pc, lr
108+
ret lr
109109
ENDPROC(debug_ll_addr)
110110
#endif
111111

@@ -116,7 +116,7 @@ ENTRY(printascii)
116116
mov r0, #0x04 @ SYS_WRITE0
117117
ARM( svc #0x123456 )
118118
THUMB( svc #0xab )
119-
mov pc, lr
119+
ret lr
120120
ENDPROC(printascii)
121121

122122
ENTRY(printch)
@@ -125,14 +125,14 @@ ENTRY(printch)
125125
mov r0, #0x03 @ SYS_WRITEC
126126
ARM( svc #0x123456 )
127127
THUMB( svc #0xab )
128-
mov pc, lr
128+
ret lr
129129
ENDPROC(printch)
130130

131131
ENTRY(debug_ll_addr)
132132
mov r2, #0
133133
str r2, [r0]
134134
str r2, [r1]
135-
mov pc, lr
135+
ret lr
136136
ENDPROC(debug_ll_addr)
137137

138138
#endif

arch/arm/kernel/entry-armv.S

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ svc_preempt:
224224
1: bl preempt_schedule_irq @ irq en/disable is done inside
225225
ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS
226226
tst r0, #_TIF_NEED_RESCHED
227-
moveq pc, r8 @ go again
227+
reteq r8 @ go again
228228
b 1b
229229
#endif
230230

@@ -490,7 +490,7 @@ ENDPROC(__und_usr)
490490
.pushsection .fixup, "ax"
491491
.align 2
492492
4: str r4, [sp, #S_PC] @ retry current instruction
493-
mov pc, r9
493+
ret r9
494494
.popsection
495495
.pushsection __ex_table,"a"
496496
.long 1b, 4b
@@ -552,7 +552,7 @@ call_fpe:
552552
#endif
553553
tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
554554
tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2
555-
moveq pc, lr
555+
reteq lr
556556
and r8, r0, #0x00000f00 @ mask out CP number
557557
THUMB( lsr r8, r8, #8 )
558558
mov r7, #1
@@ -571,33 +571,33 @@ call_fpe:
571571
THUMB( add pc, r8 )
572572
nop
573573

574-
movw_pc lr @ CP#0
574+
ret.w lr @ CP#0
575575
W(b) do_fpe @ CP#1 (FPE)
576576
W(b) do_fpe @ CP#2 (FPE)
577-
movw_pc lr @ CP#3
577+
ret.w lr @ CP#3
578578
#ifdef CONFIG_CRUNCH
579579
b crunch_task_enable @ CP#4 (MaverickCrunch)
580580
b crunch_task_enable @ CP#5 (MaverickCrunch)
581581
b crunch_task_enable @ CP#6 (MaverickCrunch)
582582
#else
583-
movw_pc lr @ CP#4
584-
movw_pc lr @ CP#5
585-
movw_pc lr @ CP#6
583+
ret.w lr @ CP#4
584+
ret.w lr @ CP#5
585+
ret.w lr @ CP#6
586586
#endif
587-
movw_pc lr @ CP#7
588-
movw_pc lr @ CP#8
589-
movw_pc lr @ CP#9
587+
ret.w lr @ CP#7
588+
ret.w lr @ CP#8
589+
ret.w lr @ CP#9
590590
#ifdef CONFIG_VFP
591591
W(b) do_vfp @ CP#10 (VFP)
592592
W(b) do_vfp @ CP#11 (VFP)
593593
#else
594-
movw_pc lr @ CP#10 (VFP)
595-
movw_pc lr @ CP#11 (VFP)
594+
ret.w lr @ CP#10 (VFP)
595+
ret.w lr @ CP#11 (VFP)
596596
#endif
597-
movw_pc lr @ CP#12
598-
movw_pc lr @ CP#13
599-
movw_pc lr @ CP#14 (Debug)
600-
movw_pc lr @ CP#15 (Control)
597+
ret.w lr @ CP#12
598+
ret.w lr @ CP#13
599+
ret.w lr @ CP#14 (Debug)
600+
ret.w lr @ CP#15 (Control)
601601

602602
#ifdef NEED_CPU_ARCHITECTURE
603603
.align 2
@@ -649,7 +649,7 @@ ENTRY(fp_enter)
649649
.popsection
650650

651651
ENTRY(no_fp)
652-
mov pc, lr
652+
ret lr
653653
ENDPROC(no_fp)
654654

655655
__und_usr_fault_32:
@@ -745,7 +745,7 @@ ENDPROC(__switch_to)
745745
#ifdef CONFIG_ARM_THUMB
746746
bx \reg
747747
#else
748-
mov pc, \reg
748+
ret \reg
749749
#endif
750750
.endm
751751

@@ -837,7 +837,7 @@ kuser_cmpxchg64_fixup:
837837
#if __LINUX_ARM_ARCH__ < 6
838838
bcc kuser_cmpxchg32_fixup
839839
#endif
840-
mov pc, lr
840+
ret lr
841841
.previous
842842

843843
#else
@@ -905,7 +905,7 @@ kuser_cmpxchg32_fixup:
905905
subs r8, r4, r7
906906
rsbcss r8, r8, #(2b - 1b)
907907
strcs r7, [sp, #S_PC]
908-
mov pc, lr
908+
ret lr
909909
.previous
910910

911911
#else

arch/arm/kernel/entry-common.S

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* published by the Free Software Foundation.
99
*/
1010

11+
#include <asm/assembler.h>
1112
#include <asm/unistd.h>
1213
#include <asm/ftrace.h>
1314
#include <asm/unwind.h>
@@ -88,7 +89,7 @@ ENTRY(ret_from_fork)
8889
cmp r5, #0
8990
movne r0, r4
9091
adrne lr, BSYM(1f)
91-
movne pc, r5
92+
retne r5
9293
1: get_thread_info tsk
9394
b ret_slow_syscall
9495
ENDPROC(ret_from_fork)
@@ -290,15 +291,15 @@ ENDPROC(ftrace_graph_caller_old)
290291

291292
.macro mcount_exit
292293
ldmia sp!, {r0-r3, ip, lr}
293-
mov pc, ip
294+
ret ip
294295
.endm
295296

296297
ENTRY(__gnu_mcount_nc)
297298
UNWIND(.fnstart)
298299
#ifdef CONFIG_DYNAMIC_FTRACE
299300
mov ip, lr
300301
ldmia sp!, {lr}
301-
mov pc, ip
302+
ret ip
302303
#else
303304
__mcount
304305
#endif
@@ -333,12 +334,12 @@ return_to_handler:
333334
bl ftrace_return_to_handler
334335
mov lr, r0 @ r0 has real ret addr
335336
ldmia sp!, {r0-r3}
336-
mov pc, lr
337+
ret lr
337338
#endif
338339

339340
ENTRY(ftrace_stub)
340341
.Lftrace_stub:
341-
mov pc, lr
342+
ret lr
342343
ENDPROC(ftrace_stub)
343344

344345
#endif /* CONFIG_FUNCTION_TRACER */
@@ -561,7 +562,7 @@ sys_mmap2:
561562
streq r5, [sp, #4]
562563
beq sys_mmap_pgoff
563564
mov r0, #-EINVAL
564-
mov pc, lr
565+
ret lr
565566
#else
566567
str r5, [sp, #4]
567568
b sys_mmap_pgoff

arch/arm/kernel/entry-header.S

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,6 @@
240240
movs pc, lr @ return & move spsr_svc into cpsr
241241
.endm
242242

243-
@
244-
@ 32-bit wide "mov pc, reg"
245-
@
246-
.macro movw_pc, reg
247-
mov pc, \reg
248-
.endm
249243
#else /* CONFIG_THUMB2_KERNEL */
250244
.macro svc_exit, rpsr, irq = 0
251245
.if \irq != 0
@@ -304,14 +298,6 @@
304298
movs pc, lr @ return & move spsr_svc into cpsr
305299
.endm
306300
#endif /* ifdef CONFIG_CPU_V7M / else */
307-
308-
@
309-
@ 32-bit wide "mov pc, reg"
310-
@
311-
.macro movw_pc, reg
312-
mov pc, \reg
313-
nop
314-
.endm
315301
#endif /* !CONFIG_THUMB2_KERNEL */
316302

317303
/*

arch/arm/kernel/fiqasm.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ ENTRY(__set_fiq_regs)
3232
ldr lr, [r0]
3333
msr cpsr_c, r1 @ return to SVC mode
3434
mov r0, r0 @ avoid hazard prior to ARMv4
35-
mov pc, lr
35+
ret lr
3636
ENDPROC(__set_fiq_regs)
3737

3838
ENTRY(__get_fiq_regs)
@@ -45,5 +45,5 @@ ENTRY(__get_fiq_regs)
4545
str lr, [r0]
4646
msr cpsr_c, r1 @ return to SVC mode
4747
mov r0, r0 @ avoid hazard prior to ARMv4
48-
mov pc, lr
48+
ret lr
4949
ENDPROC(__get_fiq_regs)

arch/arm/kernel/head-common.S

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* published by the Free Software Foundation.
1111
*
1212
*/
13+
#include <asm/assembler.h>
1314

1415
#define ATAG_CORE 0x54410001
1516
#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
@@ -61,10 +62,10 @@ __vet_atags:
6162
cmp r5, r6
6263
bne 1f
6364

64-
2: mov pc, lr @ atag/dtb pointer is ok
65+
2: ret lr @ atag/dtb pointer is ok
6566

6667
1: mov r2, #0
67-
mov pc, lr
68+
ret lr
6869
ENDPROC(__vet_atags)
6970

7071
/*
@@ -162,7 +163,7 @@ __lookup_processor_type:
162163
cmp r5, r6
163164
blo 1b
164165
mov r5, #0 @ unknown processor
165-
2: mov pc, lr
166+
2: ret lr
166167
ENDPROC(__lookup_processor_type)
167168

168169
/*

arch/arm/kernel/head-nommu.S

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ ENTRY(stext)
8282
adr lr, BSYM(1f) @ return (PIC) address
8383
ARM( add pc, r10, #PROCINFO_INITFUNC )
8484
THUMB( add r12, r10, #PROCINFO_INITFUNC )
85-
THUMB( mov pc, r12 )
85+
THUMB( ret r12 )
8686
1: b __after_proc_init
8787
ENDPROC(stext)
8888

@@ -119,7 +119,7 @@ ENTRY(secondary_startup)
119119
mov r13, r12 @ __secondary_switched address
120120
ARM( add pc, r10, #PROCINFO_INITFUNC )
121121
THUMB( add r12, r10, #PROCINFO_INITFUNC )
122-
THUMB( mov pc, r12 )
122+
THUMB( ret r12 )
123123
ENDPROC(secondary_startup)
124124

125125
ENTRY(__secondary_switched)
@@ -164,7 +164,7 @@ __after_proc_init:
164164
#endif
165165
mcr p15, 0, r0, c1, c0, 0 @ write control reg
166166
#endif /* CONFIG_CPU_CP15 */
167-
mov pc, r13
167+
ret r13
168168
ENDPROC(__after_proc_init)
169169
.ltorg
170170

@@ -254,7 +254,7 @@ ENTRY(__setup_mpu)
254254
orr r0, r0, #CR_M @ Set SCTRL.M (MPU on)
255255
mcr p15, 0, r0, c1, c0, 0 @ Enable MPU
256256
isb
257-
mov pc,lr
257+
ret lr
258258
ENDPROC(__setup_mpu)
259259
#endif
260260
#include "head-common.S"

0 commit comments

Comments
 (0)