aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/microcode.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-07-25 10:40:14 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-07-25 10:40:14 -0400
commitff877ea80efa2015b6263766f78ee42c2a1b32f9 (patch)
tree85205005c611ab774702148558321c6fb92f1ccd /arch/x86/kernel/microcode.c
parent30821fee4f0cb3e6d241d9f7ddc37742212e3eb7 (diff)
parentd37e6bf68fc1eb34a4ad21d9ae8890ed37ea80e7 (diff)
Merge branch 'linux-next' of git://git.infradead.org/~dedekind/ubi-2.6
Diffstat (limited to 'arch/x86/kernel/microcode.c')
-rw-r--r--arch/x86/kernel/microcode.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c
index 69729e38b78a..6994c751590e 100644
--- a/arch/x86/kernel/microcode.c
+++ b/arch/x86/kernel/microcode.c
@@ -5,13 +5,14 @@
5 * 2006 Shaohua Li <shaohua.li@intel.com> 5 * 2006 Shaohua Li <shaohua.li@intel.com>
6 * 6 *
7 * This driver allows to upgrade microcode on Intel processors 7 * This driver allows to upgrade microcode on Intel processors
8 * belonging to IA-32 family - PentiumPro, Pentium II, 8 * belonging to IA-32 family - PentiumPro, Pentium II,
9 * Pentium III, Xeon, Pentium 4, etc. 9 * Pentium III, Xeon, Pentium 4, etc.
10 * 10 *
11 * Reference: Section 8.10 of Volume III, Intel Pentium 4 Manual, 11 * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture
12 * Order Number 245472 or free download from: 12 * Software Developer's Manual
13 * 13 * Order Number 253668 or free download from:
14 * http://developer.intel.com/design/pentium4/manuals/245472.htm 14 *
15 * http://developer.intel.com/design/pentium4/manuals/253668.htm
15 * 16 *
16 * For more information, go to http://www.urbanmyth.org/microcode 17 * For more information, go to http://www.urbanmyth.org/microcode
17 * 18 *
@@ -58,12 +59,12 @@
58 * nature of implementation. 59 * nature of implementation.
59 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com> 60 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com>
60 * Fix the panic when writing zero-length microcode chunk. 61 * Fix the panic when writing zero-length microcode chunk.
61 * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, 62 * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>,
62 * Jun Nakajima <jun.nakajima@intel.com> 63 * Jun Nakajima <jun.nakajima@intel.com>
63 * Support for the microcode updates in the new format. 64 * Support for the microcode updates in the new format.
64 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com> 65 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com>
65 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl 66 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl
66 * because we no longer hold a copy of applied microcode 67 * because we no longer hold a copy of applied microcode
67 * in kernel memory. 68 * in kernel memory.
68 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com> 69 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com>
69 * Fix sigmatch() macro to handle old CPUs with pf == 0. 70 * Fix sigmatch() macro to handle old CPUs with pf == 0.
@@ -75,6 +76,7 @@
75#include <linux/kernel.h> 76#include <linux/kernel.h>
76#include <linux/init.h> 77#include <linux/init.h>
77#include <linux/sched.h> 78#include <linux/sched.h>
79#include <linux/smp_lock.h>
78#include <linux/cpumask.h> 80#include <linux/cpumask.h>
79#include <linux/module.h> 81#include <linux/module.h>
80#include <linux/slab.h> 82#include <linux/slab.h>
@@ -320,11 +322,11 @@ static void apply_microcode(int cpu)
320 return; 322 return;
321 323
322 /* serialize access to the physical write to MSR 0x79 */ 324 /* serialize access to the physical write to MSR 0x79 */
323 spin_lock_irqsave(&microcode_update_lock, flags); 325 spin_lock_irqsave(&microcode_update_lock, flags);
324 326
325 /* write microcode via MSR 0x79 */ 327 /* write microcode via MSR 0x79 */
326 wrmsr(MSR_IA32_UCODE_WRITE, 328 wrmsr(MSR_IA32_UCODE_WRITE,
327 (unsigned long) uci->mc->bits, 329 (unsigned long) uci->mc->bits,
328 (unsigned long) uci->mc->bits >> 16 >> 16); 330 (unsigned long) uci->mc->bits >> 16 >> 16);
329 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 331 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
330 332
@@ -341,7 +343,7 @@ static void apply_microcode(int cpu)
341 return; 343 return;
342 } 344 }
343 printk(KERN_INFO "microcode: CPU%d updated from revision " 345 printk(KERN_INFO "microcode: CPU%d updated from revision "
344 "0x%x to 0x%x, date = %08x \n", 346 "0x%x to 0x%x, date = %08x \n",
345 cpu_num, uci->rev, val[1], uci->mc->hdr.date); 347 cpu_num, uci->rev, val[1], uci->mc->hdr.date);
346 uci->rev = val[1]; 348 uci->rev = val[1];
347} 349}
@@ -386,6 +388,7 @@ static int do_microcode_update (void)
386 void *new_mc = NULL; 388 void *new_mc = NULL;
387 int cpu; 389 int cpu;
388 cpumask_t old; 390 cpumask_t old;
391 cpumask_of_cpu_ptr_declare(newmask);
389 392
390 old = current->cpus_allowed; 393 old = current->cpus_allowed;
391 394
@@ -402,7 +405,8 @@ static int do_microcode_update (void)
402 405
403 if (!uci->valid) 406 if (!uci->valid)
404 continue; 407 continue;
405 set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); 408 cpumask_of_cpu_ptr_next(newmask, cpu);
409 set_cpus_allowed_ptr(current, newmask);
406 error = get_maching_microcode(new_mc, cpu); 410 error = get_maching_microcode(new_mc, cpu);
407 if (error < 0) 411 if (error < 0)
408 goto out; 412 goto out;
@@ -422,6 +426,7 @@ out:
422 426
423static int microcode_open (struct inode *unused1, struct file *unused2) 427static int microcode_open (struct inode *unused1, struct file *unused2)
424{ 428{
429 cycle_kernel_lock();
425 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; 430 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
426} 431}
427 432
@@ -488,7 +493,7 @@ MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
488#define microcode_dev_exit() do { } while(0) 493#define microcode_dev_exit() do { } while(0)
489#endif 494#endif
490 495
491static long get_next_ucode_from_buffer(void **mc, void *buf, 496static long get_next_ucode_from_buffer(void **mc, const u8 *buf,
492 unsigned long size, long offset) 497 unsigned long size, long offset)
493{ 498{
494 microcode_header_t *mc_header; 499 microcode_header_t *mc_header;
@@ -522,7 +527,7 @@ static int cpu_request_microcode(int cpu)
522 char name[30]; 527 char name[30];
523 struct cpuinfo_x86 *c = &cpu_data(cpu); 528 struct cpuinfo_x86 *c = &cpu_data(cpu);
524 const struct firmware *firmware; 529 const struct firmware *firmware;
525 void *buf; 530 const u8 *buf;
526 unsigned long size; 531 unsigned long size;
527 long offset = 0; 532 long offset = 0;
528 int error; 533 int error;
@@ -534,7 +539,7 @@ static int cpu_request_microcode(int cpu)
534 c->x86, c->x86_model, c->x86_mask); 539 c->x86, c->x86_model, c->x86_mask);
535 error = request_firmware(&firmware, name, &microcode_pdev->dev); 540 error = request_firmware(&firmware, name, &microcode_pdev->dev);
536 if (error) { 541 if (error) {
537 pr_debug("microcode: ucode data file %s load failed\n", name); 542 pr_debug("microcode: data file %s load failed\n", name);
538 return error; 543 return error;
539 } 544 }
540 buf = firmware->data; 545 buf = firmware->data;
@@ -571,6 +576,7 @@ static int apply_microcode_check_cpu(int cpu)
571 struct cpuinfo_x86 *c = &cpu_data(cpu); 576 struct cpuinfo_x86 *c = &cpu_data(cpu);
572 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 577 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
573 cpumask_t old; 578 cpumask_t old;
579 cpumask_of_cpu_ptr(newmask, cpu);
574 unsigned int val[2]; 580 unsigned int val[2];
575 int err = 0; 581 int err = 0;
576 582
@@ -579,7 +585,7 @@ static int apply_microcode_check_cpu(int cpu)
579 return 0; 585 return 0;
580 586
581 old = current->cpus_allowed; 587 old = current->cpus_allowed;
582 set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); 588 set_cpus_allowed_ptr(current, newmask);
583 589
584 /* Check if the microcode we have in memory matches the CPU */ 590 /* Check if the microcode we have in memory matches the CPU */
585 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || 591 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
@@ -617,11 +623,12 @@ static int apply_microcode_check_cpu(int cpu)
617static void microcode_init_cpu(int cpu, int resume) 623static void microcode_init_cpu(int cpu, int resume)
618{ 624{
619 cpumask_t old; 625 cpumask_t old;
626 cpumask_of_cpu_ptr(newmask, cpu);
620 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 627 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
621 628
622 old = current->cpus_allowed; 629 old = current->cpus_allowed;
623 630
624 set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); 631 set_cpus_allowed_ptr(current, newmask);
625 mutex_lock(&microcode_mutex); 632 mutex_lock(&microcode_mutex);
626 collect_cpu_info(cpu); 633 collect_cpu_info(cpu);
627 if (uci->valid && system_state == SYSTEM_RUNNING && !resume) 634 if (uci->valid && system_state == SYSTEM_RUNNING && !resume)
@@ -641,7 +648,9 @@ static void microcode_fini_cpu(int cpu)
641 mutex_unlock(&microcode_mutex); 648 mutex_unlock(&microcode_mutex);
642} 649}
643 650
644static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz) 651static ssize_t reload_store(struct sys_device *dev,
652 struct sysdev_attribute *attr,
653 const char *buf, size_t sz)
645{ 654{
646 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; 655 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
647 char *end; 656 char *end;
@@ -653,11 +662,12 @@ static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
653 return -EINVAL; 662 return -EINVAL;
654 if (val == 1) { 663 if (val == 1) {
655 cpumask_t old; 664 cpumask_t old;
665 cpumask_of_cpu_ptr(newmask, cpu);
656 666
657 old = current->cpus_allowed; 667 old = current->cpus_allowed;
658 668
659 get_online_cpus(); 669 get_online_cpus();
660 set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); 670 set_cpus_allowed_ptr(current, newmask);
661 671
662 mutex_lock(&microcode_mutex); 672 mutex_lock(&microcode_mutex);
663 if (uci->valid) 673 if (uci->valid)
@@ -671,14 +681,16 @@ static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
671 return sz; 681 return sz;
672} 682}
673 683
674static ssize_t version_show(struct sys_device *dev, char *buf) 684static ssize_t version_show(struct sys_device *dev,
685 struct sysdev_attribute *attr, char *buf)
675{ 686{
676 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; 687 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
677 688
678 return sprintf(buf, "0x%x\n", uci->rev); 689 return sprintf(buf, "0x%x\n", uci->rev);
679} 690}
680 691
681static ssize_t pf_show(struct sys_device *dev, char *buf) 692static ssize_t pf_show(struct sys_device *dev,
693 struct sysdev_attribute *attr, char *buf)
682{ 694{
683 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; 695 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
684 696
@@ -805,6 +817,9 @@ static int __init microcode_init (void)
805{ 817{
806 int error; 818 int error;
807 819
820 printk(KERN_INFO
821 "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");
822
808 error = microcode_dev_init(); 823 error = microcode_dev_init();
809 if (error) 824 if (error)
810 return error; 825 return error;
@@ -825,9 +840,6 @@ static int __init microcode_init (void)
825 } 840 }
826 841
827 register_hotcpu_notifier(&mc_cpu_notifier); 842 register_hotcpu_notifier(&mc_cpu_notifier);
828
829 printk(KERN_INFO
830 "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");
831 return 0; 843 return 0;
832} 844}
833 845