aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-09-09 19:40:38 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-10 02:21:06 -0400
commit4052704d92c3172ebc13cc0cc8df8ba2bd446a5c (patch)
tree79747c641eda4de67e1b37b06a0cf45aa6fb812e /arch
parent879d792b66d633bbe466974f61d1acc9aa8c78eb (diff)
x86: intel.c put workaround for old cpus together
consolidate the code some more. No change in functionality intended. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/intel.c192
1 files changed, 98 insertions, 94 deletions
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 365a008080c2..5f76bf139fda 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -63,15 +63,54 @@ int __cpuinit ppro_with_ram_bug(void)
63 return 0; 63 return 0;
64} 64}
65 65
66#ifdef CONFIG_X86_F00F_BUG
67static void __cpuinit trap_init_f00f_bug(void)
68{
69 __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
66 70
67/* 71 /*
68 * P4 Xeon errata 037 workaround. 72 * Update the IDT descriptor and reload the IDT so that
69 * Hardware prefetcher may cause stale data to be loaded into the cache. 73 * it uses the read-only mapped virtual address.
70 */ 74 */
71static void __cpuinit Intel_errata_workarounds(struct cpuinfo_x86 *c) 75 idt_descr.address = fix_to_virt(FIX_F00F_IDT);
76 load_idt(&idt_descr);
77}
78#endif
79
80static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
72{ 81{
73 unsigned long lo, hi; 82 unsigned long lo, hi;
74 83
84#ifdef CONFIG_X86_F00F_BUG
85 /*
86 * All current models of Pentium and Pentium with MMX technology CPUs
87 * have the F0 0F bug, which lets nonprivileged users lock up the system.
88 * Note that the workaround only should be initialized once...
89 */
90 c->f00f_bug = 0;
91 if (!paravirt_enabled() && c->x86 == 5) {
92 static int f00f_workaround_enabled;
93
94 c->f00f_bug = 1;
95 if (!f00f_workaround_enabled) {
96 trap_init_f00f_bug();
97 printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
98 f00f_workaround_enabled = 1;
99 }
100 }
101#endif
102
103 /*
104 * SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until
105 * model 3 mask 3
106 */
107 if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
108 clear_cpu_cap(c, X86_FEATURE_SEP);
109
110 /*
111 * P4 Xeon errata 037 workaround.
112 * Hardware prefetcher may cause stale data to be loaded into the cache.
113 */
75 if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { 114 if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) {
76 rdmsr(MSR_IA32_MISC_ENABLE, lo, hi); 115 rdmsr(MSR_IA32_MISC_ENABLE, lo, hi);
77 if ((lo & (1<<9)) == 0) { 116 if ((lo & (1<<9)) == 0) {
@@ -81,23 +120,44 @@ static void __cpuinit Intel_errata_workarounds(struct cpuinfo_x86 *c)
81 wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); 120 wrmsr (MSR_IA32_MISC_ENABLE, lo, hi);
82 } 121 }
83 } 122 }
84}
85
86 123
124 /*
125 * See if we have a good local APIC by checking for buggy Pentia,
126 * i.e. all B steppings and the C2 stepping of P54C when using their
127 * integrated APIC (see 11AP erratum in "Pentium Processor
128 * Specification Update").
129 */
130 if (cpu_has_apic && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
131 (c->x86_mask < 0x6 || c->x86_mask == 0xb))
132 set_cpu_cap(c, X86_FEATURE_11AP);
87 133
88#ifdef CONFIG_X86_F00F_BUG
89static void __cpuinit trap_init_f00f_bug(void)
90{
91 __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
92 134
135#ifdef CONFIG_X86_INTEL_USERCOPY
93 /* 136 /*
94 * Update the IDT descriptor and reload the IDT so that 137 * Set up the preferred alignment for movsl bulk memory moves
95 * it uses the read-only mapped virtual address.
96 */ 138 */
97 idt_descr.address = fix_to_virt(FIX_F00F_IDT); 139 switch (c->x86) {
98 load_idt(&idt_descr); 140 case 4: /* 486: untested */
99} 141 break;
142 case 5: /* Old Pentia: untested */
143 break;
144 case 6: /* PII/PIII only like movsl with 8-byte alignment */
145 movsl_mask.mask = 7;
146 break;
147 case 15: /* P4 is OK down to 8-byte alignment */
148 movsl_mask.mask = 7;
149 break;
150 }
100#endif 151#endif
152
153#ifdef CONFIG_X86_NUMAQ
154 numaq_tsc_disable();
155#endif
156}
157#else
158static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
159{
160}
101#endif 161#endif
102 162
103static void __cpuinit srat_detect_node(void) 163static void __cpuinit srat_detect_node(void)
@@ -139,28 +199,10 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
139static void __cpuinit init_intel(struct cpuinfo_x86 *c) 199static void __cpuinit init_intel(struct cpuinfo_x86 *c)
140{ 200{
141 unsigned int l2 = 0; 201 unsigned int l2 = 0;
142 char *p = NULL;
143 202
144 early_init_intel(c); 203 early_init_intel(c);
145 204
146#ifdef CONFIG_X86_F00F_BUG 205 intel_workarounds(c);
147 /*
148 * All current models of Pentium and Pentium with MMX technology CPUs
149 * have the F0 0F bug, which lets nonprivileged users lock up the system.
150 * Note that the workaround only should be initialized once...
151 */
152 c->f00f_bug = 0;
153 if (!paravirt_enabled() && c->x86 == 5) {
154 static int f00f_workaround_enabled;
155
156 c->f00f_bug = 1;
157 if (!f00f_workaround_enabled) {
158 trap_init_f00f_bug();
159 printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
160 f00f_workaround_enabled = 1;
161 }
162 }
163#endif
164 206
165 l2 = init_intel_cacheinfo(c); 207 l2 = init_intel_cacheinfo(c);
166 if (c->cpuid_level > 9) { 208 if (c->cpuid_level > 9) {
@@ -170,17 +212,32 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
170 set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); 212 set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
171 } 213 }
172 214
173#ifdef CONFIG_X86_32 215 if (cpu_has_xmm2)
174 /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */ 216 set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
175 if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) 217 if (cpu_has_ds) {
176 clear_cpu_cap(c, X86_FEATURE_SEP); 218 unsigned int l1;
219 rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
220 if (!(l1 & (1<<11)))
221 set_cpu_cap(c, X86_FEATURE_BTS);
222 if (!(l1 & (1<<12)))
223 set_cpu_cap(c, X86_FEATURE_PEBS);
224 ds_init_intel(c);
225 }
177 226
227#ifdef CONFIG_X86_64
228 if (c->x86 == 15)
229 c->x86_cache_alignment = c->x86_clflush_size * 2;
230 if (c->x86 == 6)
231 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
232#else
178 /* 233 /*
179 * Names for the Pentium II/Celeron processors 234 * Names for the Pentium II/Celeron processors
180 * detectable only by also checking the cache size. 235 * detectable only by also checking the cache size.
181 * Dixon is NOT a Celeron. 236 * Dixon is NOT a Celeron.
182 */ 237 */
183 if (c->x86 == 6) { 238 if (c->x86 == 6) {
239 char *p = NULL;
240
184 switch (c->x86_model) { 241 switch (c->x86_model) {
185 case 5: 242 case 5:
186 if (c->x86_mask == 0) { 243 if (c->x86_mask == 0) {
@@ -203,51 +260,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
203 p = "Celeron (Coppermine)"; 260 p = "Celeron (Coppermine)";
204 break; 261 break;
205 } 262 }
206 }
207 263
208 if (p) 264 if (p)
209 strcpy(c->x86_model_id, p); 265 strcpy(c->x86_model_id, p);
210
211 Intel_errata_workarounds(c);
212
213#ifdef CONFIG_X86_INTEL_USERCOPY
214 /*
215 * Set up the preferred alignment for movsl bulk memory moves
216 */
217 switch (c->x86) {
218 case 4: /* 486: untested */
219 break;
220 case 5: /* Old Pentia: untested */
221 break;
222 case 6: /* PII/PIII only like movsl with 8-byte alignment */
223 movsl_mask.mask = 7;
224 break;
225 case 15: /* P4 is OK down to 8-byte alignment */
226 movsl_mask.mask = 7;
227 break;
228 } 266 }
229#endif
230
231#endif
232 267
233 if (cpu_has_xmm2)
234 set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
235 if (cpu_has_ds) {
236 unsigned int l1;
237 rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
238 if (!(l1 & (1<<11)))
239 set_cpu_cap(c, X86_FEATURE_BTS);
240 if (!(l1 & (1<<12)))
241 set_cpu_cap(c, X86_FEATURE_PEBS);
242 ds_init_intel(c);
243 }
244
245#ifdef CONFIG_X86_64
246 if (c->x86 == 15)
247 c->x86_cache_alignment = c->x86_clflush_size * 2;
248 if (c->x86 == 6)
249 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
250#else
251 if (c->x86 == 15) 268 if (c->x86 == 15)
252 set_cpu_cap(c, X86_FEATURE_P4); 269 set_cpu_cap(c, X86_FEATURE_P4);
253 if (c->x86 == 6) 270 if (c->x86 == 6)
@@ -256,19 +273,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
256 if (cpu_has_bts) 273 if (cpu_has_bts)
257 ptrace_bts_init_intel(c); 274 ptrace_bts_init_intel(c);
258 275
259 /*
260 * See if we have a good local APIC by checking for buggy Pentia,
261 * i.e. all B steppings and the C2 stepping of P54C when using their
262 * integrated APIC (see 11AP erratum in "Pentium Processor
263 * Specification Update").
264 */
265 if (cpu_has_apic && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
266 (c->x86_mask < 0x6 || c->x86_mask == 0xb))
267 set_cpu_cap(c, X86_FEATURE_11AP);
268
269#ifdef CONFIG_X86_NUMAQ
270 numaq_tsc_disable();
271#endif
272#endif 276#endif
273 277
274 detect_extended_topology(c); 278 detect_extended_topology(c);