Skip to content

Commit eb55307

Browse files
committed
Merge tag 'x86-core-2023-10-29-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 core updates from Thomas Gleixner: - Limit the hardcoded topology quirk for Hygon CPUs to those which have a model ID less than 4. The newer models have the topology CPUID leaf 0xB correctly implemented and are not affected. - Make SMT control more robust against enumeration failures SMT control was added to allow controlling SMT at boottime or runtime. The primary purpose was to provide a simple mechanism to disable SMT in the light of speculation attack vectors. It turned out that the code is sensible to enumeration failures and worked only by chance for XEN/PV. XEN/PV has no real APIC enumeration which means the primary thread mask is not set up correctly. By chance a XEN/PV boot ends up with smp_num_siblings == 2, which makes the hotplug control stay at its default value "enabled". So the mask is never evaluated. The ongoing rework of the topology evaluation caused XEN/PV to end up with smp_num_siblings == 1, which sets the SMT control to "not supported" and the empty primary thread mask causes the hotplug core to deny the bringup of the APS. Make the decision logic more robust and take 'not supported' and 'not implemented' into account for the decision whether a CPU should be booted or not. - Fake primary thread mask for XEN/PV Pretend that all XEN/PV vCPUs are primary threads, which makes the usage of the primary thread mask valid on XEN/PV. That is consistent with because all of the topology information on XEN/PV is fake or even non-existent. - Encapsulate topology information in cpuinfo_x86 Move the randomly scattered topology data into a separate data structure for readability and as a preparatory step for the topology evaluation overhaul. - Consolidate APIC ID data type to u32 It's fixed width hardware data and not randomly u16, int, unsigned long or whatever developers decided to use. - Cure the abuse of cpuinfo for persisting logical IDs. Per CPU cpuinfo is used to persist the logical package and die IDs. That's really not the right place simply because cpuinfo is subject to be reinitialized when a CPU goes through an offline/online cycle. Use separate per CPU data for the persisting to enable the further topology management rework. It will be removed once the new topology management is in place. - Provide a debug interface for inspecting topology information Useful in general and extremly helpful for validating the topology management rework in terms of correctness or "bug" compatibility. * tag 'x86-core-2023-10-29-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits) x86/apic, x86/hyperv: Use u32 in hv_snp_boot_ap() too x86/cpu: Provide debug interface x86/cpu/topology: Cure the abuse of cpuinfo for persisting logical ids x86/apic: Use u32 for wakeup_secondary_cpu[_64]() x86/apic: Use u32 for [gs]et_apic_id() x86/apic: Use u32 for phys_pkg_id() x86/apic: Use u32 for cpu_present_to_apicid() x86/apic: Use u32 for check_apicid_used() x86/apic: Use u32 for APIC IDs in global data x86/apic: Use BAD_APICID consistently x86/cpu: Move cpu_l[l2]c_id into topology info x86/cpu: Move logical package and die IDs into topology info x86/cpu: Remove pointless evaluation of x86_coreid_bits x86/cpu: Move cu_id into topology info x86/cpu: Move cpu_core_id into topology info hwmon: (fam15h_power) Use topology_core_id() scsi: lpfc: Use topology_core_id() x86/cpu: Move cpu_die_id into topology info x86/cpu: Move phys_proc_id into topology info x86/cpu: Encapsulate topology information in cpuinfo_x86 ...
2 parents 943af0e + 92fe9bb commit eb55307

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+371
-316
lines changed

Documentation/arch/x86/topology.rst

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,19 @@ Package-related topology information in the kernel:
5555

5656
The number of dies in a package. This information is retrieved via CPUID.
5757

58-
- cpuinfo_x86.cpu_die_id:
58+
- cpuinfo_x86.topo.die_id:
5959

6060
The physical ID of the die. This information is retrieved via CPUID.
6161

62-
- cpuinfo_x86.phys_proc_id:
62+
- cpuinfo_x86.topo.pkg_id:
6363

6464
The physical ID of the package. This information is retrieved via CPUID
6565
and deduced from the APIC IDs of the cores in the package.
6666

6767
Modern systems use this value for the socket. There may be multiple
68-
packages within a socket. This value may differ from cpu_die_id.
68+
packages within a socket. This value may differ from topo.die_id.
6969

70-
- cpuinfo_x86.logical_proc_id:
70+
- cpuinfo_x86.topo.logical_pkg_id:
7171

7272
The logical ID of the package. As we do not trust BIOSes to enumerate the
7373
packages in a consistent way, we introduced the concept of logical package
@@ -79,9 +79,7 @@ Package-related topology information in the kernel:
7979
The maximum possible number of packages in the system. Helpful for per
8080
package facilities to preallocate per package information.
8181

82-
- cpu_llc_id:
83-
84-
A per-CPU variable containing:
82+
- cpuinfo_x86.topo.llc_id:
8583

8684
- On Intel, the first APIC ID of the list of CPUs sharing the Last Level
8785
Cache

arch/x86/events/amd/uncore.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ void amd_uncore_l3_ctx_scan(struct amd_uncore *uncore, unsigned int cpu)
772772
info.split.aux_data = 0;
773773
info.split.num_pmcs = NUM_COUNTERS_L2;
774774
info.split.gid = 0;
775-
info.split.cid = get_llc_id(cpu);
775+
info.split.cid = per_cpu_llc_id(cpu);
776776

777777
if (boot_cpu_data.x86 >= 0x17)
778778
info.split.num_pmcs = NUM_COUNTERS_L3;

arch/x86/events/intel/uncore.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ int uncore_device_to_die(struct pci_dev *dev)
7474
struct cpuinfo_x86 *c = &cpu_data(cpu);
7575

7676
if (c->initialized && cpu_to_node(cpu) == node)
77-
return c->logical_die_id;
77+
return c->topo.logical_die_id;
7878
}
7979

8080
return -1;

arch/x86/hyperv/hv_vtl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ static int hv_vtl_apicid_to_vp_id(u32 apic_id)
196196
return ret;
197197
}
198198

199-
static int hv_vtl_wakeup_secondary_cpu(int apicid, unsigned long start_eip)
199+
static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
200200
{
201201
int vp_id;
202202

arch/x86/hyperv/ivm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa)
288288
free_page((unsigned long)vmsa);
289289
}
290290

291-
int hv_snp_boot_ap(int cpu, unsigned long start_ip)
291+
int hv_snp_boot_ap(u32 cpu, unsigned long start_ip)
292292
{
293293
struct sev_es_save_area *vmsa = (struct sev_es_save_area *)
294294
__get_free_page(GFP_KERNEL | __GFP_ZERO);

arch/x86/include/asm/apic.h

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ extern int local_apic_timer_c2_ok;
5454
extern bool apic_is_disabled;
5555
extern unsigned int lapic_timer_period;
5656

57-
extern int cpuid_to_apicid[];
57+
extern u32 cpuid_to_apicid[];
5858

5959
extern enum apic_intr_mode_id apic_intr_mode;
6060
enum apic_intr_mode_id {
@@ -292,19 +292,19 @@ struct apic {
292292
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
293293
bool (*apic_id_registered)(void);
294294

295-
bool (*check_apicid_used)(physid_mask_t *map, int apicid);
295+
bool (*check_apicid_used)(physid_mask_t *map, u32 apicid);
296296
void (*init_apic_ldr)(void);
297297
void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
298-
int (*cpu_present_to_apicid)(int mps_cpu);
299-
int (*phys_pkg_id)(int cpuid_apic, int index_msb);
298+
u32 (*cpu_present_to_apicid)(int mps_cpu);
299+
u32 (*phys_pkg_id)(u32 cpuid_apic, int index_msb);
300300

301-
u32 (*get_apic_id)(unsigned long x);
302-
u32 (*set_apic_id)(unsigned int id);
301+
u32 (*get_apic_id)(u32 id);
302+
u32 (*set_apic_id)(u32 apicid);
303303

304304
/* wakeup_secondary_cpu */
305-
int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
305+
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
306306
/* wakeup secondary CPU using 64-bit wakeup point */
307-
int (*wakeup_secondary_cpu_64)(int apicid, unsigned long start_eip);
307+
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip);
308308

309309
char *name;
310310
};
@@ -322,8 +322,8 @@ struct apic_override {
322322
void (*send_IPI_self)(int vector);
323323
u64 (*icr_read)(void);
324324
void (*icr_write)(u32 low, u32 high);
325-
int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
326-
int (*wakeup_secondary_cpu_64)(int apicid, unsigned long start_eip);
325+
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
326+
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip);
327327
};
328328

329329
/*
@@ -493,16 +493,6 @@ static inline bool lapic_vector_set_in_irr(unsigned int vector)
493493
return !!(irr & (1U << (vector % 32)));
494494
}
495495

496-
static inline unsigned default_get_apic_id(unsigned long x)
497-
{
498-
unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
499-
500-
if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
501-
return (x >> 24) & 0xFF;
502-
else
503-
return (x >> 24) & 0x0F;
504-
}
505-
506496
/*
507497
* Warm reset vector position:
508498
*/
@@ -517,9 +507,9 @@ extern void generic_bigsmp_probe(void);
517507

518508
extern struct apic apic_noop;
519509

520-
static inline unsigned int read_apic_id(void)
510+
static inline u32 read_apic_id(void)
521511
{
522-
unsigned int reg = apic_read(APIC_ID);
512+
u32 reg = apic_read(APIC_ID);
523513

524514
return apic->get_apic_id(reg);
525515
}
@@ -538,13 +528,12 @@ extern int default_apic_id_valid(u32 apicid);
538528
extern u32 apic_default_calc_apicid(unsigned int cpu);
539529
extern u32 apic_flat_calc_apicid(unsigned int cpu);
540530

541-
extern bool default_check_apicid_used(physid_mask_t *map, int apicid);
542531
extern void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap);
543-
extern int default_cpu_present_to_apicid(int mps_cpu);
532+
extern u32 default_cpu_present_to_apicid(int mps_cpu);
544533

545534
#else /* CONFIG_X86_LOCAL_APIC */
546535

547-
static inline unsigned int read_apic_id(void) { return 0; }
536+
static inline u32 read_apic_id(void) { return 0; }
548537

549538
#endif /* !CONFIG_X86_LOCAL_APIC */
550539

arch/x86/include/asm/cacheinfo.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ extern unsigned int memory_caching_control;
77
#define CACHE_MTRR 0x01
88
#define CACHE_PAT 0x02
99

10-
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu);
11-
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu);
12-
1310
void cache_disable(void);
1411
void cache_enable(void);
1512
void set_cache_aps_delayed_init(bool val);

arch/x86/include/asm/mpspec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ extern int mp_bus_id_to_type[MAX_MP_BUSSES];
3737

3838
extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
3939

40-
extern unsigned int boot_cpu_physical_apicid;
40+
extern u32 boot_cpu_physical_apicid;
4141
extern u8 boot_cpu_apic_version;
4242

4343
#ifdef CONFIG_X86_LOCAL_APIC

arch/x86/include/asm/mshyperv.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,11 @@ int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
276276
#ifdef CONFIG_AMD_MEM_ENCRYPT
277277
bool hv_ghcb_negotiate_protocol(void);
278278
void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
279-
int hv_snp_boot_ap(int cpu, unsigned long start_ip);
279+
int hv_snp_boot_ap(u32 cpu, unsigned long start_ip);
280280
#else
281281
static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
282282
static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
283-
static inline int hv_snp_boot_ap(int cpu, unsigned long start_ip) { return 0; }
283+
static inline int hv_snp_boot_ap(u32 cpu, unsigned long start_ip) { return 0; }
284284
#endif
285285

286286
#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)

arch/x86/include/asm/processor.h

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,36 @@ extern u16 __read_mostly tlb_lld_4m[NR_INFO];
7575
extern u16 __read_mostly tlb_lld_1g[NR_INFO];
7676

7777
/*
78-
* CPU type and hardware bug flags. Kept separately for each CPU.
79-
* Members of this structure are referenced in head_32.S, so think twice
80-
* before touching them. [mj]
78+
* CPU type and hardware bug flags. Kept separately for each CPU.
8179
*/
8280

81+
struct cpuinfo_topology {
82+
// Real APIC ID read from the local APIC
83+
u32 apicid;
84+
// The initial APIC ID provided by CPUID
85+
u32 initial_apicid;
86+
87+
// Physical package ID
88+
u32 pkg_id;
89+
90+
// Physical die ID on AMD, Relative on Intel
91+
u32 die_id;
92+
93+
// Compute unit ID - AMD specific
94+
u32 cu_id;
95+
96+
// Core ID relative to the package
97+
u32 core_id;
98+
99+
// Logical ID mappings
100+
u32 logical_pkg_id;
101+
u32 logical_die_id;
102+
103+
// Cache level topology IDs
104+
u32 llc_id;
105+
u32 l2c_id;
106+
};
107+
83108
struct cpuinfo_x86 {
84109
__u8 x86; /* CPU family */
85110
__u8 x86_vendor; /* CPU vendor */
@@ -96,7 +121,6 @@ struct cpuinfo_x86 {
96121
__u8 x86_phys_bits;
97122
/* CPUID returned core id bits: */
98123
__u8 x86_coreid_bits;
99-
__u8 cu_id;
100124
/* Max extended CPUID function supported: */
101125
__u32 extended_cpuid_level;
102126
/* Maximum supported CPUID level, -1=no CPUID: */
@@ -112,6 +136,7 @@ struct cpuinfo_x86 {
112136
};
113137
char x86_vendor_id[16];
114138
char x86_model_id[64];
139+
struct cpuinfo_topology topo;
115140
/* in KB - valid for CPUS which support this call: */
116141
unsigned int x86_cache_size;
117142
int x86_cache_alignment; /* In bytes */
@@ -125,19 +150,9 @@ struct cpuinfo_x86 {
125150
u64 ppin;
126151
/* cpuid returned max cores value: */
127152
u16 x86_max_cores;
128-
u16 apicid;
129-
u16 initial_apicid;
130153
u16 x86_clflush_size;
131154
/* number of cores as seen by the OS: */
132155
u16 booted_cores;
133-
/* Physical processor id: */
134-
u16 phys_proc_id;
135-
/* Logical processor id: */
136-
u16 logical_proc_id;
137-
/* Core id: */
138-
u16 cpu_core_id;
139-
u16 cpu_die_id;
140-
u16 logical_die_id;
141156
/* Index into per_cpu list: */
142157
u16 cpu_index;
143158
/* Is SMT active on this core? */
@@ -678,7 +693,15 @@ extern int set_tsc_mode(unsigned int val);
678693

679694
DECLARE_PER_CPU(u64, msr_misc_features_shadow);
680695

681-
extern u16 get_llc_id(unsigned int cpu);
696+
static inline u32 per_cpu_llc_id(unsigned int cpu)
697+
{
698+
return per_cpu(cpu_info.topo.llc_id, cpu);
699+
}
700+
701+
static inline u32 per_cpu_l2c_id(unsigned int cpu)
702+
{
703+
return per_cpu(cpu_info.topo.l2c_id, cpu);
704+
}
682705

683706
#ifdef CONFIG_CPU_SUP_AMD
684707
extern u32 amd_get_nodes_per_socket(void);

0 commit comments

Comments
 (0)