refactor(cpufeat): enable FEAT_RAS for FEAT_STATE_CHECKED

At the moment we only support FEAT_RAS to be either unconditionally
compiled in, or to be not supported at all.

Add support for runtime detection (FEAT_RAS=2), by splitting
is_armv8_2_feat_ras_present() into an ID register reading function and
a second function to report the support status. That function considers
both build time settings and runtime information (if needed), and is
used before we access RAS related registers.

Also move the context saving code from assembly to C, and use the new
is_feat_ras_supported() function to guard its execution.

Change the FVP platform default to the now supported dynamic
option (=2), so the right decision can be made by the code at runtime.

Change-Id: I30498f72fd80b136850856244687400456a03d0e
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
This commit is contained in:
Andre Przywara 2023-01-27 12:25:49 +00:00 committed by Manish Pandey
parent 9202d51990
commit 6503ff2910
9 changed files with 44 additions and 59 deletions

View File

@ -809,8 +809,8 @@ ifeq ($(RAS_FFH_SUPPORT),1)
endif
# When FAULT_INJECTION_SUPPORT is used, require that FEAT_RAS is enabled
ifeq ($(FAULT_INJECTION_SUPPORT),1)
ifneq ($(ENABLE_FEAT_RAS),1)
$(error For FAULT_INJECTION_SUPPORT, ENABLE_FEAT_RAS must also be 1)
ifeq ($(ENABLE_FEAT_RAS),0)
$(error For FAULT_INJECTION_SUPPORT, ENABLE_FEAT_RAS must not be 0)
endif
endif

View File

@ -60,16 +60,6 @@ check_feature(int state, unsigned long field, const char *feat_name,
}
}
/*******************************************************************************
* Feature : FEAT_RAS (Reliability, Availability, and Serviceability Extension)
******************************************************************************/
static void read_feat_ras(void)
{
#if (ENABLE_FEAT_RAS == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS");
#endif
}
/************************************************
* Feature : FEAT_PAUTH (Pointer Authentication)
***********************************************/
@ -160,9 +150,9 @@ void detect_arch_features(void)
check_feature(ENABLE_FEAT_VHE, read_feat_vhe_id_field(), "VHE", 1, 1);
/* v8.2 features */
read_feat_ras();
check_feature(ENABLE_SVE_FOR_NS, read_feat_sve_id_field(),
"SVE", 1, 1);
check_feature(ENABLE_FEAT_RAS, read_feat_ras_id_field(), "RAS", 1, 2);
/* v8.3 features */
read_feat_pauth();

View File

@ -393,6 +393,9 @@
#define ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED ULL(0x1)
#define ID_AA64PFR1_EL1_RNG_TRAP_NOT_SUPPORTED ULL(0x0)
#define VDISR_EL2 S3_4_C12_C1_1
#define VSESR_EL2 S3_4_C5_C2_3
/* Memory Tagging Extension is not implemented */
#define MTE_UNIMPLEMENTED U(0)
/* FEAT_MTE: MTE instructions accessible at EL0 are implemented */

View File

@ -499,14 +499,22 @@ static inline bool is_feat_sve_supported(void)
return read_feat_sve_id_field() >= ID_AA64PFR0_SVE_SUPPORTED;
}
/*******************************************************************************
* Function to identify the presence of FEAT_RAS (Reliability,Availability,
* and Serviceability Extension)
******************************************************************************/
static inline bool is_armv8_2_feat_ras_present(void)
static unsigned int read_feat_ras_id_field(void)
{
return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_RAS_SHIFT) &
ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_RAS);
}
static inline bool is_feat_ras_supported(void)
{
if (ENABLE_FEAT_RAS == FEAT_STATE_DISABLED) {
return false;
}
if (ENABLE_FEAT_RAS == FEAT_STATE_ALWAYS) {
return true;
}
return read_feat_ras_id_field() != 0U;
}
static unsigned int read_feat_dit_id_field(void)

View File

@ -549,6 +549,10 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
/* Armv8.2 ID Registers */
DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
/* Armv8.2 RAS Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(vdisr_el2, VDISR_EL2)
DEFINE_RENAME_SYSREG_RW_FUNCS(vsesr_el2, VSESR_EL2)
/* Armv8.2 MPAM Registers */
DEFINE_RENAME_SYSREG_READ_FUNC(mpamidr_el1, MPAMIDR_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(mpam3_el3, MPAM3_EL3)

View File

@ -523,10 +523,6 @@ void el2_sysregs_context_restore_common(el2_sysregs_t *regs);
void el2_sysregs_context_save_mte(el2_sysregs_t *regs);
void el2_sysregs_context_restore_mte(el2_sysregs_t *regs);
#endif /* CTX_INCLUDE_MTE_REGS */
#if ENABLE_FEAT_RAS
void el2_sysregs_context_save_ras(el2_sysregs_t *regs);
void el2_sysregs_context_restore_ras(el2_sysregs_t *regs);
#endif /* ENABLE_FEAT_RAS */
#endif /* CTX_INCLUDE_EL2_REGS */
#if CTX_INCLUDE_FPREGS

View File

@ -17,10 +17,6 @@
.global el2_sysregs_context_save_mte
.global el2_sysregs_context_restore_mte
#endif /* CTX_INCLUDE_MTE_REGS */
#if ENABLE_FEAT_RAS
.global el2_sysregs_context_save_ras
.global el2_sysregs_context_restore_ras
#endif /* ENABLE_FEAT_RAS */
#endif /* CTX_INCLUDE_EL2_REGS */
.global el1_sysregs_context_save
@ -210,30 +206,6 @@ func el2_sysregs_context_restore_mte
endfunc el2_sysregs_context_restore_mte
#endif /* CTX_INCLUDE_MTE_REGS */
#if ENABLE_FEAT_RAS
func el2_sysregs_context_save_ras
/*
* VDISR_EL2 and VSESR_EL2 registers are saved only when
* FEAT_RAS is supported.
*/
mrs x11, vdisr_el2
mrs x12, vsesr_el2
stp x11, x12, [x0, #CTX_VDISR_EL2]
ret
endfunc el2_sysregs_context_save_ras
func el2_sysregs_context_restore_ras
/*
* VDISR_EL2 and VSESR_EL2 registers are restored only when FEAT_RAS
* is supported.
*/
ldp x11, x12, [x0, #CTX_VDISR_EL2]
msr vdisr_el2, x11
msr vsesr_el2, x12
ret
endfunc el2_sysregs_context_restore_ras
#endif /* ENABLE_FEAT_RAS */
#endif /* CTX_INCLUDE_EL2_REGS */
/* ------------------------------------------------------------------
@ -855,7 +827,12 @@ sve_not_enabled:
1:
#endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */
#if IMAGE_BL31 && ENABLE_FEAT_RAS
/*
* This is a hot path, so we don't want to do some actual FEAT_RAS runtime
* detection here. The "esb" is a cheaper variant, so using "dsb" in the
* ENABLE_FEAT_RAS==2 case is not ideal, but won't hurt.
*/
#if IMAGE_BL31 && ENABLE_FEAT_RAS == 1
/* ----------------------------------------------------------
* Issue Error Synchronization Barrier to synchronize SErrors
* before exiting EL3. We're running with EAs unmasked, so

View File

@ -1012,9 +1012,13 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2,
read_ttbr1_el2());
}
#if ENABLE_FEAT_RAS
el2_sysregs_context_save_ras(el2_sysregs_ctx);
#endif
if (is_feat_ras_supported()) {
write_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2,
read_vdisr_el2());
write_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2,
read_vsesr_el2());
}
if (is_feat_nv2_supported()) {
write_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2,
@ -1095,9 +1099,11 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
write_contextidr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2));
write_ttbr1_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2));
}
#if ENABLE_FEAT_RAS
el2_sysregs_context_restore_ras(el2_sysregs_ctx);
#endif
if (is_feat_ras_supported()) {
write_vdisr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2));
write_vsesr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2));
}
if (is_feat_nv2_supported()) {
write_vncr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2));

View File

@ -50,6 +50,7 @@ ifneq (${SPD}, tspd)
ENABLE_FEAT_RNG := 2
ENABLE_FEAT_TWED := 2
ENABLE_FEAT_GCS := 2
ENABLE_FEAT_RAS := 2
ifeq (${ARCH}, aarch64)
ifneq (${SPD}, spmd)
ifeq (${SPM_MM}, 0)