Commit 3e135d887c973b525d43fbb67dfc5972694882f6

Authored by Peter Oruba
Committed by Ingo Molnar
1 parent 1abae31096

x86: code split to two parts

Split off existing code into two seperate files. One file holds general
code, the other file vendor specific parts.

No functional changes, only refactoring.

Temporarily Introduced a new module name 'ucode' for result,
due to already taken name 'microcode'.

Signed-off-by: Peter Oruba <peter.oruba@amd.com>
Cc: Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 3 changed files with 488 additions and 365 deletions Inline Diff

arch/x86/kernel/Makefile
1 # 1 #
2 # Makefile for the linux kernel. 2 # Makefile for the linux kernel.
3 # 3 #
4 4
5 extra-y := head_$(BITS).o head$(BITS).o head.o init_task.o vmlinux.lds 5 extra-y := head_$(BITS).o head$(BITS).o head.o init_task.o vmlinux.lds
6 6
7 CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) 7 CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
8 8
9 ifdef CONFIG_FTRACE 9 ifdef CONFIG_FTRACE
10 # Do not profile debug and lowlevel utilities 10 # Do not profile debug and lowlevel utilities
11 CFLAGS_REMOVE_tsc.o = -pg 11 CFLAGS_REMOVE_tsc.o = -pg
12 CFLAGS_REMOVE_rtc.o = -pg 12 CFLAGS_REMOVE_rtc.o = -pg
13 CFLAGS_REMOVE_paravirt.o = -pg 13 CFLAGS_REMOVE_paravirt.o = -pg
14 endif 14 endif
15 15
16 # 16 #
17 # vsyscalls (which work on the user stack) should have 17 # vsyscalls (which work on the user stack) should have
18 # no stack-protector checks: 18 # no stack-protector checks:
19 # 19 #
20 nostackp := $(call cc-option, -fno-stack-protector) 20 nostackp := $(call cc-option, -fno-stack-protector)
21 CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) 21 CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp)
22 CFLAGS_hpet.o := $(nostackp) 22 CFLAGS_hpet.o := $(nostackp)
23 CFLAGS_tsc.o := $(nostackp) 23 CFLAGS_tsc.o := $(nostackp)
24 24
25 obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o 25 obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
26 obj-y += traps_$(BITS).o irq_$(BITS).o 26 obj-y += traps_$(BITS).o irq_$(BITS).o
27 obj-y += time_$(BITS).o ioport.o ldt.o 27 obj-y += time_$(BITS).o ioport.o ldt.o
28 obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o 28 obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
29 obj-$(CONFIG_X86_VISWS) += visws_quirks.o 29 obj-$(CONFIG_X86_VISWS) += visws_quirks.o
30 obj-$(CONFIG_X86_32) += probe_roms_32.o 30 obj-$(CONFIG_X86_32) += probe_roms_32.o
31 obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o 31 obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
32 obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o 32 obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
33 obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o 33 obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o
34 obj-y += bootflag.o e820.o 34 obj-y += bootflag.o e820.o
35 obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o 35 obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
36 obj-y += alternative.o i8253.o pci-nommu.o 36 obj-y += alternative.o i8253.o pci-nommu.o
37 obj-y += tsc.o io_delay.o rtc.o 37 obj-y += tsc.o io_delay.o rtc.o
38 38
39 obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o 39 obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
40 obj-y += process.o 40 obj-y += process.o
41 obj-y += i387.o 41 obj-y += i387.o
42 obj-y += ptrace.o 42 obj-y += ptrace.o
43 obj-y += ds.o 43 obj-y += ds.o
44 obj-$(CONFIG_X86_32) += tls.o 44 obj-$(CONFIG_X86_32) += tls.o
45 obj-$(CONFIG_IA32_EMULATION) += tls.o 45 obj-$(CONFIG_IA32_EMULATION) += tls.o
46 obj-y += step.o 46 obj-y += step.o
47 obj-$(CONFIG_STACKTRACE) += stacktrace.o 47 obj-$(CONFIG_STACKTRACE) += stacktrace.o
48 obj-y += cpu/ 48 obj-y += cpu/
49 obj-y += acpi/ 49 obj-y += acpi/
50 obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o 50 obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
51 obj-$(CONFIG_MCA) += mca_32.o 51 obj-$(CONFIG_MCA) += mca_32.o
52 obj-$(CONFIG_X86_MSR) += msr.o 52 obj-$(CONFIG_X86_MSR) += msr.o
53 obj-$(CONFIG_X86_CPUID) += cpuid.o 53 obj-$(CONFIG_X86_CPUID) += cpuid.o
54 obj-$(CONFIG_MICROCODE) += microcode_intel.o 54 obj-$(CONFIG_MICROCODE) += ucode.o
55 ucode-objs := microcode.o microcode_intel.o
55 obj-$(CONFIG_PCI) += early-quirks.o 56 obj-$(CONFIG_PCI) += early-quirks.o
56 apm-y := apm_32.o 57 apm-y := apm_32.o
57 obj-$(CONFIG_APM) += apm.o 58 obj-$(CONFIG_APM) += apm.o
58 obj-$(CONFIG_X86_SMP) += smp.o 59 obj-$(CONFIG_X86_SMP) += smp.o
59 obj-$(CONFIG_X86_SMP) += smpboot.o tsc_sync.o ipi.o tlb_$(BITS).o 60 obj-$(CONFIG_X86_SMP) += smpboot.o tsc_sync.o ipi.o tlb_$(BITS).o
60 obj-$(CONFIG_X86_32_SMP) += smpcommon.o 61 obj-$(CONFIG_X86_32_SMP) += smpcommon.o
61 obj-$(CONFIG_X86_64_SMP) += tsc_sync.o smpcommon.o 62 obj-$(CONFIG_X86_64_SMP) += tsc_sync.o smpcommon.o
62 obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o 63 obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o
63 obj-$(CONFIG_X86_MPPARSE) += mpparse.o 64 obj-$(CONFIG_X86_MPPARSE) += mpparse.o
64 obj-$(CONFIG_X86_LOCAL_APIC) += apic_$(BITS).o nmi.o 65 obj-$(CONFIG_X86_LOCAL_APIC) += apic_$(BITS).o nmi.o
65 obj-$(CONFIG_X86_IO_APIC) += io_apic_$(BITS).o 66 obj-$(CONFIG_X86_IO_APIC) += io_apic_$(BITS).o
66 obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o 67 obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
67 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 68 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
68 obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o 69 obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
69 obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o 70 obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
70 obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o 71 obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
71 obj-$(CONFIG_X86_NUMAQ) += numaq_32.o 72 obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
72 obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o 73 obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o
73 obj-y += vsmp_64.o 74 obj-y += vsmp_64.o
74 obj-$(CONFIG_KPROBES) += kprobes.o 75 obj-$(CONFIG_KPROBES) += kprobes.o
75 obj-$(CONFIG_MODULES) += module_$(BITS).o 76 obj-$(CONFIG_MODULES) += module_$(BITS).o
76 obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o 77 obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
77 obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o 78 obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
78 obj-$(CONFIG_KGDB) += kgdb.o 79 obj-$(CONFIG_KGDB) += kgdb.o
79 obj-$(CONFIG_VM86) += vm86_32.o 80 obj-$(CONFIG_VM86) += vm86_32.o
80 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 81 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
81 82
82 obj-$(CONFIG_HPET_TIMER) += hpet.o 83 obj-$(CONFIG_HPET_TIMER) += hpet.o
83 84
84 obj-$(CONFIG_K8_NB) += k8.o 85 obj-$(CONFIG_K8_NB) += k8.o
85 obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o 86 obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o
86 obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o 87 obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
87 obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o 88 obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o
88 89
89 obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o 90 obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o
90 obj-$(CONFIG_KVM_GUEST) += kvm.o 91 obj-$(CONFIG_KVM_GUEST) += kvm.o
91 obj-$(CONFIG_KVM_CLOCK) += kvmclock.o 92 obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
92 obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o 93 obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o
93 obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o 94 obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o
94 95
95 obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o 96 obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
96 97
97 obj-$(CONFIG_SCx200) += scx200.o 98 obj-$(CONFIG_SCx200) += scx200.o
98 scx200-y += scx200_32.o 99 scx200-y += scx200_32.o
99 100
100 obj-$(CONFIG_OLPC) += olpc.o 101 obj-$(CONFIG_OLPC) += olpc.o
101 102
102 ### 103 ###
103 # 64 bit specific files 104 # 64 bit specific files
104 ifeq ($(CONFIG_X86_64),y) 105 ifeq ($(CONFIG_X86_64),y)
105 obj-y += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o 106 obj-y += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
106 obj-y += bios_uv.o 107 obj-y += bios_uv.o
107 obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o 108 obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
108 obj-$(CONFIG_AUDIT) += audit_64.o 109 obj-$(CONFIG_AUDIT) += audit_64.o
109 110
110 obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o 111 obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o
111 obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o 112 obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o
112 obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o 113 obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o
113 obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o 114 obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o
114 115
115 obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o 116 obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
116 endif 117 endif
117 118
arch/x86/kernel/microcode.c
File was created 1 /*
2 * Intel CPU Microcode Update Driver for Linux
3 *
4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
5 * 2006 Shaohua Li <shaohua.li@intel.com>
6 *
7 * This driver allows to upgrade microcode on Intel processors
8 * belonging to IA-32 family - PentiumPro, Pentium II,
9 * Pentium III, Xeon, Pentium 4, etc.
10 *
11 * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture
12 * Software Developer's Manual
13 * Order Number 253668 or free download from:
14 *
15 * http://developer.intel.com/design/pentium4/manuals/253668.htm
16 *
17 * For more information, go to http://www.urbanmyth.org/microcode
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version
22 * 2 of the License, or (at your option) any later version.
23 *
24 * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com>
25 * Initial release.
26 * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com>
27 * Added read() support + cleanups.
28 * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com>
29 * Added 'device trimming' support. open(O_WRONLY) zeroes
30 * and frees the saved copy of applied microcode.
31 * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com>
32 * Made to use devfs (/dev/cpu/microcode) + cleanups.
33 * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com>
34 * Added misc device support (now uses both devfs and misc).
35 * Added MICROCODE_IOCFREE ioctl to clear memory.
36 * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com>
37 * Messages for error cases (non Intel & no suitable microcode).
38 * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com>
39 * Removed ->release(). Removed exclusive open and status bitmap.
40 * Added microcode_rwsem to serialize read()/write()/ioctl().
41 * Removed global kernel lock usage.
42 * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com>
43 * Write 0 to 0x8B msr and then cpuid before reading revision,
44 * so that it works even if there were no update done by the
45 * BIOS. Otherwise, reading from 0x8B gives junk (which happened
46 * to be 0 on my machine which is why it worked even when I
47 * disabled update by the BIOS)
48 * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix.
49 * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and
50 * Tigran Aivazian <tigran@veritas.com>
51 * Intel Pentium 4 processor support and bugfixes.
52 * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com>
53 * Bugfix for HT (Hyper-Threading) enabled processors
54 * whereby processor resources are shared by all logical processors
55 * in a single CPU package.
56 * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and
57 * Tigran Aivazian <tigran@veritas.com>,
58 * Serialize updates as required on HT processors due to speculative
59 * nature of implementation.
60 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com>
61 * Fix the panic when writing zero-length microcode chunk.
62 * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>,
63 * Jun Nakajima <jun.nakajima@intel.com>
64 * Support for the microcode updates in the new format.
65 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com>
66 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl
67 * because we no longer hold a copy of applied microcode
68 * in kernel memory.
69 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com>
70 * Fix sigmatch() macro to handle old CPUs with pf == 0.
71 * Thanks to Stuart Swales for pointing out this bug.
72 */
73
74 //#define DEBUG /* pr_debug */
75 #include <linux/capability.h>
76 #include <linux/kernel.h>
77 #include <linux/init.h>
78 #include <linux/sched.h>
79 #include <linux/smp_lock.h>
80 #include <linux/cpumask.h>
81 #include <linux/module.h>
82 #include <linux/slab.h>
83 #include <linux/vmalloc.h>
84 #include <linux/miscdevice.h>
85 #include <linux/spinlock.h>
86 #include <linux/mm.h>
87 #include <linux/fs.h>
88 #include <linux/mutex.h>
89 #include <linux/cpu.h>
90 #include <linux/firmware.h>
91 #include <linux/platform_device.h>
92
93 #include <asm/msr.h>
94 #include <asm/uaccess.h>
95 #include <asm/processor.h>
96 #include <asm/microcode.h>
97
98 MODULE_DESCRIPTION("Microcode Update Driver");
99 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
100 MODULE_LICENSE("GPL");
101
102 #define MICROCODE_VERSION "1.14a"
103
104 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
105 DEFINE_MUTEX(microcode_mutex);
106
107 struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
108
109 extern long get_next_ucode(void **mc, long offset);
110 extern int microcode_sanity_check(void *mc);
111 extern int get_matching_microcode(void *mc, int cpu);
112 extern void collect_cpu_info(int cpu_num);
113 extern int cpu_request_microcode(int cpu);
114 extern void microcode_fini_cpu(int cpu);
115 extern void apply_microcode(int cpu);
116 extern int apply_microcode_check_cpu(int cpu);
117
118 #ifdef CONFIG_MICROCODE_OLD_INTERFACE
119 void __user *user_buffer; /* user area microcode data buffer */
120 unsigned int user_buffer_size; /* it's size */
121
122 static int do_microcode_update (void)
123 {
124 long cursor = 0;
125 int error = 0;
126 void *new_mc = NULL;
127 int cpu;
128 cpumask_t old;
129 cpumask_of_cpu_ptr_declare(newmask);
130
131 old = current->cpus_allowed;
132
133 while ((cursor = get_next_ucode(&new_mc, cursor)) > 0) {
134 error = microcode_sanity_check(new_mc);
135 if (error)
136 goto out;
137 /*
138 * It's possible the data file has multiple matching ucode,
139 * lets keep searching till the latest version
140 */
141 for_each_online_cpu(cpu) {
142 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
143
144 if (!uci->valid)
145 continue;
146 cpumask_of_cpu_ptr_next(newmask, cpu);
147 set_cpus_allowed_ptr(current, newmask);
148 error = get_maching_microcode(new_mc, cpu);
149 if (error < 0)
150 goto out;
151 if (error == 1)
152 apply_microcode(cpu);
153 }
154 vfree(new_mc);
155 }
156 out:
157 if (cursor > 0)
158 vfree(new_mc);
159 if (cursor < 0)
160 error = cursor;
161 set_cpus_allowed_ptr(current, &old);
162 return error;
163 }
164
165 static int microcode_open (struct inode *unused1, struct file *unused2)
166 {
167 cycle_kernel_lock();
168 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
169 }
170
171 static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
172 {
173 ssize_t ret;
174
175 if ((len >> PAGE_SHIFT) > num_physpages) {
176 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
177 return -EINVAL;
178 }
179
180 get_online_cpus();
181 mutex_lock(&microcode_mutex);
182
183 user_buffer = (void __user *) buf;
184 user_buffer_size = (int) len;
185
186 ret = do_microcode_update();
187 if (!ret)
188 ret = (ssize_t)len;
189
190 mutex_unlock(&microcode_mutex);
191 put_online_cpus();
192
193 return ret;
194 }
195
196 static const struct file_operations microcode_fops = {
197 .owner = THIS_MODULE,
198 .write = microcode_write,
199 .open = microcode_open,
200 };
201
202 static struct miscdevice microcode_dev = {
203 .minor = MICROCODE_MINOR,
204 .name = "microcode",
205 .fops = &microcode_fops,
206 };
207
208 static int __init microcode_dev_init (void)
209 {
210 int error;
211
212 error = misc_register(&microcode_dev);
213 if (error) {
214 printk(KERN_ERR
215 "microcode: can't misc_register on minor=%d\n",
216 MICROCODE_MINOR);
217 return error;
218 }
219
220 return 0;
221 }
222
223 static void microcode_dev_exit (void)
224 {
225 misc_deregister(&microcode_dev);
226 }
227
228 MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
229 #else
230 #define microcode_dev_init() 0
231 #define microcode_dev_exit() do { } while(0)
232 #endif
233
234 /* fake device for request_firmware */
235 struct platform_device *microcode_pdev;
236
237 static void microcode_init_cpu(int cpu, int resume)
238 {
239 cpumask_t old;
240 cpumask_of_cpu_ptr(newmask, cpu);
241 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
242
243 old = current->cpus_allowed;
244
245 set_cpus_allowed_ptr(current, newmask);
246 mutex_lock(&microcode_mutex);
247 collect_cpu_info(cpu);
248 if (uci->valid && system_state == SYSTEM_RUNNING && !resume)
249 cpu_request_microcode(cpu);
250 mutex_unlock(&microcode_mutex);
251 set_cpus_allowed_ptr(current, &old);
252 }
253
254 static ssize_t reload_store(struct sys_device *dev,
255 struct sysdev_attribute *attr,
256 const char *buf, size_t sz)
257 {
258 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
259 char *end;
260 unsigned long val = simple_strtoul(buf, &end, 0);
261 int err = 0;
262 int cpu = dev->id;
263
264 if (end == buf)
265 return -EINVAL;
266 if (val == 1) {
267 cpumask_t old;
268 cpumask_of_cpu_ptr(newmask, cpu);
269
270 old = current->cpus_allowed;
271
272 get_online_cpus();
273 set_cpus_allowed_ptr(current, newmask);
274
275 mutex_lock(&microcode_mutex);
276 if (uci->valid)
277 err = cpu_request_microcode(cpu);
278 mutex_unlock(&microcode_mutex);
279 put_online_cpus();
280 set_cpus_allowed_ptr(current, &old);
281 }
282 if (err)
283 return err;
284 return sz;
285 }
286
287 static ssize_t version_show(struct sys_device *dev,
288 struct sysdev_attribute *attr, char *buf)
289 {
290 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
291
292 return sprintf(buf, "0x%x\n", uci->rev);
293 }
294
295 static ssize_t pf_show(struct sys_device *dev,
296 struct sysdev_attribute *attr, char *buf)
297 {
298 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
299
300 return sprintf(buf, "0x%x\n", uci->pf);
301 }
302
303 static SYSDEV_ATTR(reload, 0200, NULL, reload_store);
304 static SYSDEV_ATTR(version, 0400, version_show, NULL);
305 static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);
306
307 static struct attribute *mc_default_attrs[] = {
308 &attr_reload.attr,
309 &attr_version.attr,
310 &attr_processor_flags.attr,
311 NULL
312 };
313
314 static struct attribute_group mc_attr_group = {
315 .attrs = mc_default_attrs,
316 .name = "microcode",
317 };
318
319 static int __mc_sysdev_add(struct sys_device *sys_dev, int resume)
320 {
321 int err, cpu = sys_dev->id;
322 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
323
324 if (!cpu_online(cpu))
325 return 0;
326
327 pr_debug("microcode: CPU%d added\n", cpu);
328 memset(uci, 0, sizeof(*uci));
329
330 err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
331 if (err)
332 return err;
333
334 microcode_init_cpu(cpu, resume);
335
336 return 0;
337 }
338
339 static int mc_sysdev_add(struct sys_device *sys_dev)
340 {
341 return __mc_sysdev_add(sys_dev, 0);
342 }
343
344 static int mc_sysdev_remove(struct sys_device *sys_dev)
345 {
346 int cpu = sys_dev->id;
347
348 if (!cpu_online(cpu))
349 return 0;
350
351 pr_debug("microcode: CPU%d removed\n", cpu);
352 microcode_fini_cpu(cpu);
353 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
354 return 0;
355 }
356
357 static int mc_sysdev_resume(struct sys_device *dev)
358 {
359 int cpu = dev->id;
360
361 if (!cpu_online(cpu))
362 return 0;
363 pr_debug("microcode: CPU%d resumed\n", cpu);
364 /* only CPU 0 will apply ucode here */
365 apply_microcode(0);
366 return 0;
367 }
368
369 static struct sysdev_driver mc_sysdev_driver = {
370 .add = mc_sysdev_add,
371 .remove = mc_sysdev_remove,
372 .resume = mc_sysdev_resume,
373 };
374
375 static __cpuinit int
376 mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
377 {
378 unsigned int cpu = (unsigned long)hcpu;
379 struct sys_device *sys_dev;
380
381 sys_dev = get_cpu_sysdev(cpu);
382 switch (action) {
383 case CPU_UP_CANCELED_FROZEN:
384 /* The CPU refused to come up during a system resume */
385 microcode_fini_cpu(cpu);
386 break;
387 case CPU_ONLINE:
388 case CPU_DOWN_FAILED:
389 mc_sysdev_add(sys_dev);
390 break;
391 case CPU_ONLINE_FROZEN:
392 /* System-wide resume is in progress, try to apply microcode */
393 if (apply_microcode_check_cpu(cpu)) {
394 /* The application of microcode failed */
395 microcode_fini_cpu(cpu);
396 __mc_sysdev_add(sys_dev, 1);
397 break;
398 }
399 case CPU_DOWN_FAILED_FROZEN:
400 if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))
401 printk(KERN_ERR "microcode: Failed to create the sysfs "
402 "group for CPU%d\n", cpu);
403 break;
404 case CPU_DOWN_PREPARE:
405 mc_sysdev_remove(sys_dev);
406 break;
407 case CPU_DOWN_PREPARE_FROZEN:
408 /* Suspend is in progress, only remove the interface */
409 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
410 break;
411 }
412 return NOTIFY_OK;
413 }
414
415 static struct notifier_block __refdata mc_cpu_notifier = {
416 .notifier_call = mc_cpu_callback,
417 };
418
419 static int __init microcode_init (void)
420 {
421 int error;
422
423 printk(KERN_INFO
424 "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");
425
426 error = microcode_dev_init();
427 if (error)
428 return error;
429 microcode_pdev = platform_device_register_simple("microcode", -1,
430 NULL, 0);
431 if (IS_ERR(microcode_pdev)) {
432 microcode_dev_exit();
433 return PTR_ERR(microcode_pdev);
434 }
435
436 get_online_cpus();
437 error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);
438 put_online_cpus();
439 if (error) {
440 microcode_dev_exit();
441 platform_device_unregister(microcode_pdev);
442 return error;
443 }
444
445 register_hotcpu_notifier(&mc_cpu_notifier);
446 return 0;
447 }
448
449 static void __exit microcode_exit (void)
450 {
451 microcode_dev_exit();
452
453 unregister_hotcpu_notifier(&mc_cpu_notifier);
454
455 get_online_cpus();
456 sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
457 put_online_cpus();
458
459 platform_device_unregister(microcode_pdev);
460 }
461
462 module_init(microcode_init)
463 module_exit(microcode_exit)
464
arch/x86/kernel/microcode_intel.c
1 /* 1 /*
2 * Intel CPU Microcode Update Driver for Linux 2 * Intel CPU Microcode Update Driver for Linux
3 * 3 *
4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
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.11 of Volume 3a, IA-32 Intel? Architecture 11 * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture
12 * Software Developer's Manual 12 * Software Developer's Manual
13 * Order Number 253668 or free download from: 13 * Order Number 253668 or free download from:
14 * 14 *
15 * http://developer.intel.com/design/pentium4/manuals/253668.htm 15 * http://developer.intel.com/design/pentium4/manuals/253668.htm
16 * 16 *
17 * For more information, go to http://www.urbanmyth.org/microcode 17 * For more information, go to http://www.urbanmyth.org/microcode
18 * 18 *
19 * This program is free software; you can redistribute it and/or 19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License 20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 21 * as published by the Free Software Foundation; either version
22 * 2 of the License, or (at your option) any later version. 22 * 2 of the License, or (at your option) any later version.
23 * 23 *
24 * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com> 24 * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com>
25 * Initial release. 25 * Initial release.
26 * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com> 26 * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com>
27 * Added read() support + cleanups. 27 * Added read() support + cleanups.
28 * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com> 28 * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com>
29 * Added 'device trimming' support. open(O_WRONLY) zeroes 29 * Added 'device trimming' support. open(O_WRONLY) zeroes
30 * and frees the saved copy of applied microcode. 30 * and frees the saved copy of applied microcode.
31 * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com> 31 * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com>
32 * Made to use devfs (/dev/cpu/microcode) + cleanups. 32 * Made to use devfs (/dev/cpu/microcode) + cleanups.
33 * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com> 33 * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com>
34 * Added misc device support (now uses both devfs and misc). 34 * Added misc device support (now uses both devfs and misc).
35 * Added MICROCODE_IOCFREE ioctl to clear memory. 35 * Added MICROCODE_IOCFREE ioctl to clear memory.
36 * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com> 36 * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com>
37 * Messages for error cases (non Intel & no suitable microcode). 37 * Messages for error cases (non Intel & no suitable microcode).
38 * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com> 38 * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com>
39 * Removed ->release(). Removed exclusive open and status bitmap. 39 * Removed ->release(). Removed exclusive open and status bitmap.
40 * Added microcode_rwsem to serialize read()/write()/ioctl(). 40 * Added microcode_rwsem to serialize read()/write()/ioctl().
41 * Removed global kernel lock usage. 41 * Removed global kernel lock usage.
42 * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com> 42 * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com>
43 * Write 0 to 0x8B msr and then cpuid before reading revision, 43 * Write 0 to 0x8B msr and then cpuid before reading revision,
44 * so that it works even if there were no update done by the 44 * so that it works even if there were no update done by the
45 * BIOS. Otherwise, reading from 0x8B gives junk (which happened 45 * BIOS. Otherwise, reading from 0x8B gives junk (which happened
46 * to be 0 on my machine which is why it worked even when I 46 * to be 0 on my machine which is why it worked even when I
47 * disabled update by the BIOS) 47 * disabled update by the BIOS)
48 * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix. 48 * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix.
49 * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and 49 * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and
50 * Tigran Aivazian <tigran@veritas.com> 50 * Tigran Aivazian <tigran@veritas.com>
51 * Intel Pentium 4 processor support and bugfixes. 51 * Intel Pentium 4 processor support and bugfixes.
52 * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com> 52 * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com>
53 * Bugfix for HT (Hyper-Threading) enabled processors 53 * Bugfix for HT (Hyper-Threading) enabled processors
54 * whereby processor resources are shared by all logical processors 54 * whereby processor resources are shared by all logical processors
55 * in a single CPU package. 55 * in a single CPU package.
56 * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and 56 * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and
57 * Tigran Aivazian <tigran@veritas.com>, 57 * Tigran Aivazian <tigran@veritas.com>,
58 * Serialize updates as required on HT processors due to speculative 58 * Serialize updates as required on HT processors due to speculative
59 * nature of implementation. 59 * nature of implementation.
60 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com> 60 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com>
61 * Fix the panic when writing zero-length microcode chunk. 61 * Fix the panic when writing zero-length microcode chunk.
62 * 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>,
63 * Jun Nakajima <jun.nakajima@intel.com> 63 * Jun Nakajima <jun.nakajima@intel.com>
64 * Support for the microcode updates in the new format. 64 * Support for the microcode updates in the new format.
65 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com> 65 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com>
66 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl 66 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl
67 * because we no longer hold a copy of applied microcode 67 * because we no longer hold a copy of applied microcode
68 * in kernel memory. 68 * in kernel memory.
69 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com> 69 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com>
70 * Fix sigmatch() macro to handle old CPUs with pf == 0. 70 * Fix sigmatch() macro to handle old CPUs with pf == 0.
71 * Thanks to Stuart Swales for pointing out this bug. 71 * Thanks to Stuart Swales for pointing out this bug.
72 */ 72 */
73 73
74 //#define DEBUG /* pr_debug */ 74 //#define DEBUG /* pr_debug */
75 #include <linux/capability.h> 75 #include <linux/capability.h>
76 #include <linux/kernel.h> 76 #include <linux/kernel.h>
77 #include <linux/init.h> 77 #include <linux/init.h>
78 #include <linux/sched.h> 78 #include <linux/sched.h>
79 #include <linux/smp_lock.h> 79 #include <linux/smp_lock.h>
80 #include <linux/cpumask.h> 80 #include <linux/cpumask.h>
81 #include <linux/module.h> 81 #include <linux/module.h>
82 #include <linux/slab.h> 82 #include <linux/slab.h>
83 #include <linux/vmalloc.h> 83 #include <linux/vmalloc.h>
84 #include <linux/miscdevice.h> 84 #include <linux/miscdevice.h>
85 #include <linux/spinlock.h> 85 #include <linux/spinlock.h>
86 #include <linux/mm.h> 86 #include <linux/mm.h>
87 #include <linux/fs.h> 87 #include <linux/fs.h>
88 #include <linux/mutex.h> 88 #include <linux/mutex.h>
89 #include <linux/cpu.h> 89 #include <linux/cpu.h>
90 #include <linux/firmware.h> 90 #include <linux/firmware.h>
91 #include <linux/platform_device.h> 91 #include <linux/platform_device.h>
92 92
93 #include <asm/msr.h> 93 #include <asm/msr.h>
94 #include <asm/uaccess.h> 94 #include <asm/uaccess.h>
95 #include <asm/processor.h> 95 #include <asm/processor.h>
96 #include <asm/microcode.h> 96 #include <asm/microcode.h>
97 97
98 MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver"); 98 MODULE_DESCRIPTION("Microcode Update Driver");
99 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); 99 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
100 MODULE_LICENSE("GPL"); 100 MODULE_LICENSE("GPL");
101 101
102 #define MICROCODE_VERSION "1.14a"
103
104 #define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ 102 #define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */
105 #define MC_HEADER_SIZE (sizeof (struct microcode_header)) /* 48 bytes */ 103 #define MC_HEADER_SIZE (sizeof(struct microcode_header)) /* 48 bytes */
106 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */ 104 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */
107 #define EXT_HEADER_SIZE (sizeof (struct extended_sigtable)) /* 20 bytes */ 105 #define EXT_HEADER_SIZE (sizeof(struct extended_sigtable)) /* 20 bytes */
108 #define EXT_SIGNATURE_SIZE (sizeof (struct extended_signature)) /* 12 bytes */ 106 #define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) /* 12 bytes */
109 #define DWSIZE (sizeof (u32)) 107 #define DWSIZE (sizeof(u32))
110 #define get_totalsize(mc) \ 108 #define get_totalsize(mc) \
111 (((struct microcode *)mc)->hdr.totalsize ? \ 109 (((struct microcode *)mc)->hdr.totalsize ? \
112 ((struct microcode *)mc)->hdr.totalsize : DEFAULT_UCODE_TOTALSIZE) 110 ((struct microcode *)mc)->hdr.totalsize : DEFAULT_UCODE_TOTALSIZE)
113 #define get_datasize(mc) \ 111 #define get_datasize(mc) \
114 (((struct microcode *)mc)->hdr.datasize ? \ 112 (((struct microcode *)mc)->hdr.datasize ? \
115 ((struct microcode *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE) 113 ((struct microcode *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE)
116 114
117 #define sigmatch(s1, s2, p1, p2) \ 115 #define sigmatch(s1, s2, p1, p2) \
118 (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0)))) 116 (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0))))
119 117
120 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) 118 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
121 119
122 /* serialize access to the physical write to MSR 0x79 */ 120 /* serialize access to the physical write to MSR 0x79 */
123 static DEFINE_SPINLOCK(microcode_update_lock); 121 static DEFINE_SPINLOCK(microcode_update_lock);
124 122
125 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ 123 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
126 static DEFINE_MUTEX(microcode_mutex); 124 extern struct mutex microcode_mutex;
127 125
128 static struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; 126 extern struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
129 127
130 static void collect_cpu_info(int cpu_num) 128 void collect_cpu_info(int cpu_num)
131 { 129 {
132 struct cpuinfo_x86 *c = &cpu_data(cpu_num); 130 struct cpuinfo_x86 *c = &cpu_data(cpu_num);
133 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 131 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
134 unsigned int val[2]; 132 unsigned int val[2];
135 133
136 /* We should bind the task to the CPU */ 134 /* We should bind the task to the CPU */
137 BUG_ON(raw_smp_processor_id() != cpu_num); 135 BUG_ON(raw_smp_processor_id() != cpu_num);
138 uci->pf = uci->rev = 0; 136 uci->pf = uci->rev = 0;
139 uci->mc = NULL; 137 uci->mc = NULL;
140 uci->valid = 1; 138 uci->valid = 1;
141 139
142 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || 140 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
143 cpu_has(c, X86_FEATURE_IA64)) { 141 cpu_has(c, X86_FEATURE_IA64)) {
144 printk(KERN_ERR "microcode: CPU%d not a capable Intel " 142 printk(KERN_ERR "microcode: CPU%d not a capable Intel "
145 "processor\n", cpu_num); 143 "processor\n", cpu_num);
146 uci->valid = 0; 144 uci->valid = 0;
147 return; 145 return;
148 } 146 }
149 147
150 uci->sig = cpuid_eax(0x00000001); 148 uci->sig = cpuid_eax(0x00000001);
151 149
152 if ((c->x86_model >= 5) || (c->x86 > 6)) { 150 if ((c->x86_model >= 5) || (c->x86 > 6)) {
153 /* get processor flags from MSR 0x17 */ 151 /* get processor flags from MSR 0x17 */
154 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 152 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
155 uci->pf = 1 << ((val[1] >> 18) & 7); 153 uci->pf = 1 << ((val[1] >> 18) & 7);
156 } 154 }
157 155
158 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 156 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
159 /* see notes above for revision 1.07. Apparent chip bug */ 157 /* see notes above for revision 1.07. Apparent chip bug */
160 sync_core(); 158 sync_core();
161 /* get the current revision from MSR 0x8B */ 159 /* get the current revision from MSR 0x8B */
162 rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev); 160 rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev);
163 pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", 161 pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n",
164 uci->sig, uci->pf, uci->rev); 162 uci->sig, uci->pf, uci->rev);
165 } 163 }
166 164
167 static inline int microcode_update_match(int cpu_num, 165 static inline int microcode_update_match(int cpu_num,
168 struct microcode_header *mc_header, int sig, int pf) 166 struct microcode_header *mc_header, int sig, int pf)
169 { 167 {
170 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 168 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
171 169
172 if (!sigmatch(sig, uci->sig, pf, uci->pf) 170 if (!sigmatch(sig, uci->sig, pf, uci->pf)
173 || mc_header->rev <= uci->rev) 171 || mc_header->rev <= uci->rev)
174 return 0; 172 return 0;
175 return 1; 173 return 1;
176 } 174 }
177 175
178 static int microcode_sanity_check(void *mc) 176 int microcode_sanity_check(void *mc)
179 { 177 {
180 struct microcode_header *mc_header = mc; 178 struct microcode_header *mc_header = mc;
181 struct extended_sigtable *ext_header = NULL; 179 struct extended_sigtable *ext_header = NULL;
182 struct extended_signature *ext_sig; 180 struct extended_signature *ext_sig;
183 unsigned long total_size, data_size, ext_table_size; 181 unsigned long total_size, data_size, ext_table_size;
184 int sum, orig_sum, ext_sigcount = 0, i; 182 int sum, orig_sum, ext_sigcount = 0, i;
185 183
186 total_size = get_totalsize(mc_header); 184 total_size = get_totalsize(mc_header);
187 data_size = get_datasize(mc_header); 185 data_size = get_datasize(mc_header);
188 if (data_size + MC_HEADER_SIZE > total_size) { 186 if (data_size + MC_HEADER_SIZE > total_size) {
189 printk(KERN_ERR "microcode: error! " 187 printk(KERN_ERR "microcode: error! "
190 "Bad data size in microcode data file\n"); 188 "Bad data size in microcode data file\n");
191 return -EINVAL; 189 return -EINVAL;
192 } 190 }
193 191
194 if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { 192 if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
195 printk(KERN_ERR "microcode: error! " 193 printk(KERN_ERR "microcode: error! "
196 "Unknown microcode update format\n"); 194 "Unknown microcode update format\n");
197 return -EINVAL; 195 return -EINVAL;
198 } 196 }
199 ext_table_size = total_size - (MC_HEADER_SIZE + data_size); 197 ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
200 if (ext_table_size) { 198 if (ext_table_size) {
201 if ((ext_table_size < EXT_HEADER_SIZE) 199 if ((ext_table_size < EXT_HEADER_SIZE)
202 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { 200 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
203 printk(KERN_ERR "microcode: error! " 201 printk(KERN_ERR "microcode: error! "
204 "Small exttable size in microcode data file\n"); 202 "Small exttable size in microcode data file\n");
205 return -EINVAL; 203 return -EINVAL;
206 } 204 }
207 ext_header = mc + MC_HEADER_SIZE + data_size; 205 ext_header = mc + MC_HEADER_SIZE + data_size;
208 if (ext_table_size != exttable_size(ext_header)) { 206 if (ext_table_size != exttable_size(ext_header)) {
209 printk(KERN_ERR "microcode: error! " 207 printk(KERN_ERR "microcode: error! "
210 "Bad exttable size in microcode data file\n"); 208 "Bad exttable size in microcode data file\n");
211 return -EFAULT; 209 return -EFAULT;
212 } 210 }
213 ext_sigcount = ext_header->count; 211 ext_sigcount = ext_header->count;
214 } 212 }
215 213
216 /* check extended table checksum */ 214 /* check extended table checksum */
217 if (ext_table_size) { 215 if (ext_table_size) {
218 int ext_table_sum = 0; 216 int ext_table_sum = 0;
219 int *ext_tablep = (int *)ext_header; 217 int *ext_tablep = (int *)ext_header;
220 218
221 i = ext_table_size / DWSIZE; 219 i = ext_table_size / DWSIZE;
222 while (i--) 220 while (i--)
223 ext_table_sum += ext_tablep[i]; 221 ext_table_sum += ext_tablep[i];
224 if (ext_table_sum) { 222 if (ext_table_sum) {
225 printk(KERN_WARNING "microcode: aborting, " 223 printk(KERN_WARNING "microcode: aborting, "
226 "bad extended signature table checksum\n"); 224 "bad extended signature table checksum\n");
227 return -EINVAL; 225 return -EINVAL;
228 } 226 }
229 } 227 }
230 228
231 /* calculate the checksum */ 229 /* calculate the checksum */
232 orig_sum = 0; 230 orig_sum = 0;
233 i = (MC_HEADER_SIZE + data_size) / DWSIZE; 231 i = (MC_HEADER_SIZE + data_size) / DWSIZE;
234 while (i--) 232 while (i--)
235 orig_sum += ((int *)mc)[i]; 233 orig_sum += ((int *)mc)[i];
236 if (orig_sum) { 234 if (orig_sum) {
237 printk(KERN_ERR "microcode: aborting, bad checksum\n"); 235 printk(KERN_ERR "microcode: aborting, bad checksum\n");
238 return -EINVAL; 236 return -EINVAL;
239 } 237 }
240 if (!ext_table_size) 238 if (!ext_table_size)
241 return 0; 239 return 0;
242 /* check extended signature checksum */ 240 /* check extended signature checksum */
243 for (i = 0; i < ext_sigcount; i++) { 241 for (i = 0; i < ext_sigcount; i++) {
244 ext_sig = (void *)ext_header + EXT_HEADER_SIZE + 242 ext_sig = (void *)ext_header + EXT_HEADER_SIZE +
245 EXT_SIGNATURE_SIZE * i; 243 EXT_SIGNATURE_SIZE * i;
246 sum = orig_sum 244 sum = orig_sum
247 - (mc_header->sig + mc_header->pf + mc_header->cksum) 245 - (mc_header->sig + mc_header->pf + mc_header->cksum)
248 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); 246 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
249 if (sum) { 247 if (sum) {
250 printk(KERN_ERR "microcode: aborting, bad checksum\n"); 248 printk(KERN_ERR "microcode: aborting, bad checksum\n");
251 return -EINVAL; 249 return -EINVAL;
252 } 250 }
253 } 251 }
254 return 0; 252 return 0;
255 } 253 }
256 254
257 /* 255 /*
258 * return 0 - no update found 256 * return 0 - no update found
259 * return 1 - found update 257 * return 1 - found update
260 * return < 0 - error 258 * return < 0 - error
261 */ 259 */
262 static int get_maching_microcode(void *mc, int cpu) 260 int get_matching_microcode(void *mc, int cpu)
263 { 261 {
264 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 262 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
265 struct microcode_header *mc_header = mc; 263 struct microcode_header *mc_header = mc;
266 struct extended_sigtable *ext_header; 264 struct extended_sigtable *ext_header;
267 unsigned long total_size = get_totalsize(mc_header); 265 unsigned long total_size = get_totalsize(mc_header);
268 int ext_sigcount, i; 266 int ext_sigcount, i;
269 struct extended_signature *ext_sig; 267 struct extended_signature *ext_sig;
270 void *new_mc; 268 void *new_mc;
271 269
272 if (microcode_update_match(cpu, mc_header, 270 if (microcode_update_match(cpu, mc_header,
273 mc_header->sig, mc_header->pf)) 271 mc_header->sig, mc_header->pf))
274 goto find; 272 goto find;
275 273
276 if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE) 274 if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE)
277 return 0; 275 return 0;
278 276
279 ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE; 277 ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE;
280 ext_sigcount = ext_header->count; 278 ext_sigcount = ext_header->count;
281 ext_sig = (void *)ext_header + EXT_HEADER_SIZE; 279 ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
282 for (i = 0; i < ext_sigcount; i++) { 280 for (i = 0; i < ext_sigcount; i++) {
283 if (microcode_update_match(cpu, mc_header, 281 if (microcode_update_match(cpu, mc_header,
284 ext_sig->sig, ext_sig->pf)) 282 ext_sig->sig, ext_sig->pf))
285 goto find; 283 goto find;
286 ext_sig++; 284 ext_sig++;
287 } 285 }
288 return 0; 286 return 0;
289 find: 287 find:
290 pr_debug("microcode: CPU%d found a matching microcode update with" 288 pr_debug("microcode: CPU%d found a matching microcode update with"
291 " version 0x%x (current=0x%x)\n", cpu, mc_header->rev,uci->rev); 289 " version 0x%x (current=0x%x)\n", cpu, mc_header->rev, uci->rev);
292 new_mc = vmalloc(total_size); 290 new_mc = vmalloc(total_size);
293 if (!new_mc) { 291 if (!new_mc) {
294 printk(KERN_ERR "microcode: error! Can not allocate memory\n"); 292 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
295 return -ENOMEM; 293 return -ENOMEM;
296 } 294 }
297 295
298 /* free previous update file */ 296 /* free previous update file */
299 vfree(uci->mc); 297 vfree(uci->mc);
300 298
301 memcpy(new_mc, mc, total_size); 299 memcpy(new_mc, mc, total_size);
302 uci->mc = new_mc; 300 uci->mc = new_mc;
303 return 1; 301 return 1;
304 } 302 }
305 303
306 static void apply_microcode(int cpu) 304 void apply_microcode(int cpu)
307 { 305 {
308 unsigned long flags; 306 unsigned long flags;
309 unsigned int val[2]; 307 unsigned int val[2];
310 int cpu_num = raw_smp_processor_id(); 308 int cpu_num = raw_smp_processor_id();
311 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 309 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
312 310
313 /* We should bind the task to the CPU */ 311 /* We should bind the task to the CPU */
314 BUG_ON(cpu_num != cpu); 312 BUG_ON(cpu_num != cpu);
315 313
316 if (uci->mc == NULL) 314 if (uci->mc == NULL)
317 return; 315 return;
318 316
319 /* serialize access to the physical write to MSR 0x79 */ 317 /* serialize access to the physical write to MSR 0x79 */
320 spin_lock_irqsave(&microcode_update_lock, flags); 318 spin_lock_irqsave(&microcode_update_lock, flags);
321 319
322 /* write microcode via MSR 0x79 */ 320 /* write microcode via MSR 0x79 */
323 wrmsr(MSR_IA32_UCODE_WRITE, 321 wrmsr(MSR_IA32_UCODE_WRITE,
324 (unsigned long) uci->mc->bits, 322 (unsigned long) uci->mc->bits,
325 (unsigned long) uci->mc->bits >> 16 >> 16); 323 (unsigned long) uci->mc->bits >> 16 >> 16);
326 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 324 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
327 325
328 /* see notes above for revision 1.07. Apparent chip bug */ 326 /* see notes above for revision 1.07. Apparent chip bug */
329 sync_core(); 327 sync_core();
330 328
331 /* get the current revision from MSR 0x8B */ 329 /* get the current revision from MSR 0x8B */
332 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 330 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
333 331
334 spin_unlock_irqrestore(&microcode_update_lock, flags); 332 spin_unlock_irqrestore(&microcode_update_lock, flags);
335 if (val[1] != uci->mc->hdr.rev) { 333 if (val[1] != uci->mc->hdr.rev) {
336 printk(KERN_ERR "microcode: CPU%d update from revision " 334 printk(KERN_ERR "microcode: CPU%d update from revision "
337 "0x%x to 0x%x failed\n", cpu_num, uci->rev, val[1]); 335 "0x%x to 0x%x failed\n", cpu_num, uci->rev, val[1]);
338 return; 336 return;
339 } 337 }
340 printk(KERN_INFO "microcode: CPU%d updated from revision " 338 printk(KERN_INFO "microcode: CPU%d updated from revision "
341 "0x%x to 0x%x, date = %08x \n", 339 "0x%x to 0x%x, date = %08x \n",
342 cpu_num, uci->rev, val[1], uci->mc->hdr.date); 340 cpu_num, uci->rev, val[1], uci->mc->hdr.date);
343 uci->rev = val[1]; 341 uci->rev = val[1];
344 } 342 }
345 343
346 #ifdef CONFIG_MICROCODE_OLD_INTERFACE 344 #ifdef CONFIG_MICROCODE_OLD_INTERFACE
347 static void __user *user_buffer; /* user area microcode data buffer */ 345 extern void __user *user_buffer; /* user area microcode data buffer */
348 static unsigned int user_buffer_size; /* it's size */ 346 extern unsigned int user_buffer_size; /* it's size */
349 347
350 static long get_next_ucode(void **mc, long offset) 348 long get_next_ucode(void **mc, long offset)
351 { 349 {
352 struct microcode_header mc_header; 350 struct microcode_header mc_header;
353 unsigned long total_size; 351 unsigned long total_size;
354 352
355 /* No more data */ 353 /* No more data */
356 if (offset >= user_buffer_size) 354 if (offset >= user_buffer_size)
357 return 0; 355 return 0;
358 if (copy_from_user(&mc_header, user_buffer + offset, MC_HEADER_SIZE)) { 356 if (copy_from_user(&mc_header, user_buffer + offset, MC_HEADER_SIZE)) {
359 printk(KERN_ERR "microcode: error! Can not read user data\n"); 357 printk(KERN_ERR "microcode: error! Can not read user data\n");
360 return -EFAULT; 358 return -EFAULT;
361 } 359 }
362 total_size = get_totalsize(&mc_header); 360 total_size = get_totalsize(&mc_header);
363 if (offset + total_size > user_buffer_size) { 361 if (offset + total_size > user_buffer_size) {
364 printk(KERN_ERR "microcode: error! Bad total size in microcode " 362 printk(KERN_ERR "microcode: error! Bad total size in microcode "
365 "data file\n"); 363 "data file\n");
366 return -EINVAL; 364 return -EINVAL;
367 } 365 }
368 *mc = vmalloc(total_size); 366 *mc = vmalloc(total_size);
369 if (!*mc) 367 if (!*mc)
370 return -ENOMEM; 368 return -ENOMEM;
371 if (copy_from_user(*mc, user_buffer + offset, total_size)) { 369 if (copy_from_user(*mc, user_buffer + offset, total_size)) {
372 printk(KERN_ERR "microcode: error! Can not read user data\n"); 370 printk(KERN_ERR "microcode: error! Can not read user data\n");
373 vfree(*mc); 371 vfree(*mc);
374 return -EFAULT; 372 return -EFAULT;
375 } 373 }
376 return offset + total_size; 374 return offset + total_size;
377 } 375 }
378
379 static int do_microcode_update (void)
380 {
381 long cursor = 0;
382 int error = 0;
383 void *new_mc = NULL;
384 int cpu;
385 cpumask_t old;
386 cpumask_of_cpu_ptr_declare(newmask);
387
388 old = current->cpus_allowed;
389
390 while ((cursor = get_next_ucode(&new_mc, cursor)) > 0) {
391 error = microcode_sanity_check(new_mc);
392 if (error)
393 goto out;
394 /*
395 * It's possible the data file has multiple matching ucode,
396 * lets keep searching till the latest version
397 */
398 for_each_online_cpu(cpu) {
399 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
400
401 if (!uci->valid)
402 continue;
403 cpumask_of_cpu_ptr_next(newmask, cpu);
404 set_cpus_allowed_ptr(current, newmask);
405 error = get_maching_microcode(new_mc, cpu);
406 if (error < 0)
407 goto out;
408 if (error == 1)
409 apply_microcode(cpu);
410 }
411 vfree(new_mc);
412 }
413 out:
414 if (cursor > 0)
415 vfree(new_mc);
416 if (cursor < 0)
417 error = cursor;
418 set_cpus_allowed_ptr(current, &old);
419 return error;
420 }
421
422 static int microcode_open (struct inode *unused1, struct file *unused2)
423 {
424 cycle_kernel_lock();
425 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
426 }
427
428 static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
429 {
430 ssize_t ret;
431
432 if ((len >> PAGE_SHIFT) > num_physpages) {
433 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
434 return -EINVAL;
435 }
436
437 get_online_cpus();
438 mutex_lock(&microcode_mutex);
439
440 user_buffer = (void __user *) buf;
441 user_buffer_size = (int) len;
442
443 ret = do_microcode_update();
444 if (!ret)
445 ret = (ssize_t)len;
446
447 mutex_unlock(&microcode_mutex);
448 put_online_cpus();
449
450 return ret;
451 }
452
453 static const struct file_operations microcode_fops = {
454 .owner = THIS_MODULE,
455 .write = microcode_write,
456 .open = microcode_open,
457 };
458
459 static struct miscdevice microcode_dev = {
460 .minor = MICROCODE_MINOR,
461 .name = "microcode",
462 .fops = &microcode_fops,
463 };
464
465 static int __init microcode_dev_init (void)
466 {
467 int error;
468
469 error = misc_register(&microcode_dev);
470 if (error) {
471 printk(KERN_ERR
472 "microcode: can't misc_register on minor=%d\n",
473 MICROCODE_MINOR);
474 return error;
475 }
476
477 return 0;
478 }
479
480 static void microcode_dev_exit (void)
481 {
482 misc_deregister(&microcode_dev);
483 }
484
485 MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
486 #else
487 #define microcode_dev_init() 0
488 #define microcode_dev_exit() do { } while(0)
489 #endif 376 #endif
490 377
491 static long get_next_ucode_from_buffer(void **mc, const u8 *buf, 378 static long get_next_ucode_from_buffer(void **mc, const u8 *buf,
492 unsigned long size, long offset) 379 unsigned long size, long offset)
493 { 380 {
494 struct microcode_header *mc_header; 381 struct microcode_header *mc_header;
495 unsigned long total_size; 382 unsigned long total_size;
496 383
497 /* No more data */ 384 /* No more data */
498 if (offset >= size) 385 if (offset >= size)
499 return 0; 386 return 0;
500 mc_header = (struct microcode_header *)(buf + offset); 387 mc_header = (struct microcode_header *)(buf + offset);
501 total_size = get_totalsize(mc_header); 388 total_size = get_totalsize(mc_header);
502 389
503 if (offset + total_size > size) { 390 if (offset + total_size > size) {
504 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 391 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
505 return -EINVAL; 392 return -EINVAL;
506 } 393 }
507 394
508 *mc = vmalloc(total_size); 395 *mc = vmalloc(total_size);
509 if (!*mc) { 396 if (!*mc) {
510 printk(KERN_ERR "microcode: error! Can not allocate memory\n"); 397 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
511 return -ENOMEM; 398 return -ENOMEM;
512 } 399 }
513 memcpy(*mc, buf + offset, total_size); 400 memcpy(*mc, buf + offset, total_size);
514 return offset + total_size; 401 return offset + total_size;
515 } 402 }
516 403
517 /* fake device for request_firmware */ 404 /* fake device for request_firmware */
518 static struct platform_device *microcode_pdev; 405 extern struct platform_device *microcode_pdev;
519 406
520 static int cpu_request_microcode(int cpu) 407 int cpu_request_microcode(int cpu)
521 { 408 {
522 char name[30]; 409 char name[30];
523 struct cpuinfo_x86 *c = &cpu_data(cpu); 410 struct cpuinfo_x86 *c = &cpu_data(cpu);
524 const struct firmware *firmware; 411 const struct firmware *firmware;
525 const u8 *buf; 412 const u8 *buf;
526 unsigned long size; 413 unsigned long size;
527 long offset = 0; 414 long offset = 0;
528 int error; 415 int error;
529 void *mc; 416 void *mc;
530 417
531 /* We should bind the task to the CPU */ 418 /* We should bind the task to the CPU */
532 BUG_ON(cpu != raw_smp_processor_id()); 419 BUG_ON(cpu != raw_smp_processor_id());
533 sprintf(name,"intel-ucode/%02x-%02x-%02x", 420 sprintf(name, "intel-ucode/%02x-%02x-%02x",
534 c->x86, c->x86_model, c->x86_mask); 421 c->x86, c->x86_model, c->x86_mask);
535 error = request_firmware(&firmware, name, &microcode_pdev->dev); 422 error = request_firmware(&firmware, name, &microcode_pdev->dev);
536 if (error) { 423 if (error) {
537 pr_debug("microcode: data file %s load failed\n", name); 424 pr_debug("microcode: data file %s load failed\n", name);
538 return error; 425 return error;
539 } 426 }
540 buf = firmware->data; 427 buf = firmware->data;
541 size = firmware->size; 428 size = firmware->size;
542 while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset)) 429 while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset))
543 > 0) { 430 > 0) {
544 error = microcode_sanity_check(mc); 431 error = microcode_sanity_check(mc);
545 if (error) 432 if (error)
546 break; 433 break;
547 error = get_maching_microcode(mc, cpu); 434 error = get_matching_microcode(mc, cpu);
548 if (error < 0) 435 if (error < 0)
549 break; 436 break;
550 /* 437 /*
551 * It's possible the data file has multiple matching ucode, 438 * It's possible the data file has multiple matching ucode,
552 * lets keep searching till the latest version 439 * lets keep searching till the latest version
553 */ 440 */
554 if (error == 1) { 441 if (error == 1) {
555 apply_microcode(cpu); 442 apply_microcode(cpu);
556 error = 0; 443 error = 0;
557 } 444 }
558 vfree(mc); 445 vfree(mc);
559 } 446 }
560 if (offset > 0) 447 if (offset > 0)
561 vfree(mc); 448 vfree(mc);
562 if (offset < 0) 449 if (offset < 0)
563 error = offset; 450 error = offset;
564 release_firmware(firmware); 451 release_firmware(firmware);
565 452
566 return error; 453 return error;
567 } 454 }
568 455
569 static int apply_microcode_check_cpu(int cpu) 456 int apply_microcode_check_cpu(int cpu)
570 { 457 {
571 struct cpuinfo_x86 *c = &cpu_data(cpu); 458 struct cpuinfo_x86 *c = &cpu_data(cpu);
572 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 459 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
573 cpumask_t old; 460 cpumask_t old;
574 cpumask_of_cpu_ptr(newmask, cpu); 461 cpumask_of_cpu_ptr(newmask, cpu);
575 unsigned int val[2]; 462 unsigned int val[2];
576 int err = 0; 463 int err = 0;
577 464
578 /* Check if the microcode is available */ 465 /* Check if the microcode is available */
579 if (!uci->mc) 466 if (!uci->mc)
580 return 0; 467 return 0;
581 468
582 old = current->cpus_allowed; 469 old = current->cpus_allowed;
583 set_cpus_allowed_ptr(current, newmask); 470 set_cpus_allowed_ptr(current, newmask);
584 471
585 /* Check if the microcode we have in memory matches the CPU */ 472 /* Check if the microcode we have in memory matches the CPU */
586 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || 473 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
587 cpu_has(c, X86_FEATURE_IA64) || uci->sig != cpuid_eax(0x00000001)) 474 cpu_has(c, X86_FEATURE_IA64) || uci->sig != cpuid_eax(0x00000001))
588 err = -EINVAL; 475 err = -EINVAL;
589 476
590 if (!err && ((c->x86_model >= 5) || (c->x86 > 6))) { 477 if (!err && ((c->x86_model >= 5) || (c->x86 > 6))) {
591 /* get processor flags from MSR 0x17 */ 478 /* get processor flags from MSR 0x17 */
592 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 479 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
593 if (uci->pf != (1 << ((val[1] >> 18) & 7))) 480 if (uci->pf != (1 << ((val[1] >> 18) & 7)))
594 err = -EINVAL; 481 err = -EINVAL;
595 } 482 }
596 483
597 if (!err) { 484 if (!err) {
598 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 485 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
599 /* see notes above for revision 1.07. Apparent chip bug */ 486 /* see notes above for revision 1.07. Apparent chip bug */
600 sync_core(); 487 sync_core();
601 /* get the current revision from MSR 0x8B */ 488 /* get the current revision from MSR 0x8B */
602 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 489 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
603 if (uci->rev != val[1]) 490 if (uci->rev != val[1])
604 err = -EINVAL; 491 err = -EINVAL;
605 } 492 }
606 493
607 if (!err) 494 if (!err)
608 apply_microcode(cpu); 495 apply_microcode(cpu);
609 else 496 else
610 printk(KERN_ERR "microcode: Could not apply microcode to CPU%d:" 497 printk(KERN_ERR "microcode: Could not apply microcode to CPU%d:"
611 " sig=0x%x, pf=0x%x, rev=0x%x\n", 498 " sig=0x%x, pf=0x%x, rev=0x%x\n",
612 cpu, uci->sig, uci->pf, uci->rev); 499 cpu, uci->sig, uci->pf, uci->rev);
613 500
614 set_cpus_allowed_ptr(current, &old); 501 set_cpus_allowed_ptr(current, &old);
615 return err; 502 return err;
616 } 503 }
617 504
618 static void microcode_init_cpu(int cpu, int resume) 505 void microcode_fini_cpu(int cpu)
619 { 506 {
620 cpumask_t old;
621 cpumask_of_cpu_ptr(newmask, cpu);
622 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 507 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
623 508
624 old = current->cpus_allowed;
625
626 set_cpus_allowed_ptr(current, newmask);
627 mutex_lock(&microcode_mutex); 509 mutex_lock(&microcode_mutex);
628 collect_cpu_info(cpu);
629 if (uci->valid && system_state == SYSTEM_RUNNING && !resume)
630 cpu_request_microcode(cpu);
631 mutex_unlock(&microcode_mutex);
632 set_cpus_allowed_ptr(current, &old);
633 }
634
635 static void microcode_fini_cpu(int cpu)
636 {
637 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
638
639 mutex_lock(&microcode_mutex);
640 uci->valid = 0; 510 uci->valid = 0;
641 vfree(uci->mc); 511 kfree(uci->mc);
642 uci->mc = NULL; 512 uci->mc = NULL;
643 mutex_unlock(&microcode_mutex); 513 mutex_unlock(&microcode_mutex);
644 } 514 }
645
646 static ssize_t reload_store(struct sys_device *dev,
647 struct sysdev_attribute *attr,
648 const char *buf, size_t sz)
649 {
650 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
651 char *end;
652 unsigned long val = simple_strtoul(buf, &end, 0);
653 int err = 0;
654 int cpu = dev->id;
655
656 if (end == buf)
657 return -EINVAL;
658 if (val == 1) {
659 cpumask_t old;
660 cpumask_of_cpu_ptr(newmask, cpu);
661
662 old = current->cpus_allowed;
663
664 get_online_cpus();
665 set_cpus_allowed_ptr(current, newmask);
666
667 mutex_lock(&microcode_mutex);
668 if (uci->valid)
669 err = cpu_request_microcode(cpu);
670 mutex_unlock(&microcode_mutex);
671 put_online_cpus();
672 set_cpus_allowed_ptr(current, &old);
673 }
674 if (err)
675 return err;
676 return sz;
677 }
678
679 static ssize_t version_show(struct sys_device *dev,
680 struct sysdev_attribute *attr, char *buf)
681 {
682 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
683
684 return sprintf(buf, "0x%x\n", uci->rev);
685 }
686
687 static ssize_t pf_show(struct sys_device *dev,
688 struct sysdev_attribute *attr, char *buf)
689 {
690 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
691
692 return sprintf(buf, "0x%x\n", uci->pf);
693 }
694
695 static SYSDEV_ATTR(reload, 0200, NULL, reload_store);
696 static SYSDEV_ATTR(version, 0400, version_show, NULL);
697 static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);
698
699 static struct attribute *mc_default_attrs[] = {
700 &attr_reload.attr,
701 &attr_version.attr,
702 &attr_processor_flags.attr,
703 NULL
704 };
705
706 static struct attribute_group mc_attr_group = {
707 .attrs = mc_default_attrs,
708 .name = "microcode",
709 };
710
711 static int __mc_sysdev_add(struct sys_device *sys_dev, int resume)
712 {
713 int err, cpu = sys_dev->id;
714 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
715
716 if (!cpu_online(cpu))
717 return 0;
718
719 pr_debug("microcode: CPU%d added\n", cpu);
720 memset(uci, 0, sizeof(*uci));
721
722 err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
723 if (err)
724 return err;
725
726 microcode_init_cpu(cpu, resume);
727
728 return 0;
729 }
730
731 static int mc_sysdev_add(struct sys_device *sys_dev)
732 {
733 return __mc_sysdev_add(sys_dev, 0);
734 }
735
736 static int mc_sysdev_remove(struct sys_device *sys_dev)
737 {
738 int cpu = sys_dev->id;
739
740 if (!cpu_online(cpu))
741 return 0;
742
743 pr_debug("microcode: CPU%d removed\n", cpu);
744 microcode_fini_cpu(cpu);
745 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
746 return 0;
747 }
748
749 static int mc_sysdev_resume(struct sys_device *dev)
750 {
751 int cpu = dev->id;
752
753 if (!cpu_online(cpu))
754 return 0;
755 pr_debug("microcode: CPU%d resumed\n", cpu);
756 /* only CPU 0 will apply ucode here */
757 apply_microcode(0);
758 return 0;
759 }
760
761 static struct sysdev_driver mc_sysdev_driver = {
762 .add = mc_sysdev_add,
763 .remove = mc_sysdev_remove,
764 .resume = mc_sysdev_resume,
765 };
766
767 static __cpuinit int
768 mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
769 {
770 unsigned int cpu = (unsigned long)hcpu;
771 struct sys_device *sys_dev;
772
773 sys_dev = get_cpu_sysdev(cpu);
774 switch (action) {
775 case CPU_UP_CANCELED_FROZEN:
776 /* The CPU refused to come up during a system resume */
777 microcode_fini_cpu(cpu);
778 break;
779 case CPU_ONLINE:
780 case CPU_DOWN_FAILED:
781 mc_sysdev_add(sys_dev);
782 break;
783 case CPU_ONLINE_FROZEN:
784 /* System-wide resume is in progress, try to apply microcode */
785 if (apply_microcode_check_cpu(cpu)) {
786 /* The application of microcode failed */
787 microcode_fini_cpu(cpu);
788 __mc_sysdev_add(sys_dev, 1);
789 break;
790 }
791 case CPU_DOWN_FAILED_FROZEN:
792 if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))
793 printk(KERN_ERR "microcode: Failed to create the sysfs "
794 "group for CPU%d\n", cpu);
795 break;
796 case CPU_DOWN_PREPARE:
797 mc_sysdev_remove(sys_dev);
798 break;
799 case CPU_DOWN_PREPARE_FROZEN:
800 /* Suspend is in progress, only remove the interface */
801 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
802 break;
803 }
804 return NOTIFY_OK;
805 }
806
807 static struct notifier_block __refdata mc_cpu_notifier = {
808 .notifier_call = mc_cpu_callback,
809 };
810
811 static int __init microcode_init (void)
812 {
813 int error;
814
815 printk(KERN_INFO
816 "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");
817
818 error = microcode_dev_init();
819 if (error)
820 return error;
821 microcode_pdev = platform_device_register_simple("microcode", -1,
822 NULL, 0);
823 if (IS_ERR(microcode_pdev)) {
824 microcode_dev_exit();
825 return PTR_ERR(microcode_pdev);
826 }
827
828 get_online_cpus();
829 error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);
830 put_online_cpus();
831 if (error) {
832 microcode_dev_exit();
833 platform_device_unregister(microcode_pdev);
834 return error;
835 }
836
837 register_hotcpu_notifier(&mc_cpu_notifier);
838 return 0;
839 }
840
841 static void __exit microcode_exit (void)
842 {
843 microcode_dev_exit();
844
845 unregister_hotcpu_notifier(&mc_cpu_notifier);
846
847 get_online_cpus();
848 sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
849 put_online_cpus();
850
851 platform_device_unregister(microcode_pdev);
852 }
853
854 module_init(microcode_init)
855 module_exit(microcode_exit)
856 515