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