Page MenuHomeFreeBSD

D26470.id.diff
No OneTemporary

D26470.id.diff

Index: head/sys/amd64/amd64/initcpu.c
===================================================================
--- head/sys/amd64/amd64/initcpu.c
+++ head/sys/amd64/amd64/initcpu.c
@@ -69,6 +69,23 @@
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,
Index: head/sys/amd64/amd64/machdep.c
===================================================================
--- head/sys/amd64/amd64/machdep.c
+++ head/sys/amd64/amd64/machdep.c
@@ -1928,8 +1928,6 @@
if (env != NULL)
strlcpy(kernelname, env, sizeof(kernelname));
- cpu_probe_amdc1e();
-
kcsan_cpu_init(0);
#ifdef FDT
Index: head/sys/i386/i386/initcpu.c
===================================================================
--- head/sys/i386/i386/initcpu.c
+++ head/sys/i386/i386/initcpu.c
@@ -720,8 +720,8 @@
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
@@ -738,8 +738,16 @@
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;
Index: head/sys/i386/i386/machdep.c
===================================================================
--- head/sys/i386/i386/machdep.c
+++ head/sys/i386/i386/machdep.c
@@ -2505,8 +2505,6 @@
thread0.td_pcb->pcb_ext = 0;
thread0.td_frame = &proc0_tf;
- cpu_probe_amdc1e();
-
#ifdef FDT
x86_init_fdt();
#endif
Index: head/sys/x86/include/specialreg.h
===================================================================
--- head/sys/x86/include/specialreg.h
+++ head/sys/x86/include/specialreg.h
@@ -1126,6 +1126,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 */
@@ -1142,6 +1143,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 */
Index: head/sys/x86/include/x86_var.h
===================================================================
--- head/sys/x86/include/x86_var.h
+++ head/sys/x86/include/x86_var.h
@@ -94,6 +94,7 @@
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;
Index: head/sys/x86/x86/cpu_machdep.c
===================================================================
--- head/sys/x86/x86/cpu_machdep.c
+++ head/sys/x86/x86/cpu_machdep.c
@@ -486,7 +486,9 @@
}
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");
@@ -587,35 +589,6 @@
}
}
-/*
- * 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
@@ -645,10 +618,11 @@
}
/* 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. */

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 6, 9:33 PM (1 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30999862
Default Alt Text
D26470.id.diff (5 KB)

Event Timeline