[PATCH] arm: boot/compressed: fix decompressor header layout for v7-M

Dave Martin Dave.Martin at arm.com
Fri May 19 09:46:04 PDT 2017


On Fri, May 19, 2017 at 03:59:59PM +0100, Ard Biesheuvel wrote:
> As reported by Patrice, the header layout of the decompressor is
> incorrect when building for v7-M. In this case, the __nop macro
> resolves to 'mov r0, r0', which is emitted as a narrow encoding,
> resulting in the header data fields to end up at lower offsets than
> required.
> 
> Given the variety of targets we need to support with the same code,
> the startup sequence is a bit of a jumble, and uses instructions
> and macros whose encoding width cannot be specified (badr), or only
> exists in a narrow encoding (bx)
> 
> So force the use of a wide encoding in __nop, and replace the start
> sequence with a simple jump to the label marking the start of code,
> preceded by a Thumb2 mode switch if required (using explicit wide
> encodings where appropriate). The label itself can be moved to the
> start of code [where it belongs] due to the larger range of branch
> instructions as compared to adr instructions.
> 
> Reported-by: Patrice CHOTARD <patrice.chotard at st.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm/boot/compressed/efi-header.S |  4 +---
>  arch/arm/boot/compressed/head.S       | 14 +++++++-------
>  2 files changed, 8 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S
> index 9d5dc4fda3c1..3f7d1b74c5e0 100644
> --- a/arch/arm/boot/compressed/efi-header.S
> +++ b/arch/arm/boot/compressed/efi-header.S
> @@ -17,14 +17,12 @@
>  		@ there.
>  		.inst	'M' | ('Z' << 8) | (0x1310 << 16)   @ tstne r0, #0x4d000
>  #else
> -		mov	r0, r0
> +		W(mov)	r0, r0
>  #endif
>  		.endm
>  
>  		.macro	__EFI_HEADER
>  #ifdef CONFIG_EFI_STUB
> -		b	__efi_start
> -
>  		.set	start_offset, __efi_start - start
>  		.org	start + 0x3c
>  		@
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index 7c711ba61417..8c336a6da210 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -130,19 +130,19 @@ start:
>  		.rept	7
>  		__nop
>  		.endr
> -   ARM(		mov	r0, r0		)
> -   ARM(		b	1f		)
> - THUMB(		badr	r12, 1f		)
> - THUMB(		bx	r12		)
> +      ARM(	b	1f		)
> + AR_CLASS(	sub	pc, pc, #3	)	@ A/R: switch to Thumb2 mode
> +  M_CLASS(	nop.w			)	@ M: already in Thumb2 mode
> +    THUMB(	.thumb			)
> +    THUMB(	b.w	1f		)

It's not so easy to see that this always assembles to two words, or that
the "sub pc, pc, #3" is assembled but not executed in an ARM kernel.

Spelling it out might be more readable:

   ARM(			mov	r0, r0		)
   ARM(			mov	r0, r0		)

 THUMB(	AR_CLASS(	sub	pc, pc, #3	))
 THUMB(	M_CLASS(	nop.w			))
 THUMB(			.thumb			)
 THUMB(			b.w	1f		)

But I guess it works either way.

Cheers
---Dave

>  
>  		.word	_magic_sig	@ Magic numbers to help the loader
>  		.word	_magic_start	@ absolute load/run zImage address
>  		.word	_magic_end	@ zImage end address
>  		.word	0x04030201	@ endianness flag
>  
> - THUMB(		.thumb			)
> -1:		__EFI_HEADER
> -
> +		__EFI_HEADER
> +1:

[...]



More information about the linux-arm-kernel mailing list