From: robert Date: Tue, 20 Sep 2022 14:28:27 +0000 (+0000) Subject: Split out handling of cpu family specific MSRs from cpu_init_msrs() X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=9f172165b574c19186ae3a65383c7fa8c8839f78;p=openbsd 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@ --- 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 * @@ -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 */