1 /*
2 * AMD CPU Microcode Update Driver for Linux
3 * Copyright (C) 2008 Advanced Micro Devices Inc.
4 *
5 * Author: Peter Oruba <peter.oruba@amd.com>
6 *
7 * Based on work by:
8 * Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
9 *
10 * This driver allows to upgrade microcode on AMD
11 * family 0x10 and later.
12 *
13 * Licensed unter the terms of the GNU General Public
14 * License version 2. See file COPYING for details.
15 */
16
17 #include <xen/lib.h>
18 #include <xen/kernel.h>
19 #include <xen/init.h>
20 #include <xen/sched.h>
21 #include <xen/smp.h>
22 #include <xen/spinlock.h>
23
24 #include <asm/msr.h>
25 #include <asm/processor.h>
26 #include <asm/microcode.h>
27 #include <asm/hvm/svm/svm.h>
28
29 #define pr_debug(x...) ((void)0)
30
31 #define CONT_HDR_SIZE 12
32 #define SECTION_HDR_SIZE 8
33 #define PATCH_HDR_SIZE 32
34
35 struct __packed equiv_cpu_entry {
36 uint32_t installed_cpu;
37 uint32_t fixed_errata_mask;
38 uint32_t fixed_errata_compare;
39 uint16_t equiv_cpu;
40 uint16_t reserved;
41 };
42
43 struct __packed microcode_header_amd {
44 uint32_t data_code;
45 uint32_t patch_id;
46 uint8_t mc_patch_data_id[2];
47 uint8_t mc_patch_data_len;
48 uint8_t init_flag;
49 uint32_t mc_patch_data_checksum;
50 uint32_t nb_dev_id;
51 uint32_t sb_dev_id;
52 uint16_t processor_rev_id;
53 uint8_t nb_rev_id;
54 uint8_t sb_rev_id;
55 uint8_t bios_api_rev;
56 uint8_t reserved1[3];
57 uint32_t match_reg[8];
58 };
59
60 #define UCODE_MAGIC 0x00414d44
61 #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
62 #define UCODE_UCODE_TYPE 0x00000001
63
64 struct microcode_amd {
65 void *mpb;
66 size_t mpb_size;
67 struct equiv_cpu_entry *equiv_cpu_table;
68 size_t equiv_cpu_table_size;
69 };
70
71 struct mpbhdr {
72 uint32_t type;
73 uint32_t len;
74 uint8_t data[];
75 };
76
77 /* serialize access to the physical write */
78 static DEFINE_SPINLOCK(microcode_update_lock);
79
80 /* See comment in start_update() for cases when this routine fails */
collect_cpu_info(unsigned int cpu,struct cpu_signature * csig)81 static int collect_cpu_info(unsigned int cpu, struct cpu_signature *csig)
82 {
83 struct cpuinfo_x86 *c = &cpu_data[cpu];
84
85 memset(csig, 0, sizeof(*csig));
86
87 if ( (c->x86_vendor != X86_VENDOR_AMD) || (c->x86 < 0x10) )
88 {
89 printk(KERN_ERR "microcode: CPU%d not a capable AMD processor\n",
90 cpu);
91 return -EINVAL;
92 }
93
94 rdmsrl(MSR_AMD_PATCHLEVEL, csig->rev);
95
96 pr_debug("microcode: CPU%d collect_cpu_info: patch_id=%#x\n",
97 cpu, csig->rev);
98
99 return 0;
100 }
101
verify_patch_size(uint32_t patch_size)102 static bool_t verify_patch_size(uint32_t patch_size)
103 {
104 uint32_t max_size;
105
106 #define F1XH_MPB_MAX_SIZE 2048
107 #define F14H_MPB_MAX_SIZE 1824
108 #define F15H_MPB_MAX_SIZE 4096
109 #define F16H_MPB_MAX_SIZE 3458
110 #define F17H_MPB_MAX_SIZE 3200
111
112 switch (boot_cpu_data.x86)
113 {
114 case 0x14:
115 max_size = F14H_MPB_MAX_SIZE;
116 break;
117 case 0x15:
118 max_size = F15H_MPB_MAX_SIZE;
119 break;
120 case 0x16:
121 max_size = F16H_MPB_MAX_SIZE;
122 break;
123 case 0x17:
124 max_size = F17H_MPB_MAX_SIZE;
125 break;
126 default:
127 max_size = F1XH_MPB_MAX_SIZE;
128 break;
129 }
130
131 return (patch_size <= max_size);
132 }
133
find_equiv_cpu_id(const struct equiv_cpu_entry * equiv_cpu_table,unsigned int current_cpu_id,unsigned int * equiv_cpu_id)134 static bool_t find_equiv_cpu_id(const struct equiv_cpu_entry *equiv_cpu_table,
135 unsigned int current_cpu_id,
136 unsigned int *equiv_cpu_id)
137 {
138 unsigned int i;
139
140 if ( !equiv_cpu_table )
141 return 0;
142
143 for ( i = 0; equiv_cpu_table[i].installed_cpu != 0; i++ )
144 {
145 if ( current_cpu_id == equiv_cpu_table[i].installed_cpu )
146 {
147 *equiv_cpu_id = equiv_cpu_table[i].equiv_cpu & 0xffff;
148 return 1;
149 }
150 }
151
152 return 0;
153 }
154
microcode_fits(const struct microcode_amd * mc_amd,unsigned int cpu)155 static bool_t microcode_fits(const struct microcode_amd *mc_amd,
156 unsigned int cpu)
157 {
158 struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
159 const struct microcode_header_amd *mc_header = mc_amd->mpb;
160 const struct equiv_cpu_entry *equiv_cpu_table = mc_amd->equiv_cpu_table;
161 unsigned int current_cpu_id;
162 unsigned int equiv_cpu_id;
163
164 /* We should bind the task to the CPU */
165 BUG_ON(cpu != raw_smp_processor_id());
166
167 current_cpu_id = cpuid_eax(0x00000001);
168
169 if ( !find_equiv_cpu_id(equiv_cpu_table, current_cpu_id, &equiv_cpu_id) )
170 return 0;
171
172 if ( (mc_header->processor_rev_id) != equiv_cpu_id )
173 return 0;
174
175 if ( !verify_patch_size(mc_amd->mpb_size) )
176 {
177 pr_debug("microcode: patch size mismatch\n");
178 return 0;
179 }
180
181 if ( mc_header->patch_id <= uci->cpu_sig.rev )
182 {
183 pr_debug("microcode: patch is already at required level or greater.\n");
184 return 0;
185 }
186
187 pr_debug("microcode: CPU%d found a matching microcode update with version %#x (current=%#x)\n",
188 cpu, mc_header->patch_id, uci->cpu_sig.rev);
189
190 return 1;
191 }
192
apply_microcode(unsigned int cpu)193 static int apply_microcode(unsigned int cpu)
194 {
195 unsigned long flags;
196 struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
197 uint32_t rev;
198 struct microcode_amd *mc_amd = uci->mc.mc_amd;
199 struct microcode_header_amd *hdr;
200 int hw_err;
201
202 /* We should bind the task to the CPU */
203 BUG_ON(raw_smp_processor_id() != cpu);
204
205 if ( mc_amd == NULL )
206 return -EINVAL;
207
208 hdr = mc_amd->mpb;
209 if ( hdr == NULL )
210 return -EINVAL;
211
212 spin_lock_irqsave(µcode_update_lock, flags);
213
214 hw_err = wrmsr_safe(MSR_AMD_PATCHLOADER, (unsigned long)hdr);
215
216 /* get patch id after patching */
217 rdmsrl(MSR_AMD_PATCHLEVEL, rev);
218
219 spin_unlock_irqrestore(µcode_update_lock, flags);
220
221 /* check current patch id and patch's id for match */
222 if ( hw_err || (rev != hdr->patch_id) )
223 {
224 printk(KERN_ERR "microcode: CPU%d update from revision "
225 "%#x to %#x failed\n", cpu, rev, hdr->patch_id);
226 return -EIO;
227 }
228
229 printk(KERN_WARNING "microcode: CPU%d updated from revision %#x to %#x\n",
230 cpu, uci->cpu_sig.rev, hdr->patch_id);
231
232 uci->cpu_sig.rev = rev;
233
234 return 0;
235 }
236
get_ucode_from_buffer_amd(struct microcode_amd * mc_amd,const void * buf,size_t bufsize,size_t * offset)237 static int get_ucode_from_buffer_amd(
238 struct microcode_amd *mc_amd,
239 const void *buf,
240 size_t bufsize,
241 size_t *offset)
242 {
243 const struct mpbhdr *mpbuf = buf + *offset;
244
245 /* No more data */
246 if ( *offset >= bufsize )
247 {
248 printk(KERN_ERR "microcode: Microcode buffer overrun\n");
249 return -EINVAL;
250 }
251
252 if ( mpbuf->type != UCODE_UCODE_TYPE )
253 {
254 printk(KERN_ERR "microcode: Wrong microcode payload type field\n");
255 return -EINVAL;
256 }
257
258 if ( (*offset + mpbuf->len) > bufsize )
259 {
260 printk(KERN_ERR "microcode: Bad data in microcode data file\n");
261 return -EINVAL;
262 }
263
264 if ( mc_amd->mpb_size < mpbuf->len )
265 {
266 if ( mc_amd->mpb )
267 {
268 xfree(mc_amd->mpb);
269 mc_amd->mpb_size = 0;
270 }
271 mc_amd->mpb = xmalloc_bytes(mpbuf->len);
272 if ( mc_amd->mpb == NULL )
273 return -ENOMEM;
274 mc_amd->mpb_size = mpbuf->len;
275 }
276 memcpy(mc_amd->mpb, mpbuf->data, mpbuf->len);
277
278 pr_debug("microcode: CPU%d size %zu, block size %u offset %zu equivID %#x rev %#x\n",
279 raw_smp_processor_id(), bufsize, mpbuf->len, *offset,
280 ((struct microcode_header_amd *)mc_amd->mpb)->processor_rev_id,
281 ((struct microcode_header_amd *)mc_amd->mpb)->patch_id);
282
283 *offset += mpbuf->len + SECTION_HDR_SIZE;
284
285 return 0;
286 }
287
install_equiv_cpu_table(struct microcode_amd * mc_amd,const void * data,size_t * offset)288 static int install_equiv_cpu_table(
289 struct microcode_amd *mc_amd,
290 const void *data,
291 size_t *offset)
292 {
293 const struct mpbhdr *mpbuf = data + *offset + 4;
294
295 *offset += mpbuf->len + CONT_HDR_SIZE; /* add header length */
296
297 if ( mpbuf->type != UCODE_EQUIV_CPU_TABLE_TYPE )
298 {
299 printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table type field\n");
300 return -EINVAL;
301 }
302
303 if ( mpbuf->len == 0 )
304 {
305 printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table length\n");
306 return -EINVAL;
307 }
308
309 mc_amd->equiv_cpu_table = xmalloc_bytes(mpbuf->len);
310 if ( !mc_amd->equiv_cpu_table )
311 {
312 printk(KERN_ERR "microcode: Cannot allocate memory for equivalent cpu table\n");
313 return -ENOMEM;
314 }
315
316 memcpy(mc_amd->equiv_cpu_table, mpbuf->data, mpbuf->len);
317 mc_amd->equiv_cpu_table_size = mpbuf->len;
318
319 return 0;
320 }
321
container_fast_forward(const void * data,size_t size_left,size_t * offset)322 static int container_fast_forward(const void *data, size_t size_left, size_t *offset)
323 {
324 for ( ; ; )
325 {
326 size_t size;
327 const uint32_t *header;
328
329 if ( size_left < SECTION_HDR_SIZE )
330 return -EINVAL;
331
332 header = data + *offset;
333
334 if ( header[0] == UCODE_MAGIC &&
335 header[1] == UCODE_EQUIV_CPU_TABLE_TYPE )
336 break;
337
338 if ( header[0] != UCODE_UCODE_TYPE )
339 return -EINVAL;
340 size = header[1] + SECTION_HDR_SIZE;
341 if ( size < PATCH_HDR_SIZE || size_left < size )
342 return -EINVAL;
343
344 size_left -= size;
345 *offset += size;
346
347 if ( !size_left )
348 return -ENODATA;
349 }
350
351 return 0;
352 }
353
354 /*
355 * The 'final_levels' of patch ids have been obtained empirically.
356 * Refer bug https://bugzilla.suse.com/show_bug.cgi?id=913996
357 * for details of the issue. The short version is that people
358 * using certain Fam10h systems noticed system hang issues when
359 * trying to update microcode levels beyond the patch IDs below.
360 * From internal discussions, we gathered that OS/hypervisor
361 * cannot reliably perform microcode updates beyond these levels
362 * due to hardware issues. Therefore, we need to abort microcode
363 * update process if we hit any of these levels.
364 */
365 static const unsigned int final_levels[] = {
366 0x01000098,
367 0x0100009f,
368 0x010000af
369 };
370
check_final_patch_levels(unsigned int cpu)371 static bool_t check_final_patch_levels(unsigned int cpu)
372 {
373 /*
374 * Check the current patch levels on the cpu. If they are equal to
375 * any of the 'final_levels', then we should not update the microcode
376 * patch on the cpu as system will hang otherwise.
377 */
378 struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
379 unsigned int i;
380
381 if ( boot_cpu_data.x86 != 0x10 )
382 return 0;
383
384 for ( i = 0; i < ARRAY_SIZE(final_levels); i++ )
385 if ( uci->cpu_sig.rev == final_levels[i] )
386 return 1;
387
388 return 0;
389 }
390
cpu_request_microcode(unsigned int cpu,const void * buf,size_t bufsize)391 static int cpu_request_microcode(unsigned int cpu, const void *buf,
392 size_t bufsize)
393 {
394 struct microcode_amd *mc_amd, *mc_old;
395 size_t offset = 0;
396 size_t last_offset, applied_offset = 0;
397 int error = 0, save_error = 1;
398 struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
399 unsigned int current_cpu_id;
400 unsigned int equiv_cpu_id;
401
402 /* We should bind the task to the CPU */
403 BUG_ON(cpu != raw_smp_processor_id());
404
405 current_cpu_id = cpuid_eax(0x00000001);
406
407 if ( *(const uint32_t *)buf != UCODE_MAGIC )
408 {
409 printk(KERN_ERR "microcode: Wrong microcode patch file magic\n");
410 error = -EINVAL;
411 goto out;
412 }
413
414 if ( check_final_patch_levels(cpu) )
415 {
416 printk(XENLOG_INFO
417 "microcode: Cannot update microcode patch on the cpu as we hit a final level\n");
418 error = -EPERM;
419 goto out;
420 }
421
422 mc_amd = xmalloc(struct microcode_amd);
423 if ( !mc_amd )
424 {
425 printk(KERN_ERR "microcode: Cannot allocate memory for microcode patch\n");
426 error = -ENOMEM;
427 goto out;
428 }
429
430 /*
431 * Multiple container file support:
432 * 1. check if this container file has equiv_cpu_id match
433 * 2. If not, fast-fwd to next container file
434 */
435 while ( offset < bufsize )
436 {
437 error = install_equiv_cpu_table(mc_amd, buf, &offset);
438 if ( error )
439 {
440 printk(KERN_ERR "microcode: installing equivalent cpu table failed\n");
441 break;
442 }
443
444 /*
445 * Could happen as we advance 'offset' early
446 * in install_equiv_cpu_table
447 */
448 if ( offset > bufsize )
449 {
450 printk(KERN_ERR "microcode: Microcode buffer overrun\n");
451 error = -EINVAL;
452 break;
453 }
454
455 if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, current_cpu_id,
456 &equiv_cpu_id) )
457 break;
458
459 error = container_fast_forward(buf, bufsize - offset, &offset);
460 if ( error == -ENODATA )
461 {
462 ASSERT(offset == bufsize);
463 break;
464 }
465 if ( error )
466 {
467 printk(KERN_ERR "microcode: CPU%d incorrect or corrupt container file\n"
468 "microcode: Failed to update patch level. "
469 "Current lvl:%#x\n", cpu, uci->cpu_sig.rev);
470 break;
471 }
472 }
473
474 if ( error )
475 {
476 xfree(mc_amd);
477 goto out;
478 }
479
480 mc_old = uci->mc.mc_amd;
481 /* implicitely validates uci->mc.mc_valid */
482 uci->mc.mc_amd = mc_amd;
483
484 /*
485 * It's possible the data file has multiple matching ucode,
486 * lets keep searching till the latest version
487 */
488 mc_amd->mpb = NULL;
489 mc_amd->mpb_size = 0;
490 last_offset = offset;
491 while ( (error = get_ucode_from_buffer_amd(mc_amd, buf, bufsize,
492 &offset)) == 0 )
493 {
494 if ( microcode_fits(mc_amd, cpu) )
495 {
496 error = apply_microcode(cpu);
497 if ( error )
498 break;
499 applied_offset = last_offset;
500 }
501
502 last_offset = offset;
503
504 if ( offset >= bufsize )
505 break;
506
507 /*
508 * 1. Given a situation where multiple containers exist and correct
509 * patch lives on a container that is not the last container.
510 * 2. We match equivalent ids using find_equiv_cpu_id() from the
511 * earlier while() (On this case, matches on earlier container
512 * file and we break)
513 * 3. Proceed to while ( (error = get_ucode_from_buffer_amd(mc_amd,
514 * buf, bufsize,&offset)) == 0 )
515 * 4. Find correct patch using microcode_fits() and apply the patch
516 * (Assume: apply_microcode() is successful)
517 * 5. The while() loop from (3) continues to parse the binary as
518 * there is a subsequent container file, but...
519 * 6. ...a correct patch can only be on one container and not on any
520 * subsequent ones. (Refer docs for more info) Therefore, we
521 * don't have to parse a subsequent container. So, we can abort
522 * the process here.
523 * 7. This ensures that we retain a success value (= 0) to 'error'
524 * before if ( mpbuf->type != UCODE_UCODE_TYPE ) evaluates to
525 * false and returns -EINVAL.
526 */
527 if ( offset + SECTION_HDR_SIZE <= bufsize &&
528 *(const uint32_t *)(buf + offset) == UCODE_MAGIC )
529 break;
530 }
531
532 /* On success keep the microcode patch for
533 * re-apply on resume.
534 */
535 if ( applied_offset )
536 {
537 save_error = get_ucode_from_buffer_amd(
538 mc_amd, buf, bufsize, &applied_offset);
539
540 if ( save_error )
541 error = save_error;
542 }
543
544 if ( save_error )
545 {
546 xfree(mc_amd);
547 uci->mc.mc_amd = mc_old;
548 }
549 else
550 xfree(mc_old);
551
552 out:
553 svm_host_osvw_init();
554
555 /*
556 * In some cases we may return an error even if processor's microcode has
557 * been updated. For example, the first patch in a container file is loaded
558 * successfully but subsequent container file processing encounters a
559 * failure.
560 */
561 return error;
562 }
563
microcode_resume_match(unsigned int cpu,const void * mc)564 static int microcode_resume_match(unsigned int cpu, const void *mc)
565 {
566 struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
567 struct microcode_amd *mc_amd = uci->mc.mc_amd;
568 const struct microcode_amd *src = mc;
569
570 if ( !microcode_fits(src, cpu) )
571 return 0;
572
573 if ( src != mc_amd )
574 {
575 if ( mc_amd )
576 {
577 xfree(mc_amd->equiv_cpu_table);
578 xfree(mc_amd->mpb);
579 xfree(mc_amd);
580 }
581
582 mc_amd = xmalloc(struct microcode_amd);
583 uci->mc.mc_amd = mc_amd;
584 if ( !mc_amd )
585 return -ENOMEM;
586 mc_amd->equiv_cpu_table = xmalloc_bytes(src->equiv_cpu_table_size);
587 if ( !mc_amd->equiv_cpu_table )
588 goto err1;
589 mc_amd->mpb = xmalloc_bytes(src->mpb_size);
590 if ( !mc_amd->mpb )
591 goto err2;
592
593 mc_amd->equiv_cpu_table_size = src->equiv_cpu_table_size;
594 mc_amd->mpb_size = src->mpb_size;
595 memcpy(mc_amd->mpb, src->mpb, src->mpb_size);
596 memcpy(mc_amd->equiv_cpu_table, src->equiv_cpu_table,
597 src->equiv_cpu_table_size);
598 }
599
600 return 1;
601
602 err2:
603 xfree(mc_amd->equiv_cpu_table);
604 err1:
605 xfree(mc_amd);
606 uci->mc.mc_amd = NULL;
607 return -ENOMEM;
608 }
609
start_update(void)610 static int start_update(void)
611 {
612 /*
613 * We assume here that svm_host_osvw_init() will be called on each cpu (from
614 * cpu_request_microcode()).
615 *
616 * Note that if collect_cpu_info() returns an error then
617 * cpu_request_microcode() will not invoked thus leaving OSVW bits not
618 * updated. Currently though collect_cpu_info() will not fail on processors
619 * supporting OSVW so we will not deal with this possibility.
620 */
621 svm_host_osvw_reset();
622
623 return 0;
624 }
625
626 static const struct microcode_ops microcode_amd_ops = {
627 .microcode_resume_match = microcode_resume_match,
628 .cpu_request_microcode = cpu_request_microcode,
629 .collect_cpu_info = collect_cpu_info,
630 .apply_microcode = apply_microcode,
631 .start_update = start_update,
632 };
633
microcode_init_amd(void)634 int __init microcode_init_amd(void)
635 {
636 if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
637 microcode_ops = µcode_amd_ops;
638 return 0;
639 }
640