aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2013-03-20 10:07:28 -0400
committerH. Peter Anvin <hpa@zytor.com>2013-04-02 13:12:55 -0400
commit7d7dc116e56c8a1ba4beb36d06a77a48fe5f750b (patch)
treeb04350b348288b521451e859964db024017e834d
parente6ee94d58dfd06ec64c55f91581f00d4f98bf1f6 (diff)
x86, cpu: Convert AMD Erratum 400
Convert AMD erratum 400 to the bug infrastructure. Then, retract all exports for modules since they're not needed now and make the AMD erratum checking machinery local to amd.c. Use forward declarations to avoid shuffling too much code around needlessly. Signed-off-by: Borislav Petkov <bp@suse.de> Link: http://lkml.kernel.org/r/1363788448-31325-7-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/x86/include/asm/cpufeature.h1
-rw-r--r--arch/x86/include/asm/processor.h19
-rw-r--r--arch/x86/kernel/cpu/amd.c23
-rw-r--r--arch/x86/kernel/process.c2
4 files changed, 18 insertions, 27 deletions
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 4cfb5c9f6029..272fdccda5d5 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -226,6 +226,7 @@
226#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ 226#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */
227#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ 227#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */
228#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* AMD Erratum 383 */ 228#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* AMD Erratum 383 */
229#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* AMD Erratum 400 */
229 230
230#if defined(__KERNEL__) && !defined(__ASSEMBLY__) 231#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
231 232
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index e044ef35f91f..22224b3b43bb 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -970,25 +970,6 @@ unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
970 return ratio; 970 return ratio;
971} 971}
972 972
973/*
974 * AMD errata checking
975 */
976#ifdef CONFIG_CPU_SUP_AMD
977extern const int amd_erratum_400[];
978extern bool cpu_has_amd_erratum(const int *);
979
980#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 }
981#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 }
982#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \
983 ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end))
984#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff)
985#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff)
986#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff)
987
988#else
989#define cpu_has_amd_erratum(x) (false)
990#endif /* CONFIG_CPU_SUP_AMD */
991
992extern unsigned long arch_align_stack(unsigned long sp); 973extern unsigned long arch_align_stack(unsigned long sp);
993extern void free_init_pages(char *what, unsigned long begin, unsigned long end); 974extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
994 975
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);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 14ae10031ff0..e718f150c880 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -495,7 +495,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
495 if (x86_idle) 495 if (x86_idle)
496 return; 496 return;
497 497
498 if (cpu_has_amd_erratum(amd_erratum_400)) { 498 if (cpu_has_bug(c, X86_BUG_AMD_APIC_C1E)) {
499 /* E400: APIC timer interrupt does not wake up CPU from C1e */ 499 /* E400: APIC timer interrupt does not wake up CPU from C1e */
500 pr_info("using AMD E400 aware idle routine\n"); 500 pr_info("using AMD E400 aware idle routine\n");
501 x86_idle = amd_e400_idle; 501 x86_idle = amd_e400_idle;