| From e7ad18d1169c62e6c78c01ff693fd362d9d65278 Mon Sep 17 00:00:00 2001 |
| From: Borislav Petkov <bp@suse.de> |
| Date: Wed, 5 Oct 2022 12:00:08 +0200 |
| Subject: x86/microcode/AMD: Apply the patch early on every logical thread |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Borislav Petkov <bp@suse.de> |
| |
| commit e7ad18d1169c62e6c78c01ff693fd362d9d65278 upstream. |
| |
| 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@yahoo.com> |
| Signed-off-by: Borislav Petkov <bp@suse.de> |
| Tested-by: Ștefan Talpalaru <stefantalpalaru@yahoo.com> |
| Cc: <stable@vger.kernel.org> |
| Link: https://bugzilla.kernel.org/show_bug.cgi?id=216211 |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/kernel/cpu/microcode/amd.c | 16 +++++++++++++--- |
| 1 file changed, 13 insertions(+), 3 deletions(-) |
| |
| --- a/arch/x86/kernel/cpu/microcode/amd.c |
| +++ b/arch/x86/kernel/cpu/microcode/amd.c |
| @@ -441,7 +441,13 @@ apply_microcode_early_amd(u32 cpuid_1_ea |
| 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)) { |
| @@ -523,8 +529,12 @@ void load_ucode_amd_ap(unsigned int cpui |
| |
| 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; |