aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/microcode/intel.c
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2017-01-09 06:41:45 -0500
committerThomas Gleixner <tglx@linutronix.de>2017-01-09 17:11:14 -0500
commit4167709bbf826512a52ebd6aafda2be104adaec9 (patch)
tree29ddbe49a559437f134819900d7b77728f5c0d5b /arch/x86/kernel/cpu/microcode/intel.c
parentf3e2a51f568d9f33370f4e8bb05669a34223241a (diff)
x86/microcode/intel: Add a helper which gives the microcode revision
Since on Intel we're required to do CPUID(1) first, before reading the microcode revision MSR, let's add a special helper which does the required steps so that we don't forget to do them next time, when we want to read the microcode revision. Signed-off-by: Borislav Petkov <bp@suse.de> Link: http://lkml.kernel.org/r/20170109114147.5082-4-bp@alien8.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/intel.c')
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c43
1 files changed, 13 insertions, 30 deletions
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index f79249fab389..faec8fa68ffd 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -390,15 +390,8 @@ static int collect_cpu_info_early(struct ucode_cpu_info *uci)
390 native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 390 native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
391 csig.pf = 1 << ((val[1] >> 18) & 7); 391 csig.pf = 1 << ((val[1] >> 18) & 7);
392 } 392 }
393 native_wrmsrl(MSR_IA32_UCODE_REV, 0);
394 393
395 /* As documented in the SDM: Do a CPUID 1 here */ 394 csig.rev = intel_get_microcode_revision();
396 native_cpuid_eax(1);
397
398 /* get the current revision from MSR 0x8B */
399 native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
400
401 csig.rev = val[1];
402 395
403 uci->cpu_sig = csig; 396 uci->cpu_sig = csig;
404 uci->valid = 1; 397 uci->valid = 1;
@@ -582,7 +575,7 @@ static inline void print_ucode(struct ucode_cpu_info *uci)
582static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) 575static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
583{ 576{
584 struct microcode_intel *mc; 577 struct microcode_intel *mc;
585 unsigned int val[2]; 578 u32 rev;
586 579
587 mc = uci->mc; 580 mc = uci->mc;
588 if (!mc) 581 if (!mc)
@@ -590,21 +583,16 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
590 583
591 /* write microcode via MSR 0x79 */ 584 /* write microcode via MSR 0x79 */
592 native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); 585 native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
593 native_wrmsrl(MSR_IA32_UCODE_REV, 0);
594 586
595 /* As documented in the SDM: Do a CPUID 1 here */ 587 rev = intel_get_microcode_revision();
596 native_cpuid_eax(1); 588 if (rev != mc->hdr.rev)
597
598 /* get the current revision from MSR 0x8B */
599 native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
600 if (val[1] != mc->hdr.rev)
601 return -1; 589 return -1;
602 590
603#ifdef CONFIG_X86_64 591#ifdef CONFIG_X86_64
604 /* Flush global tlb. This is precaution. */ 592 /* Flush global tlb. This is precaution. */
605 flush_tlb_early(); 593 flush_tlb_early();
606#endif 594#endif
607 uci->cpu_sig.rev = val[1]; 595 uci->cpu_sig.rev = rev;
608 596
609 if (early) 597 if (early)
610 print_ucode(uci); 598 print_ucode(uci);
@@ -784,8 +772,8 @@ static int apply_microcode_intel(int cpu)
784 struct microcode_intel *mc; 772 struct microcode_intel *mc;
785 struct ucode_cpu_info *uci; 773 struct ucode_cpu_info *uci;
786 struct cpuinfo_x86 *c; 774 struct cpuinfo_x86 *c;
787 unsigned int val[2];
788 static int prev_rev; 775 static int prev_rev;
776 u32 rev;
789 777
790 /* We should bind the task to the CPU */ 778 /* We should bind the task to the CPU */
791 if (WARN_ON(raw_smp_processor_id() != cpu)) 779 if (WARN_ON(raw_smp_processor_id() != cpu))
@@ -802,33 +790,28 @@ static int apply_microcode_intel(int cpu)
802 790
803 /* write microcode via MSR 0x79 */ 791 /* write microcode via MSR 0x79 */
804 wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); 792 wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
805 wrmsrl(MSR_IA32_UCODE_REV, 0);
806
807 /* As documented in the SDM: Do a CPUID 1 here */
808 native_cpuid_eax(1);
809 793
810 /* get the current revision from MSR 0x8B */ 794 rev = intel_get_microcode_revision();
811 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
812 795
813 if (val[1] != mc->hdr.rev) { 796 if (rev != mc->hdr.rev) {
814 pr_err("CPU%d update to revision 0x%x failed\n", 797 pr_err("CPU%d update to revision 0x%x failed\n",
815 cpu, mc->hdr.rev); 798 cpu, mc->hdr.rev);
816 return -1; 799 return -1;
817 } 800 }
818 801
819 if (val[1] != prev_rev) { 802 if (rev != prev_rev) {
820 pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n", 803 pr_info("updated to revision 0x%x, date = %04x-%02x-%02x\n",
821 val[1], 804 rev,
822 mc->hdr.date & 0xffff, 805 mc->hdr.date & 0xffff,
823 mc->hdr.date >> 24, 806 mc->hdr.date >> 24,
824 (mc->hdr.date >> 16) & 0xff); 807 (mc->hdr.date >> 16) & 0xff);
825 prev_rev = val[1]; 808 prev_rev = rev;
826 } 809 }
827 810
828 c = &cpu_data(cpu); 811 c = &cpu_data(cpu);
829 812
830 uci->cpu_sig.rev = val[1]; 813 uci->cpu_sig.rev = rev;
831 c->microcode = val[1]; 814 c->microcode = rev;
832 815
833 return 0; 816 return 0;
834} 817}