Browse Source

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 <andre.przywara@arm.com>
Change-Id: Ic576922ff2c4f8d3c1b87b5843b3626729fe4514
pull/1993/head
Andre Przywara 2 years ago
parent
commit
b45dd74e3a
  1. 38
      common/feat_detect.c

38
common/feat_detect.c

@ -8,6 +8,8 @@
#include <common/debug.h>
#include <common/feat_detect.h>
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();
}
}

Loading…
Cancel
Save