From b45dd74e3a1b125eb231a873c663e92da797b7fa Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 14 Nov 2022 15:42:44 +0000 Subject: refactor(cpufeat): check FEAT_FGT in a new way To implement proper runtime checking of features, and to be able to extend feat_detect.c to catch other cases, rework the FEAT_FGT check to directly call a generic function instead of providing a trivial specific one. The #ifdef is moved into the function, and rewritten as a proper C if statement. We need to force the compiler to inline that function, otherwise the optimisation won't work, once we exceed a certain number of callers. This starts with FEAT_FGT, but all the other features will be moved over eventually, in separate patches. For all features checked this way, we delay the panic() until after every feature has been checked, to list them all during one run. Signed-off-by: Andre Przywara Change-Id: Ic576922ff2c4f8d3c1b87b5843b3626729fe4514 --- common/feat_detect.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'common') diff --git a/common/feat_detect.c b/common/feat_detect.c index 05b2e4236..21dd35d4e 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -8,6 +8,8 @@ #include #include +static bool tainted; + /******************************************************************************* * This section lists the wrapper modules for each feature to evaluate the * feature states (FEAT_STATE_ALWAYS and FEAT_STATE_CHECK) and perform @@ -31,6 +33,24 @@ static inline void feature_panic(char *feat_name) panic(); } +/******************************************************************************* + * Function : check_feature + * Check for a valid combination of build time flags (ENABLE_FEAT_xxx) and + * feature availability on the hardware. + * Panics if a feature is forcefully enabled, but not available on the PE. + * + * We force inlining here to let the compiler optimise away the whole check + * if the feature is disabled at build time (FEAT_STATE_DISABLED). + ******************************************************************************/ +static inline void __attribute((__always_inline__)) +check_feature(int state, unsigned long field, const char *feat_name) +{ + if (state == FEAT_STATE_ALWAYS && field == 0U) { + ERROR("FEAT_%s not supported by the PE\n", feat_name); + tainted = true; + } +} + /****************************************** * Feature : FEAT_SB (Speculation Barrier) *****************************************/ @@ -185,16 +205,6 @@ static void read_feat_bti(void) #endif } -/**************************************** - * Feature : FEAT_FGT (Fine Grain Traps) - ***************************************/ -static void read_feat_fgt(void) -{ -#if (ENABLE_FEAT_FGT == FEAT_STATE_ALWAYS) - feat_detect_panic(is_armv8_6_fgt_present(), "FGT"); -#endif -} - /*********************************************** * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1) **********************************************/ @@ -304,6 +314,8 @@ static void read_feat_rng_trap(void) **********************************************************************************/ void detect_arch_features(void) { + tainted = false; + /* v8.0 features */ read_feat_sb(); read_feat_csv2_2(); @@ -334,7 +346,7 @@ void detect_arch_features(void) /* v8.6 features */ read_feat_amuv1p1(); - read_feat_fgt(); + check_feature(ENABLE_FEAT_FGT, is_armv8_6_fgt_present(), "FGT"); read_feat_ecv(); read_feat_twed(); @@ -347,4 +359,8 @@ void detect_arch_features(void) /* v9.2 features */ read_feat_rme(); + + if (tainted) { + panic(); + } } -- cgit v1.2.1