-/* $OpenBSD: cpu.c,v 1.112 2024/03/18 18:35:21 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.113 2024/03/18 21:57:22 kettenis Exp $ */
/*
* Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
void cpu_opp_kstat_attach(struct cpu_info *ci);
#endif
+/*
+ * Enable mitigation for Spectre-V4 speculative store bypass
+ * vulnerabilities (CVE-2018-3639).
+ */
+void
+cpu_mitigate_spectre_v4(struct cpu_info *ci)
+{
+ uint64_t id;
+
+ switch (CPU_IMPL(ci->ci_midr)) {
+ case CPU_IMPL_ARM:
+ switch (CPU_PART(ci->ci_midr)) {
+ case CPU_PART_CORTEX_A35:
+ case CPU_PART_CORTEX_A53:
+ case CPU_PART_CORTEX_A55:
+ /* Not vulnerable. */
+ return;
+ }
+ break;
+ case CPU_IMPL_QCOM:
+ switch (CPU_PART(ci->ci_midr)) {
+ case CPU_PART_KRYO400_SILVER:
+ /* Not vulnerable. */
+ return;
+ }
+ break;
+ }
+
+ /* SSBS tells us Spectre-V4 is mitigated. */
+ id = READ_SPECIALREG(id_aa64pfr1_el1);
+ if (ID_AA64PFR1_SSBS(id) >= ID_AA64PFR1_SSBS_PSTATE)
+ return;
+
+ /* Enable firmware workaround if required. */
+ smccc_enable_arch_workaround_2();
+}
+
void
cpu_identify(struct cpu_info *ci)
{
*/
#if NPSCI > 0
if (ci->ci_trampoline_vectors == (vaddr_t)trampoline_vectors_none &&
- psci_flush_bp_has_bhb()) {
+ smccc_needs_arch_workaround_3()) {
ci->ci_flush_bp = cpu_flush_bp_noop;
if (psci_method() == PSCI_METHOD_HVC)
ci->ci_trampoline_vectors =
ci->ci_trampoline_vectors = (vaddr_t)trampoline_vectors_none;
}
+ cpu_mitigate_spectre_v4(ci);
+
/*
* Apple CPUs provide detailed information for SError.
*/
-/* $OpenBSD: psci.c,v 1.14 2023/02/19 17:16:13 kettenis Exp $ */
+/* $OpenBSD: psci.c,v 1.15 2024/03/18 21:57:22 kettenis Exp $ */
/*
* Copyright (c) 2016 Jonathan Gray <jsg@openbsd.org>
#define SMCCC_VERSION 0x80000000
#define SMCCC_ARCH_FEATURES 0x80000001
#define SMCCC_ARCH_WORKAROUND_1 0x80008000
+#define SMCCC_ARCH_WORKAROUND_2 0x80007fff
#define SMCCC_ARCH_WORKAROUND_3 0x80003fff
#define PSCI_VERSION 0x84000000
}
}
+void
+smccc_enable_arch_workaround_2(void)
+{
+ struct psci_softc *sc = psci_sc;
+
+ /*
+ * SMCCC 1.1 allows us to detect if the workaround is
+ * implemented and needed.
+ */
+ if (sc && sc->sc_smccc_version >= 0x10001 &&
+ smccc_arch_features(SMCCC_ARCH_WORKAROUND_2) == 0) {
+ /* Workaround implemented and needed. */
+ (*sc->sc_callfn)(SMCCC_ARCH_WORKAROUND_2, 1, 0, 0);
+ }
+}
+
int
-psci_flush_bp_has_bhb(void)
+smccc_needs_arch_workaround_3(void)
{
struct psci_softc *sc = psci_sc;