svn commit: r366909 - in stable/12/sys: amd64/amd64 i386/i386 x86/include x86/x86
Konstantin Belousov
kib at FreeBSD.org
Wed Oct 21 15:04:15 UTC 2020
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. */
More information about the svn-src-stable-12
mailing list