Skip to content

Commit c182d2b

Browse files
ashok-rajKAGA-KOKO
authored andcommitted
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 <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Tom Lendacky <[email protected]> Tested-by: Ashok Raj <[email protected]> Cc: Arjan Van De Ven <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 854857f commit c182d2b

File tree

1 file changed

+24
-3
lines changed
  • arch/x86/kernel/cpu/microcode

1 file changed

+24
-3
lines changed

arch/x86/kernel/cpu/microcode/intel.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,17 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
589589
if (!mc)
590590
return 0;
591591

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+
592603
/* write microcode via MSR 0x79 */
593604
native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
594605

@@ -776,7 +787,7 @@ static enum ucode_state apply_microcode_intel(int cpu)
776787
{
777788
struct microcode_intel *mc;
778789
struct ucode_cpu_info *uci;
779-
struct cpuinfo_x86 *c;
790+
struct cpuinfo_x86 *c = &cpu_data(cpu);
780791
static int prev_rev;
781792
u32 rev;
782793

@@ -793,6 +804,18 @@ static enum ucode_state apply_microcode_intel(int cpu)
793804
return UCODE_NFOUND;
794805
}
795806

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+
796819
/* write microcode via MSR 0x79 */
797820
wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
798821

@@ -813,8 +836,6 @@ static enum ucode_state apply_microcode_intel(int cpu)
813836
prev_rev = rev;
814837
}
815838

816-
c = &cpu_data(cpu);
817-
818839
uci->cpu_sig.rev = rev;
819840
c->microcode = rev;
820841

0 commit comments

Comments
 (0)