From ac17e52c728e7786e80f41e41673420433637fa6 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 22 Feb 2023 17:55:59 +0000 Subject: [PATCH] refactor(cpufeat): enable FEAT_RNG for FEAT_STATE_CHECKED At the moment we only support for FEAT_RNG to be either unconditionally compiled in, or to be not supported at all. Add support for runtime detection (FEAT_RNG=2), by splitting is_armv8_5_rng_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 the RNDRRS system register. Change the QEMU platform default to the now supported dynamic option (=2), so the right decision can be made by the code at runtime. Change-Id: I1a4a538d5ad395fead7324f297d0056bda4f84cb Signed-off-by: Andre Przywara --- common/feat_detect.c | 12 +----------- include/arch/aarch64/arch_features.h | 18 +++++++++++++++--- plat/qemu/common/qemu_stack_protector.c | 4 +--- plat/qemu/qemu/platform.mk | 3 +++ 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/common/feat_detect.c b/common/feat_detect.c index 0f66157b3..9218c07e1 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -102,16 +102,6 @@ static void read_feat_mte(void) #endif } -/*********************************************** - * Feature : FEAT_RNG (Random Number Generator) - **********************************************/ -static void read_feat_rng(void) -{ -#if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS) - feat_detect_panic(is_armv8_5_rng_present(), "RNG"); -#endif -} - /**************************************************** * Feature : FEAT_BTI (Branch Target Identification) ***************************************************/ @@ -210,7 +200,7 @@ void detect_arch_features(void) /* v8.5 features */ read_feat_mte(); - read_feat_rng(); + check_feature(ENABLE_FEAT_RNG, read_feat_rng_id_field(), "RNG", 1, 1); read_feat_bti(); read_feat_rng_trap(); diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 03b005d1e..d3c626367 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -198,10 +198,22 @@ static inline bool is_feat_ecv_v2_supported(void) return read_feat_ecv_id_field() >= ID_AA64MMFR0_EL1_ECV_SELF_SYNCH; } -static inline bool is_armv8_5_rng_present(void) +static unsigned int read_feat_rng_id_field(void) { - return ((read_id_aa64isar0_el1() >> ID_AA64ISAR0_RNDR_SHIFT) & - ID_AA64ISAR0_RNDR_MASK); + return ISOLATE_FIELD(read_id_aa64isar0_el1(), ID_AA64ISAR0_RNDR); +} + +static inline bool is_feat_rng_supported(void) +{ + if (ENABLE_FEAT_RNG == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_rng_id_field() != 0U; } static unsigned int read_feat_tcrx_id_field(void) diff --git a/plat/qemu/common/qemu_stack_protector.c b/plat/qemu/common/qemu_stack_protector.c index 15ce3d6d2..d0b4a0f1d 100644 --- a/plat/qemu/common/qemu_stack_protector.c +++ b/plat/qemu/common/qemu_stack_protector.c @@ -14,12 +14,10 @@ u_register_t plat_get_stack_protector_canary(void) { -#if ENABLE_FEAT_RNG /* Use the RNDR instruction if the CPU supports it */ - if (is_armv8_5_rng_present()) { + if (is_feat_rng_supported()) { return read_rndr(); } -#endif /* * Ideally, a random number should be returned above. If a random diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 32d2b8859..f82232871 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -290,6 +290,9 @@ $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33)) ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE $(eval $(call add_define,ARM_PRELOADED_DTB_BASE)) +# QEMU will use the RNDR instruction for the stack protector canary. +ENABLE_FEAT_RNG := 2 + # Later QEMU versions support SME and SVE. ifneq (${ARCH},aarch32) ENABLE_SVE_FOR_NS := 1