]>
Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
6b44e72a | 2 | * Intel CPU Microcode Update Driver for Linux |
1da177e4 | 3 | * |
cea58224 | 4 | * Copyright (C) 2000-2006 Tigran Aivazian <aivazian.tigran@gmail.com> |
6b44e72a | 5 | * 2006 Shaohua Li <shaohua.li@intel.com> |
1da177e4 | 6 | * |
fe055896 BP |
7 | * Intel CPU microcode early update for Linux |
8 | * | |
9 | * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com> | |
10 | * H Peter Anvin" <hpa@zytor.com> | |
11 | * | |
6b44e72a BP |
12 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | |
14 | * as published by the Free Software Foundation; either version | |
15 | * 2 of the License, or (at your option) any later version. | |
1da177e4 | 16 | */ |
f58e1f53 | 17 | |
fe055896 BP |
18 | /* |
19 | * This needs to be before all headers so that pr_debug in printk.h doesn't turn | |
20 | * printk calls into no_printk(). | |
21 | * | |
22 | *#define DEBUG | |
23 | */ | |
6b26e1bf | 24 | #define pr_fmt(fmt) "microcode: " fmt |
f58e1f53 | 25 | |
fe055896 | 26 | #include <linux/earlycpio.h> |
4bae1967 | 27 | #include <linux/firmware.h> |
4bae1967 | 28 | #include <linux/uaccess.h> |
fe055896 BP |
29 | #include <linux/vmalloc.h> |
30 | #include <linux/initrd.h> | |
4bae1967 | 31 | #include <linux/kernel.h> |
fe055896 BP |
32 | #include <linux/slab.h> |
33 | #include <linux/cpu.h> | |
34 | #include <linux/mm.h> | |
1da177e4 | 35 | |
9cd4d78e | 36 | #include <asm/microcode_intel.h> |
4bae1967 | 37 | #include <asm/processor.h> |
fe055896 BP |
38 | #include <asm/tlbflush.h> |
39 | #include <asm/setup.h> | |
4bae1967 | 40 | #include <asm/msr.h> |
1da177e4 | 41 | |
06b8534c | 42 | static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin"; |
fe055896 | 43 | |
c26665ab | 44 | /* Current microcode patch used in early patching on the APs. */ |
06b8534c | 45 | struct microcode_intel *intel_ucode_patch; |
6c545647 | 46 | |
8027923a BP |
47 | static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1, |
48 | unsigned int s2, unsigned int p2) | |
49 | { | |
50 | if (s1 != s2) | |
51 | return false; | |
52 | ||
53 | /* Processor flags are either both 0 ... */ | |
54 | if (!p1 && !p2) | |
55 | return true; | |
56 | ||
57 | /* ... or they intersect. */ | |
58 | return p1 & p2; | |
59 | } | |
60 | ||
61 | /* | |
62 | * Returns 1 if update has been found, 0 otherwise. | |
63 | */ | |
64 | static int find_matching_signature(void *mc, unsigned int csig, int cpf) | |
65 | { | |
66 | struct microcode_header_intel *mc_hdr = mc; | |
67 | struct extended_sigtable *ext_hdr; | |
68 | struct extended_signature *ext_sig; | |
69 | int i; | |
70 | ||
71 | if (cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf)) | |
72 | return 1; | |
73 | ||
74 | /* Look for ext. headers: */ | |
75 | if (get_totalsize(mc_hdr) <= get_datasize(mc_hdr) + MC_HEADER_SIZE) | |
76 | return 0; | |
77 | ||
78 | ext_hdr = mc + get_datasize(mc_hdr) + MC_HEADER_SIZE; | |
79 | ext_sig = (void *)ext_hdr + EXT_HEADER_SIZE; | |
80 | ||
81 | for (i = 0; i < ext_hdr->count; i++) { | |
82 | if (cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf)) | |
83 | return 1; | |
84 | ext_sig++; | |
85 | } | |
86 | return 0; | |
87 | } | |
88 | ||
89 | /* | |
90 | * Returns 1 if update has been found, 0 otherwise. | |
91 | */ | |
92 | static int has_newer_microcode(void *mc, unsigned int csig, int cpf, int new_rev) | |
93 | { | |
94 | struct microcode_header_intel *mc_hdr = mc; | |
95 | ||
96 | if (mc_hdr->rev <= new_rev) | |
97 | return 0; | |
98 | ||
99 | return find_matching_signature(mc, csig, cpf); | |
100 | } | |
101 | ||
fe055896 BP |
102 | /* |
103 | * Given CPU signature and a microcode patch, this function finds if the | |
104 | * microcode patch has matching family and model with the CPU. | |
06b8534c BP |
105 | * |
106 | * %true - if there's a match | |
107 | * %false - otherwise | |
fe055896 | 108 | */ |
06b8534c BP |
109 | static bool microcode_matches(struct microcode_header_intel *mc_header, |
110 | unsigned long sig) | |
fe055896 | 111 | { |
fe055896 BP |
112 | unsigned long total_size = get_totalsize(mc_header); |
113 | unsigned long data_size = get_datasize(mc_header); | |
06b8534c BP |
114 | struct extended_sigtable *ext_header; |
115 | unsigned int fam_ucode, model_ucode; | |
fe055896 | 116 | struct extended_signature *ext_sig; |
06b8534c BP |
117 | unsigned int fam, model; |
118 | int ext_sigcount, i; | |
fe055896 | 119 | |
99f925ce | 120 | fam = x86_family(sig); |
fe055896 BP |
121 | model = x86_model(sig); |
122 | ||
99f925ce | 123 | fam_ucode = x86_family(mc_header->sig); |
fe055896 BP |
124 | model_ucode = x86_model(mc_header->sig); |
125 | ||
126 | if (fam == fam_ucode && model == model_ucode) | |
06b8534c | 127 | return true; |
fe055896 BP |
128 | |
129 | /* Look for ext. headers: */ | |
130 | if (total_size <= data_size + MC_HEADER_SIZE) | |
06b8534c | 131 | return false; |
fe055896 BP |
132 | |
133 | ext_header = (void *) mc_header + data_size + MC_HEADER_SIZE; | |
134 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE; | |
135 | ext_sigcount = ext_header->count; | |
136 | ||
137 | for (i = 0; i < ext_sigcount; i++) { | |
99f925ce | 138 | fam_ucode = x86_family(ext_sig->sig); |
fe055896 BP |
139 | model_ucode = x86_model(ext_sig->sig); |
140 | ||
141 | if (fam == fam_ucode && model == model_ucode) | |
06b8534c | 142 | return true; |
fe055896 BP |
143 | |
144 | ext_sig++; | |
145 | } | |
06b8534c | 146 | return false; |
fe055896 BP |
147 | } |
148 | ||
06b8534c | 149 | static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size) |
fe055896 | 150 | { |
06b8534c | 151 | struct ucode_patch *p; |
fe055896 | 152 | |
9fcf5ba2 | 153 | p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL); |
06b8534c BP |
154 | if (!p) |
155 | return ERR_PTR(-ENOMEM); | |
fe055896 | 156 | |
06b8534c BP |
157 | p->data = kmemdup(data, size, GFP_KERNEL); |
158 | if (!p->data) { | |
159 | kfree(p); | |
160 | return ERR_PTR(-ENOMEM); | |
fe055896 BP |
161 | } |
162 | ||
06b8534c | 163 | return p; |
fe055896 BP |
164 | } |
165 | ||
06b8534c | 166 | static void save_microcode_patch(void *data, unsigned int size) |
fe055896 BP |
167 | { |
168 | struct microcode_header_intel *mc_hdr, *mc_saved_hdr; | |
06b8534c BP |
169 | struct ucode_patch *iter, *tmp, *p; |
170 | bool prev_found = false; | |
fe055896 | 171 | unsigned int sig, pf; |
fe055896 | 172 | |
06b8534c | 173 | mc_hdr = (struct microcode_header_intel *)data; |
fe055896 | 174 | |
06b8534c BP |
175 | list_for_each_entry_safe(iter, tmp, µcode_cache, plist) { |
176 | mc_saved_hdr = (struct microcode_header_intel *)iter->data; | |
fe055896 BP |
177 | sig = mc_saved_hdr->sig; |
178 | pf = mc_saved_hdr->pf; | |
179 | ||
06b8534c BP |
180 | if (find_matching_signature(data, sig, pf)) { |
181 | prev_found = true; | |
fe055896 | 182 | |
06b8534c BP |
183 | if (mc_hdr->rev <= mc_saved_hdr->rev) |
184 | continue; | |
fe055896 | 185 | |
06b8534c BP |
186 | p = __alloc_microcode_buf(data, size); |
187 | if (IS_ERR(p)) | |
188 | pr_err("Error allocating buffer %p\n", data); | |
189 | else | |
190 | list_replace(&iter->plist, &p->plist); | |
191 | } | |
fe055896 BP |
192 | } |
193 | ||
06b8534c BP |
194 | /* |
195 | * There weren't any previous patches found in the list cache; save the | |
196 | * newly found. | |
197 | */ | |
198 | if (!prev_found) { | |
199 | p = __alloc_microcode_buf(data, size); | |
200 | if (IS_ERR(p)) | |
201 | pr_err("Error allocating buffer for %p\n", data); | |
202 | else | |
203 | list_add_tail(&p->plist, µcode_cache); | |
204 | } | |
fe055896 BP |
205 | } |
206 | ||
8027923a BP |
207 | static int microcode_sanity_check(void *mc, int print_err) |
208 | { | |
209 | unsigned long total_size, data_size, ext_table_size; | |
210 | struct microcode_header_intel *mc_header = mc; | |
211 | struct extended_sigtable *ext_header = NULL; | |
212 | u32 sum, orig_sum, ext_sigcount = 0, i; | |
213 | struct extended_signature *ext_sig; | |
214 | ||
215 | total_size = get_totalsize(mc_header); | |
216 | data_size = get_datasize(mc_header); | |
217 | ||
218 | if (data_size + MC_HEADER_SIZE > total_size) { | |
219 | if (print_err) | |
220 | pr_err("Error: bad microcode data file size.\n"); | |
221 | return -EINVAL; | |
222 | } | |
223 | ||
224 | if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { | |
225 | if (print_err) | |
226 | pr_err("Error: invalid/unknown microcode update format.\n"); | |
227 | return -EINVAL; | |
228 | } | |
229 | ||
230 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); | |
231 | if (ext_table_size) { | |
232 | u32 ext_table_sum = 0; | |
233 | u32 *ext_tablep; | |
234 | ||
235 | if ((ext_table_size < EXT_HEADER_SIZE) | |
236 | || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { | |
237 | if (print_err) | |
238 | pr_err("Error: truncated extended signature table.\n"); | |
239 | return -EINVAL; | |
240 | } | |
241 | ||
242 | ext_header = mc + MC_HEADER_SIZE + data_size; | |
243 | if (ext_table_size != exttable_size(ext_header)) { | |
244 | if (print_err) | |
245 | pr_err("Error: extended signature table size mismatch.\n"); | |
246 | return -EFAULT; | |
247 | } | |
248 | ||
249 | ext_sigcount = ext_header->count; | |
250 | ||
251 | /* | |
252 | * Check extended table checksum: the sum of all dwords that | |
253 | * comprise a valid table must be 0. | |
254 | */ | |
255 | ext_tablep = (u32 *)ext_header; | |
256 | ||
257 | i = ext_table_size / sizeof(u32); | |
258 | while (i--) | |
259 | ext_table_sum += ext_tablep[i]; | |
260 | ||
261 | if (ext_table_sum) { | |
262 | if (print_err) | |
263 | pr_warn("Bad extended signature table checksum, aborting.\n"); | |
264 | return -EINVAL; | |
265 | } | |
266 | } | |
267 | ||
268 | /* | |
269 | * Calculate the checksum of update data and header. The checksum of | |
270 | * valid update data and header including the extended signature table | |
271 | * must be 0. | |
272 | */ | |
273 | orig_sum = 0; | |
274 | i = (MC_HEADER_SIZE + data_size) / sizeof(u32); | |
275 | while (i--) | |
276 | orig_sum += ((u32 *)mc)[i]; | |
277 | ||
278 | if (orig_sum) { | |
279 | if (print_err) | |
280 | pr_err("Bad microcode data checksum, aborting.\n"); | |
281 | return -EINVAL; | |
282 | } | |
283 | ||
284 | if (!ext_table_size) | |
285 | return 0; | |
286 | ||
287 | /* | |
288 | * Check extended signature checksum: 0 => valid. | |
289 | */ | |
290 | for (i = 0; i < ext_sigcount; i++) { | |
291 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE + | |
292 | EXT_SIGNATURE_SIZE * i; | |
293 | ||
294 | sum = (mc_header->sig + mc_header->pf + mc_header->cksum) - | |
295 | (ext_sig->sig + ext_sig->pf + ext_sig->cksum); | |
296 | if (sum) { | |
297 | if (print_err) | |
298 | pr_err("Bad extended signature checksum, aborting.\n"); | |
299 | return -EINVAL; | |
300 | } | |
301 | } | |
302 | return 0; | |
303 | } | |
304 | ||
fe055896 BP |
305 | /* |
306 | * Get microcode matching with BSP's model. Only CPUs with the same model as | |
307 | * BSP can stay in the platform. | |
308 | */ | |
06b8534c BP |
309 | static struct microcode_intel * |
310 | scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save) | |
fe055896 | 311 | { |
f96fde53 | 312 | struct microcode_header_intel *mc_header; |
06b8534c | 313 | struct microcode_intel *patch = NULL; |
f96fde53 | 314 | unsigned int mc_size; |
fe055896 | 315 | |
06b8534c BP |
316 | while (size) { |
317 | if (size < sizeof(struct microcode_header_intel)) | |
fe055896 BP |
318 | break; |
319 | ||
06b8534c | 320 | mc_header = (struct microcode_header_intel *)data; |
fe055896 BP |
321 | |
322 | mc_size = get_totalsize(mc_header); | |
06b8534c BP |
323 | if (!mc_size || |
324 | mc_size > size || | |
325 | microcode_sanity_check(data, 0) < 0) | |
fe055896 BP |
326 | break; |
327 | ||
06b8534c | 328 | size -= mc_size; |
fe055896 | 329 | |
06b8534c BP |
330 | if (!microcode_matches(mc_header, uci->cpu_sig.sig)) { |
331 | data += mc_size; | |
fe055896 BP |
332 | continue; |
333 | } | |
334 | ||
06b8534c BP |
335 | if (save) { |
336 | save_microcode_patch(data, mc_size); | |
337 | goto next; | |
338 | } | |
fe055896 | 339 | |
fe055896 | 340 | |
06b8534c BP |
341 | if (!patch) { |
342 | if (!has_newer_microcode(data, | |
343 | uci->cpu_sig.sig, | |
344 | uci->cpu_sig.pf, | |
345 | uci->cpu_sig.rev)) | |
346 | goto next; | |
fe055896 | 347 | |
06b8534c BP |
348 | } else { |
349 | struct microcode_header_intel *phdr = &patch->hdr; | |
350 | ||
351 | if (!has_newer_microcode(data, | |
352 | phdr->sig, | |
353 | phdr->pf, | |
354 | phdr->rev)) | |
355 | goto next; | |
356 | } | |
fe055896 | 357 | |
06b8534c BP |
358 | /* We have a newer patch, save it. */ |
359 | patch = data; | |
fe055896 | 360 | |
06b8534c BP |
361 | next: |
362 | data += mc_size; | |
363 | } | |
f96fde53 | 364 | |
06b8534c BP |
365 | if (size) |
366 | return NULL; | |
367 | ||
368 | return patch; | |
fe055896 BP |
369 | } |
370 | ||
371 | static int collect_cpu_info_early(struct ucode_cpu_info *uci) | |
372 | { | |
373 | unsigned int val[2]; | |
374 | unsigned int family, model; | |
06b8534c | 375 | struct cpu_signature csig = { 0 }; |
fe055896 BP |
376 | unsigned int eax, ebx, ecx, edx; |
377 | ||
fe055896 BP |
378 | memset(uci, 0, sizeof(*uci)); |
379 | ||
380 | eax = 0x00000001; | |
381 | ecx = 0; | |
382 | native_cpuid(&eax, &ebx, &ecx, &edx); | |
383 | csig.sig = eax; | |
384 | ||
06b8534c BP |
385 | family = x86_family(eax); |
386 | model = x86_model(eax); | |
fe055896 BP |
387 | |
388 | if ((model >= 5) || (family > 6)) { | |
389 | /* get processor flags from MSR 0x17 */ | |
390 | native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); | |
391 | csig.pf = 1 << ((val[1] >> 18) & 7); | |
392 | } | |
fe055896 | 393 | |
4167709b | 394 | csig.rev = intel_get_microcode_revision(); |
fe055896 BP |
395 | |
396 | uci->cpu_sig = csig; | |
397 | uci->valid = 1; | |
398 | ||
399 | return 0; | |
400 | } | |
401 | ||
fe055896 BP |
402 | static void show_saved_mc(void) |
403 | { | |
c595ac2b | 404 | #ifdef DEBUG |
06b8534c | 405 | int i = 0, j; |
fe055896 BP |
406 | unsigned int sig, pf, rev, total_size, data_size, date; |
407 | struct ucode_cpu_info uci; | |
06b8534c | 408 | struct ucode_patch *p; |
fe055896 | 409 | |
06b8534c | 410 | if (list_empty(µcode_cache)) { |
fe055896 BP |
411 | pr_debug("no microcode data saved.\n"); |
412 | return; | |
413 | } | |
fe055896 BP |
414 | |
415 | collect_cpu_info_early(&uci); | |
416 | ||
06b8534c BP |
417 | sig = uci.cpu_sig.sig; |
418 | pf = uci.cpu_sig.pf; | |
419 | rev = uci.cpu_sig.rev; | |
fe055896 BP |
420 | pr_debug("CPU: sig=0x%x, pf=0x%x, rev=0x%x\n", sig, pf, rev); |
421 | ||
06b8534c | 422 | list_for_each_entry(p, µcode_cache, plist) { |
fe055896 BP |
423 | struct microcode_header_intel *mc_saved_header; |
424 | struct extended_sigtable *ext_header; | |
fe055896 | 425 | struct extended_signature *ext_sig; |
06b8534c BP |
426 | int ext_sigcount; |
427 | ||
428 | mc_saved_header = (struct microcode_header_intel *)p->data; | |
429 | ||
430 | sig = mc_saved_header->sig; | |
431 | pf = mc_saved_header->pf; | |
432 | rev = mc_saved_header->rev; | |
433 | date = mc_saved_header->date; | |
fe055896 | 434 | |
06b8534c BP |
435 | total_size = get_totalsize(mc_saved_header); |
436 | data_size = get_datasize(mc_saved_header); | |
fe055896 | 437 | |
c19ca6cb | 438 | pr_debug("mc_saved[%d]: sig=0x%x, pf=0x%x, rev=0x%x, total size=0x%x, date = %04x-%02x-%02x\n", |
06b8534c | 439 | i++, sig, pf, rev, total_size, |
fe055896 BP |
440 | date & 0xffff, |
441 | date >> 24, | |
442 | (date >> 16) & 0xff); | |
443 | ||
444 | /* Look for ext. headers: */ | |
445 | if (total_size <= data_size + MC_HEADER_SIZE) | |
446 | continue; | |
447 | ||
06b8534c | 448 | ext_header = (void *)mc_saved_header + data_size + MC_HEADER_SIZE; |
fe055896 BP |
449 | ext_sigcount = ext_header->count; |
450 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE; | |
451 | ||
452 | for (j = 0; j < ext_sigcount; j++) { | |
453 | sig = ext_sig->sig; | |
454 | pf = ext_sig->pf; | |
455 | ||
456 | pr_debug("\tExtended[%d]: sig=0x%x, pf=0x%x\n", | |
457 | j, sig, pf); | |
458 | ||
459 | ext_sig++; | |
460 | } | |
fe055896 | 461 | } |
fe055896 | 462 | #endif |
c595ac2b | 463 | } |
fe055896 | 464 | |
fe055896 | 465 | /* |
06b8534c BP |
466 | * Save this microcode patch. It will be loaded early when a CPU is |
467 | * hot-added or resumes. | |
fe055896 | 468 | */ |
06b8534c | 469 | static void save_mc_for_early(u8 *mc, unsigned int size) |
fe055896 | 470 | { |
0c5fa827 | 471 | #ifdef CONFIG_HOTPLUG_CPU |
9f3cc2a0 | 472 | /* Synchronization during CPU hotplug. */ |
0c5fa827 BP |
473 | static DEFINE_MUTEX(x86_cpu_microcode_mutex); |
474 | ||
fe055896 BP |
475 | mutex_lock(&x86_cpu_microcode_mutex); |
476 | ||
06b8534c | 477 | save_microcode_patch(mc, size); |
fe055896 BP |
478 | show_saved_mc(); |
479 | ||
fe055896 | 480 | mutex_unlock(&x86_cpu_microcode_mutex); |
fe055896 | 481 | #endif |
0c5fa827 | 482 | } |
fe055896 | 483 | |
06b8534c | 484 | static bool load_builtin_intel_microcode(struct cpio_data *cp) |
fe055896 | 485 | { |
06b8534c | 486 | unsigned int eax = 1, ebx, ecx = 0, edx; |
fe055896 BP |
487 | char name[30]; |
488 | ||
06b8534c BP |
489 | if (IS_ENABLED(CONFIG_X86_32)) |
490 | return false; | |
491 | ||
fe055896 BP |
492 | native_cpuid(&eax, &ebx, &ecx, &edx); |
493 | ||
99f925ce BP |
494 | sprintf(name, "intel-ucode/%02x-%02x-%02x", |
495 | x86_family(eax), x86_model(eax), x86_stepping(eax)); | |
fe055896 BP |
496 | |
497 | return get_builtin_firmware(cp, name); | |
fe055896 BP |
498 | } |
499 | ||
fe055896 BP |
500 | /* |
501 | * Print ucode update info. | |
502 | */ | |
503 | static void | |
504 | print_ucode_info(struct ucode_cpu_info *uci, unsigned int date) | |
505 | { | |
b7f500ae BP |
506 | pr_info_once("microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n", |
507 | uci->cpu_sig.rev, | |
508 | date & 0xffff, | |
509 | date >> 24, | |
510 | (date >> 16) & 0xff); | |
fe055896 BP |
511 | } |
512 | ||
513 | #ifdef CONFIG_X86_32 | |
514 | ||
515 | static int delay_ucode_info; | |
516 | static int current_mc_date; | |
517 | ||
518 | /* | |
519 | * Print early updated ucode info after printk works. This is delayed info dump. | |
520 | */ | |
521 | void show_ucode_info_early(void) | |
522 | { | |
523 | struct ucode_cpu_info uci; | |
524 | ||
525 | if (delay_ucode_info) { | |
526 | collect_cpu_info_early(&uci); | |
527 | print_ucode_info(&uci, current_mc_date); | |
528 | delay_ucode_info = 0; | |
529 | } | |
530 | } | |
531 | ||
532 | /* | |
06b8534c | 533 | * At this point, we can not call printk() yet. Delay printing microcode info in |
fe055896 BP |
534 | * show_ucode_info_early() until printk() works. |
535 | */ | |
536 | static void print_ucode(struct ucode_cpu_info *uci) | |
537 | { | |
de778275 | 538 | struct microcode_intel *mc; |
fe055896 BP |
539 | int *delay_ucode_info_p; |
540 | int *current_mc_date_p; | |
541 | ||
de778275 BP |
542 | mc = uci->mc; |
543 | if (!mc) | |
fe055896 BP |
544 | return; |
545 | ||
546 | delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info); | |
547 | current_mc_date_p = (int *)__pa_nodebug(¤t_mc_date); | |
548 | ||
549 | *delay_ucode_info_p = 1; | |
de778275 | 550 | *current_mc_date_p = mc->hdr.date; |
fe055896 BP |
551 | } |
552 | #else | |
553 | ||
554 | /* | |
555 | * Flush global tlb. We only do this in x86_64 where paging has been enabled | |
556 | * already and PGE should be enabled as well. | |
557 | */ | |
558 | static inline void flush_tlb_early(void) | |
559 | { | |
560 | __native_flush_tlb_global_irq_disabled(); | |
561 | } | |
562 | ||
563 | static inline void print_ucode(struct ucode_cpu_info *uci) | |
564 | { | |
de778275 | 565 | struct microcode_intel *mc; |
fe055896 | 566 | |
de778275 BP |
567 | mc = uci->mc; |
568 | if (!mc) | |
fe055896 BP |
569 | return; |
570 | ||
de778275 | 571 | print_ucode_info(uci, mc->hdr.date); |
fe055896 BP |
572 | } |
573 | #endif | |
574 | ||
575 | static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) | |
576 | { | |
de778275 | 577 | struct microcode_intel *mc; |
4167709b | 578 | u32 rev; |
fe055896 | 579 | |
de778275 BP |
580 | mc = uci->mc; |
581 | if (!mc) | |
fe055896 BP |
582 | return 0; |
583 | ||
584 | /* write microcode via MSR 0x79 */ | |
c416e611 | 585 | native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
fe055896 | 586 | |
4167709b BP |
587 | rev = intel_get_microcode_revision(); |
588 | if (rev != mc->hdr.rev) | |
fe055896 BP |
589 | return -1; |
590 | ||
591 | #ifdef CONFIG_X86_64 | |
592 | /* Flush global tlb. This is precaution. */ | |
593 | flush_tlb_early(); | |
594 | #endif | |
4167709b | 595 | uci->cpu_sig.rev = rev; |
fe055896 BP |
596 | |
597 | if (early) | |
598 | print_ucode(uci); | |
599 | else | |
de778275 | 600 | print_ucode_info(uci, mc->hdr.date); |
fe055896 BP |
601 | |
602 | return 0; | |
603 | } | |
604 | ||
fe055896 BP |
605 | int __init save_microcode_in_initrd_intel(void) |
606 | { | |
06b8534c BP |
607 | struct ucode_cpu_info uci; |
608 | struct cpio_data cp; | |
fe055896 | 609 | |
06b8534c BP |
610 | if (!load_builtin_intel_microcode(&cp)) |
611 | cp = find_microcode_in_initrd(ucode_path, false); | |
fe055896 | 612 | |
06b8534c BP |
613 | if (!(cp.data && cp.size)) |
614 | return 0; | |
fe055896 | 615 | |
06b8534c | 616 | collect_cpu_info_early(&uci); |
6c545647 | 617 | |
06b8534c | 618 | scan_microcode(cp.data, cp.size, &uci, true); |
6c545647 | 619 | |
06b8534c | 620 | show_saved_mc(); |
6c545647 | 621 | |
5b0bc9ac DB |
622 | /* initrd is going away, clear patch ptr. */ |
623 | intel_ucode_patch = NULL; | |
624 | ||
06b8534c BP |
625 | return 0; |
626 | } | |
6c545647 | 627 | |
06b8534c BP |
628 | /* |
629 | * @res_patch, output: a pointer to the patch we found. | |
630 | */ | |
631 | static struct microcode_intel *__load_ucode_intel(struct ucode_cpu_info *uci) | |
632 | { | |
633 | static const char *path; | |
634 | struct cpio_data cp; | |
635 | bool use_pa; | |
6c545647 | 636 | |
06b8534c BP |
637 | if (IS_ENABLED(CONFIG_X86_32)) { |
638 | path = (const char *)__pa_nodebug(ucode_path); | |
639 | use_pa = true; | |
640 | } else { | |
641 | path = ucode_path; | |
642 | use_pa = false; | |
6c545647 | 643 | } |
6c545647 | 644 | |
06b8534c BP |
645 | /* try built-in microcode first */ |
646 | if (!load_builtin_intel_microcode(&cp)) | |
647 | cp = find_microcode_in_initrd(path, use_pa); | |
6c545647 | 648 | |
06b8534c BP |
649 | if (!(cp.data && cp.size)) |
650 | return NULL; | |
6c545647 | 651 | |
06b8534c | 652 | collect_cpu_info_early(uci); |
6c545647 | 653 | |
06b8534c | 654 | return scan_microcode(cp.data, cp.size, uci, false); |
6c545647 BP |
655 | } |
656 | ||
06b8534c | 657 | void __init load_ucode_intel_bsp(void) |
fe055896 | 658 | { |
06b8534c | 659 | struct microcode_intel *patch; |
fe055896 | 660 | struct ucode_cpu_info uci; |
fe055896 | 661 | |
06b8534c BP |
662 | patch = __load_ucode_intel(&uci); |
663 | if (!patch) | |
fe055896 BP |
664 | return; |
665 | ||
06b8534c | 666 | uci.mc = patch; |
fe055896 BP |
667 | |
668 | apply_microcode_early(&uci, true); | |
669 | } | |
670 | ||
06b8534c | 671 | void load_ucode_intel_ap(void) |
fe055896 | 672 | { |
06b8534c BP |
673 | struct microcode_intel *patch, **iup; |
674 | struct ucode_cpu_info uci; | |
264285ac | 675 | |
06b8534c BP |
676 | if (IS_ENABLED(CONFIG_X86_32)) |
677 | iup = (struct microcode_intel **) __pa_nodebug(&intel_ucode_patch); | |
678 | else | |
679 | iup = &intel_ucode_patch; | |
680 | ||
681 | reget: | |
682 | if (!*iup) { | |
683 | patch = __load_ucode_intel(&uci); | |
684 | if (!patch) | |
685 | return; | |
6c545647 | 686 | |
06b8534c BP |
687 | *iup = patch; |
688 | } | |
689 | ||
690 | uci.mc = *iup; | |
691 | ||
692 | if (apply_microcode_early(&uci, true)) { | |
693 | /* Mixed-silicon system? Try to refetch the proper patch: */ | |
694 | *iup = NULL; | |
695 | ||
696 | goto reget; | |
697 | } | |
fe055896 BP |
698 | } |
699 | ||
06b8534c | 700 | static struct microcode_intel *find_patch(struct ucode_cpu_info *uci) |
fe055896 | 701 | { |
06b8534c BP |
702 | struct microcode_header_intel *phdr; |
703 | struct ucode_patch *iter, *tmp; | |
fe055896 | 704 | |
06b8534c | 705 | list_for_each_entry_safe(iter, tmp, µcode_cache, plist) { |
fe055896 | 706 | |
06b8534c | 707 | phdr = (struct microcode_header_intel *)iter->data; |
efaad554 | 708 | |
06b8534c BP |
709 | if (phdr->rev <= uci->cpu_sig.rev) |
710 | continue; | |
efaad554 | 711 | |
06b8534c BP |
712 | if (!find_matching_signature(phdr, |
713 | uci->cpu_sig.sig, | |
714 | uci->cpu_sig.pf)) | |
715 | continue; | |
fe055896 | 716 | |
06b8534c BP |
717 | return iter->data; |
718 | } | |
719 | return NULL; | |
fe055896 BP |
720 | } |
721 | ||
722 | void reload_ucode_intel(void) | |
723 | { | |
06b8534c | 724 | struct microcode_intel *p; |
fe055896 | 725 | struct ucode_cpu_info uci; |
fe055896 BP |
726 | |
727 | collect_cpu_info_early(&uci); | |
728 | ||
06b8534c BP |
729 | p = find_patch(&uci); |
730 | if (!p) | |
fe055896 BP |
731 | return; |
732 | ||
06b8534c BP |
733 | uci.mc = p; |
734 | ||
fe055896 BP |
735 | apply_microcode_early(&uci, false); |
736 | } | |
737 | ||
d45de409 | 738 | static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) |
1da177e4 | 739 | { |
354542d0 | 740 | static struct cpu_signature prev; |
92cb7612 | 741 | struct cpuinfo_x86 *c = &cpu_data(cpu_num); |
1da177e4 LT |
742 | unsigned int val[2]; |
743 | ||
d45de409 | 744 | memset(csig, 0, sizeof(*csig)); |
1da177e4 | 745 | |
d45de409 | 746 | csig->sig = cpuid_eax(0x00000001); |
9a3110bf SL |
747 | |
748 | if ((c->x86_model >= 5) || (c->x86 > 6)) { | |
749 | /* get processor flags from MSR 0x17 */ | |
750 | rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); | |
d45de409 | 751 | csig->pf = 1 << ((val[1] >> 18) & 7); |
1da177e4 LT |
752 | } |
753 | ||
506ed6b5 | 754 | csig->rev = c->microcode; |
354542d0 AK |
755 | |
756 | /* No extra locking on prev, races are harmless. */ | |
757 | if (csig->sig != prev.sig || csig->pf != prev.pf || csig->rev != prev.rev) { | |
758 | pr_info("sig=0x%x, pf=0x%x, revision=0x%x\n", | |
759 | csig->sig, csig->pf, csig->rev); | |
760 | prev = *csig; | |
761 | } | |
d45de409 DA |
762 | |
763 | return 0; | |
1da177e4 LT |
764 | } |
765 | ||
532ed374 | 766 | static int apply_microcode_intel(int cpu) |
1da177e4 | 767 | { |
de778275 | 768 | struct microcode_intel *mc; |
4bae1967 | 769 | struct ucode_cpu_info *uci; |
26cbaa4d | 770 | struct cpuinfo_x86 *c; |
354542d0 | 771 | static int prev_rev; |
4167709b | 772 | u32 rev; |
4bae1967 | 773 | |
9a3110bf | 774 | /* We should bind the task to the CPU */ |
26cbaa4d | 775 | if (WARN_ON(raw_smp_processor_id() != cpu)) |
58b5f2cc | 776 | return -1; |
9a3110bf | 777 | |
58b5f2cc BP |
778 | uci = ucode_cpu_info + cpu; |
779 | mc = uci->mc; | |
06b8534c BP |
780 | if (!mc) { |
781 | /* Look for a newer patch in our cache: */ | |
782 | mc = find_patch(uci); | |
783 | if (!mc) | |
784 | return 0; | |
785 | } | |
9cd4d78e | 786 | |
1da177e4 | 787 | /* write microcode via MSR 0x79 */ |
c416e611 | 788 | wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
245067d1 | 789 | |
4167709b | 790 | rev = intel_get_microcode_revision(); |
1da177e4 | 791 | |
4167709b | 792 | if (rev != mc->hdr.rev) { |
f58e1f53 | 793 | pr_err("CPU%d update to revision 0x%x failed\n", |
26cbaa4d | 794 | cpu, mc->hdr.rev); |
871b72dd | 795 | return -1; |
9a3110bf | 796 | } |
26cbaa4d | 797 | |
4167709b | 798 | if (rev != prev_rev) { |
354542d0 | 799 | pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n", |
4167709b | 800 | rev, |
354542d0 AK |
801 | mc->hdr.date & 0xffff, |
802 | mc->hdr.date >> 24, | |
803 | (mc->hdr.date >> 16) & 0xff); | |
4167709b | 804 | prev_rev = rev; |
354542d0 | 805 | } |
4bae1967 | 806 | |
26cbaa4d BP |
807 | c = &cpu_data(cpu); |
808 | ||
4167709b BP |
809 | uci->cpu_sig.rev = rev; |
810 | c->microcode = rev; | |
871b72dd DA |
811 | |
812 | return 0; | |
1da177e4 LT |
813 | } |
814 | ||
871b72dd DA |
815 | static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, |
816 | int (*get_ucode_data)(void *, const void *, size_t)) | |
9a3110bf | 817 | { |
a0a29b62 | 818 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
938179b4 | 819 | u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL; |
a0a29b62 DA |
820 | int new_rev = uci->cpu_sig.rev; |
821 | unsigned int leftover = size; | |
2e86222c | 822 | unsigned int curr_mc_size = 0, new_mc_size = 0; |
9cd4d78e | 823 | unsigned int csig, cpf; |
9a3110bf | 824 | |
a0a29b62 DA |
825 | while (leftover) { |
826 | struct microcode_header_intel mc_header; | |
827 | unsigned int mc_size; | |
9a3110bf | 828 | |
35a9ff4e QC |
829 | if (leftover < sizeof(mc_header)) { |
830 | pr_err("error! Truncated header in microcode data file\n"); | |
831 | break; | |
832 | } | |
833 | ||
a0a29b62 DA |
834 | if (get_ucode_data(&mc_header, ucode_ptr, sizeof(mc_header))) |
835 | break; | |
a30a6a2c | 836 | |
a0a29b62 DA |
837 | mc_size = get_totalsize(&mc_header); |
838 | if (!mc_size || mc_size > leftover) { | |
f58e1f53 | 839 | pr_err("error! Bad data in microcode data file\n"); |
a0a29b62 DA |
840 | break; |
841 | } | |
a30a6a2c | 842 | |
938179b4 DS |
843 | /* For performance reasons, reuse mc area when possible */ |
844 | if (!mc || mc_size > curr_mc_size) { | |
5cdd2de0 | 845 | vfree(mc); |
938179b4 DS |
846 | mc = vmalloc(mc_size); |
847 | if (!mc) | |
848 | break; | |
849 | curr_mc_size = mc_size; | |
850 | } | |
a0a29b62 DA |
851 | |
852 | if (get_ucode_data(mc, ucode_ptr, mc_size) || | |
9cd4d78e | 853 | microcode_sanity_check(mc, 1) < 0) { |
a0a29b62 DA |
854 | break; |
855 | } | |
856 | ||
9cd4d78e FY |
857 | csig = uci->cpu_sig.sig; |
858 | cpf = uci->cpu_sig.pf; | |
8de3eafc | 859 | if (has_newer_microcode(mc, csig, cpf, new_rev)) { |
5cdd2de0 | 860 | vfree(new_mc); |
a0a29b62 DA |
861 | new_rev = mc_header.rev; |
862 | new_mc = mc; | |
2e86222c | 863 | new_mc_size = mc_size; |
938179b4 DS |
864 | mc = NULL; /* trigger new vmalloc */ |
865 | } | |
a0a29b62 DA |
866 | |
867 | ucode_ptr += mc_size; | |
868 | leftover -= mc_size; | |
a30a6a2c SL |
869 | } |
870 | ||
5cdd2de0 | 871 | vfree(mc); |
938179b4 | 872 | |
871b72dd | 873 | if (leftover) { |
5cdd2de0 | 874 | vfree(new_mc); |
f61337d9 | 875 | return UCODE_ERROR; |
871b72dd | 876 | } |
4bae1967 | 877 | |
f61337d9 BP |
878 | if (!new_mc) |
879 | return UCODE_NFOUND; | |
a0a29b62 | 880 | |
5cdd2de0 | 881 | vfree(uci->mc); |
4bae1967 IM |
882 | uci->mc = (struct microcode_intel *)new_mc; |
883 | ||
9cd4d78e FY |
884 | /* |
885 | * If early loading microcode is supported, save this mc into | |
886 | * permanent memory. So it will be loaded early when a CPU is hot added | |
887 | * or resumes. | |
888 | */ | |
2e86222c | 889 | save_mc_for_early(new_mc, new_mc_size); |
9cd4d78e | 890 | |
f58e1f53 JP |
891 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
892 | cpu, new_rev, uci->cpu_sig.rev); | |
f61337d9 BP |
893 | |
894 | return UCODE_OK; | |
a30a6a2c SL |
895 | } |
896 | ||
a0a29b62 DA |
897 | static int get_ucode_fw(void *to, const void *from, size_t n) |
898 | { | |
899 | memcpy(to, from, n); | |
900 | return 0; | |
901 | } | |
a30a6a2c | 902 | |
48e30685 BP |
903 | static enum ucode_state request_microcode_fw(int cpu, struct device *device, |
904 | bool refresh_fw) | |
a30a6a2c SL |
905 | { |
906 | char name[30]; | |
92cb7612 | 907 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
a30a6a2c | 908 | const struct firmware *firmware; |
871b72dd | 909 | enum ucode_state ret; |
a30a6a2c | 910 | |
3e135d88 | 911 | sprintf(name, "intel-ucode/%02x-%02x-%02x", |
a30a6a2c | 912 | c->x86, c->x86_model, c->x86_mask); |
871b72dd | 913 | |
75da02b2 | 914 | if (request_firmware_direct(&firmware, name, device)) { |
f58e1f53 | 915 | pr_debug("data file %s load failed\n", name); |
871b72dd | 916 | return UCODE_NFOUND; |
a30a6a2c | 917 | } |
a0a29b62 | 918 | |
dd3feda7 JSR |
919 | ret = generic_load_microcode(cpu, (void *)firmware->data, |
920 | firmware->size, &get_ucode_fw); | |
a0a29b62 | 921 | |
a30a6a2c SL |
922 | release_firmware(firmware); |
923 | ||
a0a29b62 DA |
924 | return ret; |
925 | } | |
926 | ||
927 | static int get_ucode_user(void *to, const void *from, size_t n) | |
928 | { | |
929 | return copy_from_user(to, from, n); | |
930 | } | |
931 | ||
871b72dd DA |
932 | static enum ucode_state |
933 | request_microcode_user(int cpu, const void __user *buf, size_t size) | |
a0a29b62 | 934 | { |
dd3feda7 | 935 | return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user); |
a30a6a2c SL |
936 | } |
937 | ||
4db646b1 | 938 | static struct microcode_ops microcode_intel_ops = { |
a0a29b62 DA |
939 | .request_microcode_user = request_microcode_user, |
940 | .request_microcode_fw = request_microcode_fw, | |
8d86f390 | 941 | .collect_cpu_info = collect_cpu_info, |
532ed374 | 942 | .apply_microcode = apply_microcode_intel, |
8d86f390 PO |
943 | }; |
944 | ||
18dbc916 | 945 | struct microcode_ops * __init init_intel_microcode(void) |
8d86f390 | 946 | { |
9a2bc335 | 947 | struct cpuinfo_x86 *c = &boot_cpu_data; |
7164b3f5 SB |
948 | |
949 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || | |
950 | cpu_has(c, X86_FEATURE_IA64)) { | |
951 | pr_err("Intel CPU family 0x%x not supported\n", c->x86); | |
952 | return NULL; | |
953 | } | |
954 | ||
18dbc916 | 955 | return µcode_intel_ops; |
8d86f390 | 956 | } |