diff options
author | Borislav Petkov <bp@suse.de> | 2017-01-09 06:41:45 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-01-09 17:11:14 -0500 |
commit | 4167709bbf826512a52ebd6aafda2be104adaec9 (patch) | |
tree | 29ddbe49a559437f134819900d7b77728f5c0d5b /arch/x86/kernel/cpu/microcode/intel.c | |
parent | f3e2a51f568d9f33370f4e8bb05669a34223241a (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.c | 43 |
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) | |||
582 | 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) |
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 | } |