aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/microcode/intel.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-03-20 06:27:18 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-03-20 06:27:18 -0400
commit4958134df54c2c84e9c22ea042761d439164d26e (patch)
tree503177afab11f7d25b12a84ce25b481d305c51ba /arch/x86/kernel/cpu/microcode/intel.c
parentc4f528795d1add8b63652673f7262729f679c6c1 (diff)
parentc698ca5278934c0ae32297a8725ced2e27585d7f (diff)
Merge 4.16-rc6 into tty-next
We want the serial/tty fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/x86/kernel/cpu/microcode/intel.c')
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index a15db2b4e0d6..32b8e5724f96 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -589,6 +589,23 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
589 if (!mc) 589 if (!mc)
590 return 0; 590 return 0;
591 591
592 /*
593 * Save us the MSR write below - which is a particular expensive
594 * operation - when the other hyperthread has updated the microcode
595 * already.
596 */
597 rev = intel_get_microcode_revision();
598 if (rev >= mc->hdr.rev) {
599 uci->cpu_sig.rev = rev;
600 return UCODE_OK;
601 }
602
603 /*
604 * Writeback and invalidate caches before updating microcode to avoid
605 * internal issues depending on what the microcode is updating.
606 */
607 native_wbinvd();
608
592 /* write microcode via MSR 0x79 */ 609 /* write microcode via MSR 0x79 */
593 native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); 610 native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
594 611
@@ -772,27 +789,44 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
772 return 0; 789 return 0;
773} 790}
774 791
775static int apply_microcode_intel(int cpu) 792static enum ucode_state apply_microcode_intel(int cpu)
776{ 793{
794 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
795 struct cpuinfo_x86 *c = &cpu_data(cpu);
777 struct microcode_intel *mc; 796 struct microcode_intel *mc;
778 struct ucode_cpu_info *uci;
779 struct cpuinfo_x86 *c;
780 static int prev_rev; 797 static int prev_rev;
781 u32 rev; 798 u32 rev;
782 799
783 /* We should bind the task to the CPU */ 800 /* We should bind the task to the CPU */
784 if (WARN_ON(raw_smp_processor_id() != cpu)) 801 if (WARN_ON(raw_smp_processor_id() != cpu))
785 return -1; 802 return UCODE_ERROR;
786 803
787 uci = ucode_cpu_info + cpu; 804 /* Look for a newer patch in our cache: */
788 mc = uci->mc; 805 mc = find_patch(uci);
789 if (!mc) { 806 if (!mc) {
790 /* Look for a newer patch in our cache: */ 807 mc = uci->mc;
791 mc = find_patch(uci);
792 if (!mc) 808 if (!mc)
793 return 0; 809 return UCODE_NFOUND;
794 } 810 }
795 811
812 /*
813 * Save us the MSR write below - which is a particular expensive
814 * operation - when the other hyperthread has updated the microcode
815 * already.
816 */
817 rev = intel_get_microcode_revision();
818 if (rev >= mc->hdr.rev) {
819 uci->cpu_sig.rev = rev;
820 c->microcode = rev;
821 return UCODE_OK;
822 }
823
824 /*
825 * Writeback and invalidate caches before updating microcode to avoid
826 * internal issues depending on what the microcode is updating.
827 */
828 native_wbinvd();
829
796 /* write microcode via MSR 0x79 */ 830 /* write microcode via MSR 0x79 */
797 wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); 831 wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
798 832
@@ -801,7 +835,7 @@ static int apply_microcode_intel(int cpu)
801 if (rev != mc->hdr.rev) { 835 if (rev != mc->hdr.rev) {
802 pr_err("CPU%d update to revision 0x%x failed\n", 836 pr_err("CPU%d update to revision 0x%x failed\n",
803 cpu, mc->hdr.rev); 837 cpu, mc->hdr.rev);
804 return -1; 838 return UCODE_ERROR;
805 } 839 }
806 840
807 if (rev != prev_rev) { 841 if (rev != prev_rev) {
@@ -813,12 +847,10 @@ static int apply_microcode_intel(int cpu)
813 prev_rev = rev; 847 prev_rev = rev;
814 } 848 }
815 849
816 c = &cpu_data(cpu);
817
818 uci->cpu_sig.rev = rev; 850 uci->cpu_sig.rev = rev;
819 c->microcode = rev; 851 c->microcode = rev;
820 852
821 return 0; 853 return UCODE_UPDATED;
822} 854}
823 855
824static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, 856static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
@@ -830,6 +862,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
830 unsigned int leftover = size; 862 unsigned int leftover = size;
831 unsigned int curr_mc_size = 0, new_mc_size = 0; 863 unsigned int curr_mc_size = 0, new_mc_size = 0;
832 unsigned int csig, cpf; 864 unsigned int csig, cpf;
865 enum ucode_state ret = UCODE_OK;
833 866
834 while (leftover) { 867 while (leftover) {
835 struct microcode_header_intel mc_header; 868 struct microcode_header_intel mc_header;
@@ -871,6 +904,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
871 new_mc = mc; 904 new_mc = mc;
872 new_mc_size = mc_size; 905 new_mc_size = mc_size;
873 mc = NULL; /* trigger new vmalloc */ 906 mc = NULL; /* trigger new vmalloc */
907 ret = UCODE_NEW;
874 } 908 }
875 909
876 ucode_ptr += mc_size; 910 ucode_ptr += mc_size;
@@ -900,7 +934,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
900 pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", 934 pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
901 cpu, new_rev, uci->cpu_sig.rev); 935 cpu, new_rev, uci->cpu_sig.rev);
902 936
903 return UCODE_OK; 937 return ret;
904} 938}
905 939
906static int get_ucode_fw(void *to, const void *from, size_t n) 940static int get_ucode_fw(void *to, const void *from, size_t n)