Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7d04aec
hwmon: (fam15h_power) Use topology_core_id()
KAGA-KOKO Aug 14, 2023
e28484f
x86/cpu: Move cpu_core_id into topology info
KAGA-KOKO Aug 14, 2023
234b9f4
x86/cpu: Move cu_id into topology info
KAGA-KOKO Aug 14, 2023
426bae9
x86/cpu: Remove pointless evaluation of x86_coreid_bits
KAGA-KOKO Aug 14, 2023
5a7a9f0
x86/cpu: Move logical package and die IDs into topology info
KAGA-KOKO Aug 14, 2023
67b9a75
x86/cpu: Move cpu_l[l2]c_id into topology info
KAGA-KOKO Aug 14, 2023
349c3e9
x86/apic: Use BAD_APICID consistently
KAGA-KOKO Aug 14, 2023
9e98b59
x86/apic: Use u32 for APIC IDs in global data
KAGA-KOKO Aug 14, 2023
44ba40b
x86/apic: Use u32 for check_apicid_used()
KAGA-KOKO Aug 14, 2023
e29b3e1
x86/apic: Use u32 for cpu_present_to_apicid()
KAGA-KOKO Aug 14, 2023
4eca1b0
x86/apic: Use u32 for phys_pkg_id()
KAGA-KOKO Aug 14, 2023
655645a
x86/apic: Use u32 for [gs]et_apic_id()
KAGA-KOKO Aug 14, 2023
c139358
x86/apic, x86/hyperv: Use u32 in hv_snp_boot_ap() too
Oct 13, 2023
537ea55
x86/apic: Use u32 for wakeup_secondary_cpu[_64]()
KAGA-KOKO Aug 14, 2023
eaa55af
x86/cpu/topology: Cure the abuse of cpuinfo for persisting logical ids
KAGA-KOKO Aug 14, 2023
d67fe5c
x86/cpu: Provide debug interface
KAGA-KOKO Aug 14, 2023
fc47edb
x86/cpu: Provide cpuid_read() et al.
KAGA-KOKO Feb 14, 2024
ff8cd17
x86/cpuid: Include <linux/build_bug.h> in <asm/cpuid.h>
Mar 4, 2025
db3b630
x86/cpu: Provide cpu_init/parse_topology()
KAGA-KOKO Feb 13, 2024
a686ce2
x86/cpu: Add legacy topology parser
KAGA-KOKO Feb 13, 2024
18c15cc
x86/cpu: Use common topology code for Centaur and Zhaoxin
KAGA-KOKO Feb 13, 2024
d077676
x86/cpu: Move __max_die_per_package to common.c
KAGA-KOKO Feb 13, 2024
a37ed92
x86/cpu: Provide a sane leaf 0xb/0x1f parser
KAGA-KOKO Feb 13, 2024
8721dcd
x86/cpu: Use common topology code for Intel
KAGA-KOKO Feb 13, 2024
2fa0401
x86/topology/intel: Unlock CPUID before evaluating anything
KAGA-KOKO May 30, 2024
9ec594b
x86/cpu: Provide an AMD/HYGON specific topology parser
KAGA-KOKO Feb 13, 2024
e449ffa
x86/cpu/amd: Make the CPUID 0x80000008 parser correct
KAGA-KOKO Apr 10, 2024
2544fd5
x86/cpu/amd: Make the NODEID_MSR union actually work
KAGA-KOKO Apr 10, 2024
23d28d2
x86/cpu/amd: Move TOPOEXT enablement into the topology parser
KAGA-KOKO Apr 11, 2024
5302eb5
x86/topology/amd: Ensure that LLC ID is initialized
KAGA-KOKO May 8, 2024
fa1a39d
x86/topology/amd: Evaluate SMT in CPUID leaf 0x8000001e only on famil…
KAGA-KOKO May 28, 2024
cbba3cc
x86/smpboot: Teach it about topo.amd_node_id
KAGA-KOKO Feb 13, 2024
6133835
x86/cpu: Use common topology code for AMD
KAGA-KOKO Feb 13, 2024
70f7572
x86/cpu: Use common topology code for HYGON
KAGA-KOKO Feb 13, 2024
ac8dd1c
x86/mm/numa: Use core domain size on AMD
KAGA-KOKO Feb 13, 2024
3fce5d9
x86/cpu: Make topology_amd_node_id() use the actual node info
KAGA-KOKO Feb 13, 2024
bed7892
x86/cpu: Remove topology.c
KAGA-KOKO Feb 13, 2024
782bea5
x86/cpu: Remove x86_coreid_bits
KAGA-KOKO Feb 13, 2024
c61ea32
x86/apic: Remove unused phys_pkg_id() callback
KAGA-KOKO Feb 13, 2024
2f6c02f
x86/xen/smp_pv: Remove cpudata fiddling
KAGA-KOKO Feb 13, 2024
348260f
x86/apic/uv: Remove the private leaf 0xb parser
KAGA-KOKO Feb 13, 2024
8c7498e
x86/cpu/topology: Use initial APIC ID from XTOPOLOGY leaf on AMD/HYGON
kudureranganath Aug 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions Documentation/arch/x86/topology.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Package-related topology information in the kernel:
Modern systems use this value for the socket. There may be multiple
packages within a socket. This value may differ from topo.die_id.

- cpuinfo_x86.logical_proc_id:
- cpuinfo_x86.topo.logical_pkg_id:

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

- cpu_llc_id:

A per-CPU variable containing:
- cpuinfo_x86.topo.llc_id:

- On Intel, the first APIC ID of the list of CPUs sharing the Last Level
Cache
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/events/amd/uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ void amd_uncore_l3_ctx_scan(struct amd_uncore *uncore, unsigned int cpu)
info.split.aux_data = 0;
info.split.num_pmcs = NUM_COUNTERS_L2;
info.split.gid = 0;
info.split.cid = get_llc_id(cpu);
info.split.cid = per_cpu_llc_id(cpu);

if (boot_cpu_data.x86 >= 0x17)
info.split.num_pmcs = NUM_COUNTERS_L3;
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/events/intel/uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ int uncore_device_to_die(struct pci_dev *dev)
struct cpuinfo_x86 *c = &cpu_data(cpu);

if (c->initialized && cpu_to_node(cpu) == node)
return c->logical_die_id;
return c->topo.logical_die_id;
}

return -1;
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/hyperv/hv_vtl.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static int hv_vtl_apicid_to_vp_id(u32 apic_id)
return ret;
}

static int hv_vtl_wakeup_secondary_cpu(int apicid, unsigned long start_eip)
static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
{
int vp_id, cpu;

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/hyperv/ivm.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa)
free_page((unsigned long)vmsa);
}

int hv_snp_boot_ap(int cpu, unsigned long start_ip)
int hv_snp_boot_ap(u32 cpu, unsigned long start_ip)
{
struct sev_es_save_area *vmsa = (struct sev_es_save_area *)
__get_free_page(GFP_KERNEL | __GFP_ZERO);
Expand Down
38 changes: 13 additions & 25 deletions arch/x86/include/asm/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extern int local_apic_timer_c2_ok;
extern bool apic_is_disabled;
extern unsigned int lapic_timer_period;

extern int cpuid_to_apicid[];
extern u32 cpuid_to_apicid[];

extern enum apic_intr_mode_id apic_intr_mode;
enum apic_intr_mode_id {
Expand Down Expand Up @@ -294,19 +294,18 @@ struct apic {
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
bool (*apic_id_registered)(void);

bool (*check_apicid_used)(physid_mask_t *map, int apicid);
bool (*check_apicid_used)(physid_mask_t *map, u32 apicid);
void (*init_apic_ldr)(void);
void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
int (*cpu_present_to_apicid)(int mps_cpu);
int (*phys_pkg_id)(int cpuid_apic, int index_msb);
u32 (*cpu_present_to_apicid)(int mps_cpu);

u32 (*get_apic_id)(unsigned long x);
u32 (*set_apic_id)(unsigned int id);
u32 (*get_apic_id)(u32 id);
u32 (*set_apic_id)(u32 apicid);

/* wakeup_secondary_cpu */
int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
/* wakeup secondary CPU using 64-bit wakeup point */
int (*wakeup_secondary_cpu_64)(int apicid, unsigned long start_eip);
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip);

char *name;
};
Expand All @@ -324,8 +323,8 @@ struct apic_override {
void (*send_IPI_self)(int vector);
u64 (*icr_read)(void);
void (*icr_write)(u32 low, u32 high);
int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
int (*wakeup_secondary_cpu_64)(int apicid, unsigned long start_eip);
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip);
};

/*
Expand Down Expand Up @@ -495,16 +494,6 @@ static inline bool lapic_vector_set_in_irr(unsigned int vector)
return !!(irr & (1U << (vector % 32)));
}

static inline unsigned default_get_apic_id(unsigned long x)
{
unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));

if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
return (x >> 24) & 0xFF;
else
return (x >> 24) & 0x0F;
}

/*
* Warm reset vector position:
*/
Expand All @@ -519,9 +508,9 @@ extern void generic_bigsmp_probe(void);

extern struct apic apic_noop;

static inline unsigned int read_apic_id(void)
static inline u32 read_apic_id(void)
{
unsigned int reg = apic_read(APIC_ID);
u32 reg = apic_read(APIC_ID);

return apic->get_apic_id(reg);
}
Expand All @@ -540,15 +529,14 @@ extern int default_apic_id_valid(u32 apicid);
extern u32 apic_default_calc_apicid(unsigned int cpu);
extern u32 apic_flat_calc_apicid(unsigned int cpu);

extern bool default_check_apicid_used(physid_mask_t *map, int apicid);
extern void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap);
extern int default_cpu_present_to_apicid(int mps_cpu);
extern u32 default_cpu_present_to_apicid(int mps_cpu);

void apic_send_nmi_to_offline_cpu(unsigned int cpu);

#else /* CONFIG_X86_LOCAL_APIC */

static inline unsigned int read_apic_id(void) { return 0; }
static inline u32 read_apic_id(void) { return 0; }

#endif /* !CONFIG_X86_LOCAL_APIC */

Expand Down
3 changes: 0 additions & 3 deletions arch/x86/include/asm/cacheinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ extern unsigned int memory_caching_control;
#define CACHE_MTRR 0x01
#define CACHE_PAT 0x02

void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu);
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu);

void cache_disable(void);
void cache_enable(void);
void set_cache_aps_delayed_init(bool val);
Expand Down
37 changes: 37 additions & 0 deletions arch/x86/include/asm/cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#ifndef _ASM_X86_CPUID_H
#define _ASM_X86_CPUID_H

#include <linux/build_bug.h>
#include <asm/string.h>

struct cpuid_regs {
Expand Down Expand Up @@ -127,6 +128,42 @@ static inline unsigned int cpuid_edx(unsigned int op)
return edx;
}

static inline void __cpuid_read(unsigned int leaf, unsigned int subleaf, u32 *regs)
{
regs[CPUID_EAX] = leaf;
regs[CPUID_ECX] = subleaf;
__cpuid(regs + CPUID_EAX, regs + CPUID_EBX, regs + CPUID_ECX, regs + CPUID_EDX);
}

#define cpuid_subleaf(leaf, subleaf, regs) { \
static_assert(sizeof(*(regs)) == 16); \
__cpuid_read(leaf, subleaf, (u32 *)(regs)); \
}

#define cpuid_leaf(leaf, regs) { \
static_assert(sizeof(*(regs)) == 16); \
__cpuid_read(leaf, 0, (u32 *)(regs)); \
}

static inline void __cpuid_read_reg(unsigned int leaf, unsigned int subleaf,
enum cpuid_regs_idx regidx, u32 *reg)
{
u32 regs[4];

__cpuid_read(leaf, subleaf, regs);
*reg = regs[regidx];
}

#define cpuid_subleaf_reg(leaf, subleaf, regidx, reg) { \
static_assert(sizeof(*(reg)) == 4); \
__cpuid_read_reg(leaf, subleaf, regidx, (u32 *)(reg)); \
}

#define cpuid_leaf_reg(leaf, regidx, reg) { \
static_assert(sizeof(*(reg)) == 4); \
__cpuid_read_reg(leaf, 0, regidx, (u32 *)(reg)); \
}

static __always_inline bool cpuid_function_is_indexed(u32 function)
{
switch (function) {
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/mpspec.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ extern int mp_bus_id_to_type[MAX_MP_BUSSES];

extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);

extern unsigned int boot_cpu_physical_apicid;
extern u32 boot_cpu_physical_apicid;
extern u8 boot_cpu_apic_version;

#ifdef CONFIG_X86_LOCAL_APIC
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/include/asm/mshyperv.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,11 @@ int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
#ifdef CONFIG_AMD_MEM_ENCRYPT
bool hv_ghcb_negotiate_protocol(void);
void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
int hv_snp_boot_ap(int cpu, unsigned long start_ip);
int hv_snp_boot_ap(u32 cpu, unsigned long start_ip);
#else
static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
static inline int hv_snp_boot_ap(int cpu, unsigned long start_ip) { return 0; }
static inline int hv_snp_boot_ap(u32 cpu, unsigned long start_ip) { return 0; }
#endif

#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
Expand Down
33 changes: 22 additions & 11 deletions arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ struct cpuinfo_topology {
// AMD Node ID and Nodes per Package info
u32 amd_node_id;

// Compute unit ID - AMD specific
u32 cu_id;

// Core ID relative to the package
u32 core_id;

// Logical ID mappings
u32 logical_pkg_id;
u32 logical_die_id;

// Cache level topology IDs
u32 llc_id;
u32 l2c_id;
};

struct cpuinfo_x86 {
Expand Down Expand Up @@ -122,9 +135,6 @@ struct cpuinfo_x86 {
#endif
__u8 x86_virt_bits;
__u8 x86_phys_bits;
/* CPUID returned core id bits: */
__u8 x86_coreid_bits;
__u8 cu_id;
/* Max extended CPUID function supported: */
__u32 extended_cpuid_level;
/* Maximum supported CPUID level, -1=no CPUID: */
Expand Down Expand Up @@ -157,11 +167,6 @@ struct cpuinfo_x86 {
u16 x86_clflush_size;
/* number of cores as seen by the OS: */
u16 booted_cores;
/* Logical processor id: */
u16 logical_proc_id;
/* Core id: */
u16 cpu_core_id;
u16 logical_die_id;
/* Index into per_cpu list: */
u16 cpu_index;
/* Is SMT active on this core? */
Expand Down Expand Up @@ -703,15 +708,21 @@ extern int set_tsc_mode(unsigned int val);

DECLARE_PER_CPU(u64, msr_misc_features_shadow);

extern u16 get_llc_id(unsigned int cpu);
static inline u32 per_cpu_llc_id(unsigned int cpu)
{
return per_cpu(cpu_info.topo.llc_id, cpu);
}

static inline u32 per_cpu_l2c_id(unsigned int cpu)
{
return per_cpu(cpu_info.topo.l2c_id, cpu);
}

#ifdef CONFIG_CPU_SUP_AMD
extern u32 amd_get_nodes_per_socket(void);
extern u32 amd_get_highest_perf(void);
extern void amd_clear_divider(void);
extern void amd_check_microcode(void);
#else
static inline u32 amd_get_nodes_per_socket(void) { return 0; }
static inline u32 amd_get_highest_perf(void) { return 0; }
static inline void amd_clear_divider(void) { }
static inline void amd_check_microcode(void) { }
Expand Down
4 changes: 1 addition & 3 deletions arch/x86/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
/* cpus sharing the last level cache: */
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map);
DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id);
DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id);

DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid);
DECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_apicid);
DECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid);

struct task_struct;
Expand Down
43 changes: 37 additions & 6 deletions arch/x86/include/asm/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,51 @@ static inline void setup_node_to_cpumask_map(void) { }

#include <asm-generic/topology.h>

/* Topology information */
enum x86_topology_domains {
TOPO_SMT_DOMAIN,
TOPO_CORE_DOMAIN,
TOPO_MODULE_DOMAIN,
TOPO_TILE_DOMAIN,
TOPO_DIE_DOMAIN,
TOPO_DIEGRP_DOMAIN,
TOPO_PKG_DOMAIN,
TOPO_MAX_DOMAIN,
};

struct x86_topology_system {
unsigned int dom_shifts[TOPO_MAX_DOMAIN];
unsigned int dom_size[TOPO_MAX_DOMAIN];
};

extern struct x86_topology_system x86_topo_system;

static inline unsigned int topology_get_domain_size(enum x86_topology_domains dom)
{
return x86_topo_system.dom_size[dom];
}

static inline unsigned int topology_get_domain_shift(enum x86_topology_domains dom)
{
return dom == TOPO_SMT_DOMAIN ? 0 : x86_topo_system.dom_shifts[dom - 1];
}

extern const struct cpumask *cpu_coregroup_mask(int cpu);
extern const struct cpumask *cpu_clustergroup_mask(int cpu);

#define topology_logical_package_id(cpu) (cpu_data(cpu).logical_proc_id)
#define topology_logical_package_id(cpu) (cpu_data(cpu).topo.logical_pkg_id)
#define topology_physical_package_id(cpu) (cpu_data(cpu).topo.pkg_id)
#define topology_logical_die_id(cpu) (cpu_data(cpu).logical_die_id)
#define topology_logical_die_id(cpu) (cpu_data(cpu).topo.logical_die_id)
#define topology_die_id(cpu) (cpu_data(cpu).topo.die_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#define topology_core_id(cpu) (cpu_data(cpu).topo.core_id)
#define topology_ppin(cpu) (cpu_data(cpu).ppin)

#define topology_amd_node_id(cpu) (cpu_data(cpu).topo.die_id)
#define topology_amd_node_id(cpu) (cpu_data(cpu).topo.amd_node_id)

extern unsigned int __max_die_per_package;

#ifdef CONFIG_SMP
#define topology_cluster_id(cpu) (per_cpu(cpu_l2c_id, cpu))
#define topology_cluster_id(cpu) (cpu_data(cpu).topo.l2c_id)
#define topology_die_cpumask(cpu) (per_cpu(cpu_die_map, cpu))
#define topology_cluster_cpumask(cpu) (cpu_clustergroup_mask(cpu))
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
Expand Down Expand Up @@ -145,9 +174,11 @@ int topology_update_package_map(unsigned int apicid, unsigned int cpu);
int topology_update_die_map(unsigned int dieid, unsigned int cpu);
int topology_phys_to_logical_pkg(unsigned int pkg);

extern unsigned int __amd_nodes_per_pkg;

static inline unsigned int topology_amd_nodes_per_pkg(void)
{
return __max_die_per_package;
return __amd_nodes_per_pkg;
}

extern struct cpumask __cpu_primary_thread_mask;
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ int acpi_unmap_cpu(int cpu)
set_apicid_to_node(per_cpu(x86_cpu_to_apicid, cpu), NUMA_NO_NODE);
#endif

per_cpu(x86_cpu_to_apicid, cpu) = -1;
per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
set_cpu_present(cpu, false);
num_processors--;

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/acpi/madt_wakeup.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ static int __init acpi_mp_setup_reset(u64 reset_vector)
return 0;
}

static int acpi_wakeup_cpu(int apicid, unsigned long start_ip)
static int acpi_wakeup_cpu(u32 apicid, unsigned long start_ip)
{
if (!acpi_mp_wake_mailbox_paddr) {
pr_warn_once("No MADT mailbox: cannot bringup secondary CPUs. Booting with kexec?\n");
Expand Down
Loading