112 lines
3.5 KiB
Diff
112 lines
3.5 KiB
Diff
|
From 34d3d5458f58c88954bb3087219610f35e2b5c37 Mon Sep 17 00:00:00 2001
|
||
|
From: "Borislav Petkov (AMD)" <bp@alien8.de>
|
||
|
Date: Thu, 26 Jan 2023 16:26:17 +0100
|
||
|
Subject: [PATCH 23/36] x86/microcode/AMD: Fix mixed steppings support
|
||
|
|
||
|
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: fe055896c040 ("x86/microcode: Merge the early microcode loader")
|
||
|
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
|
||
|
Cc: <stable@kernel.org> # 2355370cd941 ("x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter")
|
||
|
Cc: <stable@kernel.org> # a5ad92134bd1 ("x86/microcode/AMD: Add a @cpu parameter to the reloading functions")
|
||
|
Link: https://lore.kernel.org/r/20230130161709.11615-4-bp@alien8.de
|
||
|
(cherry picked from commit 7ff6edf4fef38ab404ee7861f257e28eaaeed35f)
|
||
|
|
||
|
CVE: CVE-2023-20593
|
||
|
Signed-off-by: Mridula Shastry <mridula.c.shastry@oracle.com>
|
||
|
Reviewed-by: Todd Vierling <todd.vierling@oracle.com>
|
||
|
---
|
||
|
arch/x86/kernel/cpu/microcode/amd.c | 34 ++++++++++++++++++-----------
|
||
|
1 file changed, 21 insertions(+), 13 deletions(-)
|
||
|
|
||
|
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
|
||
|
index 030f69f93c00..d1d31011b8fa 100644
|
||
|
--- a/arch/x86/kernel/cpu/microcode/amd.c
|
||
|
+++ b/arch/x86/kernel/cpu/microcode/amd.c
|
||
|
@@ -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
|
||
|
@@ -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;
|
||
|
@@ -574,10 +576,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);
|
||
|
|
||
|
@@ -846,6 +848,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;
|
||
|
|
||
|
@@ -858,18 +862,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;
|
||
|
}
|
||
|
--
|
||
|
2.39.3
|
||
|
|