fix(amu): fault handling on EL2 context switch

The HAFGRTR_EL2 register is UNDEFINED unless the CPU supports both
FEAT_FGT and FEAT_AMUv1. FEAT_FGT is mandatory for v8.6-A and upwards,
but FEAT_AMUv1 is optional (from v8.4-A upwards), and as such any
8.6-A cores today without support for FEAT_AMUv1 will trigger an
undefined instruction exception on accessing this register.

Currently ARM_ARCH_AT_LEAST macro has been used to associate with an
architecture extension allowing to access HAFGRTR_EL2 register. This
condition should be replaced with macros specific to individual
features. This patch adds a new set of macros "ENABLE_FEAT_FGT,
ENABLE_FEAT_AMUv1, ENABLE_FEAT_ECV" under build options to provide
controlled access to the HAFGRTR_EL2 register.

Further to ensure that the the build options passed comply
with the given hardware implementation, a feature detection mechanism,
checking whether build options match with the architecture is required
at bootime. This will be implemented and pushed later in a separate
patch.

Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
Change-Id: Ie390f4babe233b8b09455290277edbddecd33ead
This commit is contained in:
Jayanth Dodderi Chidanand 2021-11-25 14:59:30 +00:00
parent 0628fe3fff
commit f74cb0be8a
4 changed files with 41 additions and 11 deletions

View File

@ -267,6 +267,16 @@ ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
ENABLE_FEAT_SB = 1
endif
# Determine and enable FEAT_FGT to access HDFGRTR_EL2 register for v8.6 and higher versions.
ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
ENABLE_FEAT_FGT = 1
endif
# Determine and enable FEAT_ECV to access CNTPOFF_EL2 register for v8.6 and higher versions.
ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
ENABLE_FEAT_ECV = 1
endif
ifneq ($(findstring armclang,$(notdir $(CC))),)
TF_CFLAGS_aarch32 = -target arm-arm-none-eabi $(march32-directive)
TF_CFLAGS_aarch64 = -target aarch64-arm-none-eabi $(march64-directive)
@ -1041,6 +1051,9 @@ $(eval $(call assert_booleans,\
ENABLE_FEAT_HCX \
ENABLE_MPMM \
ENABLE_MPMM_FCONF \
ENABLE_FEAT_FGT \
ENABLE_FEAT_AMUv1 \
ENABLE_FEAT_ECV \
)))
$(eval $(call assert_numerics,\
@ -1153,6 +1166,9 @@ $(eval $(call add_defines,\
ENABLE_FEAT_HCX \
ENABLE_MPMM \
ENABLE_MPMM_FCONF \
ENABLE_FEAT_FGT \
ENABLE_FEAT_AMUv1 \
ENABLE_FEAT_ECV \
)))
ifeq (${SANITIZE_UB},trap)

View File

@ -207,8 +207,8 @@
#define CTX_MPAMVPMV_EL2 U(0x158)
// Starting with Armv8.6
#define CTX_HAFGRTR_EL2 U(0x160)
#define CTX_HDFGRTR_EL2 U(0x168)
#define CTX_HDFGRTR_EL2 U(0x160)
#define CTX_HAFGRTR_EL2 U(0x168)
#define CTX_HDFGWTR_EL2 U(0x170)
#define CTX_HFGITR_EL2 U(0x178)
#define CTX_HFGRTR_EL2 U(0x180)

View File

@ -145,11 +145,14 @@ func el2_sysregs_context_save
stp x11, x12, [x0, #CTX_MPAMVPM7_EL2]
#endif
#if ARM_ARCH_AT_LEAST(8, 6)
mrs x13, HAFGRTR_EL2
mrs x14, HDFGRTR_EL2
stp x13, x14, [x0, #CTX_HAFGRTR_EL2]
#if ENABLE_FEAT_FGT
mrs x13, HDFGRTR_EL2
#if ENABLE_FEAT_AMUv1
mrs x14, HAFGRTR_EL2
stp x13, x14, [x0, #CTX_HDFGRTR_EL2]
#else
str x13, [x0, #CTX_HDFGRTR_EL2]
#endif
mrs x15, HDFGWTR_EL2
mrs x16, HFGITR_EL2
stp x15, x16, [x0, #CTX_HDFGWTR_EL2]
@ -157,7 +160,9 @@ func el2_sysregs_context_save
mrs x9, HFGRTR_EL2
mrs x10, HFGWTR_EL2
stp x9, x10, [x0, #CTX_HFGRTR_EL2]
#endif
#if ENABLE_FEAT_ECV
mrs x11, CNTPOFF_EL2
str x11, [x0, #CTX_CNTPOFF_EL2]
#endif
@ -319,10 +324,14 @@ func el2_sysregs_context_restore
msr MPAMVPMV_EL2, x12
#endif
#if ARM_ARCH_AT_LEAST(8, 6)
ldp x13, x14, [x0, #CTX_HAFGRTR_EL2]
msr HAFGRTR_EL2, x13
msr HDFGRTR_EL2, x14
#if ENABLE_FEAT_FGT
#if ENABLE_FEAT_AMUv1
ldp x13, x14, [x0, #CTX_HDFGRTR_EL2]
msr HAFGRTR_EL2, x14
#else
ldr x13, [x0, #CTX_HDFGRTR_EL2]
#endif
msr HDFGRTR_EL2, x13
ldp x15, x16, [x0, #CTX_HDFGWTR_EL2]
msr HDFGWTR_EL2, x15
@ -331,7 +340,9 @@ func el2_sysregs_context_restore
ldp x9, x10, [x0, #CTX_HFGRTR_EL2]
msr HFGRTR_EL2, x9
msr HFGWTR_EL2, x10
#endif
#if ENABLE_FEAT_ECV
ldr x11, [x0, #CTX_CNTPOFF_EL2]
msr CNTPOFF_EL2, x11
#endif

View File

@ -136,6 +136,9 @@ ENABLE_PAUTH := 0
# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
ENABLE_FEAT_HCX := 0
# Flag to enable access to the HAFGRTR_EL2 register
ENABLE_FEAT_AMUv1 := 0
# By default BL31 encryption disabled
ENCRYPT_BL31 := 0