Commit b325e04e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 cpufeature updates from Thomas Gleixner:

 - a workaround for the MONITOR instruction erratum of Goldmont CPUs

 - small fixes and cleanups here and there

* 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/cpu: Add workaround for MONITOR instruction erratum on Goldmont based CPUs
  x86/cpu: Rename "WESTMERE2" family to "NEHALEM_G"
  x86/amd_nb: Clean up init path
  x86/cpufeature: Add helper macro for mask check macros
  x86/cpufeature: Make sure DISABLED/REQUIRED macros are updated
  x86/cpufeature: Update cpufeaure macros
parents 7f7d5564 08e237fa
...@@ -36,11 +36,11 @@ static bool test_intel(int idx) ...@@ -36,11 +36,11 @@ static bool test_intel(int idx)
switch (boot_cpu_data.x86_model) { switch (boot_cpu_data.x86_model) {
case INTEL_FAM6_NEHALEM: case INTEL_FAM6_NEHALEM:
case INTEL_FAM6_NEHALEM_G:
case INTEL_FAM6_NEHALEM_EP: case INTEL_FAM6_NEHALEM_EP:
case INTEL_FAM6_NEHALEM_EX: case INTEL_FAM6_NEHALEM_EX:
case INTEL_FAM6_WESTMERE: case INTEL_FAM6_WESTMERE:
case INTEL_FAM6_WESTMERE2:
case INTEL_FAM6_WESTMERE_EP: case INTEL_FAM6_WESTMERE_EP:
case INTEL_FAM6_WESTMERE_EX: case INTEL_FAM6_WESTMERE_EX:
......
...@@ -49,43 +49,59 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; ...@@ -49,43 +49,59 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
#define test_cpu_cap(c, bit) \ #define test_cpu_cap(c, bit) \
test_bit(bit, (unsigned long *)((c)->x86_capability)) test_bit(bit, (unsigned long *)((c)->x86_capability))
#define REQUIRED_MASK_BIT_SET(bit) \ /*
( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0 )) || \ * There are 32 bits/features in each mask word. The high bits
(((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1 )) || \ * (selected with (bit>>5) give us the word number and the low 5
(((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2 )) || \ * bits give us the bit/feature number inside the word.
(((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3 )) || \ * (1UL<<((bit)&31) gives us a mask for the feature_bit so we can
(((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4 )) || \ * see if it is set in the mask word.
(((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5 )) || \ */
(((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6 )) || \ #define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
(((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7 )) || \ (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
(((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8 )) || \
(((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9 )) || \ #define REQUIRED_MASK_BIT_SET(feature_bit) \
(((bit)>>5)==10 && (1UL<<((bit)&31) & REQUIRED_MASK10)) || \ ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 0, feature_bit) || \
(((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 1, feature_bit) || \
(((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 2, feature_bit) || \
(((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 3, feature_bit) || \
(((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK14)) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 4, feature_bit) || \
(((bit)>>5)==15 && (1UL<<((bit)&31) & REQUIRED_MASK15)) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 5, feature_bit) || \
(((bit)>>5)==16 && (1UL<<((bit)&31) & REQUIRED_MASK16)) ) CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 6, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 7, feature_bit) || \
#define DISABLED_MASK_BIT_SET(bit) \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 8, feature_bit) || \
( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 9, feature_bit) || \
(((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 10, feature_bit) || \
(((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 11, feature_bit) || \
(((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 12, feature_bit) || \
(((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 13, feature_bit) || \
(((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 14, feature_bit) || \
(((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) || \
(((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \
(((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8 )) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \
(((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9 )) || \ REQUIRED_MASK_CHECK || \
(((bit)>>5)==10 && (1UL<<((bit)&31) & DISABLED_MASK10)) || \ BUILD_BUG_ON_ZERO(NCAPINTS != 18))
(((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) || \
(((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) || \ #define DISABLED_MASK_BIT_SET(feature_bit) \
(((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) || \ ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
(((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK14)) || \ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 1, feature_bit) || \
(((bit)>>5)==15 && (1UL<<((bit)&31) & DISABLED_MASK15)) || \ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 2, feature_bit) || \
(((bit)>>5)==16 && (1UL<<((bit)&31) & DISABLED_MASK16)) ) CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 3, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 4, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 5, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 6, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 7, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 8, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 9, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 10, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 11, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 12, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 13, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 14, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \
DISABLED_MASK_CHECK || \
BUILD_BUG_ON_ZERO(NCAPINTS != 18))
#define cpu_has(c, bit) \ #define cpu_has(c, bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
......
...@@ -309,5 +309,5 @@ ...@@ -309,5 +309,5 @@
#endif #endif
#define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */ #define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */
#define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */ #define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */
#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */
#endif /* _ASM_X86_CPUFEATURES_H */ #endif /* _ASM_X86_CPUFEATURES_H */
...@@ -56,5 +56,7 @@ ...@@ -56,5 +56,7 @@
#define DISABLED_MASK14 0 #define DISABLED_MASK14 0
#define DISABLED_MASK15 0 #define DISABLED_MASK15 0
#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE) #define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)
#define DISABLED_MASK17 0
#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
#endif /* _ASM_X86_DISABLED_FEATURES_H */ #endif /* _ASM_X86_DISABLED_FEATURES_H */
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* "Extreme" ones, like Broadwell-E. * "Extreme" ones, like Broadwell-E.
* *
* Things ending in "2" are usually because we have no better * Things ending in "2" are usually because we have no better
* name for them. There's no processor called "WESTMERE2". * name for them. There's no processor called "SILVERMONT2".
*/ */
#define INTEL_FAM6_CORE_YONAH 0x0E #define INTEL_FAM6_CORE_YONAH 0x0E
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
#define INTEL_FAM6_CORE2_DUNNINGTON 0x1D #define INTEL_FAM6_CORE2_DUNNINGTON 0x1D
#define INTEL_FAM6_NEHALEM 0x1E #define INTEL_FAM6_NEHALEM 0x1E
#define INTEL_FAM6_NEHALEM_G 0x1F /* Auburndale / Havendale */
#define INTEL_FAM6_NEHALEM_EP 0x1A #define INTEL_FAM6_NEHALEM_EP 0x1A
#define INTEL_FAM6_NEHALEM_EX 0x2E #define INTEL_FAM6_NEHALEM_EX 0x2E
#define INTEL_FAM6_WESTMERE 0x25 #define INTEL_FAM6_WESTMERE 0x25
#define INTEL_FAM6_WESTMERE2 0x1F
#define INTEL_FAM6_WESTMERE_EP 0x2C #define INTEL_FAM6_WESTMERE_EP 0x2C
#define INTEL_FAM6_WESTMERE_EX 0x2F #define INTEL_FAM6_WESTMERE_EX 0x2F
......
...@@ -97,7 +97,7 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx) ...@@ -97,7 +97,7 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
*/ */
static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
{ {
if (!current_set_polling_and_test()) { if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) { if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) {
mb(); mb();
clflush((void *)&current_thread_info()->flags); clflush((void *)&current_thread_info()->flags);
......
...@@ -99,5 +99,7 @@ ...@@ -99,5 +99,7 @@
#define REQUIRED_MASK14 0 #define REQUIRED_MASK14 0
#define REQUIRED_MASK15 0 #define REQUIRED_MASK15 0
#define REQUIRED_MASK16 0 #define REQUIRED_MASK16 0
#define REQUIRED_MASK17 0
#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
#endif /* _ASM_X86_REQUIRED_FEATURES_H */ #endif /* _ASM_X86_REQUIRED_FEATURES_H */
...@@ -219,24 +219,22 @@ int amd_set_subcaches(int cpu, unsigned long mask) ...@@ -219,24 +219,22 @@ int amd_set_subcaches(int cpu, unsigned long mask)
return 0; return 0;
} }
static int amd_cache_gart(void) static void amd_cache_gart(void)
{ {
u16 i; u16 i;
if (!amd_nb_has_feature(AMD_NB_GART)) if (!amd_nb_has_feature(AMD_NB_GART))
return 0; return;
flush_words = kmalloc(amd_nb_num() * sizeof(u32), GFP_KERNEL);
if (!flush_words) {
amd_northbridges.flags &= ~AMD_NB_GART;
return -ENOMEM;
}
for (i = 0; i != amd_nb_num(); i++) flush_words = kmalloc(amd_nb_num() * sizeof(u32), GFP_KERNEL);
pci_read_config_dword(node_to_amd_nb(i)->misc, 0x9c, if (!flush_words) {
&flush_words[i]); amd_northbridges.flags &= ~AMD_NB_GART;
pr_notice("Cannot initialize GART flush words, GART support disabled\n");
return;
}
return 0; for (i = 0; i != amd_nb_num(); i++)
pci_read_config_dword(node_to_amd_nb(i)->misc, 0x9c, &flush_words[i]);
} }
void amd_flush_garts(void) void amd_flush_garts(void)
...@@ -278,17 +276,10 @@ EXPORT_SYMBOL_GPL(amd_flush_garts); ...@@ -278,17 +276,10 @@ EXPORT_SYMBOL_GPL(amd_flush_garts);
static __init int init_amd_nbs(void) static __init int init_amd_nbs(void)
{ {
int err = 0; amd_cache_northbridges();
amd_cache_gart();
err = amd_cache_northbridges(); return 0;
if (err < 0)
pr_notice("Cannot enumerate AMD northbridges\n");
if (amd_cache_gart() < 0)
pr_notice("Cannot initialize GART flush words, GART support disabled\n");
return err;
} }
/* This has to go after the PCI subsystem */ /* This has to go after the PCI subsystem */
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/bugs.h> #include <asm/bugs.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/intel-family.h>
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
#include <linux/topology.h> #include <linux/topology.h>
...@@ -508,6 +509,10 @@ static void init_intel(struct cpuinfo_x86 *c) ...@@ -508,6 +509,10 @@ static void init_intel(struct cpuinfo_x86 *c)
(c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47)) (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47))
set_cpu_bug(c, X86_BUG_CLFLUSH_MONITOR); set_cpu_bug(c, X86_BUG_CLFLUSH_MONITOR);
if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_MWAIT) &&
((c->x86_model == INTEL_FAM6_ATOM_GOLDMONT)))
set_cpu_bug(c, X86_BUG_MONITOR);
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
if (c->x86 == 15) if (c->x86 == 15)
c->x86_cache_alignment = c->x86_clflush_size * 2; c->x86_cache_alignment = c->x86_clflush_size * 2;
......
...@@ -404,7 +404,7 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c) ...@@ -404,7 +404,7 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
if (c->x86_vendor != X86_VENDOR_INTEL) if (c->x86_vendor != X86_VENDOR_INTEL)
return 0; return 0;
if (!cpu_has(c, X86_FEATURE_MWAIT)) if (!cpu_has(c, X86_FEATURE_MWAIT) || static_cpu_has_bug(X86_BUG_MONITOR))
return 0; return 0;
return 1; return 1;
......
...@@ -1055,7 +1055,7 @@ static const struct idle_cpu idle_cpu_dnv = { ...@@ -1055,7 +1055,7 @@ static const struct idle_cpu idle_cpu_dnv = {
static const struct x86_cpu_id intel_idle_ids[] __initconst = { static const struct x86_cpu_id intel_idle_ids[] __initconst = {
ICPU(INTEL_FAM6_NEHALEM_EP, idle_cpu_nehalem), ICPU(INTEL_FAM6_NEHALEM_EP, idle_cpu_nehalem),
ICPU(INTEL_FAM6_NEHALEM, idle_cpu_nehalem), ICPU(INTEL_FAM6_NEHALEM, idle_cpu_nehalem),
ICPU(INTEL_FAM6_WESTMERE2, idle_cpu_nehalem), ICPU(INTEL_FAM6_NEHALEM_G, idle_cpu_nehalem),
ICPU(INTEL_FAM6_WESTMERE, idle_cpu_nehalem), ICPU(INTEL_FAM6_WESTMERE, idle_cpu_nehalem),
ICPU(INTEL_FAM6_WESTMERE_EP, idle_cpu_nehalem), ICPU(INTEL_FAM6_WESTMERE_EP, idle_cpu_nehalem),
ICPU(INTEL_FAM6_NEHALEM_EX, idle_cpu_nehalem), ICPU(INTEL_FAM6_NEHALEM_EX, idle_cpu_nehalem),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment