From 7df80220ec23deec254a4468b57a61a8b3c506c3 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 30 May 2023 14:39:57 +0200 Subject: [PATCH] hyperivsor: Add infrastructure to determine CPU vendor Signed-off-by: Anatol Belski --- hypervisor/src/cpu.rs | 9 +++++++++ hypervisor/src/hypervisor.rs | 32 ++++++++++++++++++++++++++++++++ hypervisor/src/lib.rs | 2 ++ 3 files changed, 43 insertions(+) diff --git a/hypervisor/src/cpu.rs b/hypervisor/src/cpu.rs index c2fc77057..919e1cc1f 100644 --- a/hypervisor/src/cpu.rs +++ b/hypervisor/src/cpu.rs @@ -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 diff --git a/hypervisor/src/hypervisor.rs b/hypervisor/src/hypervisor.rs index 778ba7b95..1905b85f0 100644 --- a/hypervisor/src/hypervisor.rs +++ b/hypervisor/src/hypervisor.rs @@ -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() + } + } + } } diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index ac15b6511..51c9ff535 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -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"))]