mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-03 20:15:45 +00:00
vmm, arch: x86_64: Fill the CPUID leaves with the topology
There are two CPUID leaves for handling CPU topology, 0xb and 0x1f. The difference between the two is that the 0x1f leaf (Extended Topology Leaf) supports exposing multiple die packages. Fixes: #1284 Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
e19079782d
commit
a74c6fc14f
@ -629,6 +629,69 @@ pub fn check_required_kvm_extensions(kvm: &Kvm) -> super::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_cpuid_topology(
|
||||||
|
cpuid: &mut CpuId,
|
||||||
|
threads_per_core: u8,
|
||||||
|
cores_per_die: u8,
|
||||||
|
dies_per_package: u8,
|
||||||
|
) {
|
||||||
|
let thread_width = 8 - (threads_per_core - 1).leading_zeros();
|
||||||
|
let core_width = (8 - (cores_per_die - 1).leading_zeros()) + thread_width;
|
||||||
|
let die_width = (8 - (dies_per_package - 1).leading_zeros()) + core_width;
|
||||||
|
|
||||||
|
// CPU Topology leaf 0xb
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(0), CpuidReg::EAX, thread_width);
|
||||||
|
CpuidPatch::set_cpuid_reg(
|
||||||
|
cpuid,
|
||||||
|
0xb,
|
||||||
|
Some(0),
|
||||||
|
CpuidReg::EBX,
|
||||||
|
u32::from(threads_per_core),
|
||||||
|
);
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(0), CpuidReg::ECX, 1 << 8);
|
||||||
|
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(1), CpuidReg::EAX, die_width);
|
||||||
|
CpuidPatch::set_cpuid_reg(
|
||||||
|
cpuid,
|
||||||
|
0xb,
|
||||||
|
Some(1),
|
||||||
|
CpuidReg::EBX,
|
||||||
|
u32::from(dies_per_package * cores_per_die * threads_per_core),
|
||||||
|
);
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(1), CpuidReg::ECX, 2 << 8);
|
||||||
|
|
||||||
|
// CPU Topology leaf 0x1f
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(0), CpuidReg::EAX, thread_width);
|
||||||
|
CpuidPatch::set_cpuid_reg(
|
||||||
|
cpuid,
|
||||||
|
0x1f,
|
||||||
|
Some(0),
|
||||||
|
CpuidReg::EBX,
|
||||||
|
u32::from(threads_per_core),
|
||||||
|
);
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(0), CpuidReg::ECX, 1 << 8);
|
||||||
|
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(1), CpuidReg::EAX, core_width);
|
||||||
|
CpuidPatch::set_cpuid_reg(
|
||||||
|
cpuid,
|
||||||
|
0x1f,
|
||||||
|
Some(1),
|
||||||
|
CpuidReg::EBX,
|
||||||
|
u32::from(cores_per_die * threads_per_core),
|
||||||
|
);
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(1), CpuidReg::ECX, 2 << 8);
|
||||||
|
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(2), CpuidReg::EAX, die_width);
|
||||||
|
CpuidPatch::set_cpuid_reg(
|
||||||
|
cpuid,
|
||||||
|
0x1f,
|
||||||
|
Some(2),
|
||||||
|
CpuidReg::EBX,
|
||||||
|
u32::from(dies_per_package * cores_per_die * threads_per_core),
|
||||||
|
);
|
||||||
|
CpuidPatch::set_cpuid_reg(cpuid, 0x1f, Some(2), CpuidReg::ECX, 5 << 8);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||||
//
|
//
|
||||||
|
|
||||||
use crate::config::CpusConfig;
|
use crate::config::{CpuTopology, CpusConfig};
|
||||||
use crate::device_manager::DeviceManager;
|
use crate::device_manager::DeviceManager;
|
||||||
use crate::CPU_MANAGER_SNAPSHOT_ID;
|
use crate::CPU_MANAGER_SNAPSHOT_ID;
|
||||||
#[cfg(feature = "acpi")]
|
#[cfg(feature = "acpi")]
|
||||||
@ -686,7 +686,7 @@ impl CpuManager {
|
|||||||
|
|
||||||
let device_manager = device_manager.lock().unwrap();
|
let device_manager = device_manager.lock().unwrap();
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let cpuid = CpuManager::patch_cpuid(kvm)?;
|
let cpuid = CpuManager::patch_cpuid(kvm, &config.topology)?;
|
||||||
let cpu_manager = Arc::new(Mutex::new(CpuManager {
|
let cpu_manager = Arc::new(Mutex::new(CpuManager {
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -725,7 +725,7 @@ impl CpuManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn patch_cpuid(kvm: &Kvm) -> Result<CpuId> {
|
fn patch_cpuid(kvm: &Kvm, topology: &Option<CpuTopology>) -> Result<CpuId> {
|
||||||
let mut cpuid_patches = Vec::new();
|
let mut cpuid_patches = Vec::new();
|
||||||
|
|
||||||
// Patch tsc deadline timer bit
|
// Patch tsc deadline timer bit
|
||||||
@ -757,6 +757,15 @@ impl CpuManager {
|
|||||||
|
|
||||||
CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches);
|
CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches);
|
||||||
|
|
||||||
|
if let Some(t) = topology {
|
||||||
|
arch::x86_64::update_cpuid_topology(
|
||||||
|
&mut cpuid,
|
||||||
|
t.threads_per_core,
|
||||||
|
t.cores_per_die,
|
||||||
|
t.dies_per_package,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(cpuid)
|
Ok(cpuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user