Skip to content

Commit 2613f36

Browse files
suryasaimadhuKAGA-KOKO
authored andcommitted
x86/microcode: Attempt late loading only when new microcode is present
Return UCODE_NEW from the scanning functions to denote that new microcode was found and only then attempt the expensive synchronization dance. Reported-by: Emanuel Czirai <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Emanuel Czirai <[email protected]> Tested-by: Ashok Raj <[email protected]> Tested-by: Tom Lendacky <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent e3b3121 commit 2613f36

File tree

4 files changed

+28
-19
lines changed

4 files changed

+28
-19
lines changed

arch/x86/include/asm/microcode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct device;
3939

4040
enum ucode_state {
4141
UCODE_OK = 0,
42+
UCODE_NEW,
4243
UCODE_UPDATED,
4344
UCODE_NFOUND,
4445
UCODE_ERROR,

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

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
339339
return -EINVAL;
340340

341341
ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size);
342-
if (ret != UCODE_OK)
342+
if (ret > UCODE_UPDATED)
343343
return -EINVAL;
344344

345345
return 0;
@@ -683,27 +683,35 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
683683
static enum ucode_state
684684
load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
685685
{
686+
struct ucode_patch *p;
686687
enum ucode_state ret;
687688

688689
/* free old equiv table */
689690
free_equiv_cpu_table();
690691

691692
ret = __load_microcode_amd(family, data, size);
692-
693-
if (ret != UCODE_OK)
693+
if (ret != UCODE_OK) {
694694
cleanup();
695+
return ret;
696+
}
695697

696-
#ifdef CONFIG_X86_32
697-
/* save BSP's matching patch for early load */
698-
if (save) {
699-
struct ucode_patch *p = find_patch(0);
700-
if (p) {
701-
memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
702-
memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
703-
PATCH_MAX_SIZE));
704-
}
698+
p = find_patch(0);
699+
if (!p) {
700+
return ret;
701+
} else {
702+
if (boot_cpu_data.microcode == p->patch_id)
703+
return ret;
704+
705+
ret = UCODE_NEW;
705706
}
706-
#endif
707+
708+
/* save BSP's matching patch for early load */
709+
if (!save)
710+
return ret;
711+
712+
memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
713+
memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE));
714+
707715
return ret;
708716
}
709717

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ static ssize_t reload_store(struct device *dev,
607607
return size;
608608

609609
tmp_ret = microcode_ops->request_microcode_fw(bsp, &microcode_pdev->dev, true);
610-
if (tmp_ret != UCODE_OK)
610+
if (tmp_ret != UCODE_NEW)
611611
return size;
612612

613613
get_online_cpus();
@@ -691,10 +691,8 @@ static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)
691691
if (system_state != SYSTEM_RUNNING)
692692
return UCODE_NFOUND;
693693

694-
ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev,
695-
refresh_fw);
696-
697-
if (ustate == UCODE_OK) {
694+
ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, refresh_fw);
695+
if (ustate == UCODE_NEW) {
698696
pr_debug("CPU%d updated upon init\n", cpu);
699697
apply_microcode_on_target(cpu);
700698
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
862862
unsigned int leftover = size;
863863
unsigned int curr_mc_size = 0, new_mc_size = 0;
864864
unsigned int csig, cpf;
865+
enum ucode_state ret = UCODE_OK;
865866

866867
while (leftover) {
867868
struct microcode_header_intel mc_header;
@@ -903,6 +904,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
903904
new_mc = mc;
904905
new_mc_size = mc_size;
905906
mc = NULL; /* trigger new vmalloc */
907+
ret = UCODE_NEW;
906908
}
907909

908910
ucode_ptr += mc_size;
@@ -932,7 +934,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
932934
pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
933935
cpu, new_rev, uci->cpu_sig.rev);
934936

935-
return UCODE_OK;
937+
return ret;
936938
}
937939

938940
static int get_ucode_fw(void *to, const void *from, size_t n)

0 commit comments

Comments
 (0)