aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/microcode
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2016-06-06 11:10:42 -0400
committerIngo Molnar <mingo@kernel.org>2016-06-08 05:04:19 -0400
commit6c5456474e7f0b63be66d44b0595001e2a8b44d5 (patch)
tree8846afb508f17b7da1cda7704cd9d89c6eb709bf /arch/x86/kernel/cpu/microcode
parentc8ae067f2635be0f8c7e5db1bb74b757d623e05b (diff)
x86/microcode: Fix loading precedence
So it can happen that even with builtin microcode, CONFIG_BLK_DEV_INITRD=y gets forgotten enabled. Or, even with that disabled, an initrd image gets supplied by the boot loader, by omission or is simply forgotten there. And since we do look at boot_params.hdr.ramdisk_* to know whether we have received an initrd, we might get puzzled. So let's just make the loader look for builtin microcode first and if found, ignore the ramdisk image. If no builtin found, it falls back to scanning the supplied initrd, of course. For that, we move all the initrd scanning in a separate __scan_microcode_initrd() function and fall back to it only if load_builtin_intel_microcode() has failed. Reported-and-tested-by: Gabriel Craciunescu <nix.or.die@gmail.com> Signed-off-by: Borislav Petkov <bp@suse.de> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1465225850-7352-2-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel/cpu/microcode')
-rw-r--r--arch/x86/kernel/cpu/microcode/amd.c28
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c183
2 files changed, 133 insertions, 78 deletions
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 8581963894c7..11dd1cc8e444 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -61,19 +61,20 @@ static u16 this_equiv_id;
61 61
62static struct cpio_data ucode_cpio; 62static struct cpio_data ucode_cpio;
63 63
64/*
65 * Microcode patch container file is prepended to the initrd in cpio format.
66 * See Documentation/x86/early-microcode.txt
67 */
68static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
69
70static struct cpio_data __init find_ucode_in_initrd(void) 64static struct cpio_data __init find_ucode_in_initrd(void)
71{ 65{
66#ifdef CONFIG_BLK_DEV_INITRD
72 long offset = 0; 67 long offset = 0;
73 char *path; 68 char *path;
74 void *start; 69 void *start;
75 size_t size; 70 size_t size;
76 71
72 /*
73 * Microcode patch container file is prepended to the initrd in cpio
74 * format. See Documentation/x86/early-microcode.txt
75 */
76 static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
77
77#ifdef CONFIG_X86_32 78#ifdef CONFIG_X86_32
78 struct boot_params *p; 79 struct boot_params *p;
79 80
@@ -89,9 +90,12 @@ static struct cpio_data __init find_ucode_in_initrd(void)
89 path = ucode_path; 90 path = ucode_path;
90 start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET); 91 start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET);
91 size = boot_params.hdr.ramdisk_size; 92 size = boot_params.hdr.ramdisk_size;
92#endif 93#endif /* !CONFIG_X86_32 */
93 94
94 return find_cpio_data(path, start, size, &offset); 95 return find_cpio_data(path, start, size, &offset);
96#else
97 return (struct cpio_data){ NULL, 0, "" };
98#endif
95} 99}
96 100
97static size_t compute_container_size(u8 *data, u32 total_size) 101static size_t compute_container_size(u8 *data, u32 total_size)
@@ -289,11 +293,11 @@ void __init load_ucode_amd_bsp(unsigned int family)
289 size = &ucode_cpio.size; 293 size = &ucode_cpio.size;
290#endif 294#endif
291 295
292 cp = find_ucode_in_initrd(); 296 if (!load_builtin_amd_microcode(&cp, family))
293 if (!cp.data) { 297 cp = find_ucode_in_initrd();
294 if (!load_builtin_amd_microcode(&cp, family)) 298
295 return; 299 if (!(cp.data && cp.size))
296 } 300 return;
297 301
298 *data = cp.data; 302 *data = cp.data;
299 *size = cp.size; 303 *size = cp.size;
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 65cbbcd48fe4..5835d5b0db81 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -51,6 +51,12 @@ static struct mc_saved_data {
51 struct microcode_intel **mc_saved; 51 struct microcode_intel **mc_saved;
52} mc_saved_data; 52} mc_saved_data;
53 53
54/* Microcode blobs within the initrd. 0 if builtin. */
55static struct ucode_blobs {
56 unsigned long start;
57 bool valid;
58} blobs;
59
54static enum ucode_state 60static enum ucode_state
55load_microcode_early(struct microcode_intel **saved, 61load_microcode_early(struct microcode_intel **saved,
56 unsigned int num_saved, struct ucode_cpu_info *uci) 62 unsigned int num_saved, struct ucode_cpu_info *uci)
@@ -532,37 +538,6 @@ static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
532#endif 538#endif
533} 539}
534 540
535static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
536static __init enum ucode_state
537scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
538 unsigned long start, unsigned long size,
539 struct ucode_cpu_info *uci)
540{
541 struct cpio_data cd;
542 long offset = 0;
543#ifdef CONFIG_X86_32
544 char *p = (char *)__pa_nodebug(ucode_name);
545#else
546 char *p = ucode_name;
547#endif
548
549 cd.data = NULL;
550 cd.size = 0;
551
552 /* try built-in microcode if no initrd */
553 if (!size) {
554 if (!load_builtin_intel_microcode(&cd))
555 return UCODE_ERROR;
556 } else {
557 cd = find_cpio_data(p, (void *)start, size, &offset);
558 if (!cd.data)
559 return UCODE_ERROR;
560 }
561
562 return get_matching_model_microcode(start, cd.data, cd.size,
563 mcs, mc_ptrs, uci);
564}
565
566/* 541/*
567 * Print ucode update info. 542 * Print ucode update info.
568 */ 543 */
@@ -680,14 +655,22 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
680 */ 655 */
681int __init save_microcode_in_initrd_intel(void) 656int __init save_microcode_in_initrd_intel(void)
682{ 657{
683 unsigned int count = mc_saved_data.num_saved;
684 struct microcode_intel *mc_saved[MAX_UCODE_COUNT]; 658 struct microcode_intel *mc_saved[MAX_UCODE_COUNT];
685 int ret = 0; 659 unsigned int count = mc_saved_data.num_saved;
660 unsigned long offset = 0;
661 int ret;
686 662
687 if (!count) 663 if (!count)
688 return ret; 664 return 0;
689 665
690 copy_ptrs(mc_saved, mc_tmp_ptrs, get_initrd_start(), count); 666 /*
667 * We have found a valid initrd but it might've been relocated in the
668 * meantime so get its updated address.
669 */
670 if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && blobs.valid)
671 offset = initrd_start;
672
673 copy_ptrs(mc_saved, mc_tmp_ptrs, offset, count);
691 674
692 ret = save_microcode(&mc_saved_data, mc_saved, count); 675 ret = save_microcode(&mc_saved_data, mc_saved, count);
693 if (ret) 676 if (ret)
@@ -698,20 +681,92 @@ int __init save_microcode_in_initrd_intel(void)
698 return ret; 681 return ret;
699} 682}
700 683
684static __init enum ucode_state
685__scan_microcode_initrd(struct cpio_data *cd, struct ucode_blobs *blbp)
686{
687#ifdef CONFIG_BLK_DEV_INITRD
688 long offset = 0;
689 static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
690 char *p = IS_ENABLED(CONFIG_X86_32) ? (char *)__pa_nodebug(ucode_name)
691 : ucode_name;
692# ifdef CONFIG_X86_32
693 unsigned long start = 0, size;
694 struct boot_params *params;
695
696 params = (struct boot_params *)__pa_nodebug(&boot_params);
697 size = params->hdr.ramdisk_size;
698
699 /*
700 * Set start only if we have an initrd image. We cannot use initrd_start
701 * because it is not set that early yet.
702 */
703 start = (size ? params->hdr.ramdisk_image : 0);
704
705# else /* CONFIG_X86_64 */
706 unsigned long start = 0, size;
707
708 size = (u64)boot_params.ext_ramdisk_size << 32;
709 size |= boot_params.hdr.ramdisk_size;
710
711 if (size) {
712 start = (u64)boot_params.ext_ramdisk_image << 32;
713 start |= boot_params.hdr.ramdisk_image;
714
715 start += PAGE_OFFSET;
716 }
717# endif
718
719 *cd = find_cpio_data(p, (void *)start, size, &offset);
720 if (cd->data) {
721 blbp->start = start;
722 blbp->valid = true;
723
724 return UCODE_OK;
725 } else
726#endif /* CONFIG_BLK_DEV_INITRD */
727 return UCODE_ERROR;
728}
729
730static __init enum ucode_state
731scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
732 struct ucode_cpu_info *uci, struct ucode_blobs *blbp)
733{
734 struct cpio_data cd = { NULL, 0, "" };
735 enum ucode_state ret;
736
737 /* try built-in microcode first */
738 if (load_builtin_intel_microcode(&cd))
739 /*
740 * Invalidate blobs as we might've gotten an initrd too,
741 * supplied by the boot loader, by mistake or simply forgotten
742 * there. That's fine, we ignore it since we've found builtin
743 * microcode already.
744 */
745 blbp->valid = false;
746 else {
747 ret = __scan_microcode_initrd(&cd, blbp);
748 if (ret != UCODE_OK)
749 return ret;
750 }
751
752 return get_matching_model_microcode(blbp->start, cd.data, cd.size,
753 mcs, mc_ptrs, uci);
754}
755
701static void __init 756static void __init
702_load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs, 757_load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
703 unsigned long start, unsigned long size) 758 struct ucode_blobs *blbp)
704{ 759{
705 struct ucode_cpu_info uci; 760 struct ucode_cpu_info uci;
706 enum ucode_state ret; 761 enum ucode_state ret;
707 762
708 collect_cpu_info_early(&uci); 763 collect_cpu_info_early(&uci);
709 764
710 ret = scan_microcode(mcs, mc_ptrs, start, size, &uci); 765 ret = scan_microcode(mcs, mc_ptrs, &uci, blbp);
711 if (ret != UCODE_OK) 766 if (ret != UCODE_OK)
712 return; 767 return;
713 768
714 ret = load_microcode(mcs, mc_ptrs, start, &uci); 769 ret = load_microcode(mcs, mc_ptrs, blbp->start, &uci);
715 if (ret != UCODE_OK) 770 if (ret != UCODE_OK)
716 return; 771 return;
717 772
@@ -720,54 +775,50 @@ _load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
720 775
721void __init load_ucode_intel_bsp(void) 776void __init load_ucode_intel_bsp(void)
722{ 777{
723 u64 start, size; 778 struct ucode_blobs *blobs_p;
724#ifdef CONFIG_X86_32 779 struct mc_saved_data *mcs;
725 struct boot_params *p; 780 unsigned long *ptrs;
726
727 p = (struct boot_params *)__pa_nodebug(&boot_params);
728 size = p->hdr.ramdisk_size;
729
730 /*
731 * Set start only if we have an initrd image. We cannot use initrd_start
732 * because it is not set that early yet.
733 */
734 start = (size ? p->hdr.ramdisk_image : 0);
735 781
736 _load_ucode_intel_bsp((struct mc_saved_data *)__pa_nodebug(&mc_saved_data), 782#ifdef CONFIG_X86_32
737 (unsigned long *)__pa_nodebug(&mc_tmp_ptrs), 783 mcs = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
738 start, size); 784 ptrs = (unsigned long *)__pa_nodebug(&mc_tmp_ptrs);
785 blobs_p = (struct ucode_blobs *)__pa_nodebug(&blobs);
739#else 786#else
740 size = boot_params.hdr.ramdisk_size; 787 mcs = &mc_saved_data;
741 start = (size ? boot_params.hdr.ramdisk_image + PAGE_OFFSET : 0); 788 ptrs = mc_tmp_ptrs;
742 789 blobs_p = &blobs;
743 _load_ucode_intel_bsp(&mc_saved_data, mc_tmp_ptrs, start, size);
744#endif 790#endif
791
792 _load_ucode_intel_bsp(mcs, ptrs, blobs_p);
745} 793}
746 794
747void load_ucode_intel_ap(void) 795void load_ucode_intel_ap(void)
748{ 796{
749 unsigned long *mcs_tmp_p; 797 struct ucode_blobs *blobs_p;
750 struct mc_saved_data *mcs_p; 798 struct mc_saved_data *mcs;
751 struct ucode_cpu_info uci; 799 struct ucode_cpu_info uci;
752 enum ucode_state ret; 800 enum ucode_state ret;
753#ifdef CONFIG_X86_32 801 unsigned long *ptrs;
754 802
755 mcs_tmp_p = (unsigned long *)__pa_nodebug(mc_tmp_ptrs); 803#ifdef CONFIG_X86_32
756 mcs_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data); 804 mcs = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
805 ptrs = (unsigned long *)__pa_nodebug(mc_tmp_ptrs);
806 blobs_p = (struct ucode_blobs *)__pa_nodebug(&blobs);
757#else 807#else
758 mcs_tmp_p = mc_tmp_ptrs; 808 mcs = &mc_saved_data;
759 mcs_p = &mc_saved_data; 809 ptrs = mc_tmp_ptrs;
810 blobs_p = &blobs;
760#endif 811#endif
761 812
762 /* 813 /*
763 * If there is no valid ucode previously saved in memory, no need to 814 * If there is no valid ucode previously saved in memory, no need to
764 * update ucode on this AP. 815 * update ucode on this AP.
765 */ 816 */
766 if (!mcs_p->num_saved) 817 if (!mcs->num_saved)
767 return; 818 return;
768 819
769 collect_cpu_info_early(&uci); 820 collect_cpu_info_early(&uci);
770 ret = load_microcode(mcs_p, mcs_tmp_p, get_initrd_start_addr(), &uci); 821 ret = load_microcode(mcs, ptrs, blobs_p->start, &uci);
771 if (ret != UCODE_OK) 822 if (ret != UCODE_OK)
772 return; 823 return;
773 824