aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 08:14:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 08:14:48 -0400
commit8237eb946a1a23c600fb289cf8dd3b399b10604e (patch)
treee3985782029601ede4035cfec7ee59e1a54324fd
parentcc21fe518a971bb2b0ab8370ec46ea21e84c57ab (diff)
parentbcb80e53877c2045d9e52f4a71372c3fe6501f6f (diff)
Merge branch 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, microcode, AMD: Add microcode revision to /proc/cpuinfo x86, microcode: Correct microcode revision format coretemp: Get microcode revision from cpu_data x86, intel: Use c->microcode for Atom errata check x86, intel: Output microcode revision in /proc/cpuinfo x86, microcode: Don't request microcode from userspace unnecessarily Fix up trivial conflicts in arch/x86/kernel/cpu/amd.c (conflict between moving AMD BSP code to cpu_dev helper function and adding AMD microcode revision to /proc/cpuinfo code)
-rw-r--r--arch/x86/include/asm/processor.h4
-rw-r--r--arch/x86/kernel/cpu/amd.c4
-rw-r--r--arch/x86/kernel/cpu/intel.c24
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c9
-rw-r--r--arch/x86/kernel/cpu/proc.c2
-rw-r--r--arch/x86/kernel/microcode_amd.c5
-rw-r--r--arch/x86/kernel/microcode_core.c8
-rw-r--r--arch/x86/kernel/microcode_intel.c14
-rw-r--r--drivers/hwmon/coretemp.c28
9 files changed, 48 insertions, 50 deletions
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 0d1171c97729..b650435ffb53 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -111,6 +111,7 @@ struct cpuinfo_x86 {
111 /* Index into per_cpu list: */ 111 /* Index into per_cpu list: */
112 u16 cpu_index; 112 u16 cpu_index;
113#endif 113#endif
114 u32 microcode;
114} __attribute__((__aligned__(SMP_CACHE_BYTES))); 115} __attribute__((__aligned__(SMP_CACHE_BYTES)));
115 116
116#define X86_VENDOR_INTEL 0 117#define X86_VENDOR_INTEL 0
@@ -179,7 +180,8 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
179 "=b" (*ebx), 180 "=b" (*ebx),
180 "=c" (*ecx), 181 "=c" (*ecx),
181 "=d" (*edx) 182 "=d" (*edx)
182 : "0" (*eax), "2" (*ecx)); 183 : "0" (*eax), "2" (*ecx)
184 : "memory");
183} 185}
184 186
185static inline void load_cr3(pgd_t *pgdir) 187static inline void load_cr3(pgd_t *pgdir)
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 13c6ec812545..46ae4f65fc7f 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -441,6 +441,8 @@ static void __cpuinit bsp_init_amd(struct cpuinfo_x86 *c)
441 441
442static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) 442static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
443{ 443{
444 u32 dummy;
445
444 early_init_amd_mc(c); 446 early_init_amd_mc(c);
445 447
446 /* 448 /*
@@ -470,6 +472,8 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
470 set_cpu_cap(c, X86_FEATURE_EXTD_APICID); 472 set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
471 } 473 }
472#endif 474#endif
475
476 rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
473} 477}
474 478
475static void __cpuinit init_amd(struct cpuinfo_x86 *c) 479static void __cpuinit init_amd(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index ed6086eedf1d..523131213f08 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -47,6 +47,15 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
47 (c->x86 == 0x6 && c->x86_model >= 0x0e)) 47 (c->x86 == 0x6 && c->x86_model >= 0x0e))
48 set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); 48 set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
49 49
50 if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64)) {
51 unsigned lower_word;
52
53 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
54 /* Required by the SDM */
55 sync_core();
56 rdmsr(MSR_IA32_UCODE_REV, lower_word, c->microcode);
57 }
58
50 /* 59 /*
51 * Atom erratum AAE44/AAF40/AAG38/AAH41: 60 * Atom erratum AAE44/AAF40/AAG38/AAH41:
52 * 61 *
@@ -55,17 +64,10 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
55 * need the microcode to have already been loaded... so if it is 64 * need the microcode to have already been loaded... so if it is
56 * not, recommend a BIOS update and disable large pages. 65 * not, recommend a BIOS update and disable large pages.
57 */ 66 */
58 if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2) { 67 if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2 &&
59 u32 ucode, junk; 68 c->microcode < 0x20e) {
60 69 printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n");
61 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 70 clear_cpu_cap(c, X86_FEATURE_PSE);
62 sync_core();
63 rdmsr(MSR_IA32_UCODE_REV, junk, ucode);
64
65 if (ucode < 0x20e) {
66 printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n");
67 clear_cpu_cap(c, X86_FEATURE_PSE);
68 }
69 } 71 }
70 72
71#ifdef CONFIG_X86_64 73#ifdef CONFIG_X86_64
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index fce51ad1f362..7b5063a6ad42 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -217,8 +217,13 @@ static void print_mce(struct mce *m)
217 pr_cont("MISC %llx ", m->misc); 217 pr_cont("MISC %llx ", m->misc);
218 218
219 pr_cont("\n"); 219 pr_cont("\n");
220 pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n", 220 /*
221 m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid); 221 * Note this output is parsed by external tools and old fields
222 * should not be changed.
223 */
224 pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x microcode %x\n",
225 m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid,
226 cpu_data(m->extcpu).microcode);
222 227
223 /* 228 /*
224 * Print out human-readable details about the MCE error, 229 * Print out human-readable details about the MCE error,
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 62ac8cb6ba27..14b23140e81f 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -85,6 +85,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
85 seq_printf(m, "stepping\t: %d\n", c->x86_mask); 85 seq_printf(m, "stepping\t: %d\n", c->x86_mask);
86 else 86 else
87 seq_printf(m, "stepping\t: unknown\n"); 87 seq_printf(m, "stepping\t: unknown\n");
88 if (c->microcode)
89 seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
88 90
89 if (cpu_has(c, X86_FEATURE_TSC)) { 91 if (cpu_has(c, X86_FEATURE_TSC)) {
90 unsigned int freq = cpufreq_quick_get(cpu); 92 unsigned int freq = cpufreq_quick_get(cpu);
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index 591be0ee1934..d494799aafcd 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -74,14 +74,13 @@ static struct equiv_cpu_entry *equiv_cpu_table;
74static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) 74static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
75{ 75{
76 struct cpuinfo_x86 *c = &cpu_data(cpu); 76 struct cpuinfo_x86 *c = &cpu_data(cpu);
77 u32 dummy;
78 77
79 if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { 78 if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
80 pr_warning("CPU%d: family %d not supported\n", cpu, c->x86); 79 pr_warning("CPU%d: family %d not supported\n", cpu, c->x86);
81 return -1; 80 return -1;
82 } 81 }
83 82
84 rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); 83 csig->rev = c->microcode;
85 pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); 84 pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
86 85
87 return 0; 86 return 0;
@@ -130,6 +129,7 @@ static int apply_microcode_amd(int cpu)
130 int cpu_num = raw_smp_processor_id(); 129 int cpu_num = raw_smp_processor_id();
131 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 130 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
132 struct microcode_amd *mc_amd = uci->mc; 131 struct microcode_amd *mc_amd = uci->mc;
132 struct cpuinfo_x86 *c = &cpu_data(cpu);
133 133
134 /* We should bind the task to the CPU */ 134 /* We should bind the task to the CPU */
135 BUG_ON(cpu_num != cpu); 135 BUG_ON(cpu_num != cpu);
@@ -150,6 +150,7 @@ static int apply_microcode_amd(int cpu)
150 150
151 pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev); 151 pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev);
152 uci->cpu_sig.rev = rev; 152 uci->cpu_sig.rev = rev;
153 c->microcode = rev;
153 154
154 return 0; 155 return 0;
155} 156}
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index f9242800bc84..f2d2a664e797 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -483,7 +483,13 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
483 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); 483 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
484 pr_debug("CPU%d removed\n", cpu); 484 pr_debug("CPU%d removed\n", cpu);
485 break; 485 break;
486 case CPU_DEAD: 486
487 /*
488 * When a CPU goes offline, don't free up or invalidate the copy of
489 * the microcode in kernel memory, so that we can reuse it when the
490 * CPU comes back online without unnecessarily requesting the userspace
491 * for it again.
492 */
487 case CPU_UP_CANCELED_FROZEN: 493 case CPU_UP_CANCELED_FROZEN:
488 /* The CPU refused to come up during a system resume */ 494 /* The CPU refused to come up during a system resume */
489 microcode_fini_cpu(cpu); 495 microcode_fini_cpu(cpu);
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index 1a1b606d3e92..3ca42d0e43a2 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -161,12 +161,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
161 csig->pf = 1 << ((val[1] >> 18) & 7); 161 csig->pf = 1 << ((val[1] >> 18) & 7);
162 } 162 }
163 163
164 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 164 csig->rev = c->microcode;
165 /* see notes above for revision 1.07. Apparent chip bug */
166 sync_core();
167 /* get the current revision from MSR 0x8B */
168 rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev);
169
170 pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n", 165 pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n",
171 cpu_num, csig->sig, csig->pf, csig->rev); 166 cpu_num, csig->sig, csig->pf, csig->rev);
172 167
@@ -299,9 +294,9 @@ static int apply_microcode(int cpu)
299 struct microcode_intel *mc_intel; 294 struct microcode_intel *mc_intel;
300 struct ucode_cpu_info *uci; 295 struct ucode_cpu_info *uci;
301 unsigned int val[2]; 296 unsigned int val[2];
302 int cpu_num; 297 int cpu_num = raw_smp_processor_id();
298 struct cpuinfo_x86 *c = &cpu_data(cpu_num);
303 299
304 cpu_num = raw_smp_processor_id();
305 uci = ucode_cpu_info + cpu; 300 uci = ucode_cpu_info + cpu;
306 mc_intel = uci->mc; 301 mc_intel = uci->mc;
307 302
@@ -317,7 +312,7 @@ static int apply_microcode(int cpu)
317 (unsigned long) mc_intel->bits >> 16 >> 16); 312 (unsigned long) mc_intel->bits >> 16 >> 16);
318 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 313 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
319 314
320 /* see notes above for revision 1.07. Apparent chip bug */ 315 /* As documented in the SDM: Do a CPUID 1 here */
321 sync_core(); 316 sync_core();
322 317
323 /* get the current revision from MSR 0x8B */ 318 /* get the current revision from MSR 0x8B */
@@ -335,6 +330,7 @@ static int apply_microcode(int cpu)
335 (mc_intel->hdr.date >> 16) & 0xff); 330 (mc_intel->hdr.date >> 16) & 0xff);
336 331
337 uci->cpu_sig.rev = val[1]; 332 uci->cpu_sig.rev = val[1];
333 c->microcode = val[1];
338 334
339 return 0; 335 return 0;
340} 336}
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 932383786642..ce18c046f728 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -325,15 +325,6 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
325 return adjust_tjmax(c, id, dev); 325 return adjust_tjmax(c, id, dev);
326} 326}
327 327
328static void __devinit get_ucode_rev_on_cpu(void *edx)
329{
330 u32 eax;
331
332 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
333 sync_core();
334 rdmsr(MSR_IA32_UCODE_REV, eax, *(u32 *)edx);
335}
336
337static int create_name_attr(struct platform_data *pdata, struct device *dev) 328static int create_name_attr(struct platform_data *pdata, struct device *dev)
338{ 329{
339 sysfs_attr_init(&pdata->name_attr.attr); 330 sysfs_attr_init(&pdata->name_attr.attr);
@@ -380,27 +371,16 @@ exit_free:
380static int __cpuinit chk_ucode_version(unsigned int cpu) 371static int __cpuinit chk_ucode_version(unsigned int cpu)
381{ 372{
382 struct cpuinfo_x86 *c = &cpu_data(cpu); 373 struct cpuinfo_x86 *c = &cpu_data(cpu);
383 int err;
384 u32 edx;
385 374
386 /* 375 /*
387 * Check if we have problem with errata AE18 of Core processors: 376 * Check if we have problem with errata AE18 of Core processors:
388 * Readings might stop update when processor visited too deep sleep, 377 * Readings might stop update when processor visited too deep sleep,
389 * fixed for stepping D0 (6EC). 378 * fixed for stepping D0 (6EC).
390 */ 379 */
391 if (c->x86_model == 0xe && c->x86_mask < 0xc) { 380 if (c->x86_model == 0xe && c->x86_mask < 0xc && c->microcode < 0x39) {
392 /* check for microcode update */ 381 pr_err("Errata AE18 not fixed, update BIOS or "
393 err = smp_call_function_single(cpu, get_ucode_rev_on_cpu, 382 "microcode of the CPU!\n");
394 &edx, 1); 383 return -ENODEV;
395 if (err) {
396 pr_err("Cannot determine microcode revision of "
397 "CPU#%u (%d)!\n", cpu, err);
398 return -ENODEV;
399 } else if (edx < 0x39) {
400 pr_err("Errata AE18 not fixed, update BIOS or "
401 "microcode of the CPU!\n");
402 return -ENODEV;
403 }
404 } 384 }
405 return 0; 385 return 0;
406} 386}