From 9202d51990c192e8bc041e6f53d5ce63ee908665 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Mon, 13 Feb 2023 12:39:17 +0000 Subject: [PATCH 1/2] refactor(ras): replace RAS_EXTENSION with FEAT_RAS The current usage of RAS_EXTENSION in TF-A codebase is to cater for two things in TF-A : 1. Pull in necessary framework and platform hooks for Firmware first handling(FFH) of RAS errors. 2. Manage the FEAT_RAS extension when switching the worlds. FFH means that all the EAs from NS are trapped in EL3 first and signaled to NS world later after the first handling is done in firmware. There is an alternate way of handling RAS errors viz Kernel First handling(KFH). Tying FEAT_RAS to RAS_EXTENSION build flag was not correct as the feature is needed for proper handling KFH in as well. This patch breaks down the RAS_EXTENSION flag into a flag to denote the CPU architecture `ENABLE_FEAT_RAS` which is used in context management during world switch and another flag `RAS_FFH_SUPPORT` to pull in required framework and platform hooks for FFH. Proper support for KFH will be added in future patches. BREAKING CHANGE: The previous RAS_EXTENSION is now deprecated. The equivalent functionality can be achieved by the following 2 options: - ENABLE_FEAT_RAS - RAS_FFH_SUPPORT Signed-off-by: Manish Pandey Change-Id: I1abb9ab6622b8f1b15712b12f17612804d48a6ec --- Makefile | 24 ++-- bl31/aarch64/ea_delegate.S | 4 +- bl31/aarch64/runtime_exceptions.S | 14 +-- common/feat_detect.c | 2 +- docs/components/ras.rst | 105 ++++++++++++------ docs/getting_started/build-options.rst | 9 +- docs/porting-guide.rst | 4 +- include/lib/el3_runtime/aarch64/context.h | 4 +- lib/el3_runtime/aarch64/context.S | 12 +- lib/el3_runtime/aarch64/context_mgmt.c | 4 +- make_helpers/arch_features.mk | 5 + make_helpers/defaults.mk | 5 +- plat/arm/board/fvp/platform.mk | 2 +- plat/arm/board/tc/platform.mk | 4 +- plat/arm/common/arm_bl31_setup.c | 2 +- plat/arm/common/arm_common.mk | 2 +- .../css/sgi/include/sgi_base_platform_def.h | 4 +- plat/arm/css/sgi/sgi-common.mk | 6 +- plat/arm/css/sgi/sgi_bl31_setup.c | 2 +- plat/arm/css/sgi/sgi_plat.c | 2 +- plat/common/aarch64/plat_common.c | 4 +- plat/common/aarch64/plat_ehf.c | 2 +- plat/nvidia/tegra/include/tegra_private.h | 2 +- plat/nvidia/tegra/soc/t194/plat_ras.c | 2 +- plat/nvidia/tegra/soc/t194/plat_setup.c | 2 +- plat/nvidia/tegra/soc/t194/plat_sip_calls.c | 2 +- plat/nvidia/tegra/soc/t194/platform_t194.mk | 5 +- 27 files changed, 145 insertions(+), 90 deletions(-) diff --git a/Makefile b/Makefile index cf71c0903..d5e64ea45 100644 --- a/Makefile +++ b/Makefile @@ -794,17 +794,23 @@ ifeq ($(RESET_TO_BL2)-$(BL2_IN_XIP_MEM),0-1) $(error "BL2_IN_XIP_MEM is only supported when RESET_TO_BL2 is enabled") endif -# For RAS_EXTENSION, require that EAs are handled in EL3 first +# RAS_EXTENSION is deprecated, provide alternate build options ifeq ($(RAS_EXTENSION),1) + $(error "RAS_EXTENSION is now deprecated, please use ENABLE_FEAT_RAS and RAS_FFH_SUPPORT instead") +endif +# RAS firmware first handling requires that EAs are handled in EL3 first +ifeq ($(RAS_FFH_SUPPORT),1) + ifneq ($(ENABLE_FEAT_RAS),1) + $(error For RAS_FFH_SUPPORT, ENABLE_FEAT_RAS must also be 1) + endif ifneq ($(HANDLE_EA_EL3_FIRST_NS),1) - $(error For RAS_EXTENSION, HANDLE_EA_EL3_FIRST_NS must also be 1) + $(error For RAS_FFH_SUPPORT, HANDLE_EA_EL3_FIRST_NS must also be 1) endif endif - -# When FAULT_INJECTION_SUPPORT is used, require that RAS_EXTENSION is enabled +# When FAULT_INJECTION_SUPPORT is used, require that FEAT_RAS is enabled ifeq ($(FAULT_INJECTION_SUPPORT),1) - ifneq ($(RAS_EXTENSION),1) - $(error For FAULT_INJECTION_SUPPORT, RAS_EXTENSION must also be 1) + ifneq ($(ENABLE_FEAT_RAS),1) + $(error For FAULT_INJECTION_SUPPORT, ENABLE_FEAT_RAS must also be 1) endif endif @@ -1169,6 +1175,7 @@ $(eval $(call assert_booleans,\ FEATURE_DETECTION \ TRNG_SUPPORT \ CONDITIONAL_CMO \ + RAS_FFH_SUPPORT \ ))) $(eval $(call assert_numerics,\ @@ -1187,6 +1194,7 @@ $(eval $(call assert_numerics,\ ENABLE_FEAT_AMU \ ENABLE_FEAT_AMUv1p1 \ ENABLE_FEAT_CSV2_2 \ + ENABLE_FEAT_RAS \ ENABLE_FEAT_DIT \ ENABLE_FEAT_ECV \ ENABLE_FEAT_FGT \ @@ -1213,7 +1221,6 @@ $(eval $(call assert_numerics,\ FW_ENC_STATUS \ NR_OF_FW_BANKS \ NR_OF_IMAGES_IN_FW_BANK \ - RAS_EXTENSION \ TWED_DELAY \ ENABLE_FEAT_TWED \ SVE_VECTOR_LEN \ @@ -1286,7 +1293,8 @@ $(eval $(call add_defines,\ PROGRAMMABLE_RESET_ADDRESS \ PSCI_EXTENDED_STATE_ID \ PSCI_OS_INIT_MODE \ - RAS_EXTENSION \ + ENABLE_FEAT_RAS \ + RAS_FFH_SUPPORT \ RESET_TO_BL31 \ SEPARATE_CODE_AND_RODATA \ SEPARATE_BL2_NOLOAD_REGION \ diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S index 9419476ce..5d2534b27 100644 --- a/bl31/aarch64/ea_delegate.S +++ b/bl31/aarch64/ea_delegate.S @@ -153,7 +153,7 @@ endfunc handle_lower_el_async_ea * x1: EA syndrome */ func delegate_sync_ea -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT /* * Check for Uncontainable error type. If so, route to the platform * fatal error handler rather than the generic EA one. @@ -183,7 +183,7 @@ endfunc delegate_sync_ea * x1: EA syndrome */ func delegate_async_ea -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT /* Check Exception Class to ensure SError, as this function should * only be invoked for SError. If that is not the case, which implies * either an HW error or programming error, panic. diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S index 2fa9f06c5..a41737a7d 100644 --- a/bl31/aarch64/runtime_exceptions.S +++ b/bl31/aarch64/runtime_exceptions.S @@ -50,16 +50,16 @@ /* * Macro that prepares entry to EL3 upon taking an exception. * - * With RAS_EXTENSION, this macro synchronizes pending errors with an ESB - * instruction. When an error is thus synchronized, the handling is + * With RAS_FFH_SUPPORT, this macro synchronizes pending errors with an + * ESB instruction. When an error is thus synchronized, the handling is * delegated to platform EA handler. * - * Without RAS_EXTENSION, this macro synchronizes pending errors using + * Without RAS_FFH_SUPPORT, this macro synchronizes pending errors using * a DSB, unmasks Asynchronous External Aborts and saves X30 before * setting the flag CTX_IS_IN_EL3. */ .macro check_and_unmask_ea -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT /* Synchronize pending External Aborts */ esb @@ -307,7 +307,7 @@ vector_entry fiq_sp_elx end_vector_entry fiq_sp_elx vector_entry serror_sp_elx -#if !RAS_EXTENSION +#if !RAS_FFH_SUPPORT /* * This will trigger if the exception was taken due to SError in EL3 or * because of pending asynchronous external aborts from lower EL that got @@ -359,7 +359,7 @@ end_vector_entry fiq_aarch64 vector_entry serror_aarch64 save_x30 apply_at_speculative_wa -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT msr daifclr, #DAIF_ABT_BIT #else check_and_unmask_ea @@ -402,7 +402,7 @@ end_vector_entry fiq_aarch32 vector_entry serror_aarch32 save_x30 apply_at_speculative_wa -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT msr daifclr, #DAIF_ABT_BIT #else check_and_unmask_ea diff --git a/common/feat_detect.c b/common/feat_detect.c index eb4db95a0..9b3bffc72 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -65,7 +65,7 @@ check_feature(int state, unsigned long field, const char *feat_name, ******************************************************************************/ static void read_feat_ras(void) { -#if (RAS_EXTENSION == FEAT_STATE_ALWAYS) +#if (ENABLE_FEAT_RAS == FEAT_STATE_ALWAYS) feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS"); #endif } diff --git a/docs/components/ras.rst b/docs/components/ras.rst index 871be2d76..8d003452c 100644 --- a/docs/components/ras.rst +++ b/docs/components/ras.rst @@ -1,45 +1,89 @@ Reliability, Availability, and Serviceability (RAS) Extensions -============================================================== +************************************************************** This document describes |TF-A| support for Arm Reliability, Availability, and Serviceability (RAS) extensions. RAS is a mandatory extension for Armv8.2 and later CPUs, and also an optional extension to the base Armv8.0 architecture. -In conjunction with the |EHF|, support for RAS extension enables firmware-first -paradigm for handling platform errors: exceptions resulting from errors in -Non-secure world are routed to and handled in EL3. -Said errors are Synchronous External Abort (SEA), Asynchronous External Abort -(signalled as SErrors), Fault Handling and Error Recovery interrupts. -The |EHF| document mentions various :ref:`error handling -use-cases ` . - For the description of Arm RAS extensions, Standard Error Records, and the precise definition of RAS terminology, please refer to the Arm Architecture -Reference Manual. The rest of this document assumes familiarity with -architecture and terminology. +Reference Manual and `RAS Supplement`_. The rest of this document assumes +familiarity with architecture and terminology. + +There are two philosophies for handling RAS errors from Non-secure world point +of view. + +- :ref:`Firmware First Handling (FFH)` +- :ref:`Kernel First Handling (KFH)` + +.. _Firmware First Handling (FFH): + +Firmware First Handling (FFH) +============================= + +Introduction +------------ + +EA’s and Error interrupts corresponding to NS nodes are handled first in firmware + +- Errors signaled back to NS world via suitable mechanism +- Kernel is prohibited from accessing the RAS error records directly +- Firmware creates CPER records for kernel to navigate and process +- Firmware signals error back to Kernel via SDEI Overview -------- -As mentioned above, the RAS support in |TF-A| enables routing to and handling of -exceptions resulting from platform errors in EL3. It allows the platform to -define an External Abort handler, and to register RAS nodes and interrupts. RAS -framework also provides `helpers`__ for accessing Standard Error Records as -introduced by the RAS extensions. +FFH works in conjunction with `Exception Handling Framework`. Exceptions resulting from +errors in Non-secure world are routed to and handled in EL3. Said errors are Synchronous +External Abort (SEA), Asynchronous External Abort (signalled as SErrors), Fault Handling +and Error Recovery interrupts. +RAS Framework in TF-A allows the platform to define an external abort handler and to +register RAS nodes and interrupts. It also provides `helpers`__ for accessing Standard +Error Records as introduced by the RAS extensions + .. __: `Standard Error Record helpers`_ -The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run -time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST_NS`` must also -be set ``1``. ``RAS_TRAP_NS_ERR_REC_ACCESS`` controls the access to the RAS -error record registers from Non-secure. +.. _Kernel First Handling (KFH): + +Kernel First Handling (KFH) +=========================== + +Introduction +------------ + +EA's originating/attributed to NS world are handled first in NS and Kernel navigates +the std error records directly. + +**KFH can be supported in a platform without TF-A being aware of it but there are few +corner cases where TF-A needs to have special handling, which is currently missing and +will be added in future** + +TF-A build options +================== + +- **ENABLE_FEAT_RAS**: Manage FEAT_RAS extension when switching the world. +- **RAS_FFH_SUPPORT**: Pull in necessary framework and platform hooks for Firmware first + handling(FFH) of RAS errors. +- **RAS_TRAP_NS_ERR_REC_ACCESS**: Trap Non-secure access of RAS error record registers. +- **RAS_EXTENSION**: Deprecated macro, equivalent to ENABLE_FEAT_RAS and RAS_FFH_SUPPORT + put together. + +RAS feature has dependency on some other TF-A build flags + +- **EL3_EXCEPTION_HANDLING**: Required for FFH +- **HANDLE_EA_EL3_FIRST_NS**: Required for FFH +- **FAULT_INJECTION_SUPPORT**: Required for testing RAS feature on fvp platform + +RAS Framework +============= + .. _ras-figure: .. image:: ../resources/diagrams/draw.io/ras.svg -See more on `Engaging the RAS framework`_. - Platform APIs ------------- @@ -191,19 +235,10 @@ doesn't return. Engaging the RAS framework -------------------------- -Enabling RAS support is a platform choice constructed from three distinct, but -related, build options: - -- ``RAS_EXTENSION=1`` includes the RAS framework in the run time firmware; - -- ``EL3_EXCEPTION_HANDLING=1`` enables handling of exceptions at EL3. See - `Interaction with Exception Handling Framework`_; - -- ``HANDLE_EA_EL3_FIRST_NS=1`` enables routing of External Aborts and SErrors, - resulting from errors in NS world, to EL3. +Enabling RAS support is a platform choice The RAS support in |TF-A| introduces a default implementation of -``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_EXTENSION`` +``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_FFH_SUPPORT`` is set to ``1``, it'll first call ``ras_ea_handler()`` function, which is the top-level RAS exception handler. ``ras_ea_handler`` is responsible for iterating to through platform-supplied error records, probe them, and when an error is @@ -239,4 +274,6 @@ for non-interrupt exceptions, they're explicit using :ref:`EHF APIs -------------- -*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.* + +.. _RAS Supplement: https://developer.arm.com/documentation/ddi0587/latest diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 2735f173f..3694b1c47 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -777,15 +777,14 @@ Common build options - ``PSCI_OS_INIT_MODE``: Boolean flag to enable support for optional PSCI OS-initiated mode. This option defaults to 0. -- ``RAS_EXTENSION``: Numeric value to enable Armv8.2 RAS features. RAS features +- ``ENABLE_FEAT_RAS``: Numeric value to enable Armv8.2 RAS features. RAS features are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2 or later CPUs. This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. - When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST_NS`` must also be - set to ``1``. - - This option is disabled by default. +- ``RAS_FFH_SUPPORT``: Support to enable Firmware first handling of RAS errors + originating from NS world. When ``RAS_FFH_SUPPORT`` is set to ``1``, + ``HANDLE_EA_EL3_FIRST_NS`` and ``ENABLE_FEAT_RAS`` must also be set to ``1``. - ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1 diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst index 1225a9f79..1250071ef 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -3418,11 +3418,11 @@ The third parameter (``void *cookie``) is unused for now. The fourth parameter (``uint64_t flags``) indicates the preempted security state. These parameters are received from the top-level exception handler. -If ``RAS_EXTENSION`` is set to ``1``, the default implementation of this +If ``RAS_FFH_SUPPORT`` is set to ``1``, the default implementation of this function iterates through RAS handlers registered by the platform. If any of the RAS handlers resolve the External Abort, no further action is taken. -If ``RAS_EXTENSION`` is set to ``0``, or if none of the platform RAS handlers +If ``RAS_FFH_SUPPORT`` is set to ``0``, or if none of the platform RAS handlers could resolve the External Abort, the default implementation prints an error message, and panics. diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index dd2b83681..c9590d434 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -523,10 +523,10 @@ 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 RAS_EXTENSION +#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 /* RAS_EXTENSION */ +#endif /* ENABLE_FEAT_RAS */ #endif /* CTX_INCLUDE_EL2_REGS */ #if CTX_INCLUDE_FPREGS diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 769117163..63566da06 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -17,10 +17,10 @@ .global el2_sysregs_context_save_mte .global el2_sysregs_context_restore_mte #endif /* CTX_INCLUDE_MTE_REGS */ -#if RAS_EXTENSION +#if ENABLE_FEAT_RAS .global el2_sysregs_context_save_ras .global el2_sysregs_context_restore_ras -#endif /* RAS_EXTENSION */ +#endif /* ENABLE_FEAT_RAS */ #endif /* CTX_INCLUDE_EL2_REGS */ .global el1_sysregs_context_save @@ -210,7 +210,7 @@ func el2_sysregs_context_restore_mte endfunc el2_sysregs_context_restore_mte #endif /* CTX_INCLUDE_MTE_REGS */ -#if RAS_EXTENSION +#if ENABLE_FEAT_RAS func el2_sysregs_context_save_ras /* * VDISR_EL2 and VSESR_EL2 registers are saved only when @@ -232,7 +232,7 @@ func el2_sysregs_context_restore_ras msr vsesr_el2, x12 ret endfunc el2_sysregs_context_restore_ras -#endif /* RAS_EXTENSION */ +#endif /* ENABLE_FEAT_RAS */ #endif /* CTX_INCLUDE_EL2_REGS */ @@ -855,7 +855,7 @@ sve_not_enabled: 1: #endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */ -#if IMAGE_BL31 && RAS_EXTENSION +#if IMAGE_BL31 && ENABLE_FEAT_RAS /* ---------------------------------------------------------- * Issue Error Synchronization Barrier to synchronize SErrors * before exiting EL3. We're running with EAs unmasked, so @@ -866,7 +866,7 @@ sve_not_enabled: esb #else dsb sy -#endif /* IMAGE_BL31 && RAS_EXTENSION */ +#endif /* IMAGE_BL31 && ENABLE_FEAT_RAS */ /* ---------------------------------------------------------- * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index e38b34dcd..3ddf5fa2f 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -1012,7 +1012,7 @@ void cm_el2_sysregs_context_save(uint32_t security_state) write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2, read_ttbr1_el2()); } -#if RAS_EXTENSION +#if ENABLE_FEAT_RAS el2_sysregs_context_save_ras(el2_sysregs_ctx); #endif @@ -1095,7 +1095,7 @@ 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 RAS_EXTENSION +#if ENABLE_FEAT_RAS el2_sysregs_context_restore_ras(el2_sysregs_ctx); #endif diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk index 01e3e096d..b799697fb 100644 --- a/make_helpers/arch_features.mk +++ b/make_helpers/arch_features.mk @@ -13,6 +13,11 @@ ENABLE_FEAT_PAN = 1 ENABLE_FEAT_VHE = 1 endif +# Enable the features which are mandatory from ARCH version 8.2 and upwards. +ifeq "8.2" "$(word 1, $(sort 8.2 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" +ENABLE_FEAT_RAS = 1 +endif + # Enable the features which are mandatory from ARCH version 8.4 and upwards. ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" ENABLE_FEAT_DIT = 1 diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 8ec16fa60..fd9ad92c3 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -276,8 +276,9 @@ PSCI_EXTENDED_STATE_ID := 0 # Enable PSCI OS-initiated mode support PSCI_OS_INIT_MODE := 0 -# Enable RAS support -RAS_EXTENSION := 0 +# Enable RAS Support +ENABLE_FEAT_RAS := 0 +RAS_FFH_SUPPORT := 0 # By default, BL1 acts as the reset handler, not BL31 RESET_TO_BL31 := 0 diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index f2df780c6..29835d97b 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -387,7 +387,7 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a75_pubsub.c \ endif endif -ifeq (${RAS_EXTENSION},1) +ifeq (${RAS_FFH_SUPPORT},1) BL31_SOURCES += plat/arm/board/fvp/aarch64/fvp_ras.c endif diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index c75507a51..98c2e0ed6 100644 --- a/plat/arm/board/tc/platform.mk +++ b/plat/arm/board/tc/platform.mk @@ -20,7 +20,9 @@ CSS_LOAD_SCP_IMAGES := 1 CSS_USE_SCMI_SDS_DRIVER := 1 -RAS_EXTENSION := 0 +ENABLE_FEAT_RAS := 1 + +RAS_FFH_SUPPORT := 0 SDEI_SUPPORT := 0 diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 8c62a9bb9..cfd1aac08 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -295,7 +295,7 @@ void arm_bl31_platform_setup(void) /* Initialize power controller before setting up topology */ plat_arm_pwrc_setup(); -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT ras_init(); #endif diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index fca6f4f95..647a9d932 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -386,7 +386,7 @@ endif endif # RAS sources -ifeq (${RAS_EXTENSION},1) +ifeq (${RAS_FFH_SUPPORT},1) BL31_SOURCES += lib/extensions/ras/std_err_record.c \ lib/extensions/ras/ras_common.c endif diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index c1fadc654..c6cf0e616 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -206,7 +206,7 @@ #define PLAT_SP_PRI PLAT_RAS_PRI -#if SPM_MM && RAS_EXTENSION +#if SPM_MM && RAS_FFH_SUPPORT /* * CPER buffer memory of 128KB is reserved and it is placed adjacent to the * memory shared between EL3 and S-EL0. @@ -235,7 +235,7 @@ */ #define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ PLAT_SP_IMAGE_NS_BUF_SIZE) -#endif /* SPM_MM && RAS_EXTENSION */ +#endif /* SPM_MM && RAS_FFH_SUPPORT */ /* Platform ID address */ #define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET) diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index 282a5f080..6d17bc22f 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -8,7 +8,9 @@ CSS_USE_SCMI_SDS_DRIVER := 1 CSS_ENT_BASE := plat/arm/css/sgi -RAS_EXTENSION := 0 +ENABLE_FEAT_RAS := 1 + +RAS_FFH_SUPPORT := 0 SDEI_SUPPORT := 0 @@ -52,7 +54,7 @@ BL31_SOURCES += ${INTERCONNECT_SOURCES} \ ${CSS_ENT_BASE}/sgi_bl31_setup.c \ ${CSS_ENT_BASE}/sgi_topology.c -ifeq (${RAS_EXTENSION},1) +ifeq (${RAS_FFH_SUPPORT},1) BL31_SOURCES += ${CSS_ENT_BASE}/sgi_ras.c endif diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index df2ce387a..9c8d16341 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -106,7 +106,7 @@ void sgi_bl31_common_platform_setup(void) { arm_bl31_platform_setup(); -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT sgi_ras_intr_handler_setup(); #endif diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c index b8ba49f7e..7f79d5409 100644 --- a/plat/arm/css/sgi/sgi_plat.c +++ b/plat/arm/css/sgi/sgi_plat.c @@ -93,7 +93,7 @@ const mmap_region_t plat_arm_secure_partition_mmap[] = { PLAT_ARM_SECURE_MAP_DEVICE, ARM_SP_IMAGE_MMAP, ARM_SP_IMAGE_NS_BUF_MMAP, -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT CSS_SGI_SP_CPER_BUF_MMAP, #endif ARM_SP_IMAGE_RW_MMAP, diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c index 042916a7d..eca81b11f 100644 --- a/plat/common/aarch64/plat_common.c +++ b/plat/common/aarch64/plat_common.c @@ -11,7 +11,7 @@ #include #include #include -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT #include #endif #include @@ -81,7 +81,7 @@ const char *get_el_str(unsigned int el) void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags) { -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT /* Call RAS EA handler */ int handled = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags); if (handled != 0) diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c index da768843e..e8197b3e5 100644 --- a/plat/common/aarch64/plat_ehf.c +++ b/plat/common/aarch64/plat_ehf.c @@ -12,7 +12,7 @@ * Enumeration of priority levels on ARM platforms. */ ehf_pri_desc_t plat_exceptions[] = { -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT /* RAS Priority */ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_RAS_PRI), #endif diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index 71bea0845..f93585d9d 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -154,7 +154,7 @@ int plat_sip_handler(uint32_t smc_fid, void *handle, uint64_t flags); -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT void tegra194_ras_enable(void); void tegra194_ras_corrected_err_clear(uint64_t *cookie); #endif diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c index a9fed0ac7..248f16392 100644 --- a/plat/nvidia/tegra/soc/t194/plat_ras.c +++ b/plat/nvidia/tegra/soc/t194/plat_ras.c @@ -484,7 +484,7 @@ REGISTER_RAS_INTERRUPTS(carmel_ras_interrupts); void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags) { -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT tegra194_ea_handler(ea_reason, syndrome, cookie, handle, flags); #else plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags); diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 8f7d1e9a1..d3d09d3dc 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -254,7 +254,7 @@ void plat_early_platform_setup(void) /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT /* Enable Uncorrectable RAS error */ tegra194_ras_enable(); #endif diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c index 1eef55912..f0704edb1 100644 --- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c @@ -71,7 +71,7 @@ int32_t plat_sip_handler(uint32_t smc_fid, break; -#if RAS_EXTENSION +#if RAS_FFH_SUPPORT case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS: { /* diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index 631c92691..a183d0e9d 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -34,7 +34,8 @@ $(eval $(call add_define,MAX_MMAP_REGIONS)) # enable RAS handling HANDLE_EA_EL3_FIRST_NS := 1 -RAS_EXTENSION := 1 +ENABLE_FEAT_RAS := 1 +RAS_FFH_SUPPORT := 1 # platform files PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t194 \ @@ -68,7 +69,7 @@ BL31_SOURCES += ${TEGRA_DRIVERS}/spe/shared_console.S endif # RAS sources -ifeq (${RAS_EXTENSION},1) +ifeq (${RAS_FFH_SUPPORT},1) BL31_SOURCES += lib/extensions/ras/std_err_record.c \ lib/extensions/ras/ras_common.c \ ${SOC_DIR}/plat_ras.c From 6503ff2910ae5edba9edc505c8c19dce7be4d45c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 27 Jan 2023 12:25:49 +0000 Subject: [PATCH 2/2] 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 Signed-off-by: Manish Pandey --- Makefile | 4 +-- common/feat_detect.c | 12 +------- include/arch/aarch64/arch.h | 3 ++ include/arch/aarch64/arch_features.h | 22 +++++++++----- include/arch/aarch64/arch_helpers.h | 4 +++ include/lib/el3_runtime/aarch64/context.h | 4 --- lib/el3_runtime/aarch64/context.S | 35 ++++------------------- lib/el3_runtime/aarch64/context_mgmt.c | 18 ++++++++---- plat/arm/board/fvp/platform.mk | 1 + 9 files changed, 44 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index d5e64ea45..edd435c0c 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/common/feat_detect.c b/common/feat_detect.c index 9b3bffc72..50b74d0c8 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -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(); diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index ac5eae249..20206c1c3 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -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 */ diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index a0141defa..d6f12f3f2 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -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) diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 1b4bc1113..5b3d4c26f 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -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) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index c9590d434..e6af43e58 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -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 diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 63566da06..0f2dfeb77 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -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 diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 3ddf5fa2f..e107f5ad6 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -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)); diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 29835d97b..8a6aa00f8 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -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)