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(&microcode_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(&microcode_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 = &microcode_amd_ops;
638     return 0;
639 }
640