]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
fix(bl31): allow use of EHF with S-EL2 SPMC
authorRaghu Krishnamurthy <raghu.ncstate@gmail.com>
Mon, 25 Jul 2022 21:44:33 +0000 (14:44 -0700)
committerRaghu Krishnamurthy <raghu.ncstate@gmail.com>
Tue, 30 Aug 2022 15:29:25 +0000 (08:29 -0700)
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

bl31/ehf.c
docs/getting_started/build-options.rst
include/bl31/interrupt_mgmt.h

index 745f165d4727dc48791fec90527ca70bc6bd2f0e..b328380d1c7902290501766282f2546232cf828f 100644 (file)
@@ -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,
index dc1894150f1a83066a6d496096e09b240a2dacf4..72322178b16fa42a1a1e6b24592574bcd6e6d68c 100644 (file)
@@ -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``.
index 935bf776655e56b509cb2a5119f52d051f9ef810..694f1f0a1da3eccc45893db7e7936ecb16feb155 100644 (file)
@@ -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