diff options
| author | Raghu Krishnamurthy <raghu.ncstate@gmail.com> | 2022-07-25 14:44:33 -0700 |
|---|---|---|
| committer | Raghu Krishnamurthy <raghu.ncstate@gmail.com> | 2022-08-30 08:29:25 -0700 |
| commit | 7c2fe62f1347bb94d82e9fdd3bc5eaebedaf0bc7 (patch) | |
| tree | 64db9c876c12a98c59bc100c0ee68d6d09919d93 | |
| parent | 6a5022278b0bda10708534ef5cc6c1b5256081ee (diff) | |
| download | arm-trusted-firmware-7c2fe62f1347bb94d82e9fdd3bc5eaebedaf0bc7.tar.gz | |
fix(bl31): allow use of EHF with S-EL2 SPMC
Currently, when SPMC at S-EL2 is used, we cannot use the RAS framework
to handle Group 0 interrupts. This is required on platforms where first
level of triaging needs to occur at EL3, before forwarding RAS handling
to a secure partition running atop an SPMC (hafnium).
The RAS framework depends on EHF and EHF registers for Group 0
interrupts to be trapped to EL3 when execution is both in secure world
and normal world. However, an FF-A compliant SPMC requires secure
interrupts to be trapped by the SPMC when execution is in S-EL0/S-EL1.
Consequently, the SPMC (hafnium) is incompatible with EHF, since it is
not re-entrant, and a Group 0 interrupt trapped to EL3 when execution is
in secure world, cannot be forwarded to an SP running atop SPMC.
This patch changes EHF to only register for Group 0 interrupts to be
trapped to EL3 when execution is in normal world and also makes it a
valid routing model to do so, when EL3_EXCEPTION_HANDLING is set (when
enabling the RAS framework).
Signed-off-by: Raghu Krishnamurthy <raghu.ncstate@gmail.com>
Change-Id: I72d4cf4d8ecc549a832d1c36055fbe95866747fe
| -rw-r--r-- | bl31/ehf.c | 11 | ||||
| -rw-r--r-- | docs/getting_started/build-options.rst | 7 | ||||
| -rw-r--r-- | include/bl31/interrupt_mgmt.h | 16 |
3 files changed, 26 insertions, 8 deletions
diff --git a/bl31/ehf.c b/bl31/ehf.c index 745f165d4..b328380d1 100644 --- a/bl31/ehf.c +++ b/bl31/ehf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -475,9 +475,16 @@ void __init ehf_init(void) assert((exception_data.pri_bits >= 1U) || (exception_data.pri_bits < 8U)); - /* Route EL3 interrupts when in Secure and Non-secure. */ + /* Route EL3 interrupts when in Non-secure. */ set_interrupt_rm_flag(flags, NON_SECURE); + + /* + * Route EL3 interrupts when in secure, only when SPMC is not present + * in S-EL2. + */ +#if !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)) set_interrupt_rm_flag(flags, SECURE); +#endif /* !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)) */ /* Register handler for EL3 interrupts */ ret = register_interrupt_type_handler(INTR_TYPE_EL3, diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index dc1894150..72322178b 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -461,8 +461,11 @@ Common build options - ``EL3_EXCEPTION_HANDLING``: When set to ``1``, enable handling of exceptions targeted at EL3. When set ``0`` (default), no exceptions are expected or - handled at EL3, and a panic will result. This is supported only for AArch64 - builds. + handled at EL3, and a panic will result. The exception to this rule is when + ``SPMD_SPM_AT_SEL2`` is set to ``1``, in which case, only exceptions + occuring during normal world execution, are trapped to EL3. Any exception + trapped during secure world execution are trapped to the SPMC. This is + supported only for AArch64 builds. - ``EVENT_LOG_LEVEL``: Chooses the log level to use for Measured Boot when ``MEASURED_BOOT`` is enabled. For a list of valid values, see ``LOG_LEVEL``. diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h index 935bf7766..694f1f0a1 100644 --- a/include/bl31/interrupt_mgmt.h +++ b/include/bl31/interrupt_mgmt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -107,15 +107,23 @@ static inline int32_t validate_ns_interrupt_rm(uint32_t x) static inline int32_t validate_el3_interrupt_rm(uint32_t x) { -#if EL3_EXCEPTION_HANDLING +#if defined (EL3_EXCEPTION_HANDLING) && !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)) /* * With EL3 exception handling, EL3 interrupts are always routed to EL3 - * from both Secure and Non-secure, and therefore INTR_EL3_VALID_RM1 is - * the only valid routing model. + * from both Secure and Non-secure, when the SPMC does not live in S-EL2. + * Therefore INTR_EL3_VALID_RM1 is the only valid routing model. */ if (x == INTR_EL3_VALID_RM1) return 0; #else + /* + * When EL3_EXCEPTION_HANDLING is not defined both routing modes are + * valid. This is the most common case. The exception to this rule is + * when EL3_EXCEPTION_HANDLING is defined but also when the SPMC lives + * at S-EL2. In this case, Group0 Interrupts are trapped to the SPMC + * when running in S-EL0 and S-EL1. The SPMC may handle the interrupt + * itself, delegate it to an SP or forward to EL3 for handling. + */ if ((x == INTR_EL3_VALID_RM0) || (x == INTR_EL3_VALID_RM1)) return 0; #endif |
