Merge "Aarch64: Add support for FEAT_MTE3" into integration
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 33e1134..2518e5c 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -266,9 +266,17 @@
 #define ID_AA64PFR1_EL1_MTE_SHIFT	U(8)
 #define ID_AA64PFR1_EL1_MTE_MASK	ULL(0xf)
 
-#define MTE_UNIMPLEMENTED	ULL(0)
-#define MTE_IMPLEMENTED_EL0	ULL(1)	/* MTE is only implemented at EL0 */
-#define MTE_IMPLEMENTED_ELX	ULL(2)	/* MTE is implemented at all ELs */
+/* Memory Tagging Extension is not implemented */
+#define MTE_UNIMPLEMENTED	U(0)
+/* FEAT_MTE: MTE instructions accessible at EL0 are implemented */
+#define MTE_IMPLEMENTED_EL0	U(1)
+/* FEAT_MTE2: Full MTE is implemented */
+#define MTE_IMPLEMENTED_ELX	U(2)
+/*
+ * FEAT_MTE3: MTE is implemented with support for
+ * asymmetric Tag Check Fault handling
+ */
+#define MTE_IMPLEMENTED_ASY	U(3)
 
 #define ID_AA64PFR1_MPAM_FRAC_SHIFT	ULL(16)
 #define ID_AA64PFR1_MPAM_FRAC_MASK	ULL(0xf)
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index b460731..72d463b 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -144,30 +144,33 @@
 		scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
 #endif /* !CTX_INCLUDE_PAUTH_REGS */
 
+#if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
+	/* Get Memory Tagging Extension support level */
+	unsigned int mte = get_armv8_5_mte_support();
+#endif
 	/*
 	 * Enable MTE support. Support is enabled unilaterally for the normal
 	 * world, and only for the secure world when CTX_INCLUDE_MTE_REGS is
 	 * set.
 	 */
 #if CTX_INCLUDE_MTE_REGS
-	assert(get_armv8_5_mte_support() == MTE_IMPLEMENTED_ELX);
+	assert((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY));
 	scr_el3 |= SCR_ATA_BIT;
 #else
-	unsigned int mte = get_armv8_5_mte_support();
-	if (mte == MTE_IMPLEMENTED_EL0) {
-		/*
-		 * Can enable MTE across both worlds as no MTE registers are
-		 * used
-		 */
-		scr_el3 |= SCR_ATA_BIT;
-	} else if (mte == MTE_IMPLEMENTED_ELX && security_state == NON_SECURE) {
-		/*
-		 * Can only enable MTE in Non-Secure world without register
-		 * saving
-		 */
+	/*
+	 * When MTE is only implemented at EL0, it can be enabled
+	 * across both worlds as no MTE registers are used.
+	 */
+	if ((mte == MTE_IMPLEMENTED_EL0) ||
+	/*
+	 * When MTE is implemented at all ELs, it can be only enabled
+	 * in Non-Secure world without register saving.
+	 */
+	  (((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY)) &&
+	    (security_state == NON_SECURE))) {
 		scr_el3 |= SCR_ATA_BIT;
 	}
-#endif
+#endif	/* CTX_INCLUDE_MTE_REGS */
 
 #ifdef IMAGE_BL31
 	/*