diff options
Diffstat (limited to 'arch/x86/kernel/cpu/amd.c')
-rw-r--r-- | arch/x86/kernel/cpu/amd.c | 23 |
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 | ||
516 | static const int amd_erratum_383[]; | 516 | static const int amd_erratum_383[]; |
517 | static const int amd_erratum_400[]; | ||
518 | static bool cpu_has_amd_erratum(const int *erratum); | ||
517 | 519 | ||
518 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | 520 | static 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 | ||
866 | const 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 | |||
878 | static 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)); |
869 | EXPORT_SYMBOL_GPL(amd_erratum_400); | ||
870 | 881 | ||
871 | static const int amd_erratum_383[] = | 882 | static 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 | ||
874 | bool cpu_has_amd_erratum(const int *erratum) | 885 | static 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 | |||
916 | EXPORT_SYMBOL_GPL(cpu_has_amd_erratum); | ||