diff options
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/intel.c')
-rw-r--r-- | arch/x86/kernel/cpu/microcode/intel.c | 79 |
1 files changed, 18 insertions, 61 deletions
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index b624b54912e1..8325d8a09ab0 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin"; | 42 | static const char ucode_path[] = "kernel/x86/microcode/GenuineIntel.bin"; |
43 | 43 | ||
44 | /* Current microcode patch used in early patching */ | 44 | /* Current microcode patch used in early patching on the APs. */ |
45 | struct microcode_intel *intel_ucode_patch; | 45 | struct microcode_intel *intel_ucode_patch; |
46 | 46 | ||
47 | static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1, | 47 | static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1, |
@@ -150,7 +150,7 @@ static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size) | |||
150 | { | 150 | { |
151 | struct ucode_patch *p; | 151 | struct ucode_patch *p; |
152 | 152 | ||
153 | p = kzalloc(size, GFP_KERNEL); | 153 | p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL); |
154 | if (!p) | 154 | if (!p) |
155 | return ERR_PTR(-ENOMEM); | 155 | return ERR_PTR(-ENOMEM); |
156 | 156 | ||
@@ -368,26 +368,6 @@ next: | |||
368 | return patch; | 368 | return patch; |
369 | } | 369 | } |
370 | 370 | ||
371 | static void cpuid_1(void) | ||
372 | { | ||
373 | /* | ||
374 | * According to the Intel SDM, Volume 3, 9.11.7: | ||
375 | * | ||
376 | * CPUID returns a value in a model specific register in | ||
377 | * addition to its usual register return values. The | ||
378 | * semantics of CPUID cause it to deposit an update ID value | ||
379 | * in the 64-bit model-specific register at address 08BH | ||
380 | * (IA32_BIOS_SIGN_ID). If no update is present in the | ||
381 | * processor, the value in the MSR remains unmodified. | ||
382 | * | ||
383 | * Use native_cpuid -- this code runs very early and we don't | ||
384 | * want to mess with paravirt. | ||
385 | */ | ||
386 | unsigned int eax = 1, ebx, ecx = 0, edx; | ||
387 | |||
388 | native_cpuid(&eax, &ebx, &ecx, &edx); | ||
389 | } | ||
390 | |||
391 | static int collect_cpu_info_early(struct ucode_cpu_info *uci) | 371 | static int collect_cpu_info_early(struct ucode_cpu_info *uci) |
392 | { | 372 | { |
393 | unsigned int val[2]; | 373 | unsigned int val[2]; |
@@ -410,15 +390,8 @@ static int collect_cpu_info_early(struct ucode_cpu_info *uci) | |||
410 | native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); | 390 | native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); |
411 | csig.pf = 1 << ((val[1] >> 18) & 7); | 391 | csig.pf = 1 << ((val[1] >> 18) & 7); |
412 | } | 392 | } |
413 | native_wrmsrl(MSR_IA32_UCODE_REV, 0); | ||
414 | |||
415 | /* As documented in the SDM: Do a CPUID 1 here */ | ||
416 | cpuid_1(); | ||
417 | |||
418 | /* get the current revision from MSR 0x8B */ | ||
419 | native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | ||
420 | 393 | ||
421 | csig.rev = val[1]; | 394 | csig.rev = intel_get_microcode_revision(); |
422 | 395 | ||
423 | uci->cpu_sig = csig; | 396 | uci->cpu_sig = csig; |
424 | uci->valid = 1; | 397 | uci->valid = 1; |
@@ -602,7 +575,7 @@ static inline void print_ucode(struct ucode_cpu_info *uci) | |||
602 | static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) | 575 | static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) |
603 | { | 576 | { |
604 | struct microcode_intel *mc; | 577 | struct microcode_intel *mc; |
605 | unsigned int val[2]; | 578 | u32 rev; |
606 | 579 | ||
607 | mc = uci->mc; | 580 | mc = uci->mc; |
608 | if (!mc) | 581 | if (!mc) |
@@ -610,21 +583,16 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) | |||
610 | 583 | ||
611 | /* write microcode via MSR 0x79 */ | 584 | /* write microcode via MSR 0x79 */ |
612 | native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); | 585 | native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
613 | native_wrmsrl(MSR_IA32_UCODE_REV, 0); | ||
614 | |||
615 | /* As documented in the SDM: Do a CPUID 1 here */ | ||
616 | cpuid_1(); | ||
617 | 586 | ||
618 | /* get the current revision from MSR 0x8B */ | 587 | rev = intel_get_microcode_revision(); |
619 | native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | 588 | if (rev != mc->hdr.rev) |
620 | if (val[1] != mc->hdr.rev) | ||
621 | return -1; | 589 | return -1; |
622 | 590 | ||
623 | #ifdef CONFIG_X86_64 | 591 | #ifdef CONFIG_X86_64 |
624 | /* Flush global tlb. This is precaution. */ | 592 | /* Flush global tlb. This is precaution. */ |
625 | flush_tlb_early(); | 593 | flush_tlb_early(); |
626 | #endif | 594 | #endif |
627 | uci->cpu_sig.rev = val[1]; | 595 | uci->cpu_sig.rev = rev; |
628 | 596 | ||
629 | if (early) | 597 | if (early) |
630 | print_ucode(uci); | 598 | print_ucode(uci); |
@@ -639,12 +607,6 @@ int __init save_microcode_in_initrd_intel(void) | |||
639 | struct ucode_cpu_info uci; | 607 | struct ucode_cpu_info uci; |
640 | struct cpio_data cp; | 608 | struct cpio_data cp; |
641 | 609 | ||
642 | /* | ||
643 | * AP loading didn't find any microcode patch, no need to save anything. | ||
644 | */ | ||
645 | if (!intel_ucode_patch || IS_ERR(intel_ucode_patch)) | ||
646 | return 0; | ||
647 | |||
648 | if (!load_builtin_intel_microcode(&cp)) | 610 | if (!load_builtin_intel_microcode(&cp)) |
649 | cp = find_microcode_in_initrd(ucode_path, false); | 611 | cp = find_microcode_in_initrd(ucode_path, false); |
650 | 612 | ||
@@ -660,7 +622,6 @@ int __init save_microcode_in_initrd_intel(void) | |||
660 | return 0; | 622 | return 0; |
661 | } | 623 | } |
662 | 624 | ||
663 | |||
664 | /* | 625 | /* |
665 | * @res_patch, output: a pointer to the patch we found. | 626 | * @res_patch, output: a pointer to the patch we found. |
666 | */ | 627 | */ |
@@ -804,8 +765,8 @@ static int apply_microcode_intel(int cpu) | |||
804 | struct microcode_intel *mc; | 765 | struct microcode_intel *mc; |
805 | struct ucode_cpu_info *uci; | 766 | struct ucode_cpu_info *uci; |
806 | struct cpuinfo_x86 *c; | 767 | struct cpuinfo_x86 *c; |
807 | unsigned int val[2]; | ||
808 | static int prev_rev; | 768 | static int prev_rev; |
769 | u32 rev; | ||
809 | 770 | ||
810 | /* We should bind the task to the CPU */ | 771 | /* We should bind the task to the CPU */ |
811 | if (WARN_ON(raw_smp_processor_id() != cpu)) | 772 | if (WARN_ON(raw_smp_processor_id() != cpu)) |
@@ -822,33 +783,28 @@ static int apply_microcode_intel(int cpu) | |||
822 | 783 | ||
823 | /* write microcode via MSR 0x79 */ | 784 | /* write microcode via MSR 0x79 */ |
824 | wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); | 785 | wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
825 | wrmsrl(MSR_IA32_UCODE_REV, 0); | ||
826 | |||
827 | /* As documented in the SDM: Do a CPUID 1 here */ | ||
828 | cpuid_1(); | ||
829 | 786 | ||
830 | /* get the current revision from MSR 0x8B */ | 787 | rev = intel_get_microcode_revision(); |
831 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | ||
832 | 788 | ||
833 | if (val[1] != mc->hdr.rev) { | 789 | if (rev != mc->hdr.rev) { |
834 | pr_err("CPU%d update to revision 0x%x failed\n", | 790 | pr_err("CPU%d update to revision 0x%x failed\n", |
835 | cpu, mc->hdr.rev); | 791 | cpu, mc->hdr.rev); |
836 | return -1; | 792 | return -1; |
837 | } | 793 | } |
838 | 794 | ||
839 | if (val[1] != prev_rev) { | 795 | if (rev != prev_rev) { |
840 | pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n", | 796 | pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n", |
841 | val[1], | 797 | rev, |
842 | mc->hdr.date & 0xffff, | 798 | mc->hdr.date & 0xffff, |
843 | mc->hdr.date >> 24, | 799 | mc->hdr.date >> 24, |
844 | (mc->hdr.date >> 16) & 0xff); | 800 | (mc->hdr.date >> 16) & 0xff); |
845 | prev_rev = val[1]; | 801 | prev_rev = rev; |
846 | } | 802 | } |
847 | 803 | ||
848 | c = &cpu_data(cpu); | 804 | c = &cpu_data(cpu); |
849 | 805 | ||
850 | uci->cpu_sig.rev = val[1]; | 806 | uci->cpu_sig.rev = rev; |
851 | c->microcode = val[1]; | 807 | c->microcode = rev; |
852 | 808 | ||
853 | return 0; | 809 | return 0; |
854 | } | 810 | } |
@@ -860,7 +816,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
860 | u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL; | 816 | u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL; |
861 | int new_rev = uci->cpu_sig.rev; | 817 | int new_rev = uci->cpu_sig.rev; |
862 | unsigned int leftover = size; | 818 | unsigned int leftover = size; |
863 | unsigned int curr_mc_size = 0; | 819 | unsigned int curr_mc_size = 0, new_mc_size = 0; |
864 | unsigned int csig, cpf; | 820 | unsigned int csig, cpf; |
865 | 821 | ||
866 | while (leftover) { | 822 | while (leftover) { |
@@ -901,6 +857,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
901 | vfree(new_mc); | 857 | vfree(new_mc); |
902 | new_rev = mc_header.rev; | 858 | new_rev = mc_header.rev; |
903 | new_mc = mc; | 859 | new_mc = mc; |
860 | new_mc_size = mc_size; | ||
904 | mc = NULL; /* trigger new vmalloc */ | 861 | mc = NULL; /* trigger new vmalloc */ |
905 | } | 862 | } |
906 | 863 | ||
@@ -926,7 +883,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
926 | * permanent memory. So it will be loaded early when a CPU is hot added | 883 | * permanent memory. So it will be loaded early when a CPU is hot added |
927 | * or resumes. | 884 | * or resumes. |
928 | */ | 885 | */ |
929 | save_mc_for_early(new_mc, curr_mc_size); | 886 | save_mc_for_early(new_mc, new_mc_size); |
930 | 887 | ||
931 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", | 888 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
932 | cpu, new_rev, uci->cpu_sig.rev); | 889 | cpu, new_rev, uci->cpu_sig.rev); |