--- /dev/null
+From c809b0d0e52d01c30066367b2952c4c4186b1047 Mon Sep 17 00:00:00 2001
+From: "Borislav Petkov (AMD)" <bp@alien8.de>
+Date: Tue, 19 Nov 2024 12:21:33 +0100
+Subject: x86/microcode/AMD: Flush patch buffer mapping after application
+
+From: Borislav Petkov (AMD) <bp@alien8.de>
+
+commit c809b0d0e52d01c30066367b2952c4c4186b1047 upstream.
+
+Due to specific requirements while applying microcode patches on Zen1
+and 2, the patch buffer mapping needs to be flushed from the TLB after
+application. Do so.
+
+If not, unnecessary and unnatural delays happen in the boot process.
+
+Reported-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Tested-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
+Cc: <stable@kernel.org> # f1d84b59cbb9 ("x86/mm: Carve out INVLPG inline asm for use by others")
+Link: https://lore.kernel.org/r/ZyulbYuvrkshfsd2@antipodes
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/cpu/microcode/amd.c | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -34,6 +34,7 @@
+ #include <asm/setup.h>
+ #include <asm/cpu.h>
+ #include <asm/msr.h>
++#include <asm/tlb.h>
+
+ #include "internal.h"
+
+@@ -483,11 +484,25 @@ static void scan_containers(u8 *ucode, s
+ }
+ }
+
+-static int __apply_microcode_amd(struct microcode_amd *mc)
++static int __apply_microcode_amd(struct microcode_amd *mc, unsigned int psize)
+ {
++ unsigned long p_addr = (unsigned long)&mc->hdr.data_code;
+ u32 rev, dummy;
+
+- native_wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc->hdr.data_code);
++ native_wrmsrl(MSR_AMD64_PATCH_LOADER, p_addr);
++
++ if (x86_family(bsp_cpuid_1_eax) == 0x17) {
++ unsigned long p_addr_end = p_addr + psize - 1;
++
++ invlpg(p_addr);
++
++ /*
++ * Flush next page too if patch image is crossing a page
++ * boundary.
++ */
++ if (p_addr >> PAGE_SHIFT != p_addr_end >> PAGE_SHIFT)
++ invlpg(p_addr_end);
++ }
+
+ /* verify patch application was successful */
+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+@@ -529,7 +544,7 @@ static bool early_apply_microcode(u32 ol
+ if (old_rev > mc->hdr.patch_id)
+ return ret;
+
+- return !__apply_microcode_amd(mc);
++ return !__apply_microcode_amd(mc, desc.psize);
+ }
+
+ static bool get_builtin_microcode(struct cpio_data *cp)
+@@ -745,7 +760,7 @@ void reload_ucode_amd(unsigned int cpu)
+ rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+
+ if (rev < mc->hdr.patch_id) {
+- if (!__apply_microcode_amd(mc))
++ if (!__apply_microcode_amd(mc, p->size))
+ pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id);
+ }
+ }
+@@ -798,7 +813,7 @@ static enum ucode_state apply_microcode_
+ goto out;
+ }
+
+- if (__apply_microcode_amd(mc_amd)) {
++ if (__apply_microcode_amd(mc_amd, p->size)) {
+ pr_err("CPU%d: update failed for patch_level=0x%08x\n",
+ cpu, mc_amd->hdr.patch_id);
+ return UCODE_ERROR;
--- /dev/null
+From f1d84b59cbb9547c243d93991acf187fdbe9fbe9 Mon Sep 17 00:00:00 2001
+From: "Borislav Petkov (AMD)" <bp@alien8.de>
+Date: Tue, 19 Nov 2024 12:21:32 +0100
+Subject: x86/mm: Carve out INVLPG inline asm for use by others
+
+From: Borislav Petkov (AMD) <bp@alien8.de>
+
+commit f1d84b59cbb9547c243d93991acf187fdbe9fbe9 upstream.
+
+No functional changes.
+
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/ZyulbYuvrkshfsd2@antipodes
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/tlb.h | 4 ++++
+ arch/x86/mm/tlb.c | 3 ++-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/tlb.h
++++ b/arch/x86/include/asm/tlb.h
+@@ -34,4 +34,8 @@ static inline void __tlb_remove_table(vo
+ free_page_and_swap_cache(table);
+ }
+
++static inline void invlpg(unsigned long addr)
++{
++ asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
++}
+ #endif /* _ASM_X86_TLB_H */
+--- a/arch/x86/mm/tlb.c
++++ b/arch/x86/mm/tlb.c
+@@ -20,6 +20,7 @@
+ #include <asm/cacheflush.h>
+ #include <asm/apic.h>
+ #include <asm/perf_event.h>
++#include <asm/tlb.h>
+
+ #include "mm_internal.h"
+
+@@ -1140,7 +1141,7 @@ STATIC_NOPV void native_flush_tlb_one_us
+ bool cpu_pcide;
+
+ /* Flush 'addr' from the kernel PCID: */
+- asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
++ invlpg(addr);
+
+ /* If PTI is off there is no user PCID and nothing to flush. */
+ if (!static_cpu_has(X86_FEATURE_PTI))