summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorHans Rosenfeld <rosenfeld@grumpf.hope-2000.org>2012-03-29 05:29:08 -0500
committerHans Rosenfeld <rosenfeld@grumpf.hope-2000.org>2012-03-29 05:29:08 -0500
commit5e54b56d6254caa06251211530e584534f39fba3 (patch)
tree79ce6b6f3619ee9ffe36fd5add03e3f75436c0dd /usr/src
parent5e53ed34920bc03b619b50f459f2475e7bf80b6f (diff)
downloadillumos-joyent-5e54b56d6254caa06251211530e584534f39fba3.tar.gz
2449 Add workaround for AMD K10 CPU erratum 721
Reviewed by: Dan McDonald <danmcd@nexenta.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Albert Lee <trisk@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/i86pc/Makefile.workarounds7
-rw-r--r--usr/src/uts/i86pc/os/cpuid.c7
-rw-r--r--usr/src/uts/i86pc/os/mp_startup.c18
-rw-r--r--usr/src/uts/intel/sys/controlregs.h4
4 files changed, 34 insertions, 2 deletions
diff --git a/usr/src/uts/i86pc/Makefile.workarounds b/usr/src/uts/i86pc/Makefile.workarounds
index aed875925c..2300e74393 100644
--- a/usr/src/uts/i86pc/Makefile.workarounds
+++ b/usr/src/uts/i86pc/Makefile.workarounds
@@ -21,8 +21,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# This makefile contains workaround defines to be shared
# by Makefile.i86pc and the genunix Makefile.
#
@@ -117,3 +115,8 @@ WORKAROUND_DEFS += -DOPTERON_ERRATUM_172
# Accessed or Dirty Bit.
#
WORKAROUND_DEFS += -DOPTERON_ERRATUM_298
+
+#
+# Processor May Incorrectly Update Stack Pointer
+#
+WORKAROUND_DEFS += -DOPTERON_ERRATUM_721
diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c
index 0a389e0063..b88c8c022b 100644
--- a/usr/src/uts/i86pc/os/cpuid.c
+++ b/usr/src/uts/i86pc/os/cpuid.c
@@ -3336,6 +3336,13 @@ cpuid_opteron_erratum(cpu_t *cpu, uint_t erratum)
return (DR_AX(eax) || DR_B0(eax) || DR_B1(eax) || DR_BA(eax) ||
DR_B2(eax) || RB_C0(eax));
+ case 721:
+#if defined(__amd64)
+ return (cpi->cpi_family == 0x10 || cpi->cpi_family == 0x12);
+#else
+ return (0);
+#endif
+
default:
return (-1);
diff --git a/usr/src/uts/i86pc/os/mp_startup.c b/usr/src/uts/i86pc/os/mp_startup.c
index 843c5ae73a..588d38bb7a 100644
--- a/usr/src/uts/i86pc/os/mp_startup.c
+++ b/usr/src/uts/i86pc/os/mp_startup.c
@@ -649,6 +649,10 @@ int opteron_workaround_6323525; /* if non-zero -> at least one cpu has it */
int opteron_erratum_298;
#endif
+#if defined(OPTERON_ERRATUM_721)
+int opteron_erratum_721;
+#endif
+
static void
workaround_warning(cpu_t *cp, uint_t erratum)
{
@@ -1177,6 +1181,16 @@ workaround_errata(struct cpu *cpu)
missing += do_erratum_298(cpu);
+ if (cpuid_opteron_erratum(cpu, 721) > 0) {
+#if defined(OPTERON_ERRATUM_721)
+ wrmsr(MSR_AMD_DE_CFG, rdmsr(MSR_AMD_DE_CFG) | AMD_DE_CFG_E721);
+ opteron_erratum_721++;
+#else
+ workaround_warning(cpu, 721);
+ missing++;
+#endif
+ }
+
#ifdef __xpv
return (0);
#else
@@ -1267,6 +1281,10 @@ workaround_errata_end()
" system\noperation may occur.\n");
}
#endif
+#if defined(OPTERON_ERRATUM_721)
+ if (opteron_erratum_721)
+ workaround_applied(721);
+#endif
}
/*
diff --git a/usr/src/uts/intel/sys/controlregs.h b/usr/src/uts/intel/sys/controlregs.h
index aa9ab14a89..d84bba7d3a 100644
--- a/usr/src/uts/intel/sys/controlregs.h
+++ b/usr/src/uts/intel/sys/controlregs.h
@@ -209,6 +209,10 @@ extern "C" {
#define AMD_BU_CFG_E298 (UINT64_C(1) << 1)
+#define MSR_AMD_DE_CFG 0xc0011029
+
+#define AMD_DE_CFG_E721 (UINT64_C(1))
+
/* AMD's osvw MSRs */
#define MSR_AMD_OSVW_ID_LEN 0xc0010140
#define MSR_AMD_OSVW_STATUS 0xc0010141