Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
6b44e72a | 2 | * Intel CPU Microcode Update Driver for Linux |
1da177e4 | 3 | * |
6b44e72a BP |
4 | * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> |
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 | |
06b8534c BP |
44 | /* Current microcode patch used in early patching */ |
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 | |
6c545647 | 610 | /* |
06b8534c | 611 | * AP loading didn't find any microcode patch, no need to save anything. |
6c545647 | 612 | */ |
06b8534c BP |
613 | if (!intel_ucode_patch || IS_ERR(intel_ucode_patch)) |
614 | return 0; | |
4fe9349f | 615 | |
06b8534c BP |
616 | if (!load_builtin_intel_microcode(&cp)) |
617 | cp = find_microcode_in_initrd(ucode_path, false); | |
fe055896 | 618 | |
06b8534c BP |
619 | if (!(cp.data && cp.size)) |
620 | return 0; | |
fe055896 | 621 | |
06b8534c | 622 | collect_cpu_info_early(&uci); |
6c545647 | 623 | |
06b8534c | 624 | scan_microcode(cp.data, cp.size, &uci, true); |
6c545647 | 625 | |
06b8534c | 626 | show_saved_mc(); |
6c545647 | 627 | |
06b8534c BP |
628 | return 0; |
629 | } | |
6c545647 | 630 | |
6c545647 | 631 | |
06b8534c BP |
632 | /* |
633 | * @res_patch, output: a pointer to the patch we found. | |
634 | */ | |
635 | static struct microcode_intel *__load_ucode_intel(struct ucode_cpu_info *uci) | |
636 | { | |
637 | static const char *path; | |
638 | struct cpio_data cp; | |
639 | bool use_pa; | |
6c545647 | 640 | |
06b8534c BP |
641 | if (IS_ENABLED(CONFIG_X86_32)) { |
642 | path = (const char *)__pa_nodebug(ucode_path); | |
643 | use_pa = true; | |
644 | } else { | |
645 | path = ucode_path; | |
646 | use_pa = false; | |
6c545647 | 647 | } |
6c545647 | 648 | |
06b8534c BP |
649 | /* try built-in microcode first */ |
650 | if (!load_builtin_intel_microcode(&cp)) | |
651 | cp = find_microcode_in_initrd(path, use_pa); | |
6c545647 | 652 | |
06b8534c BP |
653 | if (!(cp.data && cp.size)) |
654 | return NULL; | |
6c545647 | 655 | |
06b8534c | 656 | collect_cpu_info_early(uci); |
6c545647 | 657 | |
06b8534c | 658 | return scan_microcode(cp.data, cp.size, uci, false); |
6c545647 BP |
659 | } |
660 | ||
06b8534c | 661 | void __init load_ucode_intel_bsp(void) |
fe055896 | 662 | { |
06b8534c | 663 | struct microcode_intel *patch; |
fe055896 | 664 | struct ucode_cpu_info uci; |
fe055896 | 665 | |
06b8534c BP |
666 | patch = __load_ucode_intel(&uci); |
667 | if (!patch) | |
fe055896 BP |
668 | return; |
669 | ||
06b8534c | 670 | uci.mc = patch; |
fe055896 BP |
671 | |
672 | apply_microcode_early(&uci, true); | |
673 | } | |
674 | ||
06b8534c | 675 | void load_ucode_intel_ap(void) |
fe055896 | 676 | { |
06b8534c BP |
677 | struct microcode_intel *patch, **iup; |
678 | struct ucode_cpu_info uci; | |
264285ac | 679 | |
06b8534c BP |
680 | if (IS_ENABLED(CONFIG_X86_32)) |
681 | iup = (struct microcode_intel **) __pa_nodebug(&intel_ucode_patch); | |
682 | else | |
683 | iup = &intel_ucode_patch; | |
684 | ||
685 | reget: | |
686 | if (!*iup) { | |
687 | patch = __load_ucode_intel(&uci); | |
688 | if (!patch) | |
689 | return; | |
6c545647 | 690 | |
06b8534c BP |
691 | *iup = patch; |
692 | } | |
693 | ||
694 | uci.mc = *iup; | |
695 | ||
696 | if (apply_microcode_early(&uci, true)) { | |
697 | /* Mixed-silicon system? Try to refetch the proper patch: */ | |
698 | *iup = NULL; | |
699 | ||
700 | goto reget; | |
701 | } | |
fe055896 BP |
702 | } |
703 | ||
06b8534c | 704 | static struct microcode_intel *find_patch(struct ucode_cpu_info *uci) |
fe055896 | 705 | { |
06b8534c BP |
706 | struct microcode_header_intel *phdr; |
707 | struct ucode_patch *iter, *tmp; | |
fe055896 | 708 | |
06b8534c | 709 | list_for_each_entry_safe(iter, tmp, µcode_cache, plist) { |
fe055896 | 710 | |
06b8534c | 711 | phdr = (struct microcode_header_intel *)iter->data; |
efaad554 | 712 | |
06b8534c BP |
713 | if (phdr->rev <= uci->cpu_sig.rev) |
714 | continue; | |
efaad554 | 715 | |
06b8534c BP |
716 | if (!find_matching_signature(phdr, |
717 | uci->cpu_sig.sig, | |
718 | uci->cpu_sig.pf)) | |
719 | continue; | |
fe055896 | 720 | |
06b8534c BP |
721 | return iter->data; |
722 | } | |
723 | return NULL; | |
fe055896 BP |
724 | } |
725 | ||
726 | void reload_ucode_intel(void) | |
727 | { | |
06b8534c | 728 | struct microcode_intel *p; |
fe055896 | 729 | struct ucode_cpu_info uci; |
fe055896 BP |
730 | |
731 | collect_cpu_info_early(&uci); | |
732 | ||
06b8534c BP |
733 | p = find_patch(&uci); |
734 | if (!p) | |
fe055896 BP |
735 | return; |
736 | ||
06b8534c BP |
737 | uci.mc = p; |
738 | ||
fe055896 BP |
739 | apply_microcode_early(&uci, false); |
740 | } | |
741 | ||
d45de409 | 742 | static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) |
1da177e4 | 743 | { |
354542d0 | 744 | static struct cpu_signature prev; |
92cb7612 | 745 | struct cpuinfo_x86 *c = &cpu_data(cpu_num); |
1da177e4 LT |
746 | unsigned int val[2]; |
747 | ||
d45de409 | 748 | memset(csig, 0, sizeof(*csig)); |
1da177e4 | 749 | |
d45de409 | 750 | csig->sig = cpuid_eax(0x00000001); |
9a3110bf SL |
751 | |
752 | if ((c->x86_model >= 5) || (c->x86 > 6)) { | |
753 | /* get processor flags from MSR 0x17 */ | |
754 | rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); | |
d45de409 | 755 | csig->pf = 1 << ((val[1] >> 18) & 7); |
1da177e4 LT |
756 | } |
757 | ||
506ed6b5 | 758 | csig->rev = c->microcode; |
354542d0 AK |
759 | |
760 | /* No extra locking on prev, races are harmless. */ | |
761 | if (csig->sig != prev.sig || csig->pf != prev.pf || csig->rev != prev.rev) { | |
762 | pr_info("sig=0x%x, pf=0x%x, revision=0x%x\n", | |
763 | csig->sig, csig->pf, csig->rev); | |
764 | prev = *csig; | |
765 | } | |
d45de409 DA |
766 | |
767 | return 0; | |
1da177e4 LT |
768 | } |
769 | ||
532ed374 | 770 | static int apply_microcode_intel(int cpu) |
1da177e4 | 771 | { |
de778275 | 772 | struct microcode_intel *mc; |
4bae1967 | 773 | struct ucode_cpu_info *uci; |
26cbaa4d | 774 | struct cpuinfo_x86 *c; |
354542d0 | 775 | static int prev_rev; |
4167709b | 776 | u32 rev; |
4bae1967 | 777 | |
9a3110bf | 778 | /* We should bind the task to the CPU */ |
26cbaa4d | 779 | if (WARN_ON(raw_smp_processor_id() != cpu)) |
58b5f2cc | 780 | return -1; |
9a3110bf | 781 | |
58b5f2cc BP |
782 | uci = ucode_cpu_info + cpu; |
783 | mc = uci->mc; | |
06b8534c BP |
784 | if (!mc) { |
785 | /* Look for a newer patch in our cache: */ | |
786 | mc = find_patch(uci); | |
787 | if (!mc) | |
788 | return 0; | |
789 | } | |
9cd4d78e | 790 | |
1da177e4 | 791 | /* write microcode via MSR 0x79 */ |
c416e611 | 792 | wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
245067d1 | 793 | |
4167709b | 794 | rev = intel_get_microcode_revision(); |
1da177e4 | 795 | |
4167709b | 796 | if (rev != mc->hdr.rev) { |
f58e1f53 | 797 | pr_err("CPU%d update to revision 0x%x failed\n", |
26cbaa4d | 798 | cpu, mc->hdr.rev); |
871b72dd | 799 | return -1; |
9a3110bf | 800 | } |
26cbaa4d | 801 | |
4167709b | 802 | if (rev != prev_rev) { |
354542d0 | 803 | pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n", |
4167709b | 804 | rev, |
354542d0 AK |
805 | mc->hdr.date & 0xffff, |
806 | mc->hdr.date >> 24, | |
807 | (mc->hdr.date >> 16) & 0xff); | |
4167709b | 808 | prev_rev = rev; |
354542d0 | 809 | } |
4bae1967 | 810 | |
26cbaa4d BP |
811 | c = &cpu_data(cpu); |
812 | ||
4167709b BP |
813 | uci->cpu_sig.rev = rev; |
814 | c->microcode = rev; | |
871b72dd DA |
815 | |
816 | return 0; | |
1da177e4 LT |
817 | } |
818 | ||
871b72dd DA |
819 | static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, |
820 | int (*get_ucode_data)(void *, const void *, size_t)) | |
9a3110bf | 821 | { |
a0a29b62 | 822 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
938179b4 | 823 | u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL; |
a0a29b62 DA |
824 | int new_rev = uci->cpu_sig.rev; |
825 | unsigned int leftover = size; | |
2e86222c | 826 | unsigned int curr_mc_size = 0, new_mc_size = 0; |
9cd4d78e | 827 | unsigned int csig, cpf; |
9a3110bf | 828 | |
a0a29b62 DA |
829 | while (leftover) { |
830 | struct microcode_header_intel mc_header; | |
831 | unsigned int mc_size; | |
9a3110bf | 832 | |
35a9ff4e QC |
833 | if (leftover < sizeof(mc_header)) { |
834 | pr_err("error! Truncated header in microcode data file\n"); | |
835 | break; | |
836 | } | |
837 | ||
a0a29b62 DA |
838 | if (get_ucode_data(&mc_header, ucode_ptr, sizeof(mc_header))) |
839 | break; | |
a30a6a2c | 840 | |
a0a29b62 DA |
841 | mc_size = get_totalsize(&mc_header); |
842 | if (!mc_size || mc_size > leftover) { | |
f58e1f53 | 843 | pr_err("error! Bad data in microcode data file\n"); |
a0a29b62 DA |
844 | break; |
845 | } | |
a30a6a2c | 846 | |
938179b4 DS |
847 | /* For performance reasons, reuse mc area when possible */ |
848 | if (!mc || mc_size > curr_mc_size) { | |
5cdd2de0 | 849 | vfree(mc); |
938179b4 DS |
850 | mc = vmalloc(mc_size); |
851 | if (!mc) | |
852 | break; | |
853 | curr_mc_size = mc_size; | |
854 | } | |
a0a29b62 DA |
855 | |
856 | if (get_ucode_data(mc, ucode_ptr, mc_size) || | |
9cd4d78e | 857 | microcode_sanity_check(mc, 1) < 0) { |
a0a29b62 DA |
858 | break; |
859 | } | |
860 | ||
9cd4d78e FY |
861 | csig = uci->cpu_sig.sig; |
862 | cpf = uci->cpu_sig.pf; | |
8de3eafc | 863 | if (has_newer_microcode(mc, csig, cpf, new_rev)) { |
5cdd2de0 | 864 | vfree(new_mc); |
a0a29b62 DA |
865 | new_rev = mc_header.rev; |
866 | new_mc = mc; | |
2e86222c | 867 | new_mc_size = mc_size; |
938179b4 DS |
868 | mc = NULL; /* trigger new vmalloc */ |
869 | } | |
a0a29b62 DA |
870 | |
871 | ucode_ptr += mc_size; | |
872 | leftover -= mc_size; | |
a30a6a2c SL |
873 | } |
874 | ||
5cdd2de0 | 875 | vfree(mc); |
938179b4 | 876 | |
871b72dd | 877 | if (leftover) { |
5cdd2de0 | 878 | vfree(new_mc); |
f61337d9 | 879 | return UCODE_ERROR; |
871b72dd | 880 | } |
4bae1967 | 881 | |
f61337d9 BP |
882 | if (!new_mc) |
883 | return UCODE_NFOUND; | |
a0a29b62 | 884 | |
5cdd2de0 | 885 | vfree(uci->mc); |
4bae1967 IM |
886 | uci->mc = (struct microcode_intel *)new_mc; |
887 | ||
9cd4d78e FY |
888 | /* |
889 | * If early loading microcode is supported, save this mc into | |
890 | * permanent memory. So it will be loaded early when a CPU is hot added | |
891 | * or resumes. | |
892 | */ | |
2e86222c | 893 | save_mc_for_early(new_mc, new_mc_size); |
9cd4d78e | 894 | |
f58e1f53 JP |
895 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
896 | cpu, new_rev, uci->cpu_sig.rev); | |
f61337d9 BP |
897 | |
898 | return UCODE_OK; | |
a30a6a2c SL |
899 | } |
900 | ||
a0a29b62 DA |
901 | static int get_ucode_fw(void *to, const void *from, size_t n) |
902 | { | |
903 | memcpy(to, from, n); | |
904 | return 0; | |
905 | } | |
a30a6a2c | 906 | |
48e30685 BP |
907 | static enum ucode_state request_microcode_fw(int cpu, struct device *device, |
908 | bool refresh_fw) | |
a30a6a2c SL |
909 | { |
910 | char name[30]; | |
92cb7612 | 911 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
a30a6a2c | 912 | const struct firmware *firmware; |
871b72dd | 913 | enum ucode_state ret; |
a30a6a2c | 914 | |
3e135d88 | 915 | sprintf(name, "intel-ucode/%02x-%02x-%02x", |
a30a6a2c | 916 | c->x86, c->x86_model, c->x86_mask); |
871b72dd | 917 | |
75da02b2 | 918 | if (request_firmware_direct(&firmware, name, device)) { |
f58e1f53 | 919 | pr_debug("data file %s load failed\n", name); |
871b72dd | 920 | return UCODE_NFOUND; |
a30a6a2c | 921 | } |
a0a29b62 | 922 | |
dd3feda7 JSR |
923 | ret = generic_load_microcode(cpu, (void *)firmware->data, |
924 | firmware->size, &get_ucode_fw); | |
a0a29b62 | 925 | |
a30a6a2c SL |
926 | release_firmware(firmware); |
927 | ||
a0a29b62 DA |
928 | return ret; |
929 | } | |
930 | ||
931 | static int get_ucode_user(void *to, const void *from, size_t n) | |
932 | { | |
933 | return copy_from_user(to, from, n); | |
934 | } | |
935 | ||
871b72dd DA |
936 | static enum ucode_state |
937 | request_microcode_user(int cpu, const void __user *buf, size_t size) | |
a0a29b62 | 938 | { |
dd3feda7 | 939 | return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user); |
a30a6a2c SL |
940 | } |
941 | ||
4db646b1 | 942 | static struct microcode_ops microcode_intel_ops = { |
a0a29b62 DA |
943 | .request_microcode_user = request_microcode_user, |
944 | .request_microcode_fw = request_microcode_fw, | |
8d86f390 | 945 | .collect_cpu_info = collect_cpu_info, |
532ed374 | 946 | .apply_microcode = apply_microcode_intel, |
8d86f390 PO |
947 | }; |
948 | ||
18dbc916 | 949 | struct microcode_ops * __init init_intel_microcode(void) |
8d86f390 | 950 | { |
9a2bc335 | 951 | struct cpuinfo_x86 *c = &boot_cpu_data; |
7164b3f5 SB |
952 | |
953 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || | |
954 | cpu_has(c, X86_FEATURE_IA64)) { | |
955 | pr_err("Intel CPU family 0x%x not supported\n", c->x86); | |
956 | return NULL; | |
957 | } | |
958 | ||
18dbc916 | 959 | return µcode_intel_ops; |
8d86f390 | 960 | } |