feat(cpufeat): initialize HFG*_EL2 registers

HFG*_EL2 registers control the fine-grained traps introduced by
FEAT_FGT. These traps come enabled by default so old systems unaware
of this feature can be trapped to EL3, not being able to handle the
trap correctly. This patch disables all fine-grained traps by default
to prevent such unexpected behavior.

Change-Id: If2ae97accbeed2bea51ae03b5225ce762ecffb25
Signed-off-by: Juan Pablo Conde <juanpablo.conde@arm.com>
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index b19e8af..ce1c10c 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1376,6 +1376,13 @@
 #define HCRX_EL2_INIT_VAL	ULL(0x0)
 
 /*******************************************************************************
+ * FEAT_FGT - Definitions for Fine-Grained Trap registers
+ ******************************************************************************/
+#define HFGITR_EL2_INIT_VAL	ULL(0x180000000000000)
+#define HFGRTR_EL2_INIT_VAL	ULL(0xC4000000000000)
+#define HFGWTR_EL2_INIT_VAL	ULL(0xC4000000000000)
+
+/*******************************************************************************
  * FEAT_TCR2 - Extended Translation Control Register
  ******************************************************************************/
 #define TCR2_EL2		S3_4_C2_C0_3
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 9d717bb..70e0ec0 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -279,6 +279,20 @@
 		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HCRX_EL2,
 			HCRX_EL2_INIT_VAL);
 	}
+
+	if (is_feat_fgt_supported()) {
+		/*
+		 * Initialize HFG*_EL2 registers with a default value so legacy
+		 * systems unaware of FEAT_FGT do not get trapped due to their lack
+		 * of initialization for this feature.
+		 */
+		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGITR_EL2,
+			HFGITR_EL2_INIT_VAL);
+		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGRTR_EL2,
+			HFGRTR_EL2_INIT_VAL);
+		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGWTR_EL2,
+			HFGWTR_EL2_INIT_VAL);
+	}
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	manage_extensions_nonsecure(ctx);
@@ -829,8 +843,27 @@
 			if (is_feat_hcx_supported()) {
 				write_hcrx_el2(HCRX_EL2_INIT_VAL);
 			}
+
+			/*
+			 * Initialize Fine-grained trap registers introduced
+			 * by FEAT_FGT so all traps are initially disabled when
+			 * switching to EL2 or a lower EL, preventing undesired
+			 * behavior.
+			 */
+			if (is_feat_fgt_supported()) {
+				/*
+				 * Initialize HFG*_EL2 registers with a default
+				 * value so legacy systems unaware of FEAT_FGT
+				 * do not get trapped due to their lack of
+				 * initialization for this feature.
+				 */
+				write_hfgitr_el2(HFGITR_EL2_INIT_VAL);
+				write_hfgrtr_el2(HFGRTR_EL2_INIT_VAL);
+				write_hfgwtr_el2(HFGWTR_EL2_INIT_VAL);
+			}
 		}
 
+
 		if ((scr_el3 & SCR_HCE_BIT) != 0U) {
 			/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
 			sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),