xref: /linux/arch/x86/kernel/cpu/topology_common.c (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/cpu.h>
3 
4 #include <xen/xen.h>
5 
6 #include <asm/intel-family.h>
7 #include <asm/apic.h>
8 #include <asm/processor.h>
9 #include <asm/cpuid/api.h>
10 #include <asm/smp.h>
11 
12 #include "cpu.h"
13 
14 struct x86_topology_system x86_topo_system __ro_after_init;
15 EXPORT_SYMBOL_GPL(x86_topo_system);
16 
17 unsigned int __amd_nodes_per_pkg __ro_after_init;
18 EXPORT_SYMBOL_GPL(__amd_nodes_per_pkg);
19 
20 /* CPUs which are the primary SMT threads */
21 struct cpumask __cpu_primary_thread_mask __read_mostly;
22 
23 void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
24 		      unsigned int shift, unsigned int ncpus)
25 {
26 	topology_update_dom(tscan, dom, shift, ncpus);
27 
28 	/* Propagate to the upper levels */
29 	for (dom++; dom < TOPO_MAX_DOMAIN; dom++) {
30 		tscan->dom_shifts[dom] = tscan->dom_shifts[dom - 1];
31 		tscan->dom_ncpus[dom] = tscan->dom_ncpus[dom - 1];
32 	}
33 }
34 
35 enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c)
36 {
37 	if (c->x86_vendor == X86_VENDOR_INTEL) {
38 		switch (c->topo.intel_type) {
39 		case INTEL_CPU_TYPE_ATOM: return TOPO_CPU_TYPE_EFFICIENCY;
40 		case INTEL_CPU_TYPE_CORE: return TOPO_CPU_TYPE_PERFORMANCE;
41 		}
42 	}
43 	if (c->x86_vendor == X86_VENDOR_AMD) {
44 		switch (c->topo.amd_type) {
45 		case AMD_CPU_TYPE_PERFORMANCE:	return TOPO_CPU_TYPE_PERFORMANCE;
46 		case AMD_CPU_TYPE_EFFICIENCY:	return TOPO_CPU_TYPE_EFFICIENCY;
47 		case AMD_CPU_TYPE_LOW_POWER:	return TOPO_CPU_TYPE_LOW_POWER;
48 		}
49 	}
50 
51 	return TOPO_CPU_TYPE_UNKNOWN;
52 }
53 
54 const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c)
55 {
56 	switch (get_topology_cpu_type(c)) {
57 	case TOPO_CPU_TYPE_PERFORMANCE:
58 		return "performance";
59 	case TOPO_CPU_TYPE_EFFICIENCY:
60 		return "efficiency";
61 	case TOPO_CPU_TYPE_LOW_POWER:
62 		return "low_power";
63 	default:
64 		return "unknown";
65 	}
66 }
67 
68 static unsigned int parse_num_cores_legacy(struct cpuinfo_x86 *c)
69 {
70 	struct {
71 		u32	cache_type	:  5,
72 			unused		: 21,
73 			ncores		:  6;
74 	} eax;
75 
76 	if (c->cpuid_level < 4)
77 		return 1;
78 
79 	cpuid_subleaf_reg(4, 0, CPUID_EAX, &eax);
80 	if (!eax.cache_type)
81 		return 1;
82 
83 	return eax.ncores + 1;
84 }
85 
86 static void parse_legacy(struct topo_scan *tscan)
87 {
88 	unsigned int cores, core_shift, smt_shift = 0;
89 	struct cpuinfo_x86 *c = tscan->c;
90 
91 	cores = parse_num_cores_legacy(c);
92 	core_shift = get_count_order(cores);
93 
94 	if (cpu_has(c, X86_FEATURE_HT)) {
95 		if (!WARN_ON_ONCE(tscan->ebx1_nproc_shift < core_shift))
96 			smt_shift = tscan->ebx1_nproc_shift - core_shift;
97 		/*
98 		 * The parser expects leaf 0xb/0x1f format, which means
99 		 * the number of logical processors at core level is
100 		 * counting threads.
101 		 */
102 		core_shift += smt_shift;
103 		cores <<= smt_shift;
104 	}
105 
106 	topology_set_dom(tscan, TOPO_SMT_DOMAIN, smt_shift, 1U << smt_shift);
107 	topology_set_dom(tscan, TOPO_CORE_DOMAIN, core_shift, cores);
108 }
109 
110 static bool fake_topology(struct topo_scan *tscan)
111 {
112 	/*
113 	 * Preset the CORE level shift for CPUID less systems and XEN_PV,
114 	 * which has useless CPUID information.
115 	 */
116 	topology_set_dom(tscan, TOPO_SMT_DOMAIN, 0, 1);
117 	topology_set_dom(tscan, TOPO_CORE_DOMAIN, 0, 1);
118 
119 	return tscan->c->cpuid_level < 1;
120 }
121 
122 static void parse_topology(struct topo_scan *tscan, bool early)
123 {
124 	const struct cpuinfo_topology topo_defaults = {
125 		.cu_id			= 0xff,
126 		.llc_id			= BAD_APICID,
127 		.l2c_id			= BAD_APICID,
128 		.cpu_type		= TOPO_CPU_TYPE_UNKNOWN,
129 	};
130 	struct cpuinfo_x86 *c = tscan->c;
131 	struct {
132 		u32	unused0		: 16,
133 			nproc		:  8,
134 			apicid		:  8;
135 	} ebx;
136 
137 	c->topo = topo_defaults;
138 
139 	if (fake_topology(tscan))
140 		return;
141 
142 	/* Preset Initial APIC ID from CPUID leaf 1 */
143 	cpuid_leaf_reg(1, CPUID_EBX, &ebx);
144 	c->topo.initial_apicid = ebx.apicid;
145 
146 	/*
147 	 * The initial invocation from early_identify_cpu() happens before
148 	 * the APIC is mapped or X2APIC enabled. For establishing the
149 	 * topology, that's not required. Use the initial APIC ID.
150 	 */
151 	if (early)
152 		c->topo.apicid = c->topo.initial_apicid;
153 	else
154 		c->topo.apicid = read_apic_id();
155 
156 	/* The above is sufficient for UP */
157 	if (!IS_ENABLED(CONFIG_SMP))
158 		return;
159 
160 	tscan->ebx1_nproc_shift = get_count_order(ebx.nproc);
161 
162 	switch (c->x86_vendor) {
163 	case X86_VENDOR_AMD:
164 	case X86_VENDOR_HYGON:
165 		cpu_parse_topology_amd(tscan);
166 		break;
167 	case X86_VENDOR_CENTAUR:
168 	case X86_VENDOR_ZHAOXIN:
169 		parse_legacy(tscan);
170 		break;
171 	case X86_VENDOR_INTEL:
172 		if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan))
173 			parse_legacy(tscan);
174 
175 		if (c->cpuid_level >= 0x1a) {
176 			c->topo.hw_cpu_type = cpuid_eax(0x1a);
177 			c->topo.cpu_type    = get_topology_cpu_type(c);
178 		}
179 
180 		break;
181 	}
182 }
183 
184 static void topo_set_ids(struct topo_scan *tscan, bool early)
185 {
186 	struct cpuinfo_x86 *c = tscan->c;
187 	u32 apicid = c->topo.apicid;
188 
189 	c->topo.pkg_id = topo_shift_apicid(apicid, TOPO_PKG_DOMAIN);
190 	c->topo.die_id = topo_shift_apicid(apicid, TOPO_DIE_DOMAIN);
191 
192 	if (!early) {
193 		c->topo.logical_pkg_id = topology_get_logical_id(apicid, TOPO_PKG_DOMAIN);
194 		c->topo.logical_die_id = topology_get_logical_id(apicid, TOPO_DIE_DOMAIN);
195 		c->topo.logical_core_id = topology_get_logical_id(apicid, TOPO_CORE_DOMAIN);
196 	}
197 
198 	/* Package relative core ID */
199 	c->topo.core_id = (apicid & topo_domain_mask(TOPO_PKG_DOMAIN)) >>
200 		x86_topo_system.dom_shifts[TOPO_SMT_DOMAIN];
201 
202 	c->topo.amd_node_id = tscan->amd_node_id;
203 
204 	if (c->x86_vendor == X86_VENDOR_AMD)
205 		cpu_topology_fixup_amd(tscan);
206 }
207 
208 void cpu_parse_topology(struct cpuinfo_x86 *c)
209 {
210 	unsigned int dom, cpu = smp_processor_id();
211 	struct topo_scan tscan = { .c = c, };
212 
213 	parse_topology(&tscan, false);
214 
215 	if (IS_ENABLED(CONFIG_X86_LOCAL_APIC)) {
216 		if (c->topo.initial_apicid != c->topo.apicid) {
217 			pr_err(FW_BUG "CPU%4u: APIC ID mismatch. CPUID: 0x%04x APIC: 0x%04x\n",
218 			       cpu, c->topo.initial_apicid, c->topo.apicid);
219 		}
220 
221 		if (c->topo.apicid != cpuid_to_apicid[cpu]) {
222 			pr_err(FW_BUG "CPU%4u: APIC ID mismatch. Firmware: 0x%04x APIC: 0x%04x\n",
223 			       cpu, cpuid_to_apicid[cpu], c->topo.apicid);
224 		}
225 	}
226 
227 	for (dom = TOPO_SMT_DOMAIN; dom < TOPO_MAX_DOMAIN; dom++) {
228 		if (tscan.dom_shifts[dom] == x86_topo_system.dom_shifts[dom])
229 			continue;
230 		pr_err(FW_BUG "CPU%d: Topology domain %u shift %u != %u\n", cpu, dom,
231 		       tscan.dom_shifts[dom], x86_topo_system.dom_shifts[dom]);
232 	}
233 
234 	topo_set_ids(&tscan, false);
235 }
236 
237 void __init cpu_init_topology(struct cpuinfo_x86 *c)
238 {
239 	struct topo_scan tscan = { .c = c, };
240 	unsigned int dom, sft;
241 
242 	parse_topology(&tscan, true);
243 
244 	/* Copy the shift values and calculate the unit sizes. */
245 	memcpy(x86_topo_system.dom_shifts, tscan.dom_shifts, sizeof(x86_topo_system.dom_shifts));
246 
247 	dom = TOPO_SMT_DOMAIN;
248 	x86_topo_system.dom_size[dom] = 1U << x86_topo_system.dom_shifts[dom];
249 
250 	for (dom++; dom < TOPO_MAX_DOMAIN; dom++) {
251 		sft = x86_topo_system.dom_shifts[dom] - x86_topo_system.dom_shifts[dom - 1];
252 		x86_topo_system.dom_size[dom] = 1U << sft;
253 	}
254 
255 	topo_set_ids(&tscan, true);
256 
257 	/*
258 	 * AMD systems have Nodes per package which cannot be mapped to
259 	 * APIC ID.
260 	 */
261 	__amd_nodes_per_pkg = tscan.amd_nodes_per_pkg;
262 }
263