diff options
Diffstat (limited to 'arch/x86/kernel/microcode.c')
-rw-r--r-- | arch/x86/kernel/microcode.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c index 69729e38b78a..56b933119a04 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(µcode_update_lock, flags); | 325 | spin_lock_irqsave(µcode_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 | } |
@@ -422,6 +424,7 @@ out: | |||
422 | 424 | ||
423 | static int microcode_open (struct inode *unused1, struct file *unused2) | 425 | static int microcode_open (struct inode *unused1, struct file *unused2) |
424 | { | 426 | { |
427 | cycle_kernel_lock(); | ||
425 | return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; | 428 | return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; |
426 | } | 429 | } |
427 | 430 | ||
@@ -488,7 +491,7 @@ MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); | |||
488 | #define microcode_dev_exit() do { } while(0) | 491 | #define microcode_dev_exit() do { } while(0) |
489 | #endif | 492 | #endif |
490 | 493 | ||
491 | static long get_next_ucode_from_buffer(void **mc, void *buf, | 494 | static long get_next_ucode_from_buffer(void **mc, const u8 *buf, |
492 | unsigned long size, long offset) | 495 | unsigned long size, long offset) |
493 | { | 496 | { |
494 | microcode_header_t *mc_header; | 497 | microcode_header_t *mc_header; |
@@ -522,7 +525,7 @@ static int cpu_request_microcode(int cpu) | |||
522 | char name[30]; | 525 | char name[30]; |
523 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 526 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
524 | const struct firmware *firmware; | 527 | const struct firmware *firmware; |
525 | void *buf; | 528 | const u8 *buf; |
526 | unsigned long size; | 529 | unsigned long size; |
527 | long offset = 0; | 530 | long offset = 0; |
528 | int error; | 531 | int error; |
@@ -534,7 +537,7 @@ static int cpu_request_microcode(int cpu) | |||
534 | c->x86, c->x86_model, c->x86_mask); | 537 | c->x86, c->x86_model, c->x86_mask); |
535 | error = request_firmware(&firmware, name, µcode_pdev->dev); | 538 | error = request_firmware(&firmware, name, µcode_pdev->dev); |
536 | if (error) { | 539 | if (error) { |
537 | pr_debug("microcode: ucode data file %s load failed\n", name); | 540 | pr_debug("microcode: data file %s load failed\n", name); |
538 | return error; | 541 | return error; |
539 | } | 542 | } |
540 | buf = firmware->data; | 543 | buf = firmware->data; |
@@ -805,6 +808,9 @@ static int __init microcode_init (void) | |||
805 | { | 808 | { |
806 | int error; | 809 | int error; |
807 | 810 | ||
811 | printk(KERN_INFO | ||
812 | "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n"); | ||
813 | |||
808 | error = microcode_dev_init(); | 814 | error = microcode_dev_init(); |
809 | if (error) | 815 | if (error) |
810 | return error; | 816 | return error; |
@@ -825,9 +831,6 @@ static int __init microcode_init (void) | |||
825 | } | 831 | } |
826 | 832 | ||
827 | register_hotcpu_notifier(&mc_cpu_notifier); | 833 | 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; | 834 | return 0; |
832 | } | 835 | } |
833 | 836 | ||