From d9bb40544653cf039fe79225ec1d742183e2339a Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Fri, 22 Nov 2024 15:42:12 -0800 Subject: x86/cpu: Fix PPIN initialization On systems that enumerate PPIN (protected processor inventory number) using CPUID, but where the BIOS locked the MSR to prevent access /proc/cpuinfo reports "intel_ppin" feature as present on all logical CPUs except for CPU 0. This happens because ppin_init() uses x86_match_cpu() to determine whether PPIN is supported. When called on CPU 0 the test for locked PPIN MSR results in: clear_cpu_cap(c, info->feature); This clears the X86 FEATURE bit in boot_cpu_data. When other CPUs are brought online the x86_match_cpu() fails, and the PPIN FEATURE bit remains set for those other CPUs. Fix by using setup_clear_cpu_cap() instead of clear_cpu_cap() which force clears the FEATURE bit for all CPUS. Reported-by: Adeel Ashad Signed-off-by: Tony Luck Signed-off-by: Ingo Molnar Link: https://lore.kernel.org/r/20241122234212.27451-1-tony.luck@intel.com --- arch/x86/kernel/cpu/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86') diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 06a516f6795b..d9d2d1915491 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -169,7 +169,7 @@ static void ppin_init(struct cpuinfo_x86 *c) } clear_ppin: - clear_cpu_cap(c, info->feature); + setup_clear_cpu_cap(info->feature); } static void default_init(struct cpuinfo_x86 *c) -- cgit v1.2.3 From f1d84b59cbb9547c243d93991acf187fdbe9fbe9 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Tue, 19 Nov 2024 12:21:32 +0100 Subject: x86/mm: Carve out INVLPG inline asm for use by others No functional changes. Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/ZyulbYuvrkshfsd2@antipodes --- arch/x86/include/asm/tlb.h | 4 ++++ arch/x86/mm/tlb.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/x86') diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index 580636cdc257..4d3c9d00d6b6 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h @@ -34,4 +34,8 @@ static inline void __tlb_remove_table(void *table) 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 */ diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index b0d5a644fc84..a2becb85bea7 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "mm_internal.h" @@ -1140,7 +1141,7 @@ STATIC_NOPV void native_flush_tlb_one_user(unsigned long addr) 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)) -- cgit v1.2.3 From c809b0d0e52d01c30066367b2952c4c4186b1047 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Tue, 19 Nov 2024 12:21:33 +0100 Subject: x86/microcode/AMD: Flush patch buffer mapping after application 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 Signed-off-by: Borislav Petkov (AMD) Tested-by: Thomas De Schampheleire Cc: # f1d84b59cbb9 ("x86/mm: Carve out INVLPG inline asm for use by others") Link: https://lore.kernel.org/r/ZyulbYuvrkshfsd2@antipodes --- arch/x86/kernel/cpu/microcode/amd.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'arch/x86') diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 31a73715d755..fb5d0c67fbab 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "internal.h" @@ -483,11 +484,25 @@ static void scan_containers(u8 *ucode, size_t size, struct cont_desc *desc) } } -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 old_rev, void *ucode, size_t size) 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_amd(int cpu) 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; -- cgit v1.2.3 From ff6cdc407f4179748f4673c39b0921503199a0ad Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 26 Nov 2024 14:47:22 +0100 Subject: x86/CPU/AMD: Terminate the erratum_1386_microcode array The erratum_1386_microcode array requires an empty entry at the end. Otherwise x86_match_cpu_with_stepping() will continue iterate the array after it ended. Add an empty entry to erratum_1386_microcode to its end. Fixes: 29ba89f189528 ("x86/CPU/AMD: Improve the erratum 1386 workaround") Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Borislav Petkov (AMD) Cc: Link: https://lore.kernel.org/r/20241126134722.480975-1-bigeasy@linutronix.de --- arch/x86/kernel/cpu/amd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/x86') diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 823f44f7bc94..d8408aafeed9 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -798,6 +798,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c) static const struct x86_cpu_desc erratum_1386_microcode[] = { AMD_CPU_DESC(0x17, 0x1, 0x2, 0x0800126e), AMD_CPU_DESC(0x17, 0x31, 0x0, 0x08301052), + {}, }; static void fix_erratum_1386(struct cpuinfo_x86 *c) -- cgit v1.2.3