aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/microcode/intel_early.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/intel_early.c')
-rw-r--r--arch/x86/kernel/cpu/microcode/intel_early.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c
index b88343f7a3b3..f04d0d6638ca 100644
--- a/arch/x86/kernel/cpu/microcode/intel_early.c
+++ b/arch/x86/kernel/cpu/microcode/intel_early.c
@@ -34,6 +34,8 @@ static struct mc_saved_data {
34 struct microcode_intel **mc_saved; 34 struct microcode_intel **mc_saved;
35} mc_saved_data; 35} mc_saved_data;
36 36
37static struct microcode_intel bsp_patch;
38
37static enum ucode_state 39static enum ucode_state
38generic_load_microcode_early(struct microcode_intel **mc_saved_p, 40generic_load_microcode_early(struct microcode_intel **mc_saved_p,
39 unsigned int mc_saved_count, 41 unsigned int mc_saved_count,
@@ -650,8 +652,7 @@ static inline void print_ucode(struct ucode_cpu_info *uci)
650} 652}
651#endif 653#endif
652 654
653static int apply_microcode_early(struct mc_saved_data *mc_saved_data, 655static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
654 struct ucode_cpu_info *uci)
655{ 656{
656 struct microcode_intel *mc_intel; 657 struct microcode_intel *mc_intel;
657 unsigned int val[2]; 658 unsigned int val[2];
@@ -680,7 +681,10 @@ static int apply_microcode_early(struct mc_saved_data *mc_saved_data,
680#endif 681#endif
681 uci->cpu_sig.rev = val[1]; 682 uci->cpu_sig.rev = val[1];
682 683
683 print_ucode(uci); 684 if (early)
685 print_ucode(uci);
686 else
687 print_ucode_info(uci, mc_intel->hdr.date);
684 688
685 return 0; 689 return 0;
686} 690}
@@ -713,14 +717,22 @@ _load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data,
713 unsigned long *mc_saved_in_initrd, 717 unsigned long *mc_saved_in_initrd,
714 unsigned long initrd_start_early, 718 unsigned long initrd_start_early,
715 unsigned long initrd_end_early, 719 unsigned long initrd_end_early,
716 struct ucode_cpu_info *uci) 720 struct ucode_cpu_info *uci,
721 struct microcode_intel *bsp)
717{ 722{
723 enum ucode_state ret;
724
718 collect_cpu_info_early(uci); 725 collect_cpu_info_early(uci);
719 scan_microcode(initrd_start_early, initrd_end_early, mc_saved_data, 726 scan_microcode(initrd_start_early, initrd_end_early, mc_saved_data,
720 mc_saved_in_initrd, uci); 727 mc_saved_in_initrd, uci);
721 load_microcode(mc_saved_data, mc_saved_in_initrd, 728
722 initrd_start_early, uci); 729 ret = load_microcode(mc_saved_data, mc_saved_in_initrd,
723 apply_microcode_early(mc_saved_data, uci); 730 initrd_start_early, uci);
731
732 if (ret == UCODE_OK) {
733 apply_microcode_early(uci, true);
734 memcpy(bsp, uci->mc, sizeof(*bsp));
735 }
724} 736}
725 737
726void __init 738void __init
@@ -729,10 +741,12 @@ load_ucode_intel_bsp(void)
729 u64 ramdisk_image, ramdisk_size; 741 u64 ramdisk_image, ramdisk_size;
730 unsigned long initrd_start_early, initrd_end_early; 742 unsigned long initrd_start_early, initrd_end_early;
731 struct ucode_cpu_info uci; 743 struct ucode_cpu_info uci;
744 struct microcode_intel *bsp_p;
732#ifdef CONFIG_X86_32 745#ifdef CONFIG_X86_32
733 struct boot_params *boot_params_p; 746 struct boot_params *boot_params_p;
734 747
735 boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params); 748 boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params);
749 bsp_p = (struct microcode_intel *)__pa_nodebug(&bsp_patch);
736 ramdisk_image = boot_params_p->hdr.ramdisk_image; 750 ramdisk_image = boot_params_p->hdr.ramdisk_image;
737 ramdisk_size = boot_params_p->hdr.ramdisk_size; 751 ramdisk_size = boot_params_p->hdr.ramdisk_size;
738 initrd_start_early = ramdisk_image; 752 initrd_start_early = ramdisk_image;
@@ -741,15 +755,17 @@ load_ucode_intel_bsp(void)
741 _load_ucode_intel_bsp( 755 _load_ucode_intel_bsp(
742 (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), 756 (struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
743 (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), 757 (unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
744 initrd_start_early, initrd_end_early, &uci); 758 initrd_start_early, initrd_end_early, &uci, bsp_p);
745#else 759#else
760 bsp_p = &bsp_patch;
746 ramdisk_image = boot_params.hdr.ramdisk_image; 761 ramdisk_image = boot_params.hdr.ramdisk_image;
747 ramdisk_size = boot_params.hdr.ramdisk_size; 762 ramdisk_size = boot_params.hdr.ramdisk_size;
748 initrd_start_early = ramdisk_image + PAGE_OFFSET; 763 initrd_start_early = ramdisk_image + PAGE_OFFSET;
749 initrd_end_early = initrd_start_early + ramdisk_size; 764 initrd_end_early = initrd_start_early + ramdisk_size;
750 765
751 _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, 766 _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd,
752 initrd_start_early, initrd_end_early, &uci); 767 initrd_start_early, initrd_end_early,
768 &uci, bsp_p);
753#endif 769#endif
754} 770}
755 771
@@ -783,5 +799,17 @@ void load_ucode_intel_ap(void)
783 collect_cpu_info_early(&uci); 799 collect_cpu_info_early(&uci);
784 load_microcode(mc_saved_data_p, mc_saved_in_initrd_p, 800 load_microcode(mc_saved_data_p, mc_saved_in_initrd_p,
785 initrd_start_addr, &uci); 801 initrd_start_addr, &uci);
786 apply_microcode_early(mc_saved_data_p, &uci); 802 apply_microcode_early(&uci, true);
803}
804
805void reload_ucode_intel(void)
806{
807 struct ucode_cpu_info uci;
808
809 if (!bsp_patch.hdr.rev)
810 return;
811
812 uci.mc = &bsp_patch;
813
814 apply_microcode_early(&uci, false);
787} 815}