Re: [GIT PULL] x86/microcode for 6.7

From: Borislav Petkov
Date: Sun Nov 12 2023 - 07:26:21 EST


On Sat, Nov 11, 2023 at 11:35:49PM +0100, Borislav Petkov wrote:
> Yeah, it is on the todo list. I'll take a look next week.

Yeah, so I think something along the lines of the below.

This has been bothering me for a while now too but I wanted to get
tglx's stuff taken care of first.

Basically, we can simply report the previous and the potentially new
revision only once on driver load.

Even if the AMD side theoretically still supports mixed silicon
steppings, there's no need to do per-thread reporting as that info is
already in /proc/cpuinfo for those who are really interested.

So this below should be good enough.

I'll test it some more next week and split it.

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 9373ec01c5ae..7213dea21a15 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -104,7 +104,7 @@ struct cont_desc {
size_t size;
};

-static u32 ucode_new_rev;
+static u32 early_new_rev, old_rev;

/*
* Microcode patch container file is prepended to the initrd in cpio
@@ -447,7 +447,6 @@ static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size)
struct cont_desc desc = { 0 };
struct microcode_amd *mc;
bool ret = false;
- u32 rev, dummy;

desc.cpuid_1_eax = cpuid_1_eax;

@@ -457,22 +456,15 @@ static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size)
if (!mc)
return ret;

- native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
-
/*
* Allow application of the same revision to pick up SMT-specific
* changes even if the revision of the other SMT thread is already
* up-to-date.
*/
- if (rev > mc->hdr.patch_id)
+ if (old_rev > mc->hdr.patch_id)
return ret;

- if (!__apply_microcode_amd(mc)) {
- ucode_new_rev = mc->hdr.patch_id;
- ret = true;
- }
-
- return ret;
+ return !__apply_microcode_amd(mc);
}

static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
@@ -509,6 +501,9 @@ static void __init find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpi
void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
{
struct cpio_data cp = { };
+ u32 dummy;
+
+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, old_rev, dummy);

/* Needed in load_microcode_amd() */
ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax;
@@ -517,7 +512,8 @@ void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax)
if (!(cp.data && cp.size))
return;

- early_apply_microcode(cpuid_1_eax, cp.data, cp.size);
+ if (early_apply_microcode(cpuid_1_eax, cp.data, cp.size))
+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, early_new_rev, dummy);
}

static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
@@ -626,8 +622,8 @@ void reload_ucode_amd(unsigned int cpu)

if (rev < mc->hdr.patch_id) {
if (!__apply_microcode_amd(mc)) {
- ucode_new_rev = mc->hdr.patch_id;
- pr_info("reload patch_level=0x%08x\n", ucode_new_rev);
+ early_new_rev = mc->hdr.patch_id;
+ pr_info_once("reload revision: 0x%08x\n", early_new_rev);
}
}
}
@@ -649,8 +645,6 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
if (p && (p->patch_id == csig->rev))
uci->mc = p->data;

- pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
-
return 0;
}

@@ -691,8 +685,6 @@ static enum ucode_state apply_microcode_amd(int cpu)
rev = mc_amd->hdr.patch_id;
ret = UCODE_UPDATED;

- pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev);
-
out:
uci->cpu_sig.rev = rev;
c->microcode = rev;
@@ -936,9 +928,11 @@ struct microcode_ops * __init init_amd_microcode(void)
return NULL;
}

- if (ucode_new_rev)
- pr_info_once("microcode updated early to new patch_level=0x%08x\n",
- ucode_new_rev);
+ pr_info_once("Current revision: 0x%08x\n", (early_new_rev ?: old_rev));
+
+ if (early_new_rev)
+ pr_info_once("Updated early from: 0x%08x\n",
+ old_rev);

return &microcode_amd_ops;
}
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 666d25bbc5ad..b4be3a2c79df 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -41,8 +41,6 @@

#include "internal.h"

-#define DRIVER_VERSION "2.2"
-
static struct microcode_ops *microcode_ops;
bool dis_ucode_ldr = true;

@@ -846,8 +844,6 @@ static int __init microcode_init(void)
cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
mc_cpu_online, mc_cpu_down_prep);

- pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION);
-
return 0;

out_pdev:

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette