]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(pie/por): support permission indirection and overlay
authorMark Brown <broonie@kernel.org>
Tue, 14 Mar 2023 20:48:43 +0000 (20:48 +0000)
committerMark Brown <broonie@kernel.org>
Wed, 12 Apr 2023 14:03:22 +0000 (15:03 +0100)
Arm v8.9 introduces a series of features providing a new way to set memory
permissions. Instead of directly encoding the permissions in the page
tables the PTEs contain indexes into an array of permissions stored in
system registers, allowing greater flexibility and density of encoding.

Enable access to these features for EL2 and below, context switching the
newly added EL2 registers as appropriate. Since all of FEAT_S[12]P[IO]E
are separately discoverable we have separate build time options for
enabling them, but note that there is overlap in the registers that they
implement and the enable bit required for lower EL access.

Change the FVP platform to default to handling them as dynamic options so
the right decision can be made by the code at runtime.

Signed-off-by: Mark Brown <broonie@kernel.org>
Change-Id: Icf89e444e39e1af768739668b505661df18fb234

Makefile
common/feat_detect.c
docs/getting_started/build-options.rst
include/arch/aarch64/arch.h
include/arch/aarch64/arch_features.h
include/arch/aarch64/arch_helpers.h
include/lib/el3_runtime/aarch64/context.h
lib/el3_runtime/aarch64/context_mgmt.c
make_helpers/defaults.mk
plat/arm/board/fvp/platform.mk

index 4b6086333e445f073e3e3c0bde9f49c1028ef947..98e448faba8f954812b12641153a403de13be5a5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1185,6 +1185,10 @@ $(eval $(call assert_numerics,\
         ENABLE_FEAT_RNG_TRAP \
         ENABLE_FEAT_SEL2 \
         ENABLE_FEAT_TCR2 \
+        ENABLE_FEAT_S2PIE \
+        ENABLE_FEAT_S1PIE \
+        ENABLE_FEAT_S2POE \
+        ENABLE_FEAT_S1POE \
         ENABLE_FEAT_VHE \
         ENABLE_MPAM_FOR_LOWER_ELS \
         ENABLE_RME \
@@ -1321,6 +1325,10 @@ $(eval $(call add_defines,\
         ENABLE_FEAT_CSV2_2 \
         ENABLE_FEAT_PAN \
         ENABLE_FEAT_TCR2 \
+        ENABLE_FEAT_S2PIE \
+        ENABLE_FEAT_S1PIE \
+        ENABLE_FEAT_S2POE \
+        ENABLE_FEAT_S1POE \
         FEATURE_DETECTION \
         TWED_DELAY \
         ENABLE_FEAT_TWED \
index 9394304bf75b6339534002a3c21c99c9fdbb8931..1582b9dcbcd7cd58ab23177d2ce4253acf9d2eb9 100644 (file)
@@ -210,6 +210,14 @@ void detect_arch_features(void)
        /* v8.9 features */
        check_feature(ENABLE_FEAT_TCR2, read_feat_tcrx_id_field(),
                      "TCR2", 1, 1);
+       check_feature(ENABLE_FEAT_S2PIE, read_feat_s2pie_id_field(),
+                     "S2PIE", 1, 1);
+       check_feature(ENABLE_FEAT_S1PIE, read_feat_s1pie_id_field(),
+                     "S1PIE", 1, 1);
+       check_feature(ENABLE_FEAT_S2POE, read_feat_s2poe_id_field(),
+                     "S2POE", 1, 1);
+       check_feature(ENABLE_FEAT_S1POE, read_feat_s1poe_id_field(),
+                     "S1POE", 1, 1);
 
        /* v9.0 features */
        check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
index e078e47c675fc8ab4ea0a7e8e1d85749c7dd0ee7..03be7862e32daf7286e4ccc96f97a86a86374616 100644 (file)
@@ -354,6 +354,26 @@ Common build options
    flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_S2PIE``: Numeric value to enable support for FEAT_S2PIE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S1PIE``: Numeric value to enable support for FEAT_S1PIE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S2POE``: Numeric value to enable support for FEAT_S2POE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_S1POE``: Numeric value to enable support for FEAT_S1POE
+   at EL2 and below, and context switch relevant registers.  This flag
+   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
index dee7fdcff2b0df6ef0ba5e7a3a36bddc3449a3ca..9b55658ffc9cec6f0a785350a2f886787a6c6d88 100644 (file)
 /* ID_AA64MMFR3_EL1 definitions */
 #define ID_AA64MMFR3_EL1                       S3_0_C0_C7_3
 
+#define ID_AA64MMFR3_EL1_S2POE_SHIFT           U(20)
+#define ID_AA64MMFR3_EL1_S2POE_MASK            ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S1POE_SHIFT           U(16)
+#define ID_AA64MMFR3_EL1_S1POE_MASK            ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S2PIE_SHIFT           U(12)
+#define ID_AA64MMFR3_EL1_S2PIE_MASK            ULL(0xf)
+
+#define ID_AA64MMFR3_EL1_S1PIE_SHIFT           U(8)
+#define ID_AA64MMFR3_EL1_S1PIE_MASK            ULL(0xf)
+
 #define ID_AA64MMFR3_EL1_TCRX_SHIFT            U(0)
 #define ID_AA64MMFR3_EL1_TCRX_MASK             ULL(0xf)
 
 #define SCR_GPF_BIT            (UL(1) << 48)
 #define SCR_TWEDEL_SHIFT       U(30)
 #define SCR_TWEDEL_MASK                ULL(0xf)
+#define SCR_PIEN_BIT           (UL(1) << 45)
 #define SCR_TCR2EN_BIT         (UL(1) << 43)
 #define SCR_TRNDR_BIT          (UL(1) << 40)
 #define SCR_HXEn_BIT           (UL(1) << 38)
  ******************************************************************************/
 #define TCR2_EL2               S3_4_C2_C0_3
 
+/*******************************************************************************
+ * Permission indirection and overlay
+ ******************************************************************************/
+
+#define PIRE0_EL2              S3_4_C10_C2_2
+#define PIR_EL2                        S3_4_C10_C2_3
+#define POR_EL2                        S3_4_C10_C2_4
+#define S2PIR_EL2              S3_4_C10_C2_5
+
 /*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
index 3ea08a66570677432d9b003e6cfbb98b821b8269..840b117a0955da6c02e6035e8f8c4d81c6180426 100644 (file)
@@ -234,6 +234,88 @@ static inline bool is_feat_tcr2_supported(void)
        return read_feat_tcrx_id_field() != 0U;
 }
 
+static unsigned int read_feat_s2poe_id_field(void)
+{
+       return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE);
+}
+
+static inline bool is_feat_s2poe_supported(void)
+{
+       if (ENABLE_FEAT_S2POE == FEAT_STATE_DISABLED) {
+               return false;
+       }
+
+       if (ENABLE_FEAT_S2POE == FEAT_STATE_ALWAYS) {
+               return true;
+       }
+
+       return read_feat_s2poe_id_field() != 0U;
+}
+
+static unsigned int read_feat_s1poe_id_field(void)
+{
+       return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE);
+}
+
+static inline bool is_feat_s1poe_supported(void)
+{
+       if (ENABLE_FEAT_S1POE == FEAT_STATE_DISABLED) {
+               return false;
+       }
+
+       if (ENABLE_FEAT_S1POE == FEAT_STATE_ALWAYS) {
+               return true;
+       }
+
+       return read_feat_s1poe_id_field() != 0U;
+}
+
+static inline bool is_feat_sxpoe_supported(void)
+{
+       return is_feat_s1poe_supported() || is_feat_s2poe_supported();
+}
+
+static unsigned int read_feat_s2pie_id_field(void)
+{
+       return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE);
+}
+
+static inline bool is_feat_s2pie_supported(void)
+{
+       if (ENABLE_FEAT_S2PIE == FEAT_STATE_DISABLED) {
+               return false;
+       }
+
+       if (ENABLE_FEAT_S2PIE == FEAT_STATE_ALWAYS) {
+               return true;
+       }
+
+       return read_feat_s2pie_id_field() != 0U;
+}
+
+static unsigned int read_feat_s1pie_id_field(void)
+{
+       return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE);
+}
+
+static inline bool is_feat_s1pie_supported(void)
+{
+       if (ENABLE_FEAT_S1PIE == FEAT_STATE_DISABLED) {
+               return false;
+       }
+
+       if (ENABLE_FEAT_S1PIE == FEAT_STATE_ALWAYS) {
+               return true;
+       }
+
+       return read_feat_s1pie_id_field() != 0U;
+}
+
+static inline bool is_feat_sxpie_supported(void)
+{
+       return is_feat_s1pie_supported() || is_feat_s2pie_supported();
+}
+
 /*******************************************************************************
  * Functions to identify the presence of the Activity Monitors Extension
  ******************************************************************************/
index 04b64be5cdc639a4bda180d4d82a35923a7423d8..f877f5bc8c90b4f2e532f6343d7eee2bfa9e41a0 100644 (file)
@@ -605,6 +605,14 @@ DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr3_el1, ID_AA64MMFR3_EL1)
 /* FEAT_TCR2 Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
 
+/* FEAT_SxPIE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el2, PIRE0_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el2, PIR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(s2pir_el2, S2PIR_EL2)
+
+/* FEAT_SxPOE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2)
+
 /* DynamIQ Shared Unit power management */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
 
index e5e7e7422915f32928bb1e4ddad7b9766d1e4cf5..a8e6d8ad22d623fda6ce5af2f9a729d0a4eb3d1e 100644 (file)
 
 // Starting with Armv8.9
 #define CTX_TCR2_EL2            U(0x1d8)
+#define CTX_POR_EL2             U(0x1e0)
+#define CTX_PIRE0_EL2           U(0x1e8)
+#define CTX_PIR_EL2             U(0x1f0)
+#define CTX_S2PIR_EL2          U(0x1f8)
 
 /* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END    U(0x1e0)
+#define CTX_EL2_SYSREGS_END    U(0x200)
 
 #endif /* CTX_INCLUDE_EL2_REGS */
 
index 42166eb999c8fcd79cf837c31c475b6a8389ab5c..94d5ee1d2d5eab1489da876721ed9d70f3656124 100644 (file)
@@ -354,6 +354,14 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
                scr_el3 |= SCR_TCR2EN_BIT;
        }
 
+       /*
+        * SCR_EL3.PIEN: Enable permission indirection and overlay
+        * registers for AArch64 if present.
+        */
+       if (is_feat_sxpie_supported() || is_feat_sxpoe_supported()) {
+               scr_el3 |= SCR_PIEN_BIT;
+       }
+
        /*
         * CPTR_EL3 was initialized out of reset, copy that value to the
         * context register.
@@ -994,6 +1002,16 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
                if (is_feat_tcr2_supported()) {
                        write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
                }
+               if (is_feat_sxpie_supported()) {
+                       write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
+                       write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
+               }
+               if (is_feat_s2pie_supported()) {
+                       write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
+               }
+               if (is_feat_sxpoe_supported()) {
+                       write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
+               }
        }
 }
 
@@ -1061,6 +1079,16 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
                if (is_feat_tcr2_supported()) {
                        write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
                }
+               if (is_feat_sxpie_supported()) {
+                       write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
+                       write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
+               }
+               if (is_feat_s2pie_supported()) {
+                       write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
+               }
+               if (is_feat_sxpoe_supported()) {
+                       write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
+               }
        }
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
index af980f51801fd6485a5d3993eda9c96280fc2985..808a058b2e646fad0c1b20efb4a4e8dd7bb794aa 100644 (file)
@@ -176,6 +176,18 @@ ENABLE_FEAT_TWED           := 0
 # Flag to enable access to TCR2 (FEAT_TCR2)
 ENABLE_FEAT_TCR2               := 0
 
+# Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE)
+ENABLE_FEAT_S2PIE              := 0
+
+# Flag to enable access to Stage 1 Permission Indirection (FEAT_S1PIE)
+ENABLE_FEAT_S1PIE              := 0
+
+# Flag to enable access to Stage 2 Permission Overlay (FEAT_S2POE)
+ENABLE_FEAT_S2POE              := 0
+
+# Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE)
+ENABLE_FEAT_S1POE              := 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31                   := 0
 
index ab6e0bf5e45e4df5e287434dcd22f8005c2909b0..3fb323bd40254bb9be54c842bec52af4e69fe2ba 100644 (file)
@@ -77,6 +77,10 @@ ENABLE_TRF_FOR_NS            := 2
 ENABLE_FEAT_ECV                        := 2
 ENABLE_FEAT_FGT                        := 2
 ENABLE_FEAT_TCR2               := 2
+ENABLE_FEAT_S2PIE              := 2
+ENABLE_FEAT_S1PIE              := 2
+ENABLE_FEAT_S2POE              := 2
+ENABLE_FEAT_S1POE              := 2
 endif
 
 # The FVP platform depends on this macro to build with correct GIC driver.