Skip to content

Commit

Permalink
x86/microcode/AMD: Fix mixed steppings support
Browse files Browse the repository at this point in the history
The AMD side of the loader has always claimed to support mixed
steppings. But somewhere along the way, it broke that by assuming that
the cached patch blob is a single one instead of it being one per
*node*.

So turn it into a per-node one so that each node can stash the blob
relevant for it.

  [ NB: Fixes tag is not really the exactly correct one but it is good
    enough. ]

Fixes: fe05589 ("x86/microcode: Merge the early microcode loader")
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: <stable@kernel.org> # 2355370 ("x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter")
Cc: <stable@kernel.org> # a5ad921 ("x86/microcode/AMD: Add a @cpu parameter to the reloading functions")
Link: https://lore.kernel.org/r/20230130161709.11615-4-bp@alien8.de
  • Loading branch information
Borislav Petkov (AMD) committed Feb 6, 2023
1 parent a5ad921 commit 7ff6edf
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions arch/x86/kernel/cpu/microcode/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ struct cont_desc {
};

static u32 ucode_new_rev;
static u8 amd_ucode_patch[PATCH_MAX_SIZE];

/* One blob per node. */
static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE];

/*
* Microcode patch container file is prepended to the initrd in cpio
Expand Down Expand Up @@ -428,7 +430,7 @@ static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size, boo
patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
#else
new_rev = &ucode_new_rev;
patch = &amd_ucode_patch;
patch = &amd_ucode_patch[0];
#endif

desc.cpuid_1_eax = cpuid_1_eax;
Expand Down Expand Up @@ -580,10 +582,10 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)

void reload_ucode_amd(unsigned int cpu)
{
struct microcode_amd *mc;
u32 rev, dummy __always_unused;
struct microcode_amd *mc;

mc = (struct microcode_amd *)amd_ucode_patch;
mc = (struct microcode_amd *)amd_ucode_patch[cpu_to_node(cpu)];

rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);

Expand Down Expand Up @@ -852,6 +854,8 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,

static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size)
{
struct cpuinfo_x86 *c;
unsigned int nid, cpu;
struct ucode_patch *p;
enum ucode_state ret;

Expand All @@ -864,18 +868,22 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz
return ret;
}

p = find_patch(0);
if (!p) {
return ret;
} else {
if (boot_cpu_data.microcode >= p->patch_id)
return ret;
for_each_node(nid) {
cpu = cpumask_first(cpumask_of_node(nid));
c = &cpu_data(cpu);

p = find_patch(cpu);
if (!p)
continue;

if (c->microcode >= p->patch_id)
continue;

ret = UCODE_NEW;
}

memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
memset(&amd_ucode_patch[nid], 0, PATCH_MAX_SIZE);
memcpy(&amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
}

return ret;
}
Expand Down

0 comments on commit 7ff6edf

Please sign in to comment.