diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c index 5321ca2e5..6c210144a 100644 --- a/bl31/bl31_traps.c +++ b/bl31/bl31_traps.c @@ -14,10 +14,19 @@ #include #include +static int access_raz_wi(bool is_read, uint8_t rt, cpu_context_t *ctx) +{ + if (is_read && rt != XZR_REG_NUM) { + ctx->gpregs_ctx.ctx_regs[rt] = 0UL; + } + return TRAP_RET_CONTINUE; +} + int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx, u_register_t flags) { uint64_t opcode = EXTRACT(ESR_ISS, esr_el3) & ~(MASK(ISS_SYS64_DIR) | MASK(ISS_SYS64_RT)); uint8_t rt = EXTRACT(ISS_SYS64_RT, esr_el3); + bool is_read = EXTRACT(ISS_SYS64_DIR, opcode); if (is_feat_idte3_supported() && ((opcode >= ISS_SYSREG_OPCODE_IDREG_MIN && @@ -66,6 +75,28 @@ int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx, u_register_t flags) return ret; } + if (is_feat_ras_supported() && !FAULT_INJECTION_SUPPORT && + (opcode == ISS_SYSREG_OPCODE_ERXPFGCDN_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXPFGCTL_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXPFGF_EL1)) { + return access_raz_wi(is_read, rt, ctx); + } + + if (is_feat_ras_supported() && RAS_TRAP_NS_ERR_REC_ACCESS && + (opcode == ISS_SYSREG_OPCODE_ERRSELR_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXADDR_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXCTLR_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXMISC0_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXMISC1_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXSTATUS_EL1 || + opcode == ISS_SYSREG_OPCODE_ERRIDR_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXFR_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXMISC2_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXMISC3_EL1 || + opcode == ISS_SYSREG_OPCODE_ERXGSR_EL1)) { + return access_raz_wi(is_read, rt, ctx); + } + #if IMPDEF_SYSREG_TRAP /* isolate selected bits and check they are all set */ if (opcode & ISS_SYSREG_OPCODE_IMPDEF_MASK == ISS_SYSREG_OPCODE_IMPDEF_MASK) { diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 2268a57b9..5ada0a323 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -749,10 +749,9 @@ Common build options trapped during secure world execution are trapped to the SPMC. This is supported only for AArch64 builds. -- ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault - injection from lower ELs, and this build option enables lower ELs to use - Error Records accessed via System Registers to inject faults. This is - applicable only to AArch64 builds. +- ``FAULT_INJECTION_SUPPORT``: Boolean option to enable FEAT_RASv1p1 fault + injection. When unset, all accesses will be trapped to EL3 and emulated as + RAZ/WI. Default value is ``0``. This feature is intended for testing purposes only, and is advisable to keep disabled for production images. @@ -1363,9 +1362,9 @@ Common build options implement this workaround due to the behaviour of the errata mentioned in new SDEN document which will get published soon. -- ``RAS_TRAP_NS_ERR_REC_ACCESS``: This flag enables/disables the SCR_EL3.TERR - bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs. - This flag is disabled by default. +- ``RAS_TRAP_NS_ERR_REC_ACCESS``: Boolean option to disable FEAT_RAS access to + ERR and ERX registers from lower ELs. When set, all accesses will be trapped + to EL3 and emulated as RAZ/WI. Default value is ``0``. - ``OPENSSL_DIR``: This option is used to provide the path to a directory on the host machine where a custom installation of OpenSSL is located, which is used diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 709055b31..e34c2bff6 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -1347,6 +1347,25 @@ * (D23.3.2 of the Arm ARM) */ #define ISS_SYSREG_OPCODE_IMPDEF_MASK SYSREG_ESR(3, 0, 11, 0, 0) +/* FEAT_RASv1p1 Fault injection registers */ +#define ISS_SYSREG_OPCODE_ERXPFGCDN_EL1 SYSREG_ESR(3, 0, 5, 4, 6) +#define ISS_SYSREG_OPCODE_ERXPFGCTL_EL1 SYSREG_ESR(3, 0, 5, 4, 5) +#define ISS_SYSREG_OPCODE_ERXPFGF_EL1 SYSREG_ESR(3, 0, 5, 4, 4) + +/* FEAT_RAS ERR and ERX registers */ +#define ISS_SYSREG_OPCODE_ERRSELR_EL1 SYSREG_ESR(3, 0, 5, 3, 1) +#define ISS_SYSREG_OPCODE_ERXADDR_EL1 SYSREG_ESR(3, 0, 5, 4, 3) +#define ISS_SYSREG_OPCODE_ERXCTLR_EL1 SYSREG_ESR(3, 0, 5, 4, 1) +#define ISS_SYSREG_OPCODE_ERXMISC0_EL1 SYSREG_ESR(3, 0, 5, 5, 0) +#define ISS_SYSREG_OPCODE_ERXMISC1_EL1 SYSREG_ESR(3, 0, 5, 5, 1) +#define ISS_SYSREG_OPCODE_ERXSTATUS_EL1 SYSREG_ESR(3, 0, 5, 4, 2) +#define ISS_SYSREG_OPCODE_ERRIDR_EL1 SYSREG_ESR(3, 0, 5, 3, 0) +#define ISS_SYSREG_OPCODE_ERXFR_EL1 SYSREG_ESR(3, 0, 5, 4, 0) +#define ISS_SYSREG_OPCODE_ERXMISC2_EL1 SYSREG_ESR(3, 0, 5, 5, 2) +#define ISS_SYSREG_OPCODE_ERXMISC3_EL1 SYSREG_ESR(3, 0, 5, 5, 3) +#define ISS_SYSREG_OPCODE_ERXGSR_EL1 SYSREG_ESR(3, 0, 5, 3, 2) + + /* * External Abort bit in Instruction and Data Aborts synchronous exception * syndromes. diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 7e3a2e588..d40a03d58 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -354,15 +354,10 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info * scr_el3 |= SCR_EA_BIT; #endif -#if RAS_TRAP_NS_ERR_REC_ACCESS - /* - * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR - * and RAS ERX registers from EL1 and EL2(from any security state) - * are trapped to EL3. - * Set here to trap only for NS EL1/EL2 - */ - scr_el3 |= SCR_TERR_BIT; -#endif + if (is_feat_ras_supported() && RAS_TRAP_NS_ERR_REC_ACCESS) { + /* Trap Error record accesses. */ + scr_el3 |= SCR_TERR_BIT; + } /* CSV2 version 2 and above */ if (is_feat_csv2_2_supported()) { @@ -550,10 +545,10 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e scr_el3 |= SCR_TRNDR_BIT; } -#if FAULT_INJECTION_SUPPORT - /* Enable fault injection from lower ELs */ - scr_el3 |= SCR_FIEN_BIT; -#endif + if (is_feat_ras_supported() && FAULT_INJECTION_SUPPORT) { + /* Disable trapping of fault injection registers */ + scr_el3 |= SCR_FIEN_BIT; + } /* * Enable Pointer Authentication globally for all the worlds.