Skip to content

Commit a65879b

Browse files
committed
Merge tag 'x86_cpu_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 cpuid updates from Borislav Petkov: - Make UMIP instruction detection more robust - Correct and cleanup AMD CPU topology detection; document the relevant CPUID leaves topology parsing precedence on AMD - Add support for running the kernel as guest on FreeBSD's Bhyve hypervisor - Cleanups and improvements * tag 'x86_cpu_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/umip: Fix decoding of register forms of 0F 01 (SGDT and SIDT aliases) x86/umip: Check that the instruction opcode is at least two bytes Documentation/x86/topology: Detail CPUID leaves used for topology enumeration x86/cpu/topology: Define AMD64_CPUID_EXT_FEAT MSR x86/cpu/topology: Check for X86_FEATURE_XTOPOLOGY instead of passing has_xtopology x86/cpu/cacheinfo: Simplify cacheinfo_amd_init_llc_id() using _cpuid4_info x86/cpu: Rename and move CPU model entry for Diamond Rapids x86/cpu: Detect FreeBSD Bhyve hypervisor
2 parents d7ec0cf + 27b1fd6 commit a65879b

14 files changed

Lines changed: 329 additions & 50 deletions

File tree

Documentation/arch/x86/topology.rst

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,197 @@ Thread-related topology information in the kernel:
141141

142142

143143

144+
System topology enumeration
145+
===========================
146+
147+
The topology on x86 systems can be discovered using a combination of vendor
148+
specific CPUID leaves which enumerate the processor topology and the cache
149+
hierarchy.
150+
151+
The CPUID leaves in their preferred order of parsing for each x86 vendor is as
152+
follows:
153+
154+
1) AMD
155+
156+
1) CPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology)
157+
158+
The extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB
159+
and provides the topology information of Core, Complex, CCD (Die), and
160+
Socket in each level.
161+
162+
Support for the leaf is discovered by checking if the maximum extended
163+
CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel`
164+
in `EBX[15:0]` at a particular level (starting from 0) is non-zero.
165+
166+
The `LevelType` in `ECX[15:8]` at the level provides the topology domain
167+
the level describes - Core, Complex, CCD(Die), or the Socket.
168+
169+
The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the
170+
number of bits that need to be right-shifted from `ExtendedLocalApicId`
171+
in `EDX[31:0]` in order to get a unique Topology ID for the topology
172+
level. CPUs with the same Topology ID share the resources at that level.
173+
174+
CPUID leaf 0x80000026 also provides more information regarding the power
175+
and efficiency rankings, and about the core type on AMD processors with
176+
heterogeneous characteristics.
177+
178+
If CPUID leaf 0x80000026 is supported, further parsing is not required.
179+
180+
2) CPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum)
181+
182+
The extended CPUID leaf 0x0000000B is the predecessor on the extended
183+
CPUID leaf 0x80000026 and only describes the core, and the socket domains
184+
of the processor topology.
185+
186+
The support for the leaf is discovered by checking if the maximum supported
187+
CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level
188+
(starting from 0) is non-zero.
189+
190+
The `LevelType` in `ECX[15:8]` at the level provides the topology domain
191+
that the level describes - Thread, or Processor (Socket).
192+
193+
The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the
194+
number of bits that need to be right-shifted from the `ExtendedLocalApicId`
195+
in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs
196+
sharing the Topology ID share the resources at that level.
197+
198+
If CPUID leaf 0xB is supported, further parsing is not required.
199+
200+
201+
3) CPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId)
202+
203+
If neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of
204+
CPUs on the package is detected using the Size Identifier leaf
205+
0x80000008 ECX.
206+
207+
The support for the leaf is discovered by checking if the supported
208+
extended CPUID level is >= 0x80000008.
209+
210+
The shifts from the APIC ID for the Socket ID is calculated from the
211+
`ApicIdSize` field in `ECX[15:12]` if it is non-zero.
212+
213+
If `ApicIdSize` is reported to be zero, the shift is calculated as the
214+
order of the `number of threads` calculated from `NC` field in
215+
`ECX[7:0]` which describes the `number of threads - 1` on the package.
216+
217+
Unless Extended APIC ID is supported, the APIC ID used to find the
218+
Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001
219+
`EBX[31:24]`.
220+
221+
The topology parsing continues to detect if Extended APIC ID is
222+
supported or not.
223+
224+
225+
4) CPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers]
226+
(Core::X86::Cpuid::{ExtApicId,CoreId,NodeId})
227+
228+
The support for Extended APIC ID can be detected by checking for the
229+
presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001
230+
[Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).
231+
232+
If Topology Extensions is supported, the APIC ID from `ExtendedApicId`
233+
from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from
234+
`LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology
235+
enumeration.
236+
237+
On processors of Family 0x17 and above that do not support CPUID leaf
238+
0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core
239+
ID is calculated using the order of `number of threads per core`
240+
calculated using the `ThreadsPerCore` field in `EBX[15:8]` which
241+
describes `number of threads per core - 1`.
242+
243+
On Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the
244+
`cu_id` (Compute Unit ID) to detect CPUs that share the compute units.
245+
246+
247+
All AMD processors that support the `TopologyExtensions` feature store the
248+
`NodeId` from the `ECX[7:0]` of CPUID leaf 0x8000001E
249+
(Core::X86::Cpuid::NodeId) as the per-CPU `node_id`. On older processors,
250+
the `node_id` was discovered using MSR_FAM10H_NODE_ID MSR (MSR
251+
0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking
252+
`ECX[19]` of CPUID leaf 0x80000001 [Feature Identifiers]
253+
(Core::X86::Cpuid::FeatureExtIdEcx).
254+
255+
256+
2) Intel
257+
258+
On Intel platforms, the CPUID leaves that enumerate the processor
259+
topology are as follows:
260+
261+
1) CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf)
262+
263+
The CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides
264+
the topology information of Core, Module, Tile, Die, DieGrp, and Socket
265+
in each level.
266+
267+
The support for the leaf is discovered by checking if the supported
268+
CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level
269+
(starting from 0) is non-zero.
270+
271+
The `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology
272+
domain that the level describes - Core, Module, Tile, Die, DieGrp, and
273+
Socket.
274+
275+
The kernel uses the value from `EAX[4:0]` to discover the number of
276+
bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]`
277+
to get a unique Topology ID for the topology level. CPUs with the same
278+
Topology ID share the resources at that level.
279+
280+
If CPUID leaf 0x1F is supported, further parsing is not required.
281+
282+
283+
2) CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf)
284+
285+
The extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended
286+
Topology Enumeration Leaf 0x1F and only describes the core, and the
287+
socket domains of the processor topology.
288+
289+
The support for the leaf is iscovered by checking if the supported CPUID
290+
level is >= 0xB and then checking if `EBX[31:0]` at a particular level
291+
(starting from 0) is non-zero.
292+
293+
CPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and
294+
should be enumerated in a similar manner.
295+
296+
If CPUID leaf 0xB is supported, further parsing is not required.
297+
298+
299+
3) CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf)
300+
301+
On Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf
302+
0xB, the shifts for the SMT domains is calculated using the number of
303+
CPUs sharing the L1 cache.
304+
305+
Processors that feature Hyper-Threading is detected using `EDX[28]` of
306+
CPUID leaf 0x1 (Basic CPUID Information).
307+
308+
The order of `Maximum number of addressable IDs for logical processors
309+
sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides
310+
the shifts from the APIC ID required to compute the Core ID.
311+
312+
The APIC ID and Package information is computed using the data from
313+
CPUID leaf 0x1.
314+
315+
316+
4) CPUID leaf 0x00000001 (Basic CPUID Information)
317+
318+
The mask and shifts to derive the Physical Package (socket) ID is
319+
computed using the `Maximum number of addressable IDs for logical
320+
processors in this physical package` from `EBX[23:16]` of CPUID leaf
321+
0x1.
322+
323+
The APIC ID on the legacy platforms is derived from the `Initial APIC
324+
ID` field from `EBX[31:24]` of CPUID leaf 0x1.
325+
326+
327+
3) Centaur and Zhaoxin
328+
329+
Similar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf
330+
0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001
331+
(Basic CPUID Information) to derive the topology information.
332+
333+
334+
144335
System topology examples
145336
========================
146337

arch/x86/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,15 @@ config ACRN_GUEST
883883
IOT with small footprint and real-time features. More details can be
884884
found in https://projectacrn.org/.
885885

886+
config BHYVE_GUEST
887+
bool "Bhyve (BSD Hypervisor) Guest support"
888+
depends on X86_64
889+
help
890+
This option allows to run Linux to recognise when it is running as a
891+
guest in the Bhyve hypervisor, and to support more than 255 vCPUs when
892+
when doing so. More details about Bhyve can be found at https://bhyve.org
893+
and https://wiki.freebsd.org/bhyve/.
894+
886895
config INTEL_TDX_GUEST
887896
bool "Intel TDX (Trust Domain Extensions) - Guest Support"
888897
depends on X86_64 && CPU_SUP_INTEL

arch/x86/include/asm/hypervisor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ enum x86_hypervisor_type {
3030
X86_HYPER_KVM,
3131
X86_HYPER_JAILHOUSE,
3232
X86_HYPER_ACRN,
33+
X86_HYPER_BHYVE,
3334
};
3435

3536
#ifdef CONFIG_HYPERVISOR_GUEST
@@ -64,6 +65,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
6465
extern const struct hypervisor_x86 x86_hyper_kvm;
6566
extern const struct hypervisor_x86 x86_hyper_jailhouse;
6667
extern const struct hypervisor_x86 x86_hyper_acrn;
68+
extern const struct hypervisor_x86 x86_hyper_bhyve;
6769
extern struct hypervisor_x86 x86_hyper_xen_hvm;
6870

6971
extern bool nopv;

arch/x86/include/asm/intel-family.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
#define INTEL_PENTIUM_MMX IFM(5, 0x04) /* P55C */
5252
#define INTEL_QUARK_X1000 IFM(5, 0x09) /* Quark X1000 SoC */
5353

54-
/* Family 6 */
54+
/* Family 6, 18, 19 */
5555
#define INTEL_PENTIUM_PRO IFM(6, 0x01)
5656
#define INTEL_PENTIUM_II_KLAMATH IFM(6, 0x03)
5757
#define INTEL_PENTIUM_III_DESCHUTES IFM(6, 0x05)
@@ -126,6 +126,8 @@
126126
#define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) /* Redwood Cove */
127127
#define INTEL_GRANITERAPIDS_D IFM(6, 0xAE)
128128

129+
#define INTEL_DIAMONDRAPIDS_X IFM(19, 0x01) /* Panther Cove */
130+
129131
#define INTEL_BARTLETTLAKE IFM(6, 0xD7) /* Raptor Cove */
130132

131133
/* "Hybrid" Processors (P-Core/E-Core) */
@@ -203,9 +205,6 @@
203205
#define INTEL_P4_PRESCOTT_2M IFM(15, 0x04)
204206
#define INTEL_P4_CEDARMILL IFM(15, 0x06) /* Also Xeon Dempsey */
205207

206-
/* Family 19 */
207-
#define INTEL_PANTHERCOVE_X IFM(19, 0x01) /* Diamond Rapids */
208-
209208
/*
210209
* Intel CPU core types
211210
*

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,11 @@
633633
#define MSR_AMD_PPIN 0xc00102f1
634634
#define MSR_AMD64_CPUID_FN_7 0xc0011002
635635
#define MSR_AMD64_CPUID_FN_1 0xc0011004
636+
637+
#define MSR_AMD64_CPUID_EXT_FEAT 0xc0011005
638+
#define MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT_BIT 54
639+
#define MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT BIT_ULL(MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT_BIT)
640+
636641
#define MSR_AMD64_LS_CFG 0xc0011020
637642
#define MSR_AMD64_DC_CFG 0xc0011022
638643
#define MSR_AMD64_TW_CFG 0xc0011023

arch/x86/kernel/cpu/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ obj-$(CONFIG_X86_SGX) += sgx/
5858
obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o
5959

6060
obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
61+
obj-$(CONFIG_BHYVE_GUEST) += bhyve.o
6162
obj-$(CONFIG_ACRN_GUEST) += acrn.o
6263

6364
obj-$(CONFIG_DEBUG_FS) += debugfs.o

arch/x86/kernel/cpu/bhyve.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* FreeBSD Bhyve guest enlightenments
4+
*
5+
* Copyright © 2025 Amazon.com, Inc. or its affiliates.
6+
*
7+
* Author: David Woodhouse <dwmw2@infradead.org>
8+
*/
9+
10+
#include <linux/init.h>
11+
#include <linux/export.h>
12+
#include <asm/processor.h>
13+
#include <asm/hypervisor.h>
14+
15+
static uint32_t bhyve_cpuid_base;
16+
static uint32_t bhyve_cpuid_max;
17+
18+
#define BHYVE_SIGNATURE "bhyve bhyve "
19+
20+
#define CPUID_BHYVE_FEATURES 0x40000001
21+
22+
/* Features advertised in CPUID_BHYVE_FEATURES %eax */
23+
24+
/* MSI Extended Dest ID */
25+
#define CPUID_BHYVE_FEAT_EXT_DEST_ID (1UL << 0)
26+
27+
static uint32_t __init bhyve_detect(void)
28+
{
29+
if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
30+
return 0;
31+
32+
bhyve_cpuid_base = cpuid_base_hypervisor(BHYVE_SIGNATURE, 0);
33+
if (!bhyve_cpuid_base)
34+
return 0;
35+
36+
bhyve_cpuid_max = cpuid_eax(bhyve_cpuid_base);
37+
return bhyve_cpuid_max;
38+
}
39+
40+
static uint32_t bhyve_features(void)
41+
{
42+
unsigned int cpuid_leaf = bhyve_cpuid_base | CPUID_BHYVE_FEATURES;
43+
44+
if (bhyve_cpuid_max < cpuid_leaf)
45+
return 0;
46+
47+
return cpuid_eax(cpuid_leaf);
48+
}
49+
50+
static bool __init bhyve_ext_dest_id(void)
51+
{
52+
return !!(bhyve_features() & CPUID_BHYVE_FEAT_EXT_DEST_ID);
53+
}
54+
55+
static bool __init bhyve_x2apic_available(void)
56+
{
57+
return true;
58+
}
59+
60+
const struct hypervisor_x86 x86_hyper_bhyve __refconst = {
61+
.name = "Bhyve",
62+
.detect = bhyve_detect,
63+
.init.init_platform = x86_init_noop,
64+
.init.x2apic_available = bhyve_x2apic_available,
65+
.init.msi_ext_dest_id = bhyve_ext_dest_id,
66+
};

0 commit comments

Comments
 (0)