Skip to content

Commit 58ac609

Browse files
committed
Merge tag 'x86_urgent_for_v6.13_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Borislav Petkov: - Add a terminating zero end-element to the array describing AMD CPUs affected by erratum 1386 so that the matching loop actually terminates instead of going off into the weeds - Update the boot protocol documentation to mention the fact that the preferred address to load the kernel to is considered in the relocatable kernel case too - Flush the memory buffer containing the microcode patch after applying microcode on AMD Zen1 and Zen2, to avoid unnecessary slowdowns - Make sure the PPIN CPU feature flag is cleared on all CPUs if PPIN has been disabled * tag 'x86_urgent_for_v6.13_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/CPU/AMD: Terminate the erratum_1386_microcode array x86/Documentation: Update algo in init_size description of boot protocol x86/microcode/AMD: Flush patch buffer mapping after application x86/mm: Carve out INVLPG inline asm for use by others x86/cpu: Fix PPIN initialization
2 parents 9022ed0 + ff6cdc4 commit 58ac609

File tree

6 files changed

+41
-11
lines changed

6 files changed

+41
-11
lines changed

Documentation/arch/x86/boot.rst

+13-4
Original file line numberDiff line numberDiff line change
@@ -896,10 +896,19 @@ Offset/size: 0x260/4
896896

897897
The kernel runtime start address is determined by the following algorithm::
898898

899-
if (relocatable_kernel)
900-
runtime_start = align_up(load_address, kernel_alignment)
901-
else
902-
runtime_start = pref_address
899+
if (relocatable_kernel) {
900+
if (load_address < pref_address)
901+
load_address = pref_address;
902+
runtime_start = align_up(load_address, kernel_alignment);
903+
} else {
904+
runtime_start = pref_address;
905+
}
906+
907+
Hence the necessary memory window location and size can be estimated by
908+
a boot loader as::
909+
910+
memory_window_start = runtime_start;
911+
memory_window_size = init_size;
903912

904913
============ ===============
905914
Field name: handover_offset

arch/x86/include/asm/tlb.h

+4
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,8 @@ static inline void __tlb_remove_table(void *table)
3434
free_page_and_swap_cache(table);
3535
}
3636

37+
static inline void invlpg(unsigned long addr)
38+
{
39+
asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
40+
}
3741
#endif /* _ASM_X86_TLB_H */

arch/x86/kernel/cpu/amd.c

+1
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c)
798798
static const struct x86_cpu_desc erratum_1386_microcode[] = {
799799
AMD_CPU_DESC(0x17, 0x1, 0x2, 0x0800126e),
800800
AMD_CPU_DESC(0x17, 0x31, 0x0, 0x08301052),
801+
{},
801802
};
802803

803804
static void fix_erratum_1386(struct cpuinfo_x86 *c)

arch/x86/kernel/cpu/common.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ static void ppin_init(struct cpuinfo_x86 *c)
169169
}
170170

171171
clear_ppin:
172-
clear_cpu_cap(c, info->feature);
172+
setup_clear_cpu_cap(info->feature);
173173
}
174174

175175
static void default_init(struct cpuinfo_x86 *c)

arch/x86/kernel/cpu/microcode/amd.c

+20-5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <asm/setup.h>
3535
#include <asm/cpu.h>
3636
#include <asm/msr.h>
37+
#include <asm/tlb.h>
3738

3839
#include "internal.h"
3940

@@ -483,11 +484,25 @@ static void scan_containers(u8 *ucode, size_t size, struct cont_desc *desc)
483484
}
484485
}
485486

486-
static int __apply_microcode_amd(struct microcode_amd *mc)
487+
static int __apply_microcode_amd(struct microcode_amd *mc, unsigned int psize)
487488
{
489+
unsigned long p_addr = (unsigned long)&mc->hdr.data_code;
488490
u32 rev, dummy;
489491

490-
native_wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc->hdr.data_code);
492+
native_wrmsrl(MSR_AMD64_PATCH_LOADER, p_addr);
493+
494+
if (x86_family(bsp_cpuid_1_eax) == 0x17) {
495+
unsigned long p_addr_end = p_addr + psize - 1;
496+
497+
invlpg(p_addr);
498+
499+
/*
500+
* Flush next page too if patch image is crossing a page
501+
* boundary.
502+
*/
503+
if (p_addr >> PAGE_SHIFT != p_addr_end >> PAGE_SHIFT)
504+
invlpg(p_addr_end);
505+
}
491506

492507
/* verify patch application was successful */
493508
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)
529544
if (old_rev > mc->hdr.patch_id)
530545
return ret;
531546

532-
return !__apply_microcode_amd(mc);
547+
return !__apply_microcode_amd(mc, desc.psize);
533548
}
534549

535550
static bool get_builtin_microcode(struct cpio_data *cp)
@@ -745,7 +760,7 @@ void reload_ucode_amd(unsigned int cpu)
745760
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
746761

747762
if (rev < mc->hdr.patch_id) {
748-
if (!__apply_microcode_amd(mc))
763+
if (!__apply_microcode_amd(mc, p->size))
749764
pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id);
750765
}
751766
}
@@ -798,7 +813,7 @@ static enum ucode_state apply_microcode_amd(int cpu)
798813
goto out;
799814
}
800815

801-
if (__apply_microcode_amd(mc_amd)) {
816+
if (__apply_microcode_amd(mc_amd, p->size)) {
802817
pr_err("CPU%d: update failed for patch_level=0x%08x\n",
803818
cpu, mc_amd->hdr.patch_id);
804819
return UCODE_ERROR;

arch/x86/mm/tlb.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <asm/cacheflush.h>
2121
#include <asm/apic.h>
2222
#include <asm/perf_event.h>
23+
#include <asm/tlb.h>
2324

2425
#include "mm_internal.h"
2526

@@ -1140,7 +1141,7 @@ STATIC_NOPV void native_flush_tlb_one_user(unsigned long addr)
11401141
bool cpu_pcide;
11411142

11421143
/* Flush 'addr' from the kernel PCID: */
1143-
asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
1144+
invlpg(addr);
11441145

11451146
/* If PTI is off there is no user PCID and nothing to flush. */
11461147
if (!static_cpu_has(X86_FEATURE_PTI))

0 commit comments

Comments
 (0)