1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Intel CPU Microcode Update Driver for Linux |
4 | * |
5 | * Copyright (C) 2000-2006 Tigran Aivazian <aivazian.tigran@gmail.com> |
6 | * 2006 Shaohua Li <shaohua.li@intel.com> |
7 | * |
8 | * Intel CPU microcode early update for Linux |
9 | * |
10 | * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com> |
11 | * H Peter Anvin" <hpa@zytor.com> |
12 | */ |
13 | #define pr_fmt(fmt) "microcode: " fmt |
14 | #include <linux/earlycpio.h> |
15 | #include <linux/firmware.h> |
16 | #include <linux/uaccess.h> |
17 | #include <linux/initrd.h> |
18 | #include <linux/kernel.h> |
19 | #include <linux/slab.h> |
20 | #include <linux/cpu.h> |
21 | #include <linux/uio.h> |
22 | #include <linux/mm.h> |
23 | |
24 | #include <asm/intel-family.h> |
25 | #include <asm/processor.h> |
26 | #include <asm/tlbflush.h> |
27 | #include <asm/setup.h> |
28 | #include <asm/msr.h> |
29 | |
30 | #include "internal.h" |
31 | |
32 | static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin" ; |
33 | |
34 | #define UCODE_BSP_LOADED ((struct microcode_intel *)0x1UL) |
35 | |
36 | /* Current microcode patch used in early patching on the APs. */ |
37 | static struct microcode_intel *ucode_patch_va __read_mostly; |
38 | static struct microcode_intel *ucode_patch_late __read_mostly; |
39 | |
40 | /* last level cache size per core */ |
41 | static unsigned int llc_size_per_core __ro_after_init; |
42 | |
43 | /* microcode format is extended from prescott processors */ |
44 | struct extended_signature { |
45 | unsigned int sig; |
46 | unsigned int pf; |
47 | unsigned int cksum; |
48 | }; |
49 | |
50 | struct extended_sigtable { |
51 | unsigned int count; |
52 | unsigned int cksum; |
53 | unsigned int reserved[3]; |
54 | struct extended_signature sigs[]; |
55 | }; |
56 | |
57 | #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) |
58 | #define (sizeof(struct extended_sigtable)) |
59 | #define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) |
60 | |
61 | static inline unsigned int get_totalsize(struct microcode_header_intel *hdr) |
62 | { |
63 | return hdr->datasize ? hdr->totalsize : DEFAULT_UCODE_TOTALSIZE; |
64 | } |
65 | |
66 | static inline unsigned int exttable_size(struct extended_sigtable *et) |
67 | { |
68 | return et->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE; |
69 | } |
70 | |
71 | void intel_collect_cpu_info(struct cpu_signature *sig) |
72 | { |
73 | sig->sig = cpuid_eax(op: 1); |
74 | sig->pf = 0; |
75 | sig->rev = intel_get_microcode_revision(); |
76 | |
77 | if (x86_model(sig: sig->sig) >= 5 || x86_family(sig: sig->sig) > 6) { |
78 | unsigned int val[2]; |
79 | |
80 | /* get processor flags from MSR 0x17 */ |
81 | native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); |
82 | sig->pf = 1 << ((val[1] >> 18) & 7); |
83 | } |
84 | } |
85 | EXPORT_SYMBOL_GPL(intel_collect_cpu_info); |
86 | |
87 | static inline bool cpu_signatures_match(struct cpu_signature *s1, unsigned int sig2, |
88 | unsigned int pf2) |
89 | { |
90 | if (s1->sig != sig2) |
91 | return false; |
92 | |
93 | /* Processor flags are either both 0 or they intersect. */ |
94 | return ((!s1->pf && !pf2) || (s1->pf & pf2)); |
95 | } |
96 | |
97 | bool intel_find_matching_signature(void *mc, struct cpu_signature *sig) |
98 | { |
99 | struct microcode_header_intel *mc_hdr = mc; |
100 | struct extended_signature *ext_sig; |
101 | struct extended_sigtable *ext_hdr; |
102 | int i; |
103 | |
104 | if (cpu_signatures_match(s1: sig, sig2: mc_hdr->sig, pf2: mc_hdr->pf)) |
105 | return true; |
106 | |
107 | /* Look for ext. headers: */ |
108 | if (get_totalsize(hdr: mc_hdr) <= intel_microcode_get_datasize(hdr: mc_hdr) + MC_HEADER_SIZE) |
109 | return false; |
110 | |
111 | ext_hdr = mc + intel_microcode_get_datasize(hdr: mc_hdr) + MC_HEADER_SIZE; |
112 | ext_sig = (void *)ext_hdr + EXT_HEADER_SIZE; |
113 | |
114 | for (i = 0; i < ext_hdr->count; i++) { |
115 | if (cpu_signatures_match(s1: sig, sig2: ext_sig->sig, pf2: ext_sig->pf)) |
116 | return true; |
117 | ext_sig++; |
118 | } |
119 | return 0; |
120 | } |
121 | EXPORT_SYMBOL_GPL(intel_find_matching_signature); |
122 | |
123 | /** |
124 | * intel_microcode_sanity_check() - Sanity check microcode file. |
125 | * @mc: Pointer to the microcode file contents. |
126 | * @print_err: Display failure reason if true, silent if false. |
127 | * @hdr_type: Type of file, i.e. normal microcode file or In Field Scan file. |
128 | * Validate if the microcode header type matches with the type |
129 | * specified here. |
130 | * |
131 | * Validate certain header fields and verify if computed checksum matches |
132 | * with the one specified in the header. |
133 | * |
134 | * Return: 0 if the file passes all the checks, -EINVAL if any of the checks |
135 | * fail. |
136 | */ |
137 | int intel_microcode_sanity_check(void *mc, bool print_err, int hdr_type) |
138 | { |
139 | unsigned long total_size, data_size, ext_table_size; |
140 | struct microcode_header_intel * = mc; |
141 | struct extended_sigtable * = NULL; |
142 | u32 sum, orig_sum, ext_sigcount = 0, i; |
143 | struct extended_signature *ext_sig; |
144 | |
145 | total_size = get_totalsize(hdr: mc_header); |
146 | data_size = intel_microcode_get_datasize(hdr: mc_header); |
147 | |
148 | if (data_size + MC_HEADER_SIZE > total_size) { |
149 | if (print_err) |
150 | pr_err("Error: bad microcode data file size.\n" ); |
151 | return -EINVAL; |
152 | } |
153 | |
154 | if (mc_header->ldrver != 1 || mc_header->hdrver != hdr_type) { |
155 | if (print_err) |
156 | pr_err("Error: invalid/unknown microcode update format. Header type %d\n" , |
157 | mc_header->hdrver); |
158 | return -EINVAL; |
159 | } |
160 | |
161 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); |
162 | if (ext_table_size) { |
163 | u32 ext_table_sum = 0; |
164 | u32 *ext_tablep; |
165 | |
166 | if (ext_table_size < EXT_HEADER_SIZE || |
167 | ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { |
168 | if (print_err) |
169 | pr_err("Error: truncated extended signature table.\n" ); |
170 | return -EINVAL; |
171 | } |
172 | |
173 | ext_header = mc + MC_HEADER_SIZE + data_size; |
174 | if (ext_table_size != exttable_size(et: ext_header)) { |
175 | if (print_err) |
176 | pr_err("Error: extended signature table size mismatch.\n" ); |
177 | return -EFAULT; |
178 | } |
179 | |
180 | ext_sigcount = ext_header->count; |
181 | |
182 | /* |
183 | * Check extended table checksum: the sum of all dwords that |
184 | * comprise a valid table must be 0. |
185 | */ |
186 | ext_tablep = (u32 *)ext_header; |
187 | |
188 | i = ext_table_size / sizeof(u32); |
189 | while (i--) |
190 | ext_table_sum += ext_tablep[i]; |
191 | |
192 | if (ext_table_sum) { |
193 | if (print_err) |
194 | pr_warn("Bad extended signature table checksum, aborting.\n" ); |
195 | return -EINVAL; |
196 | } |
197 | } |
198 | |
199 | /* |
200 | * Calculate the checksum of update data and header. The checksum of |
201 | * valid update data and header including the extended signature table |
202 | * must be 0. |
203 | */ |
204 | orig_sum = 0; |
205 | i = (MC_HEADER_SIZE + data_size) / sizeof(u32); |
206 | while (i--) |
207 | orig_sum += ((u32 *)mc)[i]; |
208 | |
209 | if (orig_sum) { |
210 | if (print_err) |
211 | pr_err("Bad microcode data checksum, aborting.\n" ); |
212 | return -EINVAL; |
213 | } |
214 | |
215 | if (!ext_table_size) |
216 | return 0; |
217 | |
218 | /* |
219 | * Check extended signature checksum: 0 => valid. |
220 | */ |
221 | for (i = 0; i < ext_sigcount; i++) { |
222 | ext_sig = (void *)ext_header + EXT_HEADER_SIZE + |
223 | EXT_SIGNATURE_SIZE * i; |
224 | |
225 | sum = (mc_header->sig + mc_header->pf + mc_header->cksum) - |
226 | (ext_sig->sig + ext_sig->pf + ext_sig->cksum); |
227 | if (sum) { |
228 | if (print_err) |
229 | pr_err("Bad extended signature checksum, aborting.\n" ); |
230 | return -EINVAL; |
231 | } |
232 | } |
233 | return 0; |
234 | } |
235 | EXPORT_SYMBOL_GPL(intel_microcode_sanity_check); |
236 | |
237 | static void update_ucode_pointer(struct microcode_intel *mc) |
238 | { |
239 | kvfree(addr: ucode_patch_va); |
240 | |
241 | /* |
242 | * Save the virtual address for early loading and for eventual free |
243 | * on late loading. |
244 | */ |
245 | ucode_patch_va = mc; |
246 | } |
247 | |
248 | static void save_microcode_patch(struct microcode_intel *patch) |
249 | { |
250 | unsigned int size = get_totalsize(hdr: &patch->hdr); |
251 | struct microcode_intel *mc; |
252 | |
253 | mc = kvmemdup(src: patch, len: size, GFP_KERNEL); |
254 | if (mc) |
255 | update_ucode_pointer(mc); |
256 | else |
257 | pr_err("Unable to allocate microcode memory size: %u\n" , size); |
258 | } |
259 | |
260 | /* Scan blob for microcode matching the boot CPUs family, model, stepping */ |
261 | static __init struct microcode_intel *scan_microcode(void *data, size_t size, |
262 | struct ucode_cpu_info *uci, |
263 | bool save) |
264 | { |
265 | struct microcode_header_intel *; |
266 | struct microcode_intel *patch = NULL; |
267 | u32 cur_rev = uci->cpu_sig.rev; |
268 | unsigned int mc_size; |
269 | |
270 | for (; size >= sizeof(struct microcode_header_intel); size -= mc_size, data += mc_size) { |
271 | mc_header = (struct microcode_header_intel *)data; |
272 | |
273 | mc_size = get_totalsize(hdr: mc_header); |
274 | if (!mc_size || mc_size > size || |
275 | intel_microcode_sanity_check(data, false, MC_HEADER_TYPE_MICROCODE) < 0) |
276 | break; |
277 | |
278 | if (!intel_find_matching_signature(data, &uci->cpu_sig)) |
279 | continue; |
280 | |
281 | /* |
282 | * For saving the early microcode, find the matching revision which |
283 | * was loaded on the BSP. |
284 | * |
285 | * On the BSP during early boot, find a newer revision than |
286 | * actually loaded in the CPU. |
287 | */ |
288 | if (save) { |
289 | if (cur_rev != mc_header->rev) |
290 | continue; |
291 | } else if (cur_rev >= mc_header->rev) { |
292 | continue; |
293 | } |
294 | |
295 | patch = data; |
296 | cur_rev = mc_header->rev; |
297 | } |
298 | |
299 | return size ? NULL : patch; |
300 | } |
301 | |
302 | static enum ucode_state __apply_microcode(struct ucode_cpu_info *uci, |
303 | struct microcode_intel *mc, |
304 | u32 *cur_rev) |
305 | { |
306 | u32 rev; |
307 | |
308 | if (!mc) |
309 | return UCODE_NFOUND; |
310 | |
311 | /* |
312 | * Save us the MSR write below - which is a particular expensive |
313 | * operation - when the other hyperthread has updated the microcode |
314 | * already. |
315 | */ |
316 | *cur_rev = intel_get_microcode_revision(); |
317 | if (*cur_rev >= mc->hdr.rev) { |
318 | uci->cpu_sig.rev = *cur_rev; |
319 | return UCODE_OK; |
320 | } |
321 | |
322 | /* |
323 | * Writeback and invalidate caches before updating microcode to avoid |
324 | * internal issues depending on what the microcode is updating. |
325 | */ |
326 | native_wbinvd(); |
327 | |
328 | /* write microcode via MSR 0x79 */ |
329 | native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
330 | |
331 | rev = intel_get_microcode_revision(); |
332 | if (rev != mc->hdr.rev) |
333 | return UCODE_ERROR; |
334 | |
335 | uci->cpu_sig.rev = rev; |
336 | return UCODE_UPDATED; |
337 | } |
338 | |
339 | static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci) |
340 | { |
341 | struct microcode_intel *mc = uci->mc; |
342 | u32 cur_rev; |
343 | |
344 | return __apply_microcode(uci, mc, cur_rev: &cur_rev); |
345 | } |
346 | |
347 | static __init bool load_builtin_intel_microcode(struct cpio_data *cp) |
348 | { |
349 | unsigned int eax = 1, ebx, ecx = 0, edx; |
350 | struct firmware fw; |
351 | char name[30]; |
352 | |
353 | if (IS_ENABLED(CONFIG_X86_32)) |
354 | return false; |
355 | |
356 | native_cpuid(eax: &eax, ebx: &ebx, ecx: &ecx, edx: &edx); |
357 | |
358 | sprintf(buf: name, fmt: "intel-ucode/%02x-%02x-%02x" , |
359 | x86_family(sig: eax), x86_model(sig: eax), x86_stepping(sig: eax)); |
360 | |
361 | if (firmware_request_builtin(fw: &fw, name)) { |
362 | cp->size = fw.size; |
363 | cp->data = (void *)fw.data; |
364 | return true; |
365 | } |
366 | return false; |
367 | } |
368 | |
369 | static __init struct microcode_intel *get_microcode_blob(struct ucode_cpu_info *uci, bool save) |
370 | { |
371 | struct cpio_data cp; |
372 | |
373 | intel_collect_cpu_info(&uci->cpu_sig); |
374 | |
375 | if (!load_builtin_intel_microcode(cp: &cp)) |
376 | cp = find_microcode_in_initrd(path: ucode_path); |
377 | |
378 | if (!(cp.data && cp.size)) |
379 | return NULL; |
380 | |
381 | return scan_microcode(data: cp.data, size: cp.size, uci, save); |
382 | } |
383 | |
384 | /* |
385 | * Invoked from an early init call to save the microcode blob which was |
386 | * selected during early boot when mm was not usable. The microcode must be |
387 | * saved because initrd is going away. It's an early init call so the APs |
388 | * just can use the pointer and do not have to scan initrd/builtin firmware |
389 | * again. |
390 | */ |
391 | static int __init save_builtin_microcode(void) |
392 | { |
393 | struct ucode_cpu_info uci; |
394 | |
395 | if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED) |
396 | return 0; |
397 | |
398 | if (dis_ucode_ldr || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) |
399 | return 0; |
400 | |
401 | uci.mc = get_microcode_blob(uci: &uci, save: true); |
402 | if (uci.mc) |
403 | save_microcode_patch(patch: uci.mc); |
404 | return 0; |
405 | } |
406 | early_initcall(save_builtin_microcode); |
407 | |
408 | /* Load microcode on BSP from initrd or builtin blobs */ |
409 | void __init load_ucode_intel_bsp(struct early_load_data *ed) |
410 | { |
411 | struct ucode_cpu_info uci; |
412 | |
413 | uci.mc = get_microcode_blob(uci: &uci, save: false); |
414 | ed->old_rev = uci.cpu_sig.rev; |
415 | |
416 | if (uci.mc && apply_microcode_early(uci: &uci) == UCODE_UPDATED) { |
417 | ucode_patch_va = UCODE_BSP_LOADED; |
418 | ed->new_rev = uci.cpu_sig.rev; |
419 | } |
420 | } |
421 | |
422 | void load_ucode_intel_ap(void) |
423 | { |
424 | struct ucode_cpu_info uci; |
425 | |
426 | uci.mc = ucode_patch_va; |
427 | if (uci.mc) |
428 | apply_microcode_early(uci: &uci); |
429 | } |
430 | |
431 | /* Reload microcode on resume */ |
432 | void reload_ucode_intel(void) |
433 | { |
434 | struct ucode_cpu_info uci = { .mc = ucode_patch_va, }; |
435 | |
436 | if (uci.mc) |
437 | apply_microcode_early(uci: &uci); |
438 | } |
439 | |
440 | static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) |
441 | { |
442 | intel_collect_cpu_info(csig); |
443 | return 0; |
444 | } |
445 | |
446 | static enum ucode_state apply_microcode_late(int cpu) |
447 | { |
448 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
449 | struct microcode_intel *mc = ucode_patch_late; |
450 | enum ucode_state ret; |
451 | u32 cur_rev; |
452 | |
453 | if (WARN_ON_ONCE(smp_processor_id() != cpu)) |
454 | return UCODE_ERROR; |
455 | |
456 | ret = __apply_microcode(uci, mc, cur_rev: &cur_rev); |
457 | if (ret != UCODE_UPDATED && ret != UCODE_OK) |
458 | return ret; |
459 | |
460 | cpu_data(cpu).microcode = uci->cpu_sig.rev; |
461 | if (!cpu) |
462 | boot_cpu_data.microcode = uci->cpu_sig.rev; |
463 | |
464 | return ret; |
465 | } |
466 | |
467 | static bool ucode_validate_minrev(struct microcode_header_intel *) |
468 | { |
469 | int cur_rev = boot_cpu_data.microcode; |
470 | |
471 | /* |
472 | * When late-loading, ensure the header declares a minimum revision |
473 | * required to perform a late-load. The previously reserved field |
474 | * is 0 in older microcode blobs. |
475 | */ |
476 | if (!mc_header->min_req_ver) { |
477 | pr_info("Unsafe microcode update: Microcode header does not specify a required min version\n" ); |
478 | return false; |
479 | } |
480 | |
481 | /* |
482 | * Check whether the current revision is either greater or equal to |
483 | * to the minimum revision specified in the header. |
484 | */ |
485 | if (cur_rev < mc_header->min_req_ver) { |
486 | pr_info("Unsafe microcode update: Current revision 0x%x too old\n" , cur_rev); |
487 | pr_info("Current should be at 0x%x or higher. Use early loading instead\n" , mc_header->min_req_ver); |
488 | return false; |
489 | } |
490 | return true; |
491 | } |
492 | |
493 | static enum ucode_state parse_microcode_blobs(int cpu, struct iov_iter *iter) |
494 | { |
495 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
496 | bool is_safe, new_is_safe = false; |
497 | int cur_rev = uci->cpu_sig.rev; |
498 | unsigned int curr_mc_size = 0; |
499 | u8 *new_mc = NULL, *mc = NULL; |
500 | |
501 | while (iov_iter_count(i: iter)) { |
502 | struct microcode_header_intel ; |
503 | unsigned int mc_size, data_size; |
504 | u8 *data; |
505 | |
506 | if (!copy_from_iter_full(addr: &mc_header, bytes: sizeof(mc_header), i: iter)) { |
507 | pr_err("error! Truncated or inaccessible header in microcode data file\n" ); |
508 | goto fail; |
509 | } |
510 | |
511 | mc_size = get_totalsize(hdr: &mc_header); |
512 | if (mc_size < sizeof(mc_header)) { |
513 | pr_err("error! Bad data in microcode data file (totalsize too small)\n" ); |
514 | goto fail; |
515 | } |
516 | data_size = mc_size - sizeof(mc_header); |
517 | if (data_size > iov_iter_count(i: iter)) { |
518 | pr_err("error! Bad data in microcode data file (truncated file?)\n" ); |
519 | goto fail; |
520 | } |
521 | |
522 | /* For performance reasons, reuse mc area when possible */ |
523 | if (!mc || mc_size > curr_mc_size) { |
524 | kvfree(addr: mc); |
525 | mc = kvmalloc(size: mc_size, GFP_KERNEL); |
526 | if (!mc) |
527 | goto fail; |
528 | curr_mc_size = mc_size; |
529 | } |
530 | |
531 | memcpy(mc, &mc_header, sizeof(mc_header)); |
532 | data = mc + sizeof(mc_header); |
533 | if (!copy_from_iter_full(addr: data, bytes: data_size, i: iter) || |
534 | intel_microcode_sanity_check(mc, true, MC_HEADER_TYPE_MICROCODE) < 0) |
535 | goto fail; |
536 | |
537 | if (cur_rev >= mc_header.rev) |
538 | continue; |
539 | |
540 | if (!intel_find_matching_signature(mc, &uci->cpu_sig)) |
541 | continue; |
542 | |
543 | is_safe = ucode_validate_minrev(mc_header: &mc_header); |
544 | if (force_minrev && !is_safe) |
545 | continue; |
546 | |
547 | kvfree(addr: new_mc); |
548 | cur_rev = mc_header.rev; |
549 | new_mc = mc; |
550 | new_is_safe = is_safe; |
551 | mc = NULL; |
552 | } |
553 | |
554 | if (iov_iter_count(i: iter)) |
555 | goto fail; |
556 | |
557 | kvfree(addr: mc); |
558 | if (!new_mc) |
559 | return UCODE_NFOUND; |
560 | |
561 | ucode_patch_late = (struct microcode_intel *)new_mc; |
562 | return new_is_safe ? UCODE_NEW_SAFE : UCODE_NEW; |
563 | |
564 | fail: |
565 | kvfree(addr: mc); |
566 | kvfree(addr: new_mc); |
567 | return UCODE_ERROR; |
568 | } |
569 | |
570 | static bool is_blacklisted(unsigned int cpu) |
571 | { |
572 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
573 | |
574 | /* |
575 | * Late loading on model 79 with microcode revision less than 0x0b000021 |
576 | * and LLC size per core bigger than 2.5MB may result in a system hang. |
577 | * This behavior is documented in item BDF90, #334165 (Intel Xeon |
578 | * Processor E7-8800/4800 v4 Product Family). |
579 | */ |
580 | if (c->x86 == 6 && |
581 | c->x86_model == INTEL_FAM6_BROADWELL_X && |
582 | c->x86_stepping == 0x01 && |
583 | llc_size_per_core > 2621440 && |
584 | c->microcode < 0x0b000021) { |
585 | pr_err_once("Erratum BDF90: late loading with revision < 0x0b000021 (0x%x) disabled.\n" , c->microcode); |
586 | pr_err_once("Please consider either early loading through initrd/built-in or a potential BIOS update.\n" ); |
587 | return true; |
588 | } |
589 | |
590 | return false; |
591 | } |
592 | |
593 | static enum ucode_state request_microcode_fw(int cpu, struct device *device) |
594 | { |
595 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
596 | const struct firmware *firmware; |
597 | struct iov_iter iter; |
598 | enum ucode_state ret; |
599 | struct kvec kvec; |
600 | char name[30]; |
601 | |
602 | if (is_blacklisted(cpu)) |
603 | return UCODE_NFOUND; |
604 | |
605 | sprintf(buf: name, fmt: "intel-ucode/%02x-%02x-%02x" , |
606 | c->x86, c->x86_model, c->x86_stepping); |
607 | |
608 | if (request_firmware_direct(fw: &firmware, name, device)) { |
609 | pr_debug("data file %s load failed\n" , name); |
610 | return UCODE_NFOUND; |
611 | } |
612 | |
613 | kvec.iov_base = (void *)firmware->data; |
614 | kvec.iov_len = firmware->size; |
615 | iov_iter_kvec(i: &iter, ITER_SOURCE, kvec: &kvec, nr_segs: 1, count: firmware->size); |
616 | ret = parse_microcode_blobs(cpu, iter: &iter); |
617 | |
618 | release_firmware(fw: firmware); |
619 | |
620 | return ret; |
621 | } |
622 | |
623 | static void finalize_late_load(int result) |
624 | { |
625 | if (!result) |
626 | update_ucode_pointer(mc: ucode_patch_late); |
627 | else |
628 | kvfree(addr: ucode_patch_late); |
629 | ucode_patch_late = NULL; |
630 | } |
631 | |
632 | static struct microcode_ops microcode_intel_ops = { |
633 | .request_microcode_fw = request_microcode_fw, |
634 | .collect_cpu_info = collect_cpu_info, |
635 | .apply_microcode = apply_microcode_late, |
636 | .finalize_late_load = finalize_late_load, |
637 | .use_nmi = IS_ENABLED(CONFIG_X86_64), |
638 | }; |
639 | |
640 | static __init void calc_llc_size_per_core(struct cpuinfo_x86 *c) |
641 | { |
642 | u64 llc_size = c->x86_cache_size * 1024ULL; |
643 | |
644 | do_div(llc_size, topology_num_cores_per_package()); |
645 | llc_size_per_core = (unsigned int)llc_size; |
646 | } |
647 | |
648 | struct microcode_ops * __init init_intel_microcode(void) |
649 | { |
650 | struct cpuinfo_x86 *c = &boot_cpu_data; |
651 | |
652 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || |
653 | cpu_has(c, X86_FEATURE_IA64)) { |
654 | pr_err("Intel CPU family 0x%x not supported\n" , c->x86); |
655 | return NULL; |
656 | } |
657 | |
658 | calc_llc_size_per_core(c); |
659 | |
660 | return µcode_intel_ops; |
661 | } |
662 | |