feat(pie/por): support permission indirection and overlay
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
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 3ea08a6..840b117 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -234,6 +234,88 @@
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
******************************************************************************/