28dba1a6e4aa38507b73dda8743de3de0d3c8366
[safe/jmp/linux-2.6] / arch / x86 / kernel / microcode.c
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       "2.00"
103
104 struct microcode_ops *microcode_ops;
105
106 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
107 DEFINE_MUTEX(microcode_mutex);
108 EXPORT_SYMBOL_GPL(microcode_mutex);
109
110 struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
111 EXPORT_SYMBOL_GPL(ucode_cpu_info);
112
113 #ifdef CONFIG_MICROCODE_OLD_INTERFACE
114 void __user *user_buffer;               /* user area microcode data buffer */
115 EXPORT_SYMBOL_GPL(user_buffer);
116 unsigned int user_buffer_size;          /* it's size */
117 EXPORT_SYMBOL_GPL(user_buffer_size);
118
119 static int do_microcode_update (void)
120 {
121         long cursor = 0;
122         int error = 0;
123         void *new_mc = NULL;
124         int cpu;
125         cpumask_t old;
126
127         old = current->cpus_allowed;
128
129         while ((cursor = microcode_ops->get_next_ucode(&new_mc, cursor)) > 0) {
130                 error = microcode_ops->microcode_sanity_check(new_mc);
131                 if (error)
132                         goto out;
133                 /*
134                  * It's possible the data file has multiple matching ucode,
135                  * lets keep searching till the latest version
136                  */
137                 for_each_online_cpu(cpu) {
138                         struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
139
140                         if (!uci->valid)
141                                 continue;
142                         set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
143                         error = microcode_ops->get_matching_microcode(new_mc,
144                                                                       cpu);
145                         if (error < 0)
146                                 goto out;
147                         if (error == 1)
148                                 microcode_ops->apply_microcode(cpu);
149                 }
150                 vfree(new_mc);
151         }
152 out:
153         if (cursor > 0)
154                 vfree(new_mc);
155         if (cursor < 0)
156                 error = cursor;
157         set_cpus_allowed_ptr(current, &old);
158         return error;
159 }
160
161 static int microcode_open (struct inode *unused1, struct file *unused2)
162 {
163         cycle_kernel_lock();
164         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
165 }
166
167 static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
168 {
169         ssize_t ret;
170
171         if ((len >> PAGE_SHIFT) > num_physpages) {
172                 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
173                 return -EINVAL;
174         }
175
176         get_online_cpus();
177         mutex_lock(&microcode_mutex);
178
179         user_buffer = (void __user *) buf;
180         user_buffer_size = (int) len;
181
182         ret = do_microcode_update();
183         if (!ret)
184                 ret = (ssize_t)len;
185
186         mutex_unlock(&microcode_mutex);
187         put_online_cpus();
188
189         return ret;
190 }
191
192 static const struct file_operations microcode_fops = {
193         .owner          = THIS_MODULE,
194         .write          = microcode_write,
195         .open           = microcode_open,
196 };
197
198 static struct miscdevice microcode_dev = {
199         .minor          = MICROCODE_MINOR,
200         .name           = "microcode",
201         .fops           = &microcode_fops,
202 };
203
204 static int __init microcode_dev_init (void)
205 {
206         int error;
207
208         error = misc_register(&microcode_dev);
209         if (error) {
210                 printk(KERN_ERR
211                         "microcode: can't misc_register on minor=%d\n",
212                         MICROCODE_MINOR);
213                 return error;
214         }
215
216         return 0;
217 }
218
219 static void microcode_dev_exit (void)
220 {
221         misc_deregister(&microcode_dev);
222 }
223
224 MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
225 #else
226 #define microcode_dev_init() 0
227 #define microcode_dev_exit() do { } while(0)
228 #endif
229
230 /* fake device for request_firmware */
231 struct platform_device *microcode_pdev;
232 EXPORT_SYMBOL_GPL(microcode_pdev);
233
234 static void microcode_init_cpu(int cpu, int resume)
235 {
236         cpumask_t old;
237         struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
238
239         old = current->cpus_allowed;
240
241         set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
242         mutex_lock(&microcode_mutex);
243         microcode_ops->collect_cpu_info(cpu);
244         if (uci->valid && system_state == SYSTEM_RUNNING && !resume)
245                 microcode_ops->cpu_request_microcode(cpu);
246         mutex_unlock(&microcode_mutex);
247         set_cpus_allowed_ptr(current, &old);
248 }
249
250 static ssize_t reload_store(struct sys_device *dev,
251                             struct sysdev_attribute *attr,
252                             const char *buf, size_t sz)
253 {
254         struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
255         char *end;
256         unsigned long val = simple_strtoul(buf, &end, 0);
257         int err = 0;
258         int cpu = dev->id;
259
260         if (end == buf)
261                 return -EINVAL;
262         if (val == 1) {
263                 cpumask_t old = current->cpus_allowed;
264
265                 get_online_cpus();
266                 set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
267
268                 mutex_lock(&microcode_mutex);
269                 if (uci->valid)
270                         err = microcode_ops->cpu_request_microcode(cpu);
271                 mutex_unlock(&microcode_mutex);
272                 put_online_cpus();
273                 set_cpus_allowed_ptr(current, &old);
274         }
275         if (err)
276                 return err;
277         return sz;
278 }
279
280 static ssize_t version_show(struct sys_device *dev,
281                         struct sysdev_attribute *attr, char *buf)
282 {
283         struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
284
285         return sprintf(buf, "0x%x\n", uci->rev);
286 }
287
288 static ssize_t pf_show(struct sys_device *dev,
289                         struct sysdev_attribute *attr, char *buf)
290 {
291         struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
292
293         return sprintf(buf, "0x%x\n", uci->pf);
294 }
295
296 static SYSDEV_ATTR(reload, 0200, NULL, reload_store);
297 static SYSDEV_ATTR(version, 0400, version_show, NULL);
298 static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);
299
300 static struct attribute *mc_default_attrs[] = {
301         &attr_reload.attr,
302         &attr_version.attr,
303         &attr_processor_flags.attr,
304         NULL
305 };
306
307 static struct attribute_group mc_attr_group = {
308         .attrs = mc_default_attrs,
309         .name = "microcode",
310 };
311
312 static int __mc_sysdev_add(struct sys_device *sys_dev, int resume)
313 {
314         int err, cpu = sys_dev->id;
315         struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
316
317         if (!cpu_online(cpu))
318                 return 0;
319
320         pr_debug("microcode: CPU%d added\n", cpu);
321         memset(uci, 0, sizeof(*uci));
322
323         err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
324         if (err)
325                 return err;
326
327         microcode_init_cpu(cpu, resume);
328
329         return 0;
330 }
331
332 static int mc_sysdev_add(struct sys_device *sys_dev)
333 {
334         return __mc_sysdev_add(sys_dev, 0);
335 }
336
337 static int mc_sysdev_remove(struct sys_device *sys_dev)
338 {
339         int cpu = sys_dev->id;
340
341         if (!cpu_online(cpu))
342                 return 0;
343
344         pr_debug("microcode: CPU%d removed\n", cpu);
345         microcode_ops->microcode_fini_cpu(cpu);
346         sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
347         return 0;
348 }
349
350 static int mc_sysdev_resume(struct sys_device *dev)
351 {
352         int cpu = dev->id;
353
354         if (!cpu_online(cpu))
355                 return 0;
356         pr_debug("microcode: CPU%d resumed\n", cpu);
357         /* only CPU 0 will apply ucode here */
358         microcode_ops->apply_microcode(0);
359         return 0;
360 }
361
362 static struct sysdev_driver mc_sysdev_driver = {
363         .add = mc_sysdev_add,
364         .remove = mc_sysdev_remove,
365         .resume = mc_sysdev_resume,
366 };
367
368 static __cpuinit int
369 mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
370 {
371         unsigned int cpu = (unsigned long)hcpu;
372         struct sys_device *sys_dev;
373
374         sys_dev = get_cpu_sysdev(cpu);
375         switch (action) {
376         case CPU_UP_CANCELED_FROZEN:
377                 /* The CPU refused to come up during a system resume */
378                 microcode_ops->microcode_fini_cpu(cpu);
379                 break;
380         case CPU_ONLINE:
381         case CPU_DOWN_FAILED:
382                 mc_sysdev_add(sys_dev);
383                 break;
384         case CPU_ONLINE_FROZEN:
385                 /* System-wide resume is in progress, try to apply microcode */
386                 if (microcode_ops->apply_microcode_check_cpu(cpu)) {
387                         /* The application of microcode failed */
388                         microcode_ops->microcode_fini_cpu(cpu);
389                         __mc_sysdev_add(sys_dev, 1);
390                         break;
391                 }
392         case CPU_DOWN_FAILED_FROZEN:
393                 if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))
394                         printk(KERN_ERR "microcode: Failed to create the sysfs "
395                                 "group for CPU%d\n", cpu);
396                 break;
397         case CPU_DOWN_PREPARE:
398                 mc_sysdev_remove(sys_dev);
399                 break;
400         case CPU_DOWN_PREPARE_FROZEN:
401                 /* Suspend is in progress, only remove the interface */
402                 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
403                 break;
404         }
405         return NOTIFY_OK;
406 }
407
408 static struct notifier_block __refdata mc_cpu_notifier = {
409         .notifier_call = mc_cpu_callback,
410 };
411
412 int microcode_init(void *opaque, struct module *module)
413 {
414         struct microcode_ops *ops = (struct microcode_ops *)opaque;
415         int error;
416
417         if (microcode_ops) {
418                 printk(KERN_ERR "microcode: already loaded the other module\n");
419                 return -EEXIST;
420         }
421
422         microcode_ops = ops;
423
424         error = microcode_dev_init();
425         if (error)
426                 return error;
427         microcode_pdev = platform_device_register_simple("microcode", -1,
428                                                          NULL, 0);
429         if (IS_ERR(microcode_pdev)) {
430                 microcode_dev_exit();
431                 return PTR_ERR(microcode_pdev);
432         }
433
434         get_online_cpus();
435         error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);
436         put_online_cpus();
437         if (error) {
438                 microcode_dev_exit();
439                 platform_device_unregister(microcode_pdev);
440                 return error;
441         }
442
443         register_hotcpu_notifier(&mc_cpu_notifier);
444
445         printk(KERN_INFO
446                "Microcode Update Driver: v" MICROCODE_VERSION
447                " <tigran@aivazian.fsnet.co.uk>"
448                " <peter.oruba@amd.com>\n");
449
450         return 0;
451 }
452 EXPORT_SYMBOL_GPL(microcode_init);
453
454 void __exit microcode_exit (void)
455 {
456         microcode_dev_exit();
457
458         unregister_hotcpu_notifier(&mc_cpu_notifier);
459
460         get_online_cpus();
461         sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
462         put_online_cpus();
463
464         platform_device_unregister(microcode_pdev);
465
466         microcode_ops = NULL;
467
468         printk(KERN_INFO
469                "Microcode Update Driver: v" MICROCODE_VERSION " removed.\n");
470 }
471 EXPORT_SYMBOL_GPL(microcode_exit);