diff --git a/sys/arm64/arm64/cpu_errata.c b/sys/arm64/arm64/cpu_errata.c --- a/sys/arm64/arm64/cpu_errata.c +++ b/sys/arm64/arm64/cpu_errata.c @@ -42,6 +42,11 @@ #include +/* msr ssbs, #0 */ +#define SSBS_ENABLE() __asm __volatile(".inst 0xd503403f | (0 << 8)") +/* msr ssbs, #1 */ +#define SSBS_DISABLE() __asm __volatile(".inst 0xd503403f | (1 << 8)") + typedef void (cpu_quirk_install)(u_int); struct cpu_quirks { cpu_quirk_install *quirk_install; @@ -142,6 +147,26 @@ return; } + if (ID_AA64PFR1_SSBS_VAL(READ_SPECIALREG(id_aa64pfr1_el1)) != + ID_AA64PFR1_SSBS_NONE) { + uint64_t sctlr; + + sctlr = READ_SPECIALREG(sctlr_el1); + /* + * TODO: Userspace can set the SSBS flag so SSBD_FORCE_OFF + * and SSBD_FORCE_ON can be overridden. + */ + if (ssbd_method == SSBD_FORCE_OFF) { + SSBS_DISABLE(); + sctlr |= SCTLR_DSSBS; + } else { + SSBS_ENABLE(); + sctlr &= ~SCTLR_DSSBS; + } + WRITE_SPECIALREG(sctlr_el1, sctlr); + return; + } + /* Enable the workaround on this CPU if it's enabled in the firmware */ if (smccc_arch_features(SMCCC_ARCH_WORKAROUND_2) != SMCCC_RET_SUCCESS) { if (ssbd_method == SSBD_FORCE_ON)