Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
microcode_intel.c
Go to the documentation of this file.
1 /*
2  * Intel CPU Microcode Update Driver for Linux
3  *
4  * Copyright (C) 2000-2006 Tigran Aivazian <[email protected]>
5  * 2006 Shaohua Li <[email protected]>
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/Assets/PDF/manual/253668.pdf
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 <[email protected]>
25  * Initial release.
26  * 1.01 18 Feb 2000, Tigran Aivazian <[email protected]>
27  * Added read() support + cleanups.
28  * 1.02 21 Feb 2000, Tigran Aivazian <[email protected]>
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 <[email protected]>
32  * Made to use devfs (/dev/cpu/microcode) + cleanups.
33  * 1.04 06 Jun 2000, Simon Trimmer <[email protected]>
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 <[email protected]>
37  * Messages for error cases (non Intel & no suitable microcode).
38  * 1.06 03 Aug 2000, Tigran Aivazian <[email protected]>
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 <[email protected]>
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 <[email protected]> for the fix.
49  * 1.08 11 Dec 2000, Richard Schaal <[email protected]> and
50  * Tigran Aivazian <[email protected]>
51  * Intel Pentium 4 processor support and bugfixes.
52  * 1.09 30 Oct 2001, Tigran Aivazian <[email protected]>
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 <[email protected]> and
57  * Tigran Aivazian <[email protected]>,
58  * Serialize updates as required on HT processors due to
59  * speculative nature of implementation.
60  * 1.11 22 Mar 2002 Tigran Aivazian <[email protected]>
61  * Fix the panic when writing zero-length microcode chunk.
62  * 1.12 29 Sep 2003 Nitin Kamble <[email protected]>,
63  * Jun Nakajima <[email protected]>
64  * Support for the microcode updates in the new format.
65  * 1.13 10 Oct 2003 Tigran Aivazian <[email protected]>
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 <[email protected]>
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 pr_fmt(fmt) KBUILD_MODNAME ": " fmt
75 
76 #include <linux/firmware.h>
77 #include <linux/uaccess.h>
78 #include <linux/kernel.h>
79 #include <linux/module.h>
80 #include <linux/vmalloc.h>
81 
82 #include <asm/microcode.h>
83 #include <asm/processor.h>
84 #include <asm/msr.h>
85 
86 MODULE_DESCRIPTION("Microcode Update Driver");
87 MODULE_AUTHOR("Tigran Aivazian <[email protected]>");
88 MODULE_LICENSE("GPL");
89 
91  unsigned int hdrver;
92  unsigned int rev;
93  unsigned int date;
94  unsigned int sig;
95  unsigned int cksum;
96  unsigned int ldrver;
97  unsigned int pf;
98  unsigned int datasize;
99  unsigned int totalsize;
100  unsigned int reserved[3];
101 };
102 
105  unsigned int bits[0];
106 };
107 
108 /* microcode format is extended from prescott processors */
110  unsigned int sig;
111  unsigned int pf;
112  unsigned int cksum;
113 };
114 
116  unsigned int count;
117  unsigned int cksum;
118  unsigned int reserved[3];
120 };
121 
122 #define DEFAULT_UCODE_DATASIZE (2000)
123 #define MC_HEADER_SIZE (sizeof(struct microcode_header_intel))
124 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
125 #define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))
126 #define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))
127 #define DWSIZE (sizeof(u32))
128 
129 #define get_totalsize(mc) \
130  (((struct microcode_intel *)mc)->hdr.totalsize ? \
131  ((struct microcode_intel *)mc)->hdr.totalsize : \
132  DEFAULT_UCODE_TOTALSIZE)
133 
134 #define get_datasize(mc) \
135  (((struct microcode_intel *)mc)->hdr.datasize ? \
136  ((struct microcode_intel *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE)
137 
138 #define sigmatch(s1, s2, p1, p2) \
139  (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0))))
140 
141 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
142 
143 static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
144 {
145  struct cpuinfo_x86 *c = &cpu_data(cpu_num);
146  unsigned int val[2];
147 
148  memset(csig, 0, sizeof(*csig));
149 
150  csig->sig = cpuid_eax(0x00000001);
151 
152  if ((c->x86_model >= 5) || (c->x86 > 6)) {
153  /* get processor flags from MSR 0x17 */
154  rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
155  csig->pf = 1 << ((val[1] >> 18) & 7);
156  }
157 
158  csig->rev = c->microcode;
159  pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n",
160  cpu_num, csig->sig, csig->pf, csig->rev);
161 
162  return 0;
163 }
164 
165 static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf)
166 {
167  return (!sigmatch(sig, csig->sig, pf, csig->pf)) ? 0 : 1;
168 }
169 
170 static inline int
171 update_match_revision(struct microcode_header_intel *mc_header, int rev)
172 {
173  return (mc_header->rev <= rev) ? 0 : 1;
174 }
175 
176 static int microcode_sanity_check(void *mc)
177 {
178  unsigned long total_size, data_size, ext_table_size;
179  struct microcode_header_intel *mc_header = mc;
180  struct extended_sigtable *ext_header = NULL;
181  int sum, orig_sum, ext_sigcount = 0, i;
182  struct extended_signature *ext_sig;
183 
184  total_size = get_totalsize(mc_header);
185  data_size = get_datasize(mc_header);
186 
187  if (data_size + MC_HEADER_SIZE > total_size) {
188  pr_err("error! Bad data size in microcode data file\n");
189  return -EINVAL;
190  }
191 
192  if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
193  pr_err("error! Unknown microcode update format\n");
194  return -EINVAL;
195  }
196  ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
197  if (ext_table_size) {
198  if ((ext_table_size < EXT_HEADER_SIZE)
199  || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
200  pr_err("error! Small exttable size in microcode data file\n");
201  return -EINVAL;
202  }
203  ext_header = mc + MC_HEADER_SIZE + data_size;
204  if (ext_table_size != exttable_size(ext_header)) {
205  pr_err("error! Bad exttable size in microcode data file\n");
206  return -EFAULT;
207  }
208  ext_sigcount = ext_header->count;
209  }
210 
211  /* check extended table checksum */
212  if (ext_table_size) {
213  int ext_table_sum = 0;
214  int *ext_tablep = (int *)ext_header;
215 
216  i = ext_table_size / DWSIZE;
217  while (i--)
218  ext_table_sum += ext_tablep[i];
219  if (ext_table_sum) {
220  pr_warning("aborting, bad extended signature table checksum\n");
221  return -EINVAL;
222  }
223  }
224 
225  /* calculate the checksum */
226  orig_sum = 0;
228  while (i--)
229  orig_sum += ((int *)mc)[i];
230  if (orig_sum) {
231  pr_err("aborting, bad checksum\n");
232  return -EINVAL;
233  }
234  if (!ext_table_size)
235  return 0;
236  /* check extended signature checksum */
237  for (i = 0; i < ext_sigcount; i++) {
238  ext_sig = (void *)ext_header + EXT_HEADER_SIZE +
239  EXT_SIGNATURE_SIZE * i;
240  sum = orig_sum
241  - (mc_header->sig + mc_header->pf + mc_header->cksum)
242  + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
243  if (sum) {
244  pr_err("aborting, bad checksum\n");
245  return -EINVAL;
246  }
247  }
248  return 0;
249 }
250 
251 /*
252  * return 0 - no update found
253  * return 1 - found update
254  */
255 static int
256 get_matching_microcode(struct cpu_signature *cpu_sig, void *mc, int rev)
257 {
258  struct microcode_header_intel *mc_header = mc;
259  struct extended_sigtable *ext_header;
260  unsigned long total_size = get_totalsize(mc_header);
261  int ext_sigcount, i;
262  struct extended_signature *ext_sig;
263 
264  if (!update_match_revision(mc_header, rev))
265  return 0;
266 
267  if (update_match_cpu(cpu_sig, mc_header->sig, mc_header->pf))
268  return 1;
269 
270  /* Look for ext. headers: */
271  if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE)
272  return 0;
273 
274  ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE;
275  ext_sigcount = ext_header->count;
276  ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
277 
278  for (i = 0; i < ext_sigcount; i++) {
279  if (update_match_cpu(cpu_sig, ext_sig->sig, ext_sig->pf))
280  return 1;
281  ext_sig++;
282  }
283  return 0;
284 }
285 
286 static int apply_microcode(int cpu)
287 {
288  struct microcode_intel *mc_intel;
289  struct ucode_cpu_info *uci;
290  unsigned int val[2];
291  int cpu_num = raw_smp_processor_id();
292  struct cpuinfo_x86 *c = &cpu_data(cpu_num);
293 
294  uci = ucode_cpu_info + cpu;
295  mc_intel = uci->mc;
296 
297  /* We should bind the task to the CPU */
298  BUG_ON(cpu_num != cpu);
299 
300  if (mc_intel == NULL)
301  return 0;
302 
303  /* write microcode via MSR 0x79 */
305  (unsigned long) mc_intel->bits,
306  (unsigned long) mc_intel->bits >> 16 >> 16);
307  wrmsr(MSR_IA32_UCODE_REV, 0, 0);
308 
309  /* As documented in the SDM: Do a CPUID 1 here */
310  sync_core();
311 
312  /* get the current revision from MSR 0x8B */
313  rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
314 
315  if (val[1] != mc_intel->hdr.rev) {
316  pr_err("CPU%d update to revision 0x%x failed\n",
317  cpu_num, mc_intel->hdr.rev);
318  return -1;
319  }
320  pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x\n",
321  cpu_num, val[1],
322  mc_intel->hdr.date & 0xffff,
323  mc_intel->hdr.date >> 24,
324  (mc_intel->hdr.date >> 16) & 0xff);
325 
326  uci->cpu_sig.rev = val[1];
327  c->microcode = val[1];
328 
329  return 0;
330 }
331 
332 static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
333  int (*get_ucode_data)(void *, const void *, size_t))
334 {
335  struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
336  u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL;
337  int new_rev = uci->cpu_sig.rev;
338  unsigned int leftover = size;
339  enum ucode_state state = UCODE_OK;
340  unsigned int curr_mc_size = 0;
341 
342  while (leftover) {
343  struct microcode_header_intel mc_header;
344  unsigned int mc_size;
345 
346  if (get_ucode_data(&mc_header, ucode_ptr, sizeof(mc_header)))
347  break;
348 
349  mc_size = get_totalsize(&mc_header);
350  if (!mc_size || mc_size > leftover) {
351  pr_err("error! Bad data in microcode data file\n");
352  break;
353  }
354 
355  /* For performance reasons, reuse mc area when possible */
356  if (!mc || mc_size > curr_mc_size) {
357  vfree(mc);
358  mc = vmalloc(mc_size);
359  if (!mc)
360  break;
361  curr_mc_size = mc_size;
362  }
363 
364  if (get_ucode_data(mc, ucode_ptr, mc_size) ||
365  microcode_sanity_check(mc) < 0) {
366  break;
367  }
368 
369  if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {
370  vfree(new_mc);
371  new_rev = mc_header.rev;
372  new_mc = mc;
373  mc = NULL; /* trigger new vmalloc */
374  }
375 
376  ucode_ptr += mc_size;
377  leftover -= mc_size;
378  }
379 
380  vfree(mc);
381 
382  if (leftover) {
383  vfree(new_mc);
384  state = UCODE_ERROR;
385  goto out;
386  }
387 
388  if (!new_mc) {
389  state = UCODE_NFOUND;
390  goto out;
391  }
392 
393  vfree(uci->mc);
394  uci->mc = (struct microcode_intel *)new_mc;
395 
396  pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
397  cpu, new_rev, uci->cpu_sig.rev);
398 out:
399  return state;
400 }
401 
402 static int get_ucode_fw(void *to, const void *from, size_t n)
403 {
404  memcpy(to, from, n);
405  return 0;
406 }
407 
408 static enum ucode_state request_microcode_fw(int cpu, struct device *device,
409  bool refresh_fw)
410 {
411  char name[30];
412  struct cpuinfo_x86 *c = &cpu_data(cpu);
413  const struct firmware *firmware;
414  enum ucode_state ret;
415 
416  sprintf(name, "intel-ucode/%02x-%02x-%02x",
417  c->x86, c->x86_model, c->x86_mask);
418 
419  if (request_firmware(&firmware, name, device)) {
420  pr_debug("data file %s load failed\n", name);
421  return UCODE_NFOUND;
422  }
423 
424  ret = generic_load_microcode(cpu, (void *)firmware->data,
425  firmware->size, &get_ucode_fw);
426 
427  release_firmware(firmware);
428 
429  return ret;
430 }
431 
432 static int get_ucode_user(void *to, const void *from, size_t n)
433 {
434  return copy_from_user(to, from, n);
435 }
436 
437 static enum ucode_state
438 request_microcode_user(int cpu, const void __user *buf, size_t size)
439 {
440  return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
441 }
442 
443 static void microcode_fini_cpu(int cpu)
444 {
445  struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
446 
447  vfree(uci->mc);
448  uci->mc = NULL;
449 }
450 
451 static struct microcode_ops microcode_intel_ops = {
452  .request_microcode_user = request_microcode_user,
453  .request_microcode_fw = request_microcode_fw,
454  .collect_cpu_info = collect_cpu_info,
455  .apply_microcode = apply_microcode,
456  .microcode_fini_cpu = microcode_fini_cpu,
457 };
458 
460 {
461  struct cpuinfo_x86 *c = &cpu_data(0);
462 
463  if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
464  cpu_has(c, X86_FEATURE_IA64)) {
465  pr_err("Intel CPU family 0x%x not supported\n", c->x86);
466  return NULL;
467  }
468 
469  return &microcode_intel_ops;
470 }
471