Skip to content

Commit 1d81d85

Browse files
committed
x86/microcode/AMD: Split load_microcode_amd()
This function should've been split a long time ago because it is used in two paths: 1) On the late loading path, when the microcode is loaded through the request_firmware interface 2) In the save_microcode_in_initrd() path which collects all the microcode patches which are relevant for the current system before the initrd with the microcode container has been jettisoned. In that path, it is not really necessary to iterate over the nodes on a system and match a patch however it didn't cause any trouble so it was left for a later cleanup However, that later cleanup was expedited by the fact that Jens was enabling "Use L3 as a NUMA node" in the BIOS setting in his machine and so this causes the NUMA CPU masks used in cpumask_of_node() to be generated *after* 2) above happened on the first node. Which means, all those masks were funky, wrong, uninitialized and whatnot, leading to explosions when dereffing c->microcode in load_microcode_amd(). So split that function and do only the necessary work needed at each stage. Fixes: 94838d2 ("x86/microcode/AMD: Use the family,model,stepping encoded in the patch ID") Reported-by: Jens Axboe <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Tested-by: Jens Axboe <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent d1744a4 commit 1d81d85

File tree

1 file changed

+17
-8
lines changed
  • arch/x86/kernel/cpu/microcode

1 file changed

+17
-8
lines changed

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_
584584
native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy);
585585
}
586586

587-
static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
587+
static enum ucode_state _load_microcode_amd(u8 family, const u8 *data, size_t size);
588588

589589
static int __init save_microcode_in_initrd(void)
590590
{
@@ -605,7 +605,7 @@ static int __init save_microcode_in_initrd(void)
605605
if (!desc.mc)
606606
return -EINVAL;
607607

608-
ret = load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size);
608+
ret = _load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size);
609609
if (ret > UCODE_UPDATED)
610610
return -EINVAL;
611611

@@ -954,21 +954,30 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
954954
return UCODE_OK;
955955
}
956956

957-
static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size)
957+
static enum ucode_state _load_microcode_amd(u8 family, const u8 *data, size_t size)
958958
{
959-
struct cpuinfo_x86 *c;
960-
unsigned int nid, cpu;
961-
struct ucode_patch *p;
962959
enum ucode_state ret;
963960

964961
/* free old equiv table */
965962
free_equiv_cpu_table();
966963

967964
ret = __load_microcode_amd(family, data, size);
968-
if (ret != UCODE_OK) {
965+
if (ret != UCODE_OK)
969966
cleanup();
967+
968+
return ret;
969+
}
970+
971+
static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size)
972+
{
973+
struct cpuinfo_x86 *c;
974+
unsigned int nid, cpu;
975+
struct ucode_patch *p;
976+
enum ucode_state ret;
977+
978+
ret = _load_microcode_amd(family, data, size);
979+
if (ret != UCODE_OK)
970980
return ret;
971-
}
972981

973982
for_each_node(nid) {
974983
cpu = cpumask_first(cpumask_of_node(nid));

0 commit comments

Comments
 (0)