diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S index 9b18ba3..2438423 100644 --- a/include/common/aarch32/el3_common_macros.S +++ b/include/common/aarch32/el3_common_macros.S @@ -177,9 +177,13 @@ * * SCTLR.V: Set to zero to select the normal exception vectors * with base address held in VBAR. + * + * SCTLR.DSSBS: Set to zero to disable speculation store bypass + * safe behaviour upon exception entry to EL3. * ------------------------------------------------------------- */ - ldr r0, =(SCTLR_RESET_VAL & ~(SCTLR_TE_BIT | SCTLR_EE_BIT | SCTLR_V_BIT)) + ldr r0, =(SCTLR_RESET_VAL & ~(SCTLR_TE_BIT | SCTLR_EE_BIT | \ + SCTLR_V_BIT | SCTLR_DSSBS_BIT)) stcopr r0, SCTLR isb .endif /* _init_sctlr */ diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S index adfb54e..008daca 100644 --- a/include/common/aarch64/el3_common_macros.S +++ b/include/common/aarch64/el3_common_macros.S @@ -194,10 +194,13 @@ * SCTLR_EL3.SA: Set to zero to disable Stack Alignment check. * * SCTLR_EL3.A: Set to zero to disable Alignment fault checking. + * + * SCTLR.DSSBS: Set to zero to disable speculation store bypass + * safe behaviour upon exception entry to EL3. * ------------------------------------------------------------- */ mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \ - | SCTLR_SA_BIT | SCTLR_A_BIT)) + | SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT)) msr sctlr_el3, x0 isb .endif /* _init_sctlr */ diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index 3e5e3fb..fa6e5db 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -132,6 +132,7 @@ #define SCTLR_TRE_BIT (U(1) << 28) #define SCTLR_AFE_BIT (U(1) << 29) #define SCTLR_TE_BIT (U(1) << 30) +#define SCTLR_DSSBS_BIT (U(1) << 31) #define SCTLR_RESET_VAL (SCTLR_RES1 | SCTLR_NTWE_BIT | \ SCTLR_NTWI_BIT | SCTLR_CP15BEN_BIT) diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index d7867bc..97595e9 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -198,6 +198,12 @@ #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED ULL(0x1) #define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED ULL(0x0) +/* ID_AA64PFR1_EL1 definitions */ +#define ID_AA64PFR1_EL1_SSBS_SHIFT U(4) +#define ID_AA64PFR1_EL1_SSBS_MASK ULL(0xf) + +#define SSBS_UNAVAILABLE ULL(0) /* No architectural SSBS support */ + /* ID_PFR1_EL1 definitions */ #define ID_PFR1_VIRTEXT_SHIFT U(12) #define ID_PFR1_VIRTEXT_MASK U(0xf) @@ -219,29 +225,30 @@ (U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \ (U(1) << 11) | (U(1) << 5) | (U(1) << 4)) -#define SCTLR_M_BIT (U(1) << 0) -#define SCTLR_A_BIT (U(1) << 1) -#define SCTLR_C_BIT (U(1) << 2) -#define SCTLR_SA_BIT (U(1) << 3) -#define SCTLR_SA0_BIT (U(1) << 4) -#define SCTLR_CP15BEN_BIT (U(1) << 5) -#define SCTLR_ITD_BIT (U(1) << 7) -#define SCTLR_SED_BIT (U(1) << 8) -#define SCTLR_UMA_BIT (U(1) << 9) -#define SCTLR_I_BIT (U(1) << 12) -#define SCTLR_V_BIT (U(1) << 13) -#define SCTLR_DZE_BIT (U(1) << 14) -#define SCTLR_UCT_BIT (U(1) << 15) -#define SCTLR_NTWI_BIT (U(1) << 16) -#define SCTLR_NTWE_BIT (U(1) << 18) -#define SCTLR_WXN_BIT (U(1) << 19) -#define SCTLR_UWXN_BIT (U(1) << 20) -#define SCTLR_E0E_BIT (U(1) << 24) -#define SCTLR_EE_BIT (U(1) << 25) -#define SCTLR_UCI_BIT (U(1) << 26) -#define SCTLR_TRE_BIT (U(1) << 28) -#define SCTLR_AFE_BIT (U(1) << 29) -#define SCTLR_TE_BIT (U(1) << 30) +#define SCTLR_M_BIT (ULL(1) << 0) +#define SCTLR_A_BIT (ULL(1) << 1) +#define SCTLR_C_BIT (ULL(1) << 2) +#define SCTLR_SA_BIT (ULL(1) << 3) +#define SCTLR_SA0_BIT (ULL(1) << 4) +#define SCTLR_CP15BEN_BIT (ULL(1) << 5) +#define SCTLR_ITD_BIT (ULL(1) << 7) +#define SCTLR_SED_BIT (ULL(1) << 8) +#define SCTLR_UMA_BIT (ULL(1) << 9) +#define SCTLR_I_BIT (ULL(1) << 12) +#define SCTLR_V_BIT (ULL(1) << 13) +#define SCTLR_DZE_BIT (ULL(1) << 14) +#define SCTLR_UCT_BIT (ULL(1) << 15) +#define SCTLR_NTWI_BIT (ULL(1) << 16) +#define SCTLR_NTWE_BIT (ULL(1) << 18) +#define SCTLR_WXN_BIT (ULL(1) << 19) +#define SCTLR_UWXN_BIT (ULL(1) << 20) +#define SCTLR_E0E_BIT (ULL(1) << 24) +#define SCTLR_EE_BIT (ULL(1) << 25) +#define SCTLR_UCI_BIT (ULL(1) << 26) +#define SCTLR_TRE_BIT (ULL(1) << 28) +#define SCTLR_AFE_BIT (ULL(1) << 29) +#define SCTLR_TE_BIT (ULL(1) << 30) +#define SCTLR_DSSBS_BIT (ULL(1) << 44) #define SCTLR_RESET_VAL SCTLR_EL3_RES1 /* CPACR_El1 definitions */ diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index 1697c55..4def143 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -208,14 +208,20 @@ func cortex_a76_reset_func mov x19, x30 + #if WORKAROUND_CVE_2018_3639 + /* If the PE implements SSBS, we don't need the dynamic workaround */ + mrs x0, id_aa64pfr1_el1 + lsr x0, x0, #ID_AA64PFR1_EL1_SSBS_SHIFT + and x0, x0, #ID_AA64PFR1_EL1_SSBS_MASK + cbnz x0, 1f + mrs x0, CORTEX_A76_CPUACTLR2_EL1 orr x0, x0, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE msr CORTEX_A76_CPUACTLR2_EL1, x0 isb -#endif -#if IMAGE_BL31 && WORKAROUND_CVE_2018_3639 +#ifdef IMAGE_BL31 /* * The Cortex-A76 generic vectors are overwritten to use the vectors * defined above. This is required in order to apply mitigation @@ -226,6 +232,9 @@ isb #endif +1: +#endif + #if ERRATA_DSU_936184 bl errata_dsu_936184_wa #endif diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c index 45c4704..3a5299f 100644 --- a/services/arm_arch_svc/arm_arch_svc_setup.c +++ b/services/arm_arch_svc/arm_arch_svc_setup.c @@ -30,9 +30,27 @@ return 1; return 0; /* ERRATA_APPLIES || ERRATA_MISSING */ #endif + #if WORKAROUND_CVE_2018_3639 - case SMCCC_ARCH_WORKAROUND_2: + case SMCCC_ARCH_WORKAROUND_2: { #if DYNAMIC_WORKAROUND_CVE_2018_3639 + unsigned long long ssbs; + + /* + * Firmware doesn't have to carry out dynamic workaround if the + * PE implements architectural Speculation Store Bypass Safe + * (SSBS) feature. + */ + ssbs = (read_id_aa64pfr0_el1() >> ID_AA64PFR1_EL1_SSBS_SHIFT) & + ID_AA64PFR1_EL1_SSBS_MASK; + + /* + * If architectural SSBS is available on this PE, no firmware + * mitigation via SMCCC_ARCH_WORKAROUND_2 is required. + */ + if (ssbs != SSBS_UNAVAILABLE) + return 1; + /* * On a platform where at least one CPU requires * dynamic mitigation but others are either unaffected @@ -50,7 +68,11 @@ /* Either the CPUs are unaffected or permanently mitigated */ return SMCCC_ARCH_NOT_REQUIRED; #endif + } #endif + + /* Fallthrough */ + default: return SMC_UNK; }