feat(hcx): add build option to enable FEAT_HCX

FEAT_HCX adds the extended hypervisor configuration register (HCRX_EL2)
and access to this register must be explicitly enabled through the
SCR_EL3.HXEn bit.  This patch adds a new build flag ENABLE_FEAT_HCX to
allow the register to be accessed from EL2.

Signed-off-by: John Powell <john.powell@arm.com>
Change-Id: Ibb36ad90622f1dc857adab4b0d4d7a89456a522b
This commit is contained in:
johpow01 2021-08-04 19:38:18 -05:00 committed by John
parent c7c22ab662
commit cb4ec47b5c
10 changed files with 65 additions and 0 deletions

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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
******************************************************************************/

View File

@ -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 */

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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