* FEAT_HCX - Extended Hypervisor Configuration Register
******************************************************************************/
#define HCRX_EL2 S3_4_C1_C2_2
+#define HCRX_EL2_MSCEn_BIT (UL(1) << 11)
+#define HCRX_EL2_MCE2_BIT (UL(1) << 10)
+#define HCRX_EL2_CMOW_BIT (UL(1) << 9)
+#define HCRX_EL2_VFNMI_BIT (UL(1) << 8)
+#define HCRX_EL2_VINMI_BIT (UL(1) << 7)
+#define HCRX_EL2_TALLINT_BIT (UL(1) << 6)
+#define HCRX_EL2_SMPME_BIT (UL(1) << 5)
#define HCRX_EL2_FGTnXS_BIT (UL(1) << 4)
#define HCRX_EL2_FnXS_BIT (UL(1) << 3)
#define HCRX_EL2_EnASR_BIT (UL(1) << 2)
#define HCRX_EL2_EnALS_BIT (UL(1) << 1)
#define HCRX_EL2_EnAS0_BIT (UL(1) << 0)
+#define HCRX_EL2_INIT_VAL ULL(0x0)
/*******************************************************************************
* FEAT_TCR2 - Extended Translation Control Register
u_register_t mdcr_el2 = ((read_pmcr_el0() >> PMCR_EL0_N_SHIFT) &
PMCR_EL0_N_MASK);
write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2, mdcr_el2);
+
+ if (is_feat_hcx_supported()) {
+ /*
+ * Initialize register HCRX_EL2 with its init value.
+ * As the value of HCRX_EL2 is UNKNOWN on reset, there is a
+ * chance that this can lead to unexpected behavior in lower
+ * ELs that have not been updated since the introduction of
+ * this feature if not properly initialized, especially when
+ * it comes to those bits that enable/disable traps.
+ */
+ write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HCRX_EL2,
+ HCRX_EL2_INIT_VAL);
+ }
#endif /* CTX_INCLUDE_EL2_REGS */
}
assert(ctx != NULL);
if (security_state == NON_SECURE) {
+ uint64_t el2_implemented = el_implemented(2);
+
scr_el3 = read_ctx_reg(get_el3state_ctx(ctx),
CTX_SCR_EL3);
+
+ if (((scr_el3 & SCR_HCE_BIT) != 0U)
+ || (el2_implemented != EL_IMPL_NONE)) {
+ /*
+ * If context is not being used for EL2, initialize
+ * HCRX_EL2 with its init value here.
+ */
+ if (is_feat_hcx_supported()) {
+ write_hcrx_el2(HCRX_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),
sctlr_elx |= SCTLR_IESB_BIT;
#endif
write_sctlr_el2(sctlr_elx);
- } else if (el_implemented(2) != EL_IMPL_NONE) {
+ } else if (el2_implemented != EL_IMPL_NONE) {
el2_unused = true;
/*