diff options
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/intel_early.c')
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/intel_early.c | 48 |
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 | ||
| 37 | static struct microcode_intel bsp_patch; | ||
| 38 | |||
| 37 | static enum ucode_state | 39 | static enum ucode_state |
| 38 | generic_load_microcode_early(struct microcode_intel **mc_saved_p, | 40 | generic_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 | ||
| 653 | static int apply_microcode_early(struct mc_saved_data *mc_saved_data, | 655 | static 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 | ||
| 726 | void __init | 738 | void __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 | |||
| 805 | void 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 | } |
