aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/amd.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/amd.c')
-rw-r--r--arch/x86/kernel/cpu/amd.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 85f84e13d2dd..9a2a71669c5d 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -514,6 +514,8 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
514} 514}
515 515
516static const int amd_erratum_383[]; 516static const int amd_erratum_383[];
517static const int amd_erratum_400[];
518static bool cpu_has_amd_erratum(const int *erratum);
517 519
518static void __cpuinit init_amd(struct cpuinfo_x86 *c) 520static void __cpuinit init_amd(struct cpuinfo_x86 *c)
519{ 521{
@@ -734,6 +736,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
734 set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); 736 set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH);
735 } 737 }
736 738
739 if (cpu_has_amd_erratum(amd_erratum_400))
740 set_cpu_bug(c, X86_BUG_AMD_APIC_C1E);
741
737 rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); 742 rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
738} 743}
739 744
@@ -852,8 +857,7 @@ cpu_dev_register(amd_cpu_dev);
852 * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that 857 * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that
853 * have an OSVW id assigned, which it takes as first argument. Both take a 858 * have an OSVW id assigned, which it takes as first argument. Both take a
854 * variable number of family-specific model-stepping ranges created by 859 * variable number of family-specific model-stepping ranges created by
855 * AMD_MODEL_RANGE(). Each erratum also has to be declared as extern const 860 * AMD_MODEL_RANGE().
856 * int[] in arch/x86/include/asm/processor.h.
857 * 861 *
858 * Example: 862 * Example:
859 * 863 *
@@ -863,15 +867,22 @@ cpu_dev_register(amd_cpu_dev);
863 * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); 867 * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0));
864 */ 868 */
865 869
866const int amd_erratum_400[] = 870#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 }
871#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 }
872#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \
873 ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end))
874#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff)
875#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff)
876#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff)
877
878static const int amd_erratum_400[] =
867 AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), 879 AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf),
868 AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); 880 AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf));
869EXPORT_SYMBOL_GPL(amd_erratum_400);
870 881
871static const int amd_erratum_383[] = 882static const int amd_erratum_383[] =
872 AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); 883 AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
873 884
874bool cpu_has_amd_erratum(const int *erratum) 885static bool cpu_has_amd_erratum(const int *erratum)
875{ 886{
876 struct cpuinfo_x86 *cpu = __this_cpu_ptr(&cpu_info); 887 struct cpuinfo_x86 *cpu = __this_cpu_ptr(&cpu_info);
877 int osvw_id = *erratum++; 888 int osvw_id = *erratum++;
@@ -912,5 +923,3 @@ bool cpu_has_amd_erratum(const int *erratum)
912 923
913 return false; 924 return false;
914} 925}
915
916EXPORT_SYMBOL_GPL(cpu_has_amd_erratum);