Date: Wed, 21 Oct 2020 15:04:13 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r366909 - in stable/12/sys: amd64/amd64 i386/i386 x86/include x86/x86 Message-ID: <202010211504.09LF4DZh044907@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Wed Oct 21 15:04:12 2020 New Revision: 366909 URL: https://svnweb.freebsd.org/changeset/base/366909 Log: MFC r366712: Limit workaround for errata E400 to appropriate AMD cpus. Modified: stable/12/sys/amd64/amd64/initcpu.c stable/12/sys/amd64/amd64/machdep.c stable/12/sys/i386/i386/initcpu.c stable/12/sys/i386/i386/machdep.c stable/12/sys/x86/include/specialreg.h stable/12/sys/x86/include/x86_var.h stable/12/sys/x86/x86/cpu_machdep.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/amd64/amd64/initcpu.c ============================================================================== --- stable/12/sys/amd64/amd64/initcpu.c Wed Oct 21 15:01:33 2020 (r366908) +++ stable/12/sys/amd64/amd64/initcpu.c Wed Oct 21 15:04:12 2020 (r366909) @@ -69,6 +69,23 @@ init_amd(void) uint64_t msr; /* + * C1E renders the local APIC timer dead, so we disable it by + * reading the Interrupt Pending Message register and clearing + * both C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27). + * + * Reference: + * "BIOS and Kernel Developer's Guide for AMD NPT Family 0Fh Processors" + * #32559 revision 3.00+ + * + * Detect the presence of C1E capability mostly on latest + * dual-cores (or future) k8 family. Affected models range is + * taken from Linux sources. + */ + if ((CPUID_TO_FAMILY(cpu_id) == 0xf || + CPUID_TO_FAMILY(cpu_id) == 0x10) && (cpu_feature2 & CPUID2_HV) == 0) + cpu_amdc1e_bug = 1; + + /* * Work around Erratum 721 for Family 10h and 12h processors. * These processors may incorrectly update the stack pointer * after a long series of push and/or near-call instructions, Modified: stable/12/sys/amd64/amd64/machdep.c ============================================================================== --- stable/12/sys/amd64/amd64/machdep.c Wed Oct 21 15:01:33 2020 (r366908) +++ stable/12/sys/amd64/amd64/machdep.c Wed Oct 21 15:04:12 2020 (r366909) @@ -1910,8 +1910,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) if (env != NULL) strlcpy(kernelname, env, sizeof(kernelname)); - cpu_probe_amdc1e(); - #ifdef FDT x86_init_fdt(); #endif Modified: stable/12/sys/i386/i386/initcpu.c ============================================================================== --- stable/12/sys/i386/i386/initcpu.c Wed Oct 21 15:01:33 2020 (r366908) +++ stable/12/sys/i386/i386/initcpu.c Wed Oct 21 15:04:12 2020 (r366909) @@ -721,8 +721,8 @@ initializecpu(void) break; } break; -#ifdef CPU_ATHLON_SSE_HACK case CPU_VENDOR_AMD: +#ifdef CPU_ATHLON_SSE_HACK /* * Sometimes the BIOS doesn't enable SSE instructions. * According to AMD document 20734, the mobile @@ -739,8 +739,16 @@ initializecpu(void) do_cpuid(1, regs); cpu_feature = regs[3]; } - break; #endif + /* + * Detect C1E that breaks APIC. See comment in + * amd64/initcpu.c. + */ + if ((CPUID_TO_FAMILY(cpu_id) == 0xf || + CPUID_TO_FAMILY(cpu_id) == 0x10) && + (cpu_feature2 & CPUID2_HV) == 0) + cpu_amdc1e_bug = 1; + break; case CPU_VENDOR_CENTAUR: init_via(); break; Modified: stable/12/sys/i386/i386/machdep.c ============================================================================== --- stable/12/sys/i386/i386/machdep.c Wed Oct 21 15:01:33 2020 (r366908) +++ stable/12/sys/i386/i386/machdep.c Wed Oct 21 15:04:12 2020 (r366909) @@ -2518,8 +2518,6 @@ init386(int first) thread0.td_pcb->pcb_ext = 0; thread0.td_frame = &proc0_tf; - cpu_probe_amdc1e(); - #ifdef FDT x86_init_fdt(); #endif Modified: stable/12/sys/x86/include/specialreg.h ============================================================================== --- stable/12/sys/x86/include/specialreg.h Wed Oct 21 15:01:33 2020 (r366908) +++ stable/12/sys/x86/include/specialreg.h Wed Oct 21 15:04:12 2020 (r366909) @@ -1078,6 +1078,7 @@ #define MSR_NB_CFG1 0xc001001f /* NB configuration 1 */ #define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */ #define MSR_MC0_CTL_MASK 0xc0010044 +#define MSR_AMDK8_IPM 0xc0010055 #define MSR_P_STATE_LIMIT 0xc0010061 /* P-state Current Limit Register */ #define MSR_P_STATE_CONTROL 0xc0010062 /* P-state Control Register */ #define MSR_P_STATE_STATUS 0xc0010063 /* P-state Status Register */ @@ -1093,6 +1094,9 @@ /* MSR_VM_CR related */ #define VM_CR_SVMDIS 0x10 /* SVM: disabled by BIOS */ + +#define AMDK8_SMIONCMPHALT (1ULL << 27) +#define AMDK8_C1EONCMPHALT (1ULL << 28) /* VIA ACE crypto featureset: for via_feature_rng */ #define VIA_HAS_RNG 1 /* cpu has RNG */ Modified: stable/12/sys/x86/include/x86_var.h ============================================================================== --- stable/12/sys/x86/include/x86_var.h Wed Oct 21 15:01:33 2020 (r366908) +++ stable/12/sys/x86/include/x86_var.h Wed Oct 21 15:04:12 2020 (r366909) @@ -89,6 +89,7 @@ extern int hw_ssb_active; extern int x86_taa_enable; extern int cpu_flush_rsb_ctxsw; extern int x86_rngds_mitg_enable; +extern int cpu_amdc1e_bug; struct pcb; struct thread; Modified: stable/12/sys/x86/x86/cpu_machdep.c ============================================================================== --- stable/12/sys/x86/x86/cpu_machdep.c Wed Oct 21 15:01:33 2020 (r366908) +++ stable/12/sys/x86/x86/cpu_machdep.c Wed Oct 21 15:04:12 2020 (r366909) @@ -485,7 +485,9 @@ cpu_mwait_usable(void) } void (*cpu_idle_hook)(sbintime_t) = NULL; /* ACPI idle hook. */ -static int cpu_ident_amdc1e = 0; /* AMD C1E supported. */ + +int cpu_amdc1e_bug = 0; /* AMD C1E APIC workaround required. */ + static int idle_mwait = 1; /* Use MONITOR/MWAIT for short idle. */ SYSCTL_INT(_machdep, OID_AUTO, idle_mwait, CTLFLAG_RWTUN, &idle_mwait, 0, "Use MONITOR/MWAIT for short idle"); @@ -586,35 +588,6 @@ cpu_idle_spin(sbintime_t sbt) } } -/* - * C1E renders the local APIC timer dead, so we disable it by - * reading the Interrupt Pending Message register and clearing - * both C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27). - * - * Reference: - * "BIOS and Kernel Developer's Guide for AMD NPT Family 0Fh Processors" - * #32559 revision 3.00+ - */ -#define MSR_AMDK8_IPM 0xc0010055 -#define AMDK8_SMIONCMPHALT (1ULL << 27) -#define AMDK8_C1EONCMPHALT (1ULL << 28) -#define AMDK8_CMPHALT (AMDK8_SMIONCMPHALT | AMDK8_C1EONCMPHALT) - -void -cpu_probe_amdc1e(void) -{ - - /* - * Detect the presence of C1E capability mostly on latest - * dual-cores (or future) k8 family. - */ - if (cpu_vendor_id == CPU_VENDOR_AMD && - (cpu_id & 0x00000f00) == 0x00000f00 && - (cpu_id & 0x0fff0000) >= 0x00040000) { - cpu_ident_amdc1e = 1; - } -} - void (*cpu_idle_fn)(sbintime_t) = cpu_idle_acpi; void @@ -644,10 +617,11 @@ cpu_idle(int busy) } /* Apply AMD APIC timer C1E workaround. */ - if (cpu_ident_amdc1e && cpu_disable_c3_sleep) { + if (cpu_amdc1e_bug && cpu_disable_c3_sleep) { msr = rdmsr(MSR_AMDK8_IPM); - if (msr & AMDK8_CMPHALT) - wrmsr(MSR_AMDK8_IPM, msr & ~AMDK8_CMPHALT); + if ((msr & (AMDK8_SMIONCMPHALT | AMDK8_C1EONCMPHALT)) != 0) + wrmsr(MSR_AMDK8_IPM, msr & ~(AMDK8_SMIONCMPHALT | + AMDK8_C1EONCMPHALT)); } /* Call main idle method. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202010211504.09LF4DZh044907>