refactor(aarch64): refactor usage of elx_panic

Currently we call el3_panic for panics from EL3 and elx_panic for
panics from lower ELs.

When we boot into a rich OS environment and interact with BL31 using
SMC/ABI calls and we can also decide to handle any lower EL panics in
EL3. Panic can occur in lower EL from rich OS or during SMC/ABI calls
after context switch to EL3.

But after booting into any rich OS we may land in panic either from
rich OS or while servicing any SMC call, here the logic to use
el3_panic or elx_panic is flawed as spsr_el3[3:0] is always EL3h
and end up in elx_panic even if panic occurred from EL3 during
SMC handling.

We try to decouple the elx_panic usage for its intended purpose,
introduce lower_el_panic which would call elx_panic, currently
lower_el_panic is called from default platform_ea_handle which
would be called due to panic from any of the lower ELs.

Also remove the weak linkage for elx_panic and rename it to
report_elx_panic which could be used with lower_el_panic.

Change-Id: I268bca89c01c60520d127ef6c7ba851460edc747
Signed-off-by: Govindraj Raja <govindraj.raja@arm.com>
This commit is contained in:
Govindraj Raja 2023-01-16 15:11:47 +00:00
parent f4be868be9
commit 7e619ecc89
4 changed files with 29 additions and 39 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -16,7 +16,7 @@
.globl report_unhandled_exception
.globl report_unhandled_interrupt
.globl el3_panic
.globl elx_panic
.globl report_elx_panic
#if CRASH_REPORTING
@ -64,7 +64,7 @@ intr_excpt_msg:
x30_msg:
.asciz "x30"
excpt_msg_el:
.asciz "Unhandled Exception from EL"
.asciz "Unhandled Exception from lower EL.\n"
/*
* Helper function to print from crash buf.
@ -194,28 +194,20 @@ endfunc report_unhandled_interrupt
/* -----------------------------------------------------
* This function allows to report a crash from the lower
* exception level (if crash reporting is enabled) when
* panic() is invoked from C Runtime.
* lower_el_panic() is invoked from C Runtime.
* It prints the CPU state via the crash console making
* use of 'cpu_context' structure where general purpose
* registers are saved and the crash buf.
* This function will not return.
*
* x0: Exception level
* -----------------------------------------------------
*/
func elx_panic
func report_elx_panic
msr spsel, #MODE_SP_ELX
mov x8, x0
/* Print the crash message */
adr x4, excpt_msg_el
bl asm_print_str
/* Print exception level */
add x0, x8, #'0'
bl plat_crash_console_putc
bl asm_print_newline
/* Report x0 - x29 values stored in 'gpregs_ctx' structure */
/* Store the ascii list pointer in x6 */
adr x6, gp_regs
@ -295,7 +287,7 @@ from_el1:
mrs x2, sctlr_el1
mrs x1, tcr_el1
b test_pauth
endfunc elx_panic
endfunc report_elx_panic
/* -----------------------------------------------------
* This function allows to report a crash (if crash

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2023 Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -160,31 +160,10 @@ endfunc asm_print_newline
/* This is for the non el3 BL stages to compile through */
.weak el3_panic
.weak elx_panic
func do_panic
#if CRASH_REPORTING
str x0, [sp, #-0x10]!
mrs x0, currentel
ubfx x0, x0, #MODE_EL_SHIFT, #MODE_EL_WIDTH
cmp x0, #MODE_EL3
#if !HANDLE_EA_EL3_FIRST_NS
ldr x0, [sp], #0x10
b.eq el3_panic
#else
b.ne to_panic_common
/* Check EL the exception taken from */
mrs x0, spsr_el3
ubfx x0, x0, #SPSR_EL_SHIFT, #SPSR_EL_WIDTH
cmp x0, #MODE_EL3
b.ne elx_panic
ldr x0, [sp], #0x10
b el3_panic
to_panic_common:
ldr x0, [sp], #0x10
#endif /* HANDLE_EA_EL3_FIRST_NS */
#endif /* CRASH_REPORTING */
panic_common:

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -100,6 +100,7 @@ void backtrace(const char *cookie);
#endif
void __dead2 do_panic(void);
void __dead2 report_elx_panic(void);
#define panic() \
do { \
@ -108,6 +109,21 @@ void __dead2 do_panic(void);
do_panic(); \
} while (false)
#if CRASH_REPORTING
/* --------------------------------------------------------------------
* do_lower_el_panic assumes it's called due to a panic from a lower EL
* This call will not return.
* --------------------------------------------------------------------
*/
#define lower_el_panic() \
do { \
console_flush(); \
report_elx_panic(); \
} while (false)
#else
#define lower_el_panic()
#endif
/* Function called when stack protection check code detects a corrupted stack */
void __dead2 __stack_chk_fail(void);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -94,5 +94,8 @@ void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *co
read_mpidr_el1(), get_el_str(level));
ERROR("exception reason=%u syndrome=0x%" PRIx64 "\n", ea_reason, syndrome);
panic();
/* We reached here due to a panic from a lower EL and assuming this is the default
* platform registered handler that we could call on a lower EL panic.
*/
lower_el_panic();
}