diff mbox series

[BOOT-WRAPPER,v2,03/10] aarch64: Always enter kernel via exception return

Message ID 20240812101555.3558589-4-mark.rutland@arm.com (mailing list archive)
State New, archived
Headers show
Series Cleanup initialization | expand

Commit Message

Mark Rutland Aug. 12, 2024, 10:15 a.m. UTC
When the boot-wrapper is entered at EL3 it will enter the kernel via
ERET, and when entered at EL2 it will branch to the kernel directly.
This is an artifact of the way the boot-wrapper was originally written
in assembly, and it would be preferable to always enter the kernel via
ERET so that PSTATE is always initialized to a known-good value.

Rework jump_kernel() to always enter the kernel via ERET.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Marc Zyngier <maz@kernel.org>
Cc: Akos Denke <akos.denke@arm.com>
Cc: Andre Przywara <andre.przywara@arm.com>
Cc: Luca Fancellu <luca.fancellu@arm.com>
---
 arch/aarch64/boot.S | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

Comments

Andre Przywara Aug. 13, 2024, 5:14 p.m. UTC | #1
On Mon, 12 Aug 2024 11:15:48 +0100
Mark Rutland <mark.rutland@arm.com> wrote:

> When the boot-wrapper is entered at EL3 it will enter the kernel via
> ERET, and when entered at EL2 it will branch to the kernel directly.
> This is an artifact of the way the boot-wrapper was originally written
> in assembly, and it would be preferable to always enter the kernel via
> ERET so that PSTATE is always initialized to a known-good value.
> 
> Rework jump_kernel() to always enter the kernel via ERET.

That looks fine and still boots when entered in EL2 or EL3. Just one nit
below, with that:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Acked-by: Marc Zyngier <maz@kernel.org>
> Cc: Akos Denke <akos.denke@arm.com>
> Cc: Andre Przywara <andre.przywara@arm.com>
> Cc: Luca Fancellu <luca.fancellu@arm.com>
> ---
>  arch/aarch64/boot.S | 30 +++++++++++++-----------------
>  1 file changed, 13 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 52c617d..0ac0c98 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -76,10 +76,6 @@ reset_at_el2:
>  	b.eq	err_invalid_id
>  	bl	setup_stack
>  
> -	mov	w0, #1
> -	ldr	x1, =flag_no_el3
> -	str	w0, [x1]
> -
>  	bl	cpu_init_bootwrapper
>  
>  	bl	cpu_init_arch
> @@ -111,18 +107,11 @@ ASM_FUNC(jump_kernel)
>  	bl	find_logical_id
>  	bl	setup_stack		// Reset stack pointer
>  
> -	ldr	w0, flag_no_el3
> -	cmp	w0, #0			// Prepare Z flag
> -
>  	mov	x0, x20
>  	mov	x1, x21
>  	mov	x2, x22
>  	mov	x3, x23
> -
> -	b.eq	1f
> -	br	x19			// No EL3
> -
> -1:	mov	x4, #SPSR_KERNEL
> +	mov	x4, #SPSR_KERNEL
>  
>  	/*
>  	 * If bit 0 of the kernel address is set, we're entering in AArch32
> @@ -130,13 +119,20 @@ ASM_FUNC(jump_kernel)
>  	 */
>  	bfi	x4, x19, #5, #1
>  
> +	mrs	x5, CurrentEL
> +	cmp	x5, #CURRENTEL_EL3
> +	b.eq	eret_at_el3
> +	cmp	x5, #CURRENTEL_EL2
> +	b.eq	eret_at_el2
> +	b	.			// Not possible
> +
> +eret_at_el3:
>  	msr	elr_el3, x19
>  	msr	spsr_el3, x4
>  	eret
> +eret_at_el2:
> +	msr	elr_el2, x19
> +	msr	spsr_el2, x4
> +	eret
>  
>  	.ltorg

Looks like we don't need this directive anymore.

Cheers,
Andre

> -
> -	.data
> -	.align 3
> -flag_no_el3:
> -	.long 0
diff mbox series

Patch

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 52c617d..0ac0c98 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -76,10 +76,6 @@  reset_at_el2:
 	b.eq	err_invalid_id
 	bl	setup_stack
 
-	mov	w0, #1
-	ldr	x1, =flag_no_el3
-	str	w0, [x1]
-
 	bl	cpu_init_bootwrapper
 
 	bl	cpu_init_arch
@@ -111,18 +107,11 @@  ASM_FUNC(jump_kernel)
 	bl	find_logical_id
 	bl	setup_stack		// Reset stack pointer
 
-	ldr	w0, flag_no_el3
-	cmp	w0, #0			// Prepare Z flag
-
 	mov	x0, x20
 	mov	x1, x21
 	mov	x2, x22
 	mov	x3, x23
-
-	b.eq	1f
-	br	x19			// No EL3
-
-1:	mov	x4, #SPSR_KERNEL
+	mov	x4, #SPSR_KERNEL
 
 	/*
 	 * If bit 0 of the kernel address is set, we're entering in AArch32
@@ -130,13 +119,20 @@  ASM_FUNC(jump_kernel)
 	 */
 	bfi	x4, x19, #5, #1
 
+	mrs	x5, CurrentEL
+	cmp	x5, #CURRENTEL_EL3
+	b.eq	eret_at_el3
+	cmp	x5, #CURRENTEL_EL2
+	b.eq	eret_at_el2
+	b	.			// Not possible
+
+eret_at_el3:
 	msr	elr_el3, x19
 	msr	spsr_el3, x4
 	eret
+eret_at_el2:
+	msr	elr_el2, x19
+	msr	spsr_el2, x4
+	eret
 
 	.ltorg
-
-	.data
-	.align 3
-flag_no_el3:
-	.long 0