Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/cpu_errata.c
Show All 32 Lines | |||||
#include "opt_platform.h" | #include "opt_platform.h" | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/pcpu.h> | #include <sys/pcpu.h> | ||||
#include <sys/systm.h> | |||||
#include <machine/cpu.h> | #include <machine/cpu.h> | ||||
#include <dev/psci/smccc.h> | #include <dev/psci/smccc.h> | ||||
typedef void (cpu_quirk_install)(void); | typedef void (cpu_quirk_install)(void); | ||||
struct cpu_quirks { | struct cpu_quirks { | ||||
cpu_quirk_install *quirk_install; | cpu_quirk_install *quirk_install; | ||||
u_int midr_mask; | u_int midr_mask; | ||||
u_int midr_value; | u_int midr_value; | ||||
}; | }; | ||||
static enum { | |||||
SSBD_FORCE_ON, | |||||
SSBD_FORCE_OFF, | |||||
SSBD_KERNEL, | |||||
} ssbd_method = SSBD_KERNEL; | |||||
static cpu_quirk_install install_psci_bp_hardening; | static cpu_quirk_install install_psci_bp_hardening; | ||||
static cpu_quirk_install install_ssbd_workaround; | |||||
static struct cpu_quirks cpu_quirks[] = { | static struct cpu_quirks cpu_quirks[] = { | ||||
{ | { | ||||
.midr_mask = CPU_IMPL_MASK | CPU_PART_MASK, | .midr_mask = CPU_IMPL_MASK | CPU_PART_MASK, | ||||
.midr_value = CPU_ID_RAW(CPU_IMPL_ARM, CPU_PART_CORTEX_A57,0,0), | .midr_value = CPU_ID_RAW(CPU_IMPL_ARM, CPU_PART_CORTEX_A57,0,0), | ||||
.quirk_install = install_psci_bp_hardening, | .quirk_install = install_psci_bp_hardening, | ||||
}, | }, | ||||
{ | { | ||||
Show All 12 Lines | static struct cpu_quirks cpu_quirks[] = { | ||||
.quirk_install = install_psci_bp_hardening, | .quirk_install = install_psci_bp_hardening, | ||||
}, | }, | ||||
{ | { | ||||
.midr_mask = CPU_IMPL_MASK | CPU_PART_MASK, | .midr_mask = CPU_IMPL_MASK | CPU_PART_MASK, | ||||
.midr_value = | .midr_value = | ||||
CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDERX2, 0,0), | CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDERX2, 0,0), | ||||
.quirk_install = install_psci_bp_hardening, | .quirk_install = install_psci_bp_hardening, | ||||
}, | }, | ||||
{ | |||||
.midr_mask = 0, | |||||
.midr_value = 0, | |||||
.quirk_install = install_ssbd_workaround, | |||||
}, | |||||
}; | }; | ||||
static void | static void | ||||
install_psci_bp_hardening(void) | install_psci_bp_hardening(void) | ||||
{ | { | ||||
if (smccc_arch_features(SMCCC_ARCH_WORKAROUND_1) != SMCCC_RET_SUCCESS) | if (smccc_arch_features(SMCCC_ARCH_WORKAROUND_1) != SMCCC_RET_SUCCESS) | ||||
return; | return; | ||||
PCPU_SET(bp_harden, smccc_arch_workaround_1); | PCPU_SET(bp_harden, smccc_arch_workaround_1); | ||||
} | |||||
static void | |||||
install_ssbd_workaround(void) | |||||
{ | |||||
char *env; | |||||
if (PCPU_GET(cpuid) == 0) { | |||||
env = kern_getenv("kern.cfg.ssbd"); | |||||
if (env != NULL) { | |||||
if (strcmp(env, "force-on") == 0) { | |||||
ssbd_method = SSBD_FORCE_ON; | |||||
} else if (strcmp(env, "force-off") == 0) { | |||||
ssbd_method = SSBD_FORCE_OFF; | |||||
} | |||||
} | |||||
} | |||||
/* Enable the workaround on this CPU if it's enabled in the firmware */ | |||||
if (smccc_arch_features(SMCCC_ARCH_WORKAROUND_2) != SMCCC_RET_SUCCESS) | |||||
return; | |||||
switch(ssbd_method) { | |||||
case SSBD_FORCE_ON: | |||||
smccc_arch_workaround_2(true); | |||||
break; | |||||
case SSBD_FORCE_OFF: | |||||
smccc_arch_workaround_2(false); | |||||
break; | |||||
case SSBD_KERNEL: | |||||
default: | |||||
PCPU_SET(ssbd, smccc_arch_workaround_2); | |||||
break; | |||||
} | |||||
} | } | ||||
void | void | ||||
install_cpu_errata(void) | install_cpu_errata(void) | ||||
{ | { | ||||
u_int midr; | u_int midr; | ||||
size_t i; | size_t i; | ||||
Show All 9 Lines |