diff --git a/Makefile b/Makefile index 9d1e94566..a11e55f9f 100644 --- a/Makefile +++ b/Makefile @@ -971,6 +971,7 @@ $(eval $(call assert_booleans,\ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_TRF_FOR_NS \ + ENABLE_FEAT_HCX \ ))) $(eval $(call assert_numerics,\ @@ -1074,6 +1075,7 @@ $(eval $(call add_defines,\ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_TRF_FOR_NS \ + ENABLE_FEAT_HCX \ ))) ifeq (${SANITIZE_UB},trap) diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 44bf32cb7..f272af502 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -85,6 +85,15 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, /* Perform late platform-specific setup */ bl31_plat_arch_setup(); +#if ENABLE_FEAT_HCX + /* + * Assert that FEAT_HCX is supported on this system, without this check + * an exception would occur during context save/restore if enabled but + * not supported. + */ + assert(is_feat_hcx_present()); +#endif /* ENABLE_FEAT_HCX */ + #if CTX_INCLUDE_PAUTH_REGS /* * Assert that the ARMv8.3-PAuth registers are present or an access diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 115b2b228..0ec10f5db 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -235,6 +235,10 @@ Common build options builds, but this behaviour can be overridden in each platform's Makefile or in the build command line. +- ``ENABLE_FEAT_HCX``: This option sets the bit SCR_EL3.HXEn in EL3 to allow + access to HCRX_EL2 (extended hypervisor control register) from EL2 as well as + adding HCRX_EL2 to the EL2 context save/restore operations. + - ``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. diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 9ea111452..d260ecf45 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -281,6 +281,11 @@ #define ID_AA64MMFR1_EL1_VHE_SHIFT U(8) #define ID_AA64MMFR1_EL1_VHE_MASK ULL(0xf) +#define ID_AA64MMFR1_EL1_HCX_SHIFT U(40) +#define ID_AA64MMFR1_EL1_HCX_MASK ULL(0xf) +#define ID_AA64MMFR1_EL1_HCX_SUPPORTED ULL(0x1) +#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED ULL(0x0) + /* ID_AA64MMFR2_EL1 definitions */ #define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 @@ -429,6 +434,7 @@ #define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5)) #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) +#define SCR_HXEn_BIT (UL(1) << 38) #define SCR_AMVOFFEN_BIT (UL(1) << 35) #define SCR_TWEDEn_BIT (UL(1) << 29) #define SCR_ECVEN_BIT (UL(1) << 28) @@ -1143,6 +1149,16 @@ #define RGSR_EL1 S3_0_C1_C0_5 #define GCR_EL1 S3_0_C1_C0_6 +/******************************************************************************* + * FEAT_HCX - Extended Hypervisor Configuration Register + ******************************************************************************/ +#define HCRX_EL2 S3_4_C1_C2_2 +#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) + /******************************************************************************* * Definitions for DynamicIQ Shared Unit registers ******************************************************************************/ diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index dc0b7f306..3ff67e571 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -117,4 +117,10 @@ static inline unsigned int get_mpam_version(void) ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK)); } +static inline bool is_feat_hcx_present(void) +{ + return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) & + ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED); +} + #endif /* ARCH_FEATURES_H */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index a41b3258e..549ae6600 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -532,6 +532,9 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1) DEFINE_SYSREG_READ_FUNC(rndr) DEFINE_SYSREG_READ_FUNC(rndrrs) +/* FEAT_HCX Register */ +DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2) + /* DynamIQ Shared Unit power management */ DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index d449a65ed..c3f41179f 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -228,6 +228,10 @@ // Starting with Armv8.5 #define CTX_SCXTNUM_EL2 U(0x1e0) + +// Register for FEAT_HCX +#define CTX_HCRX_EL2 U(0x1e8) + /* Align to the next 16 byte boundary */ #define CTX_EL2_SYSREGS_END U(0x1f0) diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 40e7ddfa1..e270ad0a9 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -193,6 +193,11 @@ func el2_sysregs_context_save str x13, [x0, #CTX_SCXTNUM_EL2] #endif +#if ENABLE_FEAT_HCX + mrs x14, hcrx_el2 + str x14, [x0, #CTX_HCRX_EL2] +#endif + ret endfunc el2_sysregs_context_save @@ -362,6 +367,11 @@ func el2_sysregs_context_restore msr scxtnum_el2, x13 #endif +#if ENABLE_FEAT_HCX + ldr x14, [x0, #CTX_HCRX_EL2] + msr hcrx_el2, x14 +#endif + ret endfunc el2_sysregs_context_restore diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 52102ddd4..08022d4ad 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -112,6 +112,14 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) if (EP_GET_ST(ep->h.attr) != 0U) scr_el3 |= SCR_ST_BIT; + /* + * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting + * SCR_EL3.HXEn. + */ +#if ENABLE_FEAT_HCX + scr_el3 |= SCR_HXEn_BIT; +#endif + #if RAS_TRAP_LOWER_EL_ERR_ACCESS /* * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index c1886218d..18092e7fa 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -121,6 +121,9 @@ ENABLE_BTI := 0 # Use BRANCH_PROTECTION to enable PAUTH. ENABLE_PAUTH := 0 +# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn. +ENABLE_FEAT_HCX := 0 + # By default BL31 encryption disabled ENCRYPT_BL31 := 0