diff mbox

[2/2] ARM: prefer "bx reg" over "mov pc, reg" for all registers

Message ID 1429607372-7598-1-git-send-email-ard.biesheuvel@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Ard Biesheuvel April 21, 2015, 9:09 a.m. UTC
Commit 6ebbf2ce437b (ARM: convert all "mov.* pc, reg" to "bx reg"
for ARMv6+) replaced all occurrences of 'mov pc, <reg>' with the
'ret' macro. However, this macro only emits the 'bx' instruction
when used with the 'lr' register, but still uses 'mov pc, <reg>'
for everything else.

Since ARM/Thumb2 interworking is allowed in the static kernel
(i.e., inside vmlinux), this is potentially unsafe, since the mov
instruction will not switch modes based on the Thumb bit.

So instead, emit the 'bx' instruction in all cases, and not just
for the 'lr' register.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm/include/asm/assembler.h | 4 ----
 1 file changed, 4 deletions(-)

Comments

Russell King - ARM Linux April 21, 2015, 10:07 a.m. UTC | #1
On Tue, Apr 21, 2015 at 11:09:32AM +0200, Ard Biesheuvel wrote:
> Commit 6ebbf2ce437b (ARM: convert all "mov.* pc, reg" to "bx reg"
> for ARMv6+) replaced all occurrences of 'mov pc, <reg>' with the
> 'ret' macro. However, this macro only emits the 'bx' instruction
> when used with the 'lr' register, but still uses 'mov pc, <reg>'
> for everything else.
> 
> Since ARM/Thumb2 interworking is allowed in the static kernel
> (i.e., inside vmlinux), this is potentially unsafe, since the mov
> instruction will not switch modes based on the Thumb bit.
> 
> So instead, emit the 'bx' instruction in all cases, and not just
> for the 'lr' register.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

NAK.  This is very much intentional, but I'm unable to explain why
publically.  Not every "mov pc, xx" should be a bx instruction.
Ard Biesheuvel April 21, 2015, 10:08 a.m. UTC | #2
On 21 April 2015 at 12:07, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Apr 21, 2015 at 11:09:32AM +0200, Ard Biesheuvel wrote:
>> Commit 6ebbf2ce437b (ARM: convert all "mov.* pc, reg" to "bx reg"
>> for ARMv6+) replaced all occurrences of 'mov pc, <reg>' with the
>> 'ret' macro. However, this macro only emits the 'bx' instruction
>> when used with the 'lr' register, but still uses 'mov pc, <reg>'
>> for everything else.
>>
>> Since ARM/Thumb2 interworking is allowed in the static kernel
>> (i.e., inside vmlinux), this is potentially unsafe, since the mov
>> instruction will not switch modes based on the Thumb bit.
>>
>> So instead, emit the 'bx' instruction in all cases, and not just
>> for the 'lr' register.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> NAK.  This is very much intentional, but I'm unable to explain why
> publically.  Not every "mov pc, xx" should be a bx instruction.
>

Hhm, ok. How about only for CONFIG_THUMB2_KERNEL then?
diff mbox

Patch

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 186270b3e194..6dda6e3378ea 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -435,11 +435,7 @@  THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 #if __LINUX_ARM_ARCH__ < 6
 	mov\c	pc, \reg
 #else
-	.ifeqs	"\reg", "lr"
 	bx\c	\reg
-	.else
-	mov\c	pc, \reg
-	.endif
 #endif
 	.endm
 	.endr