Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x86/x86 On certain AMD f10h CPUs (like mine), the B...
details: https://anonhg.NetBSD.org/src/rev/dd7c1d93e9ee
branches: trunk
changeset: 447489:dd7c1d93e9ee
user: maxv <maxv%NetBSD.org@localhost>
date: Sun Jan 13 12:16:58 2019 +0000
description:
On certain AMD f10h CPUs (like mine), the BIOS does not enable WC+. It
means that the guest pages that are WC+ become CD, and this degrades
performance of the guests.
Explicitly enable WC+.
While here clarify the AMD identification code.
diffstat:
sys/arch/x86/x86/identcpu.c | 63 +++++++++++++++++++++++++-------------------
1 files changed, 36 insertions(+), 27 deletions(-)
diffs (103 lines):
diff -r ca9c42bae2e0 -r dd7c1d93e9ee sys/arch/x86/x86/identcpu.c
--- a/sys/arch/x86/x86/identcpu.c Sun Jan 13 11:03:20 2019 +0000
+++ b/sys/arch/x86/x86/identcpu.c Sun Jan 13 12:16:58 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: identcpu.c,v 1.85 2019/01/06 16:13:51 maxv Exp $ */
+/* $NetBSD: identcpu.c,v 1.86 2019/01/13 12:16:58 maxv Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.85 2019/01/06 16:13:51 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.86 2019/01/13 12:16:58 maxv Exp $");
#include "opt_xen.h"
@@ -354,41 +354,51 @@
}
static void
-cpu_probe_k5(struct cpu_info *ci)
+cpu_probe_amd(struct cpu_info *ci)
{
+ uint64_t val;
int flag;
- if (cpu_vendor != CPUVENDOR_AMD ||
- CPUID_TO_FAMILY(ci->ci_signature) != 5)
+ if (cpu_vendor != CPUVENDOR_AMD)
+ return;
+ if (CPUID_TO_FAMILY(ci->ci_signature) < 5)
return;
- if (CPUID_TO_MODEL(ci->ci_signature) == 0) {
+ switch (CPUID_TO_FAMILY(ci->ci_signature)) {
+ case 0x05: /* K5 */
+ if (CPUID_TO_MODEL(ci->ci_signature) == 0) {
+ /*
+ * According to the AMD Processor Recognition App Note,
+ * the AMD-K5 Model 0 uses the wrong bit to indicate
+ * support for global PTEs, instead using bit 9 (APIC)
+ * rather than bit 13 (i.e. "0x200" vs. 0x2000").
+ */
+ flag = ci->ci_feat_val[0];
+ if ((flag & CPUID_APIC) != 0)
+ flag = (flag & ~CPUID_APIC) | CPUID_PGE;
+ ci->ci_feat_val[0] = flag;
+ }
+ break;
+
+ case 0x10: /* Family 10h */
/*
- * According to the AMD Processor Recognition App Note,
- * the AMD-K5 Model 0 uses the wrong bit to indicate
- * support for global PTEs, instead using bit 9 (APIC)
- * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!).
+ * On Family 10h, certain BIOSes do not enable WC+ support.
+ * This causes WC+ to become CD, and degrades guest
+ * performance at the NPT level.
+ *
+ * Explicitly enable WC+ if we're not a guest.
*/
- flag = ci->ci_feat_val[0];
- if ((flag & CPUID_APIC) != 0)
- flag = (flag & ~CPUID_APIC) | CPUID_PGE;
- ci->ci_feat_val[0] = flag;
+ if (!ISSET(ci->ci_feat_val[1], CPUID2_RAZ)) {
+ val = rdmsr(MSR_BU_CFG2);
+ val &= ~BU_CFG2_CWPLUS_DIS;
+ wrmsr(MSR_BU_CFG2, val);
+ }
+ break;
}
cpu_probe_amd_cache(ci);
}
-static void
-cpu_probe_k678(struct cpu_info *ci)
-{
-
- if (cpu_vendor != CPUVENDOR_AMD ||
- CPUID_TO_FAMILY(ci->ci_signature) < 6)
- return;
-
- cpu_probe_amd_cache(ci);
-}
-
static inline uint8_t
cyrix_read_reg(uint8_t reg)
{
@@ -956,8 +966,7 @@
}
cpu_probe_intel(ci);
- cpu_probe_k5(ci);
- cpu_probe_k678(ci);
+ cpu_probe_amd(ci);
cpu_probe_cyrix(ci);
cpu_probe_winchip(ci);
cpu_probe_c3(ci);
Home |
Main Index |
Thread Index |
Old Index