[tip: x86/urgent] x86/microcode/AMD: Apply the patch early on every logical thread

From: tip-bot2 for Borislav Petkov
Date: Tue Oct 18 2022 - 05:26:51 EST


The following commit has been merged into the x86/urgent branch of tip:

Commit-ID: e7ad18d1169c62e6c78c01ff693fd362d9d65278
Gitweb: https://git.kernel.org/tip/e7ad18d1169c62e6c78c01ff693fd362d9d65278
Author: Borislav Petkov <bp@xxxxxxx>
AuthorDate: Wed, 05 Oct 2022 12:00:08 +02:00
Committer: Borislav Petkov <bp@xxxxxxx>
CommitterDate: Tue, 18 Oct 2022 11:03:27 +02:00

x86/microcode/AMD: Apply the patch early on every logical thread

Currently, the patch application logic checks whether the revision
needs to be applied on each logical CPU (SMT thread). Therefore, on SMT
designs where the microcode engine is shared between the two threads,
the application happens only on one of them as that is enough to update
the shared microcode engine.

However, there are microcode patches which do per-thread modification,
see Link tag below.

Therefore, drop the revision check and try applying on each thread. This
is what the BIOS does too so this method is very much tested.

Btw, change only the early paths. On the late loading paths, there's no
point in doing per-thread modification because if is it some case like
in the bugzilla below - removing a CPUID flag - the kernel cannot go and
un-use features it has detected are there early. For that, one should
use early loading anyway.

[ bp: Fixes does not contain the oldest commit which did check for
equality but that is good enough. ]

Fixes: 8801b3fcb574 ("x86/microcode/AMD: Rework container parsing")
Reported-by: Ștefan Talpalaru <stefantalpalaru@xxxxxxxxx>
Signed-off-by: Borislav Petkov <bp@xxxxxxx>
Tested-by: Ștefan Talpalaru <stefantalpalaru@xxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216211
---
arch/x86/kernel/cpu/microcode/amd.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index e7410e9..3a35dec 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -440,7 +440,13 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size, bool save_p
return ret;

native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
- if (rev >= mc->hdr.patch_id)
+
+ /*
+ * 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)
return ret;

if (!__apply_microcode_amd(mc)) {
@@ -528,8 +534,12 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)

native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);

- /* Check whether we have saved a new patch already: */
- if (*new_rev && rev < mc->hdr.patch_id) {
+ /*
+ * Check whether a new patch has been saved already. Also, allow application of
+ * the same revision in order to pick up SMT-thread-specific configuration even
+ * if the sibling SMT thread already has an up-to-date revision.
+ */
+ if (*new_rev && rev <= mc->hdr.patch_id) {
if (!__apply_microcode_amd(mc)) {
*new_rev = mc->hdr.patch_id;
return;