diff options
Diffstat (limited to 'arch/x86/kernel/cpu/intel.c')
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 24ff26a38ade..c1c04bf0df77 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/string.h> | 4 | #include <linux/string.h> |
5 | #include <linux/bitops.h> | 5 | #include <linux/bitops.h> |
6 | #include <linux/smp.h> | 6 | #include <linux/smp.h> |
7 | #include <linux/sched.h> | ||
7 | #include <linux/thread_info.h> | 8 | #include <linux/thread_info.h> |
8 | #include <linux/module.h> | 9 | #include <linux/module.h> |
9 | 10 | ||
@@ -13,6 +14,7 @@ | |||
13 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
14 | #include <asm/ds.h> | 15 | #include <asm/ds.h> |
15 | #include <asm/bugs.h> | 16 | #include <asm/bugs.h> |
17 | #include <asm/cpu.h> | ||
16 | 18 | ||
17 | #ifdef CONFIG_X86_64 | 19 | #ifdef CONFIG_X86_64 |
18 | #include <asm/topology.h> | 20 | #include <asm/topology.h> |
@@ -24,7 +26,6 @@ | |||
24 | #ifdef CONFIG_X86_LOCAL_APIC | 26 | #ifdef CONFIG_X86_LOCAL_APIC |
25 | #include <asm/mpspec.h> | 27 | #include <asm/mpspec.h> |
26 | #include <asm/apic.h> | 28 | #include <asm/apic.h> |
27 | #include <mach_apic.h> | ||
28 | #endif | 29 | #endif |
29 | 30 | ||
30 | static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | 31 | static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) |
@@ -56,13 +57,30 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | |||
56 | 57 | ||
57 | /* | 58 | /* |
58 | * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate | 59 | * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate |
59 | * with P/T states and does not stop in deep C-states | 60 | * with P/T states and does not stop in deep C-states. |
61 | * | ||
62 | * It is also reliable across cores and sockets. (but not across | ||
63 | * cabinets - we turn it off in that case explicitly.) | ||
60 | */ | 64 | */ |
61 | if (c->x86_power & (1 << 8)) { | 65 | if (c->x86_power & (1 << 8)) { |
62 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 66 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); |
63 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); | 67 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); |
68 | set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE); | ||
69 | sched_clock_stable = 1; | ||
64 | } | 70 | } |
65 | 71 | ||
72 | /* | ||
73 | * There is a known erratum on Pentium III and Core Solo | ||
74 | * and Core Duo CPUs. | ||
75 | * " Page with PAT set to WC while associated MTRR is UC | ||
76 | * may consolidate to UC " | ||
77 | * Because of this erratum, it is better to stick with | ||
78 | * setting WC in MTRR rather than using PAT on these CPUs. | ||
79 | * | ||
80 | * Enable PAT WC only on P4, Core 2 or later CPUs. | ||
81 | */ | ||
82 | if (c->x86 == 6 && c->x86_model < 15) | ||
83 | clear_cpu_cap(c, X86_FEATURE_PAT); | ||
66 | } | 84 | } |
67 | 85 | ||
68 | #ifdef CONFIG_X86_32 | 86 | #ifdef CONFIG_X86_32 |
@@ -99,6 +117,28 @@ static void __cpuinit trap_init_f00f_bug(void) | |||
99 | } | 117 | } |
100 | #endif | 118 | #endif |
101 | 119 | ||
120 | static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c) | ||
121 | { | ||
122 | #ifdef CONFIG_SMP | ||
123 | /* calling is from identify_secondary_cpu() ? */ | ||
124 | if (c->cpu_index == boot_cpu_id) | ||
125 | return; | ||
126 | |||
127 | /* | ||
128 | * Mask B, Pentium, but not Pentium MMX | ||
129 | */ | ||
130 | if (c->x86 == 5 && | ||
131 | c->x86_mask >= 1 && c->x86_mask <= 4 && | ||
132 | c->x86_model <= 3) { | ||
133 | /* | ||
134 | * Remember we have B step Pentia with bugs | ||
135 | */ | ||
136 | WARN_ONCE(1, "WARNING: SMP operation may be unreliable" | ||
137 | "with B stepping processors.\n"); | ||
138 | } | ||
139 | #endif | ||
140 | } | ||
141 | |||
102 | static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) | 142 | static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) |
103 | { | 143 | { |
104 | unsigned long lo, hi; | 144 | unsigned long lo, hi; |
@@ -135,10 +175,10 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) | |||
135 | */ | 175 | */ |
136 | if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { | 176 | if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { |
137 | rdmsr(MSR_IA32_MISC_ENABLE, lo, hi); | 177 | rdmsr(MSR_IA32_MISC_ENABLE, lo, hi); |
138 | if ((lo & (1<<9)) == 0) { | 178 | if ((lo & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE) == 0) { |
139 | printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); | 179 | printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); |
140 | printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); | 180 | printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); |
141 | lo |= (1<<9); /* Disable hw prefetching */ | 181 | lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE; |
142 | wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); | 182 | wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); |
143 | } | 183 | } |
144 | } | 184 | } |
@@ -175,6 +215,8 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) | |||
175 | #ifdef CONFIG_X86_NUMAQ | 215 | #ifdef CONFIG_X86_NUMAQ |
176 | numaq_tsc_disable(); | 216 | numaq_tsc_disable(); |
177 | #endif | 217 | #endif |
218 | |||
219 | intel_smp_check(c); | ||
178 | } | 220 | } |
179 | #else | 221 | #else |
180 | static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) | 222 | static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) |