hyperivsor: Add infrastructure to determine CPU vendor

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski 2023-05-30 14:39:57 +02:00 committed by Anatol Belski
parent 84d2511de0
commit 7df80220ec
3 changed files with 43 additions and 0 deletions

View File

@ -21,6 +21,15 @@ use crate::MpState;
use thiserror::Error;
use vm_memory::GuestAddress;
#[cfg(target_arch = "x86_64")]
#[derive(Copy, Clone, Default)]
pub enum CpuVendor {
#[default]
Unknown,
Intel,
AMD,
}
#[derive(Error, Debug)]
///
/// Enum for CPU error

View File

@ -9,10 +9,14 @@
//
#[cfg(target_arch = "x86_64")]
use crate::arch::x86::CpuIdEntry;
#[cfg(target_arch = "x86_64")]
use crate::cpu::CpuVendor;
#[cfg(feature = "tdx")]
use crate::kvm::TdxCapabilities;
use crate::vm::Vm;
use crate::HypervisorType;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64;
use std::sync::Arc;
use thiserror::Error;
@ -75,6 +79,11 @@ pub enum HypervisorError {
///
#[error("Failed to set partition property:{0}")]
SetPartitionProperty(#[source] anyhow::Error),
///
/// Running on an unsupported CPU
///
#[error("Unsupported CPU:{0}")]
UnsupportedCpu(#[source] anyhow::Error),
}
///
@ -136,4 +145,27 @@ pub trait Hypervisor: Send + Sync {
/// Get maximum number of vCPUs
fn get_max_vcpus(&self) -> u32;
#[cfg(target_arch = "x86_64")]
///
/// Determine CPU vendor
///
fn get_cpu_vendor(&self) -> CpuVendor {
// SAFETY: call cpuid with valid leaves
unsafe {
let leaf = x86_64::__cpuid(0x0);
if leaf.ebx == 0x756e_6547 && leaf.ecx == 0x6c65_746e && leaf.edx == 0x4965_6e69 {
// Vendor string GenuineIntel
CpuVendor::Intel
} else if leaf.ebx == 0x6874_7541 && leaf.ecx == 0x444d_4163 && leaf.edx == 0x6974_6e65
{
// Vendor string AuthenticAMD
CpuVendor::AMD
} else {
// Not known yet, the corresponding manufacturer manual should contain the
// necesssary info. See also https://wiki.osdev.org/CPUID#CPU_Vendor_ID_String
CpuVendor::default()
}
}
}
}

View File

@ -49,6 +49,8 @@ mod cpu;
mod device;
pub use crate::hypervisor::{Hypervisor, HypervisorError};
#[cfg(target_arch = "x86_64")]
pub use cpu::CpuVendor;
pub use cpu::{HypervisorCpuError, Vcpu, VmExit};
pub use device::HypervisorDeviceError;
#[cfg(all(feature = "kvm", target_arch = "aarch64"))]