mirror of https://github.com/torvalds/linux.git
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmjWZx4ACgkQEsHwGGHe VUqskRAAuhsxDxqbA/HnHlDkLM2YgfpE8j9XkFen9R1kFNi8WtQ7DPNdA9SeDJF2 NpRuZZpzpQrmHwwlERHzOY6AxwWJXdK2lA2GF/jkdvB9lRDAwlb4nenBZNnTL1zo NDctnKPto1Nz1fOLFl3Hve++PoOkdzOQZZPQ7LYS5wm6zaRv2O5h0s6Rfw7Kt9YC Sl+WYFZ3SA8KOoaHZKhGcgsLNkxv0lV7oXyhSQ1MXT3rFkG2jt/IzjwCyOVK50bj iob6MOfpuM9SG2ZMGBL4P82GBUG1E3BMhqiLbYYxyuMdxRgt/t3zlK4x/yjNbOET 3iQM+aimqOlHKmnJm/qzs2rjRhYQmBjNjIPcuCoiVVG0U6er6VKl+x2wLdAPlTq4 Du6Oj7veEOLF9lAMQOq/9ZeG7IVlQT1xJ5RwtMpnZKhnlStnFlyDgPAAYs88L3Uf aAga/XdLd40mxOj/z3+2Fn7snOHNK/79NWB35DFOjjivNyQXMgk9hPxibECb+9bO sXFwhFfujFI+X7UZbfISoaTLq7c/D0EV9uqIEYjbpFXhxTXgMcey/tMDWxCLnGyl camkN8An1PmCsZdD9vud4QhuDqPhX6S8ndyK1C/EaStxT9t76sOSpEpybeee0xxq eiktBLp0uqlyK6Oo7J0/LcBnNRrYFeipU6HwztY3bz3VH/ejYWM= =sMTE -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
a65879b458
|
|
@ -141,6 +141,197 @@ Thread-related topology information in the kernel:
|
|||
|
||||
|
||||
|
||||
System topology enumeration
|
||||
===========================
|
||||
|
||||
The topology on x86 systems can be discovered using a combination of vendor
|
||||
specific CPUID leaves which enumerate the processor topology and the cache
|
||||
hierarchy.
|
||||
|
||||
The CPUID leaves in their preferred order of parsing for each x86 vendor is as
|
||||
follows:
|
||||
|
||||
1) AMD
|
||||
|
||||
1) CPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology)
|
||||
|
||||
The extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB
|
||||
and provides the topology information of Core, Complex, CCD (Die), and
|
||||
Socket in each level.
|
||||
|
||||
Support for the leaf is discovered by checking if the maximum extended
|
||||
CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel`
|
||||
in `EBX[15:0]` at a particular level (starting from 0) is non-zero.
|
||||
|
||||
The `LevelType` in `ECX[15:8]` at the level provides the topology domain
|
||||
the level describes - Core, Complex, CCD(Die), or the Socket.
|
||||
|
||||
The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the
|
||||
number of bits that need to be right-shifted from `ExtendedLocalApicId`
|
||||
in `EDX[31:0]` in order to get a unique Topology ID for the topology
|
||||
level. CPUs with the same Topology ID share the resources at that level.
|
||||
|
||||
CPUID leaf 0x80000026 also provides more information regarding the power
|
||||
and efficiency rankings, and about the core type on AMD processors with
|
||||
heterogeneous characteristics.
|
||||
|
||||
If CPUID leaf 0x80000026 is supported, further parsing is not required.
|
||||
|
||||
2) CPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum)
|
||||
|
||||
The extended CPUID leaf 0x0000000B is the predecessor on the extended
|
||||
CPUID leaf 0x80000026 and only describes the core, and the socket domains
|
||||
of the processor topology.
|
||||
|
||||
The support for the leaf is discovered by checking if the maximum supported
|
||||
CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level
|
||||
(starting from 0) is non-zero.
|
||||
|
||||
The `LevelType` in `ECX[15:8]` at the level provides the topology domain
|
||||
that the level describes - Thread, or Processor (Socket).
|
||||
|
||||
The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the
|
||||
number of bits that need to be right-shifted from the `ExtendedLocalApicId`
|
||||
in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs
|
||||
sharing the Topology ID share the resources at that level.
|
||||
|
||||
If CPUID leaf 0xB is supported, further parsing is not required.
|
||||
|
||||
|
||||
3) CPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId)
|
||||
|
||||
If neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of
|
||||
CPUs on the package is detected using the Size Identifier leaf
|
||||
0x80000008 ECX.
|
||||
|
||||
The support for the leaf is discovered by checking if the supported
|
||||
extended CPUID level is >= 0x80000008.
|
||||
|
||||
The shifts from the APIC ID for the Socket ID is calculated from the
|
||||
`ApicIdSize` field in `ECX[15:12]` if it is non-zero.
|
||||
|
||||
If `ApicIdSize` is reported to be zero, the shift is calculated as the
|
||||
order of the `number of threads` calculated from `NC` field in
|
||||
`ECX[7:0]` which describes the `number of threads - 1` on the package.
|
||||
|
||||
Unless Extended APIC ID is supported, the APIC ID used to find the
|
||||
Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001
|
||||
`EBX[31:24]`.
|
||||
|
||||
The topology parsing continues to detect if Extended APIC ID is
|
||||
supported or not.
|
||||
|
||||
|
||||
4) CPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers]
|
||||
(Core::X86::Cpuid::{ExtApicId,CoreId,NodeId})
|
||||
|
||||
The support for Extended APIC ID can be detected by checking for the
|
||||
presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001
|
||||
[Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).
|
||||
|
||||
If Topology Extensions is supported, the APIC ID from `ExtendedApicId`
|
||||
from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from
|
||||
`LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology
|
||||
enumeration.
|
||||
|
||||
On processors of Family 0x17 and above that do not support CPUID leaf
|
||||
0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core
|
||||
ID is calculated using the order of `number of threads per core`
|
||||
calculated using the `ThreadsPerCore` field in `EBX[15:8]` which
|
||||
describes `number of threads per core - 1`.
|
||||
|
||||
On Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the
|
||||
`cu_id` (Compute Unit ID) to detect CPUs that share the compute units.
|
||||
|
||||
|
||||
All AMD processors that support the `TopologyExtensions` feature store the
|
||||
`NodeId` from the `ECX[7:0]` of CPUID leaf 0x8000001E
|
||||
(Core::X86::Cpuid::NodeId) as the per-CPU `node_id`. On older processors,
|
||||
the `node_id` was discovered using MSR_FAM10H_NODE_ID MSR (MSR
|
||||
0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking
|
||||
`ECX[19]` of CPUID leaf 0x80000001 [Feature Identifiers]
|
||||
(Core::X86::Cpuid::FeatureExtIdEcx).
|
||||
|
||||
|
||||
2) Intel
|
||||
|
||||
On Intel platforms, the CPUID leaves that enumerate the processor
|
||||
topology are as follows:
|
||||
|
||||
1) CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf)
|
||||
|
||||
The CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides
|
||||
the topology information of Core, Module, Tile, Die, DieGrp, and Socket
|
||||
in each level.
|
||||
|
||||
The support for the leaf is discovered by checking if the supported
|
||||
CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level
|
||||
(starting from 0) is non-zero.
|
||||
|
||||
The `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology
|
||||
domain that the level describes - Core, Module, Tile, Die, DieGrp, and
|
||||
Socket.
|
||||
|
||||
The kernel uses the value from `EAX[4:0]` to discover the number of
|
||||
bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]`
|
||||
to get a unique Topology ID for the topology level. CPUs with the same
|
||||
Topology ID share the resources at that level.
|
||||
|
||||
If CPUID leaf 0x1F is supported, further parsing is not required.
|
||||
|
||||
|
||||
2) CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf)
|
||||
|
||||
The extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended
|
||||
Topology Enumeration Leaf 0x1F and only describes the core, and the
|
||||
socket domains of the processor topology.
|
||||
|
||||
The support for the leaf is iscovered by checking if the supported CPUID
|
||||
level is >= 0xB and then checking if `EBX[31:0]` at a particular level
|
||||
(starting from 0) is non-zero.
|
||||
|
||||
CPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and
|
||||
should be enumerated in a similar manner.
|
||||
|
||||
If CPUID leaf 0xB is supported, further parsing is not required.
|
||||
|
||||
|
||||
3) CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf)
|
||||
|
||||
On Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf
|
||||
0xB, the shifts for the SMT domains is calculated using the number of
|
||||
CPUs sharing the L1 cache.
|
||||
|
||||
Processors that feature Hyper-Threading is detected using `EDX[28]` of
|
||||
CPUID leaf 0x1 (Basic CPUID Information).
|
||||
|
||||
The order of `Maximum number of addressable IDs for logical processors
|
||||
sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides
|
||||
the shifts from the APIC ID required to compute the Core ID.
|
||||
|
||||
The APIC ID and Package information is computed using the data from
|
||||
CPUID leaf 0x1.
|
||||
|
||||
|
||||
4) CPUID leaf 0x00000001 (Basic CPUID Information)
|
||||
|
||||
The mask and shifts to derive the Physical Package (socket) ID is
|
||||
computed using the `Maximum number of addressable IDs for logical
|
||||
processors in this physical package` from `EBX[23:16]` of CPUID leaf
|
||||
0x1.
|
||||
|
||||
The APIC ID on the legacy platforms is derived from the `Initial APIC
|
||||
ID` field from `EBX[31:24]` of CPUID leaf 0x1.
|
||||
|
||||
|
||||
3) Centaur and Zhaoxin
|
||||
|
||||
Similar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf
|
||||
0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001
|
||||
(Basic CPUID Information) to derive the topology information.
|
||||
|
||||
|
||||
|
||||
System topology examples
|
||||
========================
|
||||
|
||||
|
|
|
|||
|
|
@ -883,6 +883,15 @@ config ACRN_GUEST
|
|||
IOT with small footprint and real-time features. More details can be
|
||||
found in https://projectacrn.org/.
|
||||
|
||||
config BHYVE_GUEST
|
||||
bool "Bhyve (BSD Hypervisor) Guest support"
|
||||
depends on X86_64
|
||||
help
|
||||
This option allows to run Linux to recognise when it is running as a
|
||||
guest in the Bhyve hypervisor, and to support more than 255 vCPUs when
|
||||
when doing so. More details about Bhyve can be found at https://bhyve.org
|
||||
and https://wiki.freebsd.org/bhyve/.
|
||||
|
||||
config INTEL_TDX_GUEST
|
||||
bool "Intel TDX (Trust Domain Extensions) - Guest Support"
|
||||
depends on X86_64 && CPU_SUP_INTEL
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ enum x86_hypervisor_type {
|
|||
X86_HYPER_KVM,
|
||||
X86_HYPER_JAILHOUSE,
|
||||
X86_HYPER_ACRN,
|
||||
X86_HYPER_BHYVE,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HYPERVISOR_GUEST
|
||||
|
|
@ -64,6 +65,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
|
|||
extern const struct hypervisor_x86 x86_hyper_kvm;
|
||||
extern const struct hypervisor_x86 x86_hyper_jailhouse;
|
||||
extern const struct hypervisor_x86 x86_hyper_acrn;
|
||||
extern const struct hypervisor_x86 x86_hyper_bhyve;
|
||||
extern struct hypervisor_x86 x86_hyper_xen_hvm;
|
||||
|
||||
extern bool nopv;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
#define INTEL_PENTIUM_MMX IFM(5, 0x04) /* P55C */
|
||||
#define INTEL_QUARK_X1000 IFM(5, 0x09) /* Quark X1000 SoC */
|
||||
|
||||
/* Family 6 */
|
||||
/* Family 6, 18, 19 */
|
||||
#define INTEL_PENTIUM_PRO IFM(6, 0x01)
|
||||
#define INTEL_PENTIUM_II_KLAMATH IFM(6, 0x03)
|
||||
#define INTEL_PENTIUM_III_DESCHUTES IFM(6, 0x05)
|
||||
|
|
@ -126,6 +126,8 @@
|
|||
#define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) /* Redwood Cove */
|
||||
#define INTEL_GRANITERAPIDS_D IFM(6, 0xAE)
|
||||
|
||||
#define INTEL_DIAMONDRAPIDS_X IFM(19, 0x01) /* Panther Cove */
|
||||
|
||||
#define INTEL_BARTLETTLAKE IFM(6, 0xD7) /* Raptor Cove */
|
||||
|
||||
/* "Hybrid" Processors (P-Core/E-Core) */
|
||||
|
|
@ -203,9 +205,6 @@
|
|||
#define INTEL_P4_PRESCOTT_2M IFM(15, 0x04)
|
||||
#define INTEL_P4_CEDARMILL IFM(15, 0x06) /* Also Xeon Dempsey */
|
||||
|
||||
/* Family 19 */
|
||||
#define INTEL_PANTHERCOVE_X IFM(19, 0x01) /* Diamond Rapids */
|
||||
|
||||
/*
|
||||
* Intel CPU core types
|
||||
*
|
||||
|
|
|
|||
|
|
@ -633,6 +633,11 @@
|
|||
#define MSR_AMD_PPIN 0xc00102f1
|
||||
#define MSR_AMD64_CPUID_FN_7 0xc0011002
|
||||
#define MSR_AMD64_CPUID_FN_1 0xc0011004
|
||||
|
||||
#define MSR_AMD64_CPUID_EXT_FEAT 0xc0011005
|
||||
#define MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT_BIT 54
|
||||
#define MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT BIT_ULL(MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT_BIT)
|
||||
|
||||
#define MSR_AMD64_LS_CFG 0xc0011020
|
||||
#define MSR_AMD64_DC_CFG 0xc0011022
|
||||
#define MSR_AMD64_TW_CFG 0xc0011023
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ obj-$(CONFIG_X86_SGX) += sgx/
|
|||
obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o
|
||||
|
||||
obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
|
||||
obj-$(CONFIG_BHYVE_GUEST) += bhyve.o
|
||||
obj-$(CONFIG_ACRN_GUEST) += acrn.o
|
||||
|
||||
obj-$(CONFIG_DEBUG_FS) += debugfs.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* FreeBSD Bhyve guest enlightenments
|
||||
*
|
||||
* Copyright © 2025 Amazon.com, Inc. or its affiliates.
|
||||
*
|
||||
* Author: David Woodhouse <dwmw2@infradead.org>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/hypervisor.h>
|
||||
|
||||
static uint32_t bhyve_cpuid_base;
|
||||
static uint32_t bhyve_cpuid_max;
|
||||
|
||||
#define BHYVE_SIGNATURE "bhyve bhyve "
|
||||
|
||||
#define CPUID_BHYVE_FEATURES 0x40000001
|
||||
|
||||
/* Features advertised in CPUID_BHYVE_FEATURES %eax */
|
||||
|
||||
/* MSI Extended Dest ID */
|
||||
#define CPUID_BHYVE_FEAT_EXT_DEST_ID (1UL << 0)
|
||||
|
||||
static uint32_t __init bhyve_detect(void)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
|
||||
return 0;
|
||||
|
||||
bhyve_cpuid_base = cpuid_base_hypervisor(BHYVE_SIGNATURE, 0);
|
||||
if (!bhyve_cpuid_base)
|
||||
return 0;
|
||||
|
||||
bhyve_cpuid_max = cpuid_eax(bhyve_cpuid_base);
|
||||
return bhyve_cpuid_max;
|
||||
}
|
||||
|
||||
static uint32_t bhyve_features(void)
|
||||
{
|
||||
unsigned int cpuid_leaf = bhyve_cpuid_base | CPUID_BHYVE_FEATURES;
|
||||
|
||||
if (bhyve_cpuid_max < cpuid_leaf)
|
||||
return 0;
|
||||
|
||||
return cpuid_eax(cpuid_leaf);
|
||||
}
|
||||
|
||||
static bool __init bhyve_ext_dest_id(void)
|
||||
{
|
||||
return !!(bhyve_features() & CPUID_BHYVE_FEAT_EXT_DEST_ID);
|
||||
}
|
||||
|
||||
static bool __init bhyve_x2apic_available(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct hypervisor_x86 x86_hyper_bhyve __refconst = {
|
||||
.name = "Bhyve",
|
||||
.detect = bhyve_detect,
|
||||
.init.init_platform = x86_init_noop,
|
||||
.init.x2apic_available = bhyve_x2apic_available,
|
||||
.init.msi_ext_dest_id = bhyve_ext_dest_id,
|
||||
};
|
||||
|
|
@ -289,6 +289,22 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
|
|||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* The max shared threads number comes from CPUID(0x4) EAX[25-14] with input
|
||||
* ECX as cache index. Then right shift apicid by the number's order to get
|
||||
* cache id for this cache node.
|
||||
*/
|
||||
static unsigned int get_cache_id(u32 apicid, const struct _cpuid4_info *id4)
|
||||
{
|
||||
unsigned long num_threads_sharing;
|
||||
int index_msb;
|
||||
|
||||
num_threads_sharing = 1 + id4->eax.split.num_threads_sharing;
|
||||
index_msb = get_count_order(num_threads_sharing);
|
||||
|
||||
return apicid >> index_msb;
|
||||
}
|
||||
|
||||
/*
|
||||
* AMD/Hygon CPUs may have multiple LLCs if L3 caches exist.
|
||||
*/
|
||||
|
|
@ -312,18 +328,11 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)
|
|||
* Newer families: LLC ID is calculated from the number
|
||||
* of threads sharing the L3 cache.
|
||||
*/
|
||||
u32 eax, ebx, ecx, edx, num_sharing_cache = 0;
|
||||
u32 llc_index = find_num_cache_leaves(c) - 1;
|
||||
struct _cpuid4_info id4 = {};
|
||||
|
||||
cpuid_count(0x8000001d, llc_index, &eax, &ebx, &ecx, &edx);
|
||||
if (eax)
|
||||
num_sharing_cache = ((eax >> 14) & 0xfff) + 1;
|
||||
|
||||
if (num_sharing_cache) {
|
||||
int index_msb = get_count_order(num_sharing_cache);
|
||||
|
||||
c->topo.llc_id = c->topo.apicid >> index_msb;
|
||||
}
|
||||
if (!amd_fill_cpuid4_info(llc_index, &id4))
|
||||
c->topo.llc_id = get_cache_id(c->topo.apicid, &id4);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -598,27 +607,12 @@ int init_cache_level(unsigned int cpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The max shared threads number comes from CPUID(0x4) EAX[25-14] with input
|
||||
* ECX as cache index. Then right shift apicid by the number's order to get
|
||||
* cache id for this cache node.
|
||||
*/
|
||||
static void get_cache_id(int cpu, struct _cpuid4_info *id4)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
unsigned long num_threads_sharing;
|
||||
int index_msb;
|
||||
|
||||
num_threads_sharing = 1 + id4->eax.split.num_threads_sharing;
|
||||
index_msb = get_count_order(num_threads_sharing);
|
||||
id4->id = c->topo.apicid >> index_msb;
|
||||
}
|
||||
|
||||
int populate_cache_leaves(unsigned int cpu)
|
||||
{
|
||||
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
|
||||
struct cacheinfo *ci = this_cpu_ci->info_list;
|
||||
u8 cpu_vendor = boot_cpu_data.x86_vendor;
|
||||
u32 apicid = cpu_data(cpu).topo.apicid;
|
||||
struct amd_northbridge *nb = NULL;
|
||||
struct _cpuid4_info id4 = {};
|
||||
int idx, ret;
|
||||
|
|
@ -628,7 +622,7 @@ int populate_cache_leaves(unsigned int cpu)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
get_cache_id(cpu, &id4);
|
||||
id4.id = get_cache_id(apicid, &id4);
|
||||
|
||||
if (cpu_vendor == X86_VENDOR_AMD || cpu_vendor == X86_VENDOR_HYGON)
|
||||
nb = amd_init_l3_cache(idx);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] =
|
|||
#ifdef CONFIG_ACRN_GUEST
|
||||
&x86_hyper_acrn,
|
||||
#endif
|
||||
#ifdef CONFIG_BHYVE_GUEST
|
||||
&x86_hyper_bhyve,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum x86_hypervisor_type x86_hyper_type;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ static void store_node(struct topo_scan *tscan, u16 nr_nodes, u16 node_id)
|
|||
tscan->amd_node_id = node_id;
|
||||
}
|
||||
|
||||
static bool parse_8000_001e(struct topo_scan *tscan, bool has_topoext)
|
||||
static bool parse_8000_001e(struct topo_scan *tscan)
|
||||
{
|
||||
struct {
|
||||
// eax
|
||||
|
|
@ -85,7 +85,7 @@ static bool parse_8000_001e(struct topo_scan *tscan, bool has_topoext)
|
|||
* If leaf 0xb/0x26 is available, then the APIC ID and the domain
|
||||
* shifts are set already.
|
||||
*/
|
||||
if (!has_topoext) {
|
||||
if (!cpu_feature_enabled(X86_FEATURE_XTOPOLOGY)) {
|
||||
tscan->c->topo.initial_apicid = leaf.ext_apic_id;
|
||||
|
||||
/*
|
||||
|
|
@ -163,11 +163,12 @@ static void topoext_fixup(struct topo_scan *tscan)
|
|||
c->x86 != 0x15 || c->x86_model < 0x10 || c->x86_model > 0x6f)
|
||||
return;
|
||||
|
||||
if (msr_set_bit(0xc0011005, 54) <= 0)
|
||||
if (msr_set_bit(MSR_AMD64_CPUID_EXT_FEAT,
|
||||
MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT_BIT) <= 0)
|
||||
return;
|
||||
|
||||
rdmsrq(0xc0011005, msrval);
|
||||
if (msrval & BIT_64(54)) {
|
||||
rdmsrq(MSR_AMD64_CPUID_EXT_FEAT, msrval);
|
||||
if (msrval & MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT) {
|
||||
set_cpu_cap(c, X86_FEATURE_TOPOEXT);
|
||||
pr_info_once(FW_INFO "CPU: Re-enabling disabled Topology Extensions Support.\n");
|
||||
}
|
||||
|
|
@ -175,30 +176,27 @@ static void topoext_fixup(struct topo_scan *tscan)
|
|||
|
||||
static void parse_topology_amd(struct topo_scan *tscan)
|
||||
{
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES))
|
||||
tscan->c->topo.cpu_type = cpuid_ebx(0x80000026);
|
||||
|
||||
/*
|
||||
* Try to get SMT, CORE, TILE, and DIE shifts from extended
|
||||
* CPUID leaf 0x8000_0026 on supported processors first. If
|
||||
* extended CPUID leaf 0x8000_0026 is not supported, try to
|
||||
* get SMT and CORE shift from leaf 0xb. If either leaf is
|
||||
* available, cpu_parse_topology_ext() will return true.
|
||||
*/
|
||||
bool has_xtopology = cpu_parse_topology_ext(tscan);
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES))
|
||||
tscan->c->topo.cpu_type = cpuid_ebx(0x80000026);
|
||||
|
||||
/*
|
||||
*
|
||||
* If XTOPOLOGY leaves (0x26/0xb) are not available, try to
|
||||
* get the CORE shift from leaf 0x8000_0008 first.
|
||||
*/
|
||||
if (!has_xtopology && !parse_8000_0008(tscan))
|
||||
if (!cpu_parse_topology_ext(tscan) && !parse_8000_0008(tscan))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Prefer leaf 0x8000001e if available to get the SMT shift and
|
||||
* the initial APIC ID if XTOPOLOGY leaves are not available.
|
||||
*/
|
||||
if (parse_8000_001e(tscan, has_xtopology))
|
||||
if (parse_8000_001e(tscan))
|
||||
return;
|
||||
|
||||
/* Try the NODEID MSR */
|
||||
|
|
|
|||
|
|
@ -156,15 +156,26 @@ static int identify_insn(struct insn *insn)
|
|||
if (!insn->modrm.nbytes)
|
||||
return -EINVAL;
|
||||
|
||||
/* All the instructions of interest start with 0x0f. */
|
||||
if (insn->opcode.bytes[0] != 0xf)
|
||||
/* The instructions of interest have 2-byte opcodes: 0F 00 or 0F 01. */
|
||||
if (insn->opcode.nbytes < 2 || insn->opcode.bytes[0] != 0xf)
|
||||
return -EINVAL;
|
||||
|
||||
if (insn->opcode.bytes[1] == 0x1) {
|
||||
switch (X86_MODRM_REG(insn->modrm.value)) {
|
||||
case 0:
|
||||
/* The reg form of 0F 01 /0 encodes VMX instructions. */
|
||||
if (X86_MODRM_MOD(insn->modrm.value) == 3)
|
||||
return -EINVAL;
|
||||
|
||||
return UMIP_INST_SGDT;
|
||||
case 1:
|
||||
/*
|
||||
* The reg form of 0F 01 /1 encodes MONITOR/MWAIT,
|
||||
* STAC/CLAC, and ENCLS.
|
||||
*/
|
||||
if (X86_MODRM_MOD(insn->modrm.value) == 3)
|
||||
return -EINVAL;
|
||||
|
||||
return UMIP_INST_SIDT;
|
||||
case 4:
|
||||
return UMIP_INST_SMSW;
|
||||
|
|
|
|||
|
|
@ -790,7 +790,7 @@ static const struct x86_cpu_id isst_cpu_ids[] = {
|
|||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, SST_HPM_SUPPORTED),
|
||||
X86_MATCH_VFM(INTEL_ICELAKE_D, 0),
|
||||
X86_MATCH_VFM(INTEL_ICELAKE_X, 0),
|
||||
X86_MATCH_VFM(INTEL_PANTHERCOVE_X, SST_HPM_SUPPORTED),
|
||||
X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, SST_HPM_SUPPORTED),
|
||||
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0),
|
||||
X86_MATCH_VFM(INTEL_SKYLAKE_X, SST_MBOX_SUPPORTED),
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ static const struct x86_cpu_id tpmi_cpu_ids[] = {
|
|||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, NULL),
|
||||
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, NULL),
|
||||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, NULL),
|
||||
X86_MATCH_VFM(INTEL_PANTHERCOVE_X, NULL),
|
||||
X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, NULL),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, tpmi_cpu_ids);
|
||||
|
|
|
|||
|
|
@ -1195,7 +1195,7 @@ static const struct platform_data turbostat_pdata[] = {
|
|||
{ INTEL_EMERALDRAPIDS_X, &spr_features },
|
||||
{ INTEL_GRANITERAPIDS_X, &spr_features },
|
||||
{ INTEL_GRANITERAPIDS_D, &spr_features },
|
||||
{ INTEL_PANTHERCOVE_X, &dmr_features },
|
||||
{ INTEL_DIAMONDRAPIDS_X, &dmr_features },
|
||||
{ INTEL_LAKEFIELD, &cnl_features },
|
||||
{ INTEL_ALDERLAKE, &adl_features },
|
||||
{ INTEL_ALDERLAKE_L, &adl_features },
|
||||
|
|
|
|||
Loading…
Reference in New Issue