diff options
author | Ashok Raj <ashok.raj@intel.com> | 2018-02-28 05:28:41 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2018-03-08 04:19:25 -0500 |
commit | c182d2b7d0ca48e0d6ff16f7d883161238c447ed (patch) | |
tree | dd43afcf1c29fba71f5c3fbf680de823a9daa2d5 | |
parent | 854857f5944c59a881ff607b37ed9ed41d031a3b (diff) |
x86/microcode/intel: Check microcode revision before updating sibling threads
After updating microcode on one of the threads of a core, the other
thread sibling automatically gets the update since the microcode
resources on a hyperthreaded core are shared between the two threads.
Check the microcode revision on the CPU before performing a microcode
update and thus save us the WRMSR 0x79 because it is a particularly
expensive operation.
[ Borislav: Massage changelog and coding style. ]
Signed-off-by: Ashok Raj <ashok.raj@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Tested-by: Ashok Raj <ashok.raj@intel.com>
Cc: Arjan Van De Ven <arjan.van.de.ven@intel.com>
Link: http://lkml.kernel.org/r/1519352533-15992-2-git-send-email-ashok.raj@intel.com
Link: https://lkml.kernel.org/r/20180228102846.13447-3-bp@alien8.de
-rw-r--r-- | arch/x86/kernel/cpu/microcode/intel.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 923054a6b760..87bd6dc94081 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c | |||
@@ -589,6 +589,17 @@ 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 | |||
592 | /* write microcode via MSR 0x79 */ | 603 | /* write microcode via MSR 0x79 */ |
593 | native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); | 604 | native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
594 | 605 | ||
@@ -776,7 +787,7 @@ static enum ucode_state apply_microcode_intel(int cpu) | |||
776 | { | 787 | { |
777 | struct microcode_intel *mc; | 788 | struct microcode_intel *mc; |
778 | struct ucode_cpu_info *uci; | 789 | struct ucode_cpu_info *uci; |
779 | struct cpuinfo_x86 *c; | 790 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
780 | static int prev_rev; | 791 | static int prev_rev; |
781 | u32 rev; | 792 | u32 rev; |
782 | 793 | ||
@@ -793,6 +804,18 @@ static enum ucode_state apply_microcode_intel(int cpu) | |||
793 | return UCODE_NFOUND; | 804 | return UCODE_NFOUND; |
794 | } | 805 | } |
795 | 806 | ||
807 | /* | ||
808 | * Save us the MSR write below - which is a particular expensive | ||
809 | * operation - when the other hyperthread has updated the microcode | ||
810 | * already. | ||
811 | */ | ||
812 | rev = intel_get_microcode_revision(); | ||
813 | if (rev >= mc->hdr.rev) { | ||
814 | uci->cpu_sig.rev = rev; | ||
815 | c->microcode = rev; | ||
816 | return UCODE_OK; | ||
817 | } | ||
818 | |||
796 | /* write microcode via MSR 0x79 */ | 819 | /* write microcode via MSR 0x79 */ |
797 | wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); | 820 | wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits); |
798 | 821 | ||
@@ -813,8 +836,6 @@ static enum ucode_state apply_microcode_intel(int cpu) | |||
813 | prev_rev = rev; | 836 | prev_rev = rev; |
814 | } | 837 | } |
815 | 838 | ||
816 | c = &cpu_data(cpu); | ||
817 | |||
818 | uci->cpu_sig.rev = rev; | 839 | uci->cpu_sig.rev = rev; |
819 | c->microcode = rev; | 840 | c->microcode = rev; |
820 | 841 | ||