aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaghu Krishnamurthy <raghu.ncstate@gmail.com>2022-07-25 14:44:33 -0700
committerRaghu Krishnamurthy <raghu.ncstate@gmail.com>2022-08-30 08:29:25 -0700
commit7c2fe62f1347bb94d82e9fdd3bc5eaebedaf0bc7 (patch)
tree64db9c876c12a98c59bc100c0ee68d6d09919d93
parent6a5022278b0bda10708534ef5cc6c1b5256081ee (diff)
downloadtrusted-firmware-a-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.c11
-rw-r--r--docs/getting_started/build-options.rst7
-rw-r--r--include/bl31/interrupt_mgmt.h16
3 files changed, 26 insertions, 8 deletions
diff --git a/bl31/ehf.c b/bl31/ehf.c
index 745f165d47..b328380d1c 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 dc1894150f..72322178b1 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 935bf77665..694f1f0a1d 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