Skip to content

Commit c23719a

Browse files
committed
Merge tag 'x86-urgent-2026-03-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar: - Fix SEV guest boot failures in certain circumstances, due to very early code relying on a BSS-zeroed variable that isn't actually zeroed yet an may contain non-zero bootup values Move the variable into the .data section go gain even earlier zeroing - Expose & allow the IBPB-on-Entry feature on SNP guests, which was not properly exposed to guests due to initial implementational caution - Fix O= build failure when CONFIG_EFI_SBAT_FILE is using relative file paths - Fix the various SNC (Sub-NUMA Clustering) topology enumeration bugs/artifacts (sched-domain build errors mostly). SNC enumeration data got more complicated with Granite Rapids X (GNR) and Clearwater Forest X (CWF), which exposed these bugs and made their effects more serious - Also use the now sane(r) SNC code to fix resctrl SNC detection bugs - Work around a historic libgcc unwinder bug in the vdso32 sigreturn code (again), which regressed during an overly aggressive recent cleanup of DWARF annotations * tag 'x86-urgent-2026-03-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/entry/vdso32: Work around libgcc unwinder bug x86/resctrl: Fix SNC detection x86/topo: Fix SNC topology mess x86/topo: Replace x86_has_numa_in_package x86/topo: Add topology_num_nodes_per_package() x86/numa: Store extra copy of numa_nodes_parsed x86/boot: Handle relative CONFIG_EFI_SBAT_FILE file paths x86/sev: Allow IBPB-on-Entry feature for SNP guests x86/boot/sev: Move SEV decompressor variables into the .data section
2 parents 6ff1020 + b5ef09a commit c23719a

14 files changed

Lines changed: 228 additions & 95 deletions

File tree

arch/x86/boot/compressed/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ vmlinux-objs-$(CONFIG_EFI_SBAT) += $(obj)/sbat.o
113113

114114
ifdef CONFIG_EFI_SBAT
115115
$(obj)/sbat.o: $(CONFIG_EFI_SBAT_FILE)
116+
AFLAGS_sbat.o += -I $(srctree)
116117
endif
117118

118119
$(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE

arch/x86/boot/compressed/sev.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@
2828
#include "sev.h"
2929

3030
static struct ghcb boot_ghcb_page __aligned(PAGE_SIZE);
31-
struct ghcb *boot_ghcb;
31+
struct ghcb *boot_ghcb __section(".data");
3232

3333
#undef __init
3434
#define __init
3535

3636
#define __BOOT_COMPRESSED
3737

38-
u8 snp_vmpl;
39-
u16 ghcb_version;
38+
u8 snp_vmpl __section(".data");
39+
u16 ghcb_version __section(".data");
4040

41-
u64 boot_svsm_caa_pa;
41+
u64 boot_svsm_caa_pa __section(".data");
4242

4343
/* Include code for early handlers */
4444
#include "../../boot/startup/sev-shared.c"
@@ -188,6 +188,7 @@ bool sev_es_check_ghcb_fault(unsigned long address)
188188
MSR_AMD64_SNP_RESERVED_BIT13 | \
189189
MSR_AMD64_SNP_RESERVED_BIT15 | \
190190
MSR_AMD64_SNP_SECURE_AVIC | \
191+
MSR_AMD64_SNP_RESERVED_BITS19_22 | \
191192
MSR_AMD64_SNP_RESERVED_MASK)
192193

193194
#ifdef CONFIG_AMD_SECURE_AVIC

arch/x86/boot/startup/sev-shared.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static u32 cpuid_std_range_max __ro_after_init;
3131
static u32 cpuid_hyp_range_max __ro_after_init;
3232
static u32 cpuid_ext_range_max __ro_after_init;
3333

34-
bool sev_snp_needs_sfw;
34+
bool sev_snp_needs_sfw __section(".data");
3535

3636
void __noreturn
3737
sev_es_terminate(unsigned int set, unsigned int reason)

arch/x86/coco/sev/core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static const char * const sev_status_feat_names[] = {
8989
[MSR_AMD64_SNP_VMSA_REG_PROT_BIT] = "VMSARegProt",
9090
[MSR_AMD64_SNP_SMT_PROT_BIT] = "SMTProt",
9191
[MSR_AMD64_SNP_SECURE_AVIC_BIT] = "SecureAVIC",
92+
[MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT] = "IBPBOnEntry",
9293
};
9394

9495
/*

arch/x86/entry/vdso/vdso32/sigreturn.S

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,38 @@
3535
#endif
3636
.endm
3737

38+
/*
39+
* WARNING:
40+
*
41+
* A bug in the libgcc unwinder as of at least gcc 15.2 (2026) means that
42+
* the unwinder fails to recognize the signal frame flag.
43+
*
44+
* There is a hacky legacy fallback path in libgcc which ends up
45+
* getting invoked instead. It happens to work as long as BOTH of the
46+
* following conditions are true:
47+
*
48+
* 1. There is at least one byte before the each of the sigreturn
49+
* functions which falls outside any function. This is enforced by
50+
* an explicit nop instruction before the ALIGN.
51+
* 2. The code sequences between the entry point up to and including
52+
* the int $0x80 below need to match EXACTLY. Do not change them
53+
* in any way. The exact byte sequences are:
54+
*
55+
* __kernel_sigreturn:
56+
* 0: 58 pop %eax
57+
* 1: b8 77 00 00 00 mov $0x77,%eax
58+
* 6: cd 80 int $0x80
59+
*
60+
* __kernel_rt_sigreturn:
61+
* 0: b8 ad 00 00 00 mov $0xad,%eax
62+
* 5: cd 80 int $0x80
63+
*
64+
* For details, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124050
65+
*/
3866
.text
3967
.globl __kernel_sigreturn
4068
.type __kernel_sigreturn,@function
69+
nop /* libgcc hack: see comment above */
4170
ALIGN
4271
__kernel_sigreturn:
4372
STARTPROC_SIGNAL_FRAME IA32_SIGFRAME_sigcontext
@@ -52,6 +81,7 @@ SYM_INNER_LABEL(vdso32_sigreturn_landing_pad, SYM_L_GLOBAL)
5281

5382
.globl __kernel_rt_sigreturn
5483
.type __kernel_rt_sigreturn,@function
84+
nop /* libgcc hack: see comment above */
5585
ALIGN
5686
__kernel_rt_sigreturn:
5787
STARTPROC_SIGNAL_FRAME IA32_RT_SIGFRAME_sigcontext

arch/x86/include/asm/msr-index.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,10 @@
740740
#define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
741741
#define MSR_AMD64_SNP_SECURE_AVIC_BIT 18
742742
#define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
743-
#define MSR_AMD64_SNP_RESV_BIT 19
743+
#define MSR_AMD64_SNP_RESERVED_BITS19_22 GENMASK_ULL(22, 19)
744+
#define MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT 23
745+
#define MSR_AMD64_SNP_IBPB_ON_ENTRY BIT_ULL(MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT)
746+
#define MSR_AMD64_SNP_RESV_BIT 24
744747
#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
745748
#define MSR_AMD64_SAVIC_CONTROL 0xc0010138
746749
#define MSR_AMD64_SAVIC_EN_BIT 0

arch/x86/include/asm/numa.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern int numa_off;
2222
*/
2323
extern s16 __apicid_to_node[MAX_LOCAL_APIC];
2424
extern nodemask_t numa_nodes_parsed __initdata;
25+
extern nodemask_t numa_phys_nodes_parsed __initdata;
2526

2627
static inline void set_apicid_to_node(int apicid, s16 node)
2728
{
@@ -48,13 +49,18 @@ extern void __init init_cpu_to_node(void);
4849
extern void numa_add_cpu(unsigned int cpu);
4950
extern void numa_remove_cpu(unsigned int cpu);
5051
extern void init_gi_nodes(void);
52+
extern int num_phys_nodes(void);
5153
#else /* CONFIG_NUMA */
5254
static inline void numa_set_node(int cpu, int node) { }
5355
static inline void numa_clear_node(int cpu) { }
5456
static inline void init_cpu_to_node(void) { }
5557
static inline void numa_add_cpu(unsigned int cpu) { }
5658
static inline void numa_remove_cpu(unsigned int cpu) { }
5759
static inline void init_gi_nodes(void) { }
60+
static inline int num_phys_nodes(void)
61+
{
62+
return 1;
63+
}
5864
#endif /* CONFIG_NUMA */
5965

6066
#ifdef CONFIG_DEBUG_PER_CPU_MAPS

arch/x86/include/asm/topology.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ extern unsigned int __max_logical_packages;
155155
extern unsigned int __max_threads_per_core;
156156
extern unsigned int __num_threads_per_package;
157157
extern unsigned int __num_cores_per_package;
158+
extern unsigned int __num_nodes_per_package;
158159

159160
const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c);
160161
enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c);
@@ -179,6 +180,11 @@ static inline unsigned int topology_num_threads_per_package(void)
179180
return __num_threads_per_package;
180181
}
181182

183+
static inline unsigned int topology_num_nodes_per_package(void)
184+
{
185+
return __num_nodes_per_package;
186+
}
187+
182188
#ifdef CONFIG_X86_LOCAL_APIC
183189
int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level);
184190
#else

arch/x86/kernel/cpu/common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ EXPORT_SYMBOL(__max_dies_per_package);
9595
unsigned int __max_logical_packages __ro_after_init = 1;
9696
EXPORT_SYMBOL(__max_logical_packages);
9797

98+
unsigned int __num_nodes_per_package __ro_after_init = 1;
99+
EXPORT_SYMBOL(__num_nodes_per_package);
100+
98101
unsigned int __num_cores_per_package __ro_after_init = 1;
99102
EXPORT_SYMBOL(__num_cores_per_package);
100103

arch/x86/kernel/cpu/resctrl/monitor.c

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ void arch_mon_domain_online(struct rdt_resource *r, struct rdt_l3_mon_domain *d)
364364
msr_clear_bit(MSR_RMID_SNC_CONFIG, 0);
365365
}
366366

367-
/* CPU models that support MSR_RMID_SNC_CONFIG */
367+
/* CPU models that support SNC and MSR_RMID_SNC_CONFIG */
368368
static const struct x86_cpu_id snc_cpu_ids[] __initconst = {
369369
X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
370370
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0),
@@ -375,40 +375,14 @@ static const struct x86_cpu_id snc_cpu_ids[] __initconst = {
375375
{}
376376
};
377377

378-
/*
379-
* There isn't a simple hardware bit that indicates whether a CPU is running
380-
* in Sub-NUMA Cluster (SNC) mode. Infer the state by comparing the
381-
* number of CPUs sharing the L3 cache with CPU0 to the number of CPUs in
382-
* the same NUMA node as CPU0.
383-
* It is not possible to accurately determine SNC state if the system is
384-
* booted with a maxcpus=N parameter. That distorts the ratio of SNC nodes
385-
* to L3 caches. It will be OK if system is booted with hyperthreading
386-
* disabled (since this doesn't affect the ratio).
387-
*/
388378
static __init int snc_get_config(void)
389379
{
390-
struct cacheinfo *ci = get_cpu_cacheinfo_level(0, RESCTRL_L3_CACHE);
391-
const cpumask_t *node0_cpumask;
392-
int cpus_per_node, cpus_per_l3;
393-
int ret;
394-
395-
if (!x86_match_cpu(snc_cpu_ids) || !ci)
396-
return 1;
380+
int ret = topology_num_nodes_per_package();
397381

398-
cpus_read_lock();
399-
if (num_online_cpus() != num_present_cpus())
400-
pr_warn("Some CPUs offline, SNC detection may be incorrect\n");
401-
cpus_read_unlock();
402-
403-
node0_cpumask = cpumask_of_node(cpu_to_node(0));
404-
405-
cpus_per_node = cpumask_weight(node0_cpumask);
406-
cpus_per_l3 = cpumask_weight(&ci->shared_cpu_map);
407-
408-
if (!cpus_per_node || !cpus_per_l3)
382+
if (ret > 1 && !x86_match_cpu(snc_cpu_ids)) {
383+
pr_warn("CoD enabled system? Resctrl not supported\n");
409384
return 1;
410-
411-
ret = cpus_per_l3 / cpus_per_node;
385+
}
412386

413387
/* sanity check: Only valid results are 1, 2, 3, 4, 6 */
414388
switch (ret) {

0 commit comments

Comments
 (0)