summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorRobert Nagy <robert@cvs.openbsd.org>2022-09-20 14:28:28 +0000
committerRobert Nagy <robert@cvs.openbsd.org>2022-09-20 14:28:28 +0000
commit33ad2b93f618cc5cf0565c911db1f3be222f6420 (patch)
tree7cdc51550559c3f2f46f41e54735fc496f7a1b2b /sys/arch
parent099fa5d507e8afe5aaaf178e0035428cb012c13e (diff)
Split out handling of cpu family specific MSRs from cpu_init_msrs()
to a separate function that gets called after identifycpu() so that we have the required information to handle the correct MSRs for each cpu. Additionally, move the handling of the DE_CFG_SERIALIZE_LFENCE and IA32_DEBUG_INTERFACE_LOCK MSRs out of identifycpu() to the new function so that they get set again after a suspend/resume cycle as well, which in fixes TSC sync failures. discussed with and input from deraadt@, mlarkin@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/amd64/amd64/acpi_machdep.c3
-rw-r--r--sys/arch/amd64/amd64/cpu.c70
-rw-r--r--sys/arch/amd64/amd64/identcpu.c43
-rw-r--r--sys/arch/amd64/include/cpu.h3
4 files changed, 62 insertions, 57 deletions
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c
index db68939ed1e..1d979315716 100644
--- a/sys/arch/amd64/amd64/acpi_machdep.c
+++ b/sys/arch/amd64/amd64/acpi_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi_machdep.c,v 1.104 2022/08/07 23:56:06 guenther Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.105 2022/09/20 14:28:27 robert Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -456,6 +456,7 @@ void
acpi_resume_cpu(struct acpi_softc *sc, int state)
{
cpu_init_msrs(&cpu_info_primary);
+ cpu_fix_msrs(&cpu_info_primary);
#if NISA > 0
i8259_default_setup();
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c
index 8ebd254786f..68c83d902a6 100644
--- a/sys/arch/amd64/amd64/cpu.c
+++ b/sys/arch/amd64/amd64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.159 2022/09/15 19:30:51 cheloha Exp $ */
+/* $OpenBSD: cpu.c,v 1.160 2022/09/20 14:28:27 robert Exp $ */
/* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
@@ -601,6 +601,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
#endif
cpu_tsx_disable(ci);
identifycpu(ci);
+ cpu_fix_msrs(ci);
#ifdef MTRR
mem_range_attach();
#endif /* MTRR */
@@ -615,6 +616,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
CPUF_PRESENT | CPUF_BSP | CPUF_PRIMARY);
cpu_intr_init(ci);
identifycpu(ci);
+ cpu_fix_msrs(ci);
#ifdef MTRR
mem_range_attach();
#endif /* MTRR */
@@ -955,6 +957,9 @@ cpu_hatch(void *v)
atomic_setbits_int(&ci->ci_flags, CPUF_IDENTIFIED);
}
+ /* These have to run after identifycpu() */
+ cpu_fix_msrs(ci);
+
/*
* Test if our TSC is synchronized for the first time.
* Note that interrupts are off at this point.
@@ -1095,9 +1100,6 @@ extern vector Xsyscall_meltdown, Xsyscall, Xsyscall32;
void
cpu_init_msrs(struct cpu_info *ci)
{
- uint64_t msr;
- int family;
-
wrmsr(MSR_STAR,
((uint64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
((uint64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48));
@@ -1109,18 +1111,60 @@ cpu_init_msrs(struct cpu_info *ci)
wrmsr(MSR_FSBASE, 0);
wrmsr(MSR_GSBASE, (u_int64_t)ci);
wrmsr(MSR_KERNELGSBASE, 0);
+ patinit(ci);
+}
- family = ci->ci_family;
- if (strcmp(cpu_vendor, "GenuineIntel") == 0 &&
- (family > 6 || (family == 6 && ci->ci_model >= 0xd)) &&
- rdmsr_safe(MSR_MISC_ENABLE, &msr) == 0 &&
- (msr & MISC_ENABLE_FAST_STRINGS) == 0) {
- msr |= MISC_ENABLE_FAST_STRINGS;
- wrmsr(MSR_MISC_ENABLE, msr);
- DPRINTF("%s: enabled fast strings\n", ci->ci_dev->dv_xname);
+void
+cpu_fix_msrs(struct cpu_info *ci)
+{
+ int family = ci->ci_family;
+ uint64_t msr;
+
+ if (!strcmp(cpu_vendor, "GenuineIntel")) {
+ if ((family > 6 || (family == 6 && ci->ci_model >= 0xd)) &&
+ rdmsr_safe(MSR_MISC_ENABLE, &msr) == 0 &&
+ (msr & MISC_ENABLE_FAST_STRINGS) == 0) {
+ msr |= MISC_ENABLE_FAST_STRINGS;
+ wrmsr(MSR_MISC_ENABLE, msr);
+ DPRINTF("%s: enabled fast strings\n", ci->ci_dev->dv_xname);
+
+ /*
+ * Attempt to disable Silicon Debug and lock the configuration
+ * if it's enabled and unlocked.
+ */
+ if (cpu_ecxfeature & CPUIDECX_SDBG) {
+ msr = rdmsr(IA32_DEBUG_INTERFACE);
+ if ((msr & IA32_DEBUG_INTERFACE_ENABLE) &&
+ (msr & IA32_DEBUG_INTERFACE_LOCK) == 0) {
+ msr &= IA32_DEBUG_INTERFACE_MASK;
+ msr |= IA32_DEBUG_INTERFACE_LOCK;
+ wrmsr(IA32_DEBUG_INTERFACE, msr);
+ } else if (msr & IA32_DEBUG_INTERFACE_ENABLE)
+ printf("%s: cannot disable silicon debug\n",
+ ci->ci_dev->dv_xname);
+ }
+ }
}
- patinit(ci);
+ /*
+ * "Mitigation G-2" per AMD's Whitepaper "Software Techniques
+ * for Managing Speculation on AMD Processors"
+ *
+ * By setting MSR C001_1029[1]=1, LFENCE becomes a dispatch
+ * serializing instruction.
+ *
+ * This MSR is available on all AMD families >= 10h, except 11h
+ * where LFENCE is always serializing.
+ */
+ if (!strcmp(cpu_vendor, "AuthenticAMD")) {
+ if (family >= 0x10 && family != 0x11) {
+ msr = rdmsr(MSR_DE_CFG);
+ if ((msr & DE_CFG_SERIALIZE_LFENCE) == 0) {
+ msr |= DE_CFG_SERIALIZE_LFENCE;
+ wrmsr(MSR_DE_CFG, msr);
+ }
+ }
+ }
}
void
diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c
index 7cb1d8116fa..09c7ce842fa 100644
--- a/sys/arch/amd64/amd64/identcpu.c
+++ b/sys/arch/amd64/amd64/identcpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: identcpu.c,v 1.127 2022/08/30 17:09:21 dv Exp $ */
+/* $OpenBSD: identcpu.c,v 1.128 2022/09/20 14:28:27 robert Exp $ */
/* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */
/*
@@ -699,47 +699,6 @@ identifycpu(struct cpu_info *ci)
replacemeltdown();
x86_print_cacheinfo(ci);
- /*
- * "Mitigation G-2" per AMD's Whitepaper "Software Techniques
- * for Managing Speculation on AMD Processors"
- *
- * By setting MSR C001_1029[1]=1, LFENCE becomes a dispatch
- * serializing instruction.
- *
- * This MSR is available on all AMD families >= 10h, except 11h
- * where LFENCE is always serializing.
- */
- if (!strcmp(cpu_vendor, "AuthenticAMD")) {
- if (ci->ci_family >= 0x10 && ci->ci_family != 0x11) {
- uint64_t msr;
-
- msr = rdmsr(MSR_DE_CFG);
- if ((msr & DE_CFG_SERIALIZE_LFENCE) == 0) {
- msr |= DE_CFG_SERIALIZE_LFENCE;
- wrmsr(MSR_DE_CFG, msr);
- }
- }
- }
-
- /*
- * Attempt to disable Silicon Debug and lock the configuration
- * if it's enabled and unlocked.
- */
- if (!strcmp(cpu_vendor, "GenuineIntel") &&
- (cpu_ecxfeature & CPUIDECX_SDBG)) {
- uint64_t msr;
-
- msr = rdmsr(IA32_DEBUG_INTERFACE);
- if ((msr & IA32_DEBUG_INTERFACE_ENABLE) &&
- (msr & IA32_DEBUG_INTERFACE_LOCK) == 0) {
- msr &= IA32_DEBUG_INTERFACE_MASK;
- msr |= IA32_DEBUG_INTERFACE_LOCK;
- wrmsr(IA32_DEBUG_INTERFACE, msr);
- } else if (msr & IA32_DEBUG_INTERFACE_ENABLE)
- printf("%s: cannot disable silicon debug\n",
- ci->ci_dev->dv_xname);
- }
-
if (CPU_IS_PRIMARY(ci)) {
#ifndef SMALL_KERNEL
if (!strcmp(cpu_vendor, "AuthenticAMD") &&
diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h
index 26895056757..1a8c6ddb7b9 100644
--- a/sys/arch/amd64/include/cpu.h
+++ b/sys/arch/amd64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.150 2022/08/30 17:09:21 dv Exp $ */
+/* $OpenBSD: cpu.h,v 1.151 2022/09/20 14:28:27 robert Exp $ */
/* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */
/*-
@@ -428,6 +428,7 @@ void i8254_inittimecounter_simple(void);
void i8259_default_setup(void);
void cpu_init_msrs(struct cpu_info *);
+void cpu_fix_msrs(struct cpu_info *);
void cpu_tsx_disable(struct cpu_info *);
/* dkcsum.c */