From 1e8996f94f512780363b368053001774839d25fa Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Fri, 12 Sep 2025 17:30:26 -0700 Subject: [PATCH] vmm: hypervisor: simplify VM creation API For MSHV customers don't want to make everything default during partition creation. For example nested support, some synthetic features could be controlled from CLI through platform argument. Create_vm API getting messy after adding more flags. This patch introduces common data struct to be passed from vmm crate to hypervisor crate during partition creation. Signed-off-by: Muminul Islam --- hypervisor/src/hypervisor.rs | 22 +--- hypervisor/src/kvm/aarch64/gic/mod.rs | 11 +- hypervisor/src/kvm/mod.rs | 95 ++++++-------- hypervisor/src/kvm/riscv64/aia.rs | 3 +- hypervisor/src/lib.rs | 10 ++ hypervisor/src/mshv/mod.rs | 174 +++++++++++--------------- vmm/src/cpu.rs | 32 +++-- vmm/src/vm.rs | 36 +++--- 8 files changed, 167 insertions(+), 216 deletions(-) diff --git a/hypervisor/src/hypervisor.rs b/hypervisor/src/hypervisor.rs index 13d00fa00..5db46d990 100644 --- a/hypervisor/src/hypervisor.rs +++ b/hypervisor/src/hypervisor.rs @@ -13,7 +13,6 @@ use std::sync::Arc; use thiserror::Error; -use crate::HypervisorType; #[cfg(target_arch = "x86_64")] use crate::arch::x86::CpuIdEntry; #[cfg(target_arch = "x86_64")] @@ -21,6 +20,7 @@ use crate::cpu::CpuVendor; #[cfg(feature = "tdx")] use crate::kvm::TdxCapabilities; use crate::vm::Vm; +use crate::{HypervisorType, HypervisorVmConfig}; #[derive(Error, Debug)] pub enum HypervisorError { @@ -110,25 +110,7 @@ pub trait Hypervisor: Send + Sync { /// Create a Vm using the underlying hypervisor /// Return a hypervisor-agnostic Vm trait object /// - fn create_vm(&self) -> Result>; - /// - /// Create a Vm of a specific type using the underlying hypervisor - /// Return a hypervisor-agnostic Vm trait object - /// - fn create_vm_with_type(&self, _vm_type: u64) -> Result> { - unreachable!() - } - /// - /// Create a Vm of a specific type using the underlying hypervisor, passing memory size - /// Return a hypervisor-agnostic Vm trait object - /// - fn create_vm_with_type_and_memory( - &self, - _vm_type: u64, - #[cfg(feature = "sev_snp")] _mem_size: u64, - ) -> Result> { - unreachable!() - } + fn create_vm(&self, config: HypervisorVmConfig) -> Result>; #[cfg(target_arch = "x86_64")] /// /// Get the supported CpuID diff --git a/hypervisor/src/kvm/aarch64/gic/mod.rs b/hypervisor/src/kvm/aarch64/gic/mod.rs index 8bb79be2b..8bd0ed240 100644 --- a/hypervisor/src/kvm/aarch64/gic/mod.rs +++ b/hypervisor/src/kvm/aarch64/gic/mod.rs @@ -482,6 +482,7 @@ impl Vgic for KvmGicV3Its { #[cfg(test)] mod tests { + use crate::HypervisorVmConfig; use crate::aarch64::gic::{ get_dist_regs, get_icc_regs, get_redist_regs, set_dist_regs, set_icc_regs, set_redist_regs, }; @@ -506,7 +507,7 @@ mod tests { #[test] fn test_create_gic() { let hv = crate::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); KvmGicV3Its::new(&*vm, create_test_vgic_config()).unwrap(); } @@ -514,7 +515,7 @@ mod tests { #[test] fn test_get_set_dist_regs() { let hv = crate::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let _ = vm.create_vcpu(0, None).unwrap(); let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic"); @@ -527,7 +528,7 @@ mod tests { #[test] fn test_get_set_redist_regs() { let hv = crate::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let _ = vm.create_vcpu(0, None).unwrap(); let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic"); @@ -542,7 +543,7 @@ mod tests { #[test] fn test_get_set_icc_regs() { let hv = crate::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let _ = vm.create_vcpu(0, None).unwrap(); let gic = KvmGicV3Its::new(&*vm, create_test_vgic_config()).expect("Cannot create gic"); @@ -557,7 +558,7 @@ mod tests { #[test] fn test_save_data_tables() { let hv = crate::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let _ = vm.create_vcpu(0, None).unwrap(); let gic = vm .create_vgic(create_test_vgic_config()) diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 6becd0e41..8e516bb76 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -46,7 +46,7 @@ pub use crate::riscv64::{ #[cfg(target_arch = "riscv64")] use crate::riscv64_reg_id; use crate::vm::{self, InterruptSourceConfig, VmOps}; -use crate::{HypervisorType, cpu, hypervisor}; +use crate::{HypervisorType, HypervisorVmConfig, cpu, hypervisor}; // x86_64 dependencies #[cfg(target_arch = "x86_64")] pub mod x86_64; @@ -103,7 +103,7 @@ use kvm_bindings::{ #[cfg(target_arch = "riscv64")] use kvm_bindings::{KVM_REG_RISCV_CORE, kvm_riscv_core}; #[cfg(feature = "tdx")] -use kvm_bindings::{KVMIO, kvm_run__bindgen_ty_1}; +use kvm_bindings::{KVM_X86_DEFAULT_VM, KVM_X86_SW_PROTECTED_VM, KVMIO, kvm_run__bindgen_ty_1}; pub use kvm_ioctls::{Cap, Kvm, VcpuExit}; use thiserror::Error; use vfio_ioctls::VfioDeviceFd; @@ -539,10 +539,11 @@ impl KvmVm { /// /// ``` /// # use hypervisor::kvm::KvmHypervisor; +/// # use hypervisor::HypervisorVmConfig; /// # use std::sync::Arc; /// let kvm = KvmHypervisor::new().unwrap(); /// let hypervisor = Arc::new(kvm); -/// let vm = hypervisor.create_vm().expect("new VM fd creation failed"); +/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed"); /// ``` impl vm::Vm for KvmVm { #[cfg(target_arch = "x86_64")] @@ -1161,10 +1162,11 @@ impl KvmHypervisor { /// /// ``` /// # use hypervisor::kvm::KvmHypervisor; +/// # use hypervisor::HypervisorVmConfig; /// # use std::sync::Arc; /// let kvm = KvmHypervisor::new().unwrap(); /// let hypervisor = Arc::new(kvm); -/// let vm = hypervisor.create_vm().expect("new VM fd creation failed"); +/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed"); /// ``` impl hypervisor::Hypervisor for KvmHypervisor { /// @@ -1174,38 +1176,39 @@ impl hypervisor::Hypervisor for KvmHypervisor { HypervisorType::Kvm } - /// - /// Create a Vm of a specific type using the underlying hypervisor, passing memory size - /// Return a hypervisor-agnostic Vm trait object - /// - /// # Examples - /// - /// ``` - /// # use hypervisor::kvm::KvmHypervisor; - /// use hypervisor::kvm::KvmVm; - /// let hypervisor = KvmHypervisor::new().unwrap(); - /// let vm = hypervisor.create_vm_with_type_and_memory(0).unwrap(); - /// ``` - fn create_vm_with_type_and_memory( - &self, - vm_type: u64, - #[cfg(feature = "sev_snp")] _mem_size: u64, - ) -> hypervisor::Result> { - self.create_vm_with_type(vm_type) - } - /// Create a KVM vm object of a specific VM type and return the object as Vm trait object /// /// # Examples /// /// ``` /// # use hypervisor::kvm::KvmHypervisor; - /// use hypervisor::kvm::KvmVm; + /// # use hypervisor::kvm::KvmVm; + /// # use hypervisor::HypervisorVmConfig; /// let hypervisor = KvmHypervisor::new().unwrap(); - /// let vm = hypervisor.create_vm_with_type(0).unwrap(); + /// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).unwrap(); /// ``` - fn create_vm_with_type(&self, vm_type: u64) -> hypervisor::Result> { + fn create_vm(&self, _config: HypervisorVmConfig) -> hypervisor::Result> { let fd: VmFd; + + #[allow(unused_mut)] + #[allow(unused_assignments)] + let mut vm_type: u64 = 0; // Create with default platform type + + // When KVM supports Cap::ArmVmIPASize, it is better to get the IPA + // size from the host and use that when creating the VM, which may + // avoid unnecessary VM creation failures. + #[cfg(target_arch = "aarch64")] + if self.kvm.check_extension(Cap::ArmVmIPASize) { + vm_type = self.kvm.get_host_ipa_limit().try_into().unwrap(); + } + + #[cfg(feature = "tdx")] + if _config.tdx_enabled { + vm_type = KVM_X86_SW_PROTECTED_VM.into(); + } else { + vm_type = KVM_X86_DEFAULT_VM.into(); + }; + loop { match self.kvm.create_vm_with_type(vm_type) { Ok(res) => fd = res, @@ -1256,31 +1259,6 @@ impl hypervisor::Hypervisor for KvmHypervisor { } } - /// Create a KVM vm object and return the object as Vm trait object - /// - /// # Examples - /// - /// ``` - /// # use hypervisor::kvm::KvmHypervisor; - /// use hypervisor::kvm::KvmVm; - /// let hypervisor = KvmHypervisor::new().unwrap(); - /// let vm = hypervisor.create_vm().unwrap(); - /// ``` - fn create_vm(&self) -> hypervisor::Result> { - #[allow(unused_mut)] - let mut vm_type: u64 = 0; // Create with default platform type - - // When KVM supports Cap::ArmVmIPASize, it is better to get the IPA - // size from the host and use that when creating the VM, which may - // avoid unnecessary VM creation failures. - #[cfg(target_arch = "aarch64")] - if self.kvm.check_extension(Cap::ArmVmIPASize) { - vm_type = self.kvm.get_host_ipa_limit().try_into().unwrap(); - } - - self.create_vm_with_type(vm_type) - } - fn check_required_extensions(&self) -> hypervisor::Result<()> { check_required_kvm_extensions(&self.kvm) .map_err(|e| hypervisor::HypervisorError::CheckExtensions(e.into())) @@ -1367,10 +1345,11 @@ pub struct KvmVcpu { /// /// ``` /// # use hypervisor::kvm::KvmHypervisor; +/// # use hypervisor::HypervisorVmConfig; /// # use std::sync::Arc; /// let kvm = KvmHypervisor::new().unwrap(); /// let hypervisor = Arc::new(kvm); -/// let vm = hypervisor.create_vm().expect("new VM fd creation failed"); +/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed"); /// let vcpu = vm.create_vcpu(0, None).unwrap(); /// ``` impl cpu::Vcpu for KvmVcpu { @@ -2449,9 +2428,10 @@ impl cpu::Vcpu for KvmVcpu { /// ```rust /// # use hypervisor::kvm::KvmHypervisor; /// # use std::sync::Arc; + /// # use hypervisor::HypervisorVmConfig; /// let kvm = KvmHypervisor::new().unwrap(); /// let hv = Arc::new(kvm); - /// let vm = hv.create_vm().expect("new VM fd creation failed"); + /// let vm = hv.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed"); /// vm.enable_split_irq().unwrap(); /// let vcpu = vm.create_vcpu(0, None).unwrap(); /// let state = vcpu.state().unwrap(); @@ -2686,10 +2666,11 @@ impl cpu::Vcpu for KvmVcpu { /// /// ```rust /// # use hypervisor::kvm::KvmHypervisor; + /// # use hypervisor::HypervisorVmConfig; /// # use std::sync::Arc; /// let kvm = KvmHypervisor::new().unwrap(); /// let hv = Arc::new(kvm); - /// let vm = hv.create_vm().expect("new VM fd creation failed"); + /// let vm = hv.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed"); /// vm.enable_split_irq().unwrap(); /// let vcpu = vm.create_vcpu(0, None).unwrap(); /// let state = vcpu.state().unwrap(); @@ -3069,7 +3050,9 @@ mod tests { let kvm = KvmHypervisor::new().unwrap(); let hypervisor = Arc::new(kvm); - let vm = hypervisor.create_vm().expect("new VM fd creation failed"); + let vm = hypervisor + .create_vm(HypervisorVmConfig::default()) + .expect("new VM fd creation failed"); let vcpu0 = vm.create_vcpu(0, None).unwrap(); let core_regs = StandardRegisters::from(kvm_riscv_core { diff --git a/hypervisor/src/kvm/riscv64/aia.rs b/hypervisor/src/kvm/riscv64/aia.rs index 1aebbafbe..88ca061c0 100644 --- a/hypervisor/src/kvm/riscv64/aia.rs +++ b/hypervisor/src/kvm/riscv64/aia.rs @@ -251,6 +251,7 @@ impl Vaia for KvmAiaImsics { #[cfg(test)] mod tests { + use crate::HypervisorVmConfig; use crate::arch::riscv64::aia::VaiaConfig; use crate::kvm::KvmAiaImsics; @@ -266,7 +267,7 @@ mod tests { #[test] fn test_create_aia() { let hv = crate::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let _vcpu = vm.create_vcpu(0, None).unwrap(); assert!(KvmAiaImsics::new(&*vm, create_test_vaia_config()).is_ok()); diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index 205691a42..d9448c8c6 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -188,6 +188,16 @@ impl ClockData { } } +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] +pub struct HypervisorVmConfig { + #[cfg(feature = "tdx")] + pub tdx_enabled: bool, + #[cfg(feature = "sev_snp")] + pub sev_snp_enabled: bool, + #[cfg(feature = "sev_snp")] + pub mem_size: u64, +} + #[derive(Copy, Clone)] pub enum IrqRoutingEntry { #[cfg(feature = "kvm")] diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 373e338f1..385a44462 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -32,7 +32,7 @@ use crate::arch::x86::emulator::Emulator; use crate::mshv::aarch64::emulator; use crate::mshv::emulator::MshvEmulatorContext; use crate::vm::{self, InterruptSourceConfig, VmOps}; -use crate::{HypervisorType, cpu, hypervisor, vec_with_array_field}; +use crate::{HypervisorType, HypervisorVmConfig, cpu, hypervisor, vec_with_array_field}; #[cfg(feature = "sev_snp")] mod snp_constants; // x86_64 dependencies @@ -269,16 +269,74 @@ impl MshvHypervisor { .get_msr_index_list() .map_err(|e| hypervisor::HypervisorError::GetMsrList(e.into())) } +} + +impl MshvHypervisor { + /// Create a hypervisor based on Mshv + #[allow(clippy::new_ret_no_self)] + pub fn new() -> hypervisor::Result> { + let mshv_obj = + Mshv::new().map_err(|e| hypervisor::HypervisorError::HypervisorCreate(e.into()))?; + Ok(Arc::new(MshvHypervisor { mshv: mshv_obj })) + } + /// Check if the hypervisor is available + pub fn is_available() -> hypervisor::Result { + match std::fs::metadata("/dev/mshv") { + Ok(_) => Ok(true), + Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(false), + Err(err) => Err(hypervisor::HypervisorError::HypervisorAvailableCheck( + err.into(), + )), + } + } +} + +/// Implementation of Hypervisor trait for Mshv +/// +/// # Examples +/// +/// ``` +/// use hypervisor::mshv::MshvHypervisor; +/// # use hypervisor::HypervisorVmConfig; +/// use std::sync::Arc; +/// let mshv = MshvHypervisor::new().unwrap(); +/// let hypervisor = Arc::new(mshv); +/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed"); +/// ``` +impl hypervisor::Hypervisor for MshvHypervisor { + /// + /// Returns the type of the hypervisor + /// + fn hypervisor_type(&self) -> HypervisorType { + HypervisorType::Mshv + } + + /// Create a mshv vm object and return the object as Vm trait object + /// + /// # Examples + /// + /// ``` + /// # extern crate hypervisor; + /// use hypervisor::mshv::MshvHypervisor; + /// use hypervisor::mshv::MshvVm; + /// use hypervisor::HypervisorVmConfig; + /// let config = HypervisorVmConfig::default(); + /// let hypervisor = MshvHypervisor::new().unwrap(); + /// let vm = hypervisor.create_vm(config).unwrap(); + /// ``` + fn create_vm(&self, _config: HypervisorVmConfig) -> hypervisor::Result> { + #[allow(unused_mut)] + #[allow(unused_assignments)] + let mut mshv_vm_type = VmType::Normal; // Create with default platform type + #[cfg(feature = "sev_snp")] + { + mshv_vm_type = if _config.sev_snp_enabled { + VmType::Snp + } else { + VmType::Normal + }; + } - fn create_vm_with_type_and_memory_int( - &self, - vm_type: u64, - #[cfg(feature = "sev_snp")] _mem_size: Option, - ) -> hypervisor::Result> { - let mshv_vm_type: VmType = match VmType::try_from(vm_type) { - Ok(vm_type) => vm_type, - Err(_) => return Err(hypervisor::HypervisorError::UnsupportedVmType()), - }; let fd: VmFd; loop { match self.mshv.create_vm_with_type(mshv_vm_type) { @@ -321,7 +379,7 @@ impl MshvHypervisor { #[cfg(feature = "sev_snp")] host_access_pages: ArcSwap::new( AtomicBitmap::new( - _mem_size.unwrap_or_default() as usize, + _config.mem_size as usize, NonZeroUsize::new(HV_PAGE_SIZE).unwrap(), ) .into(), @@ -337,94 +395,6 @@ impl MshvHypervisor { })) } } -} - -impl MshvHypervisor { - /// Create a hypervisor based on Mshv - #[allow(clippy::new_ret_no_self)] - pub fn new() -> hypervisor::Result> { - let mshv_obj = - Mshv::new().map_err(|e| hypervisor::HypervisorError::HypervisorCreate(e.into()))?; - Ok(Arc::new(MshvHypervisor { mshv: mshv_obj })) - } - /// Check if the hypervisor is available - pub fn is_available() -> hypervisor::Result { - match std::fs::metadata("/dev/mshv") { - Ok(_) => Ok(true), - Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(false), - Err(err) => Err(hypervisor::HypervisorError::HypervisorAvailableCheck( - err.into(), - )), - } - } -} - -/// Implementation of Hypervisor trait for Mshv -/// -/// # Examples -/// -/// ``` -/// use hypervisor::mshv::MshvHypervisor; -/// use std::sync::Arc; -/// let mshv = MshvHypervisor::new().unwrap(); -/// let hypervisor = Arc::new(mshv); -/// let vm = hypervisor.create_vm().expect("new VM fd creation failed"); -/// ``` -impl hypervisor::Hypervisor for MshvHypervisor { - /// - /// Returns the type of the hypervisor - /// - fn hypervisor_type(&self) -> HypervisorType { - HypervisorType::Mshv - } - - /// - /// Create a Vm of a specific type using the underlying hypervisor, passing memory size - /// Return a hypervisor-agnostic Vm trait object - /// - /// # Examples - /// - /// ``` - /// use hypervisor::kvm::KvmHypervisor; - /// use hypervisor::kvm::KvmVm; - /// let hypervisor = KvmHypervisor::new().unwrap(); - /// let vm = hypervisor.create_vm_with_type(0, 512*1024*1024).unwrap(); - /// ``` - fn create_vm_with_type_and_memory( - &self, - vm_type: u64, - #[cfg(feature = "sev_snp")] _mem_size: u64, - ) -> hypervisor::Result> { - self.create_vm_with_type_and_memory_int( - vm_type, - #[cfg(feature = "sev_snp")] - Some(_mem_size), - ) - } - - fn create_vm_with_type(&self, vm_type: u64) -> hypervisor::Result> { - self.create_vm_with_type_and_memory_int( - vm_type, - #[cfg(feature = "sev_snp")] - None, - ) - } - - /// Create a mshv vm object and return the object as Vm trait object - /// - /// # Examples - /// - /// ``` - /// # extern crate hypervisor; - /// use hypervisor::mshv::MshvHypervisor; - /// use hypervisor::mshv::MshvVm; - /// let hypervisor = MshvHypervisor::new().unwrap(); - /// let vm = hypervisor.create_vm().unwrap(); - /// ``` - fn create_vm(&self) -> hypervisor::Result> { - let vm_type = 0; - self.create_vm_with_type(vm_type) - } #[cfg(target_arch = "x86_64")] /// /// Get the supported CpuID @@ -508,10 +478,11 @@ pub struct MshvVcpu { /// /// ``` /// use hypervisor::mshv::MshvHypervisor; +/// use hypervisor::HypervisorVmConfig; /// use std::sync::Arc; /// let mshv = MshvHypervisor::new().unwrap(); /// let hypervisor = Arc::new(mshv); -/// let vm = hypervisor.create_vm().expect("new VM fd creation failed"); +/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed"); /// let vcpu = vm.create_vcpu(0, None).unwrap(); /// ``` impl cpu::Vcpu for MshvVcpu { @@ -1787,10 +1758,11 @@ impl MshvVm { /// ``` /// extern crate hypervisor; /// use hypervisor::mshv::MshvHypervisor; +/// use hypervisor::HypervisorVmConfig; /// use std::sync::Arc; /// let mshv = MshvHypervisor::new().unwrap(); /// let hypervisor = Arc::new(mshv); -/// let vm = hypervisor.create_vm().expect("new VM fd creation failed"); +/// let vm = hypervisor.create_vm(HypervisorVmConfig::default()).expect("new VM fd creation failed"); /// ``` impl vm::Vm for MshvVm { #[cfg(target_arch = "x86_64")] diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 43edf5015..2b52f950c 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -2861,14 +2861,16 @@ mod tests { use arch::layout::{BOOT_STACK_POINTER, ZERO_PAGE_START}; use arch::x86_64::interrupts::*; use arch::x86_64::regs::*; - use hypervisor::StandardRegisters; use hypervisor::arch::x86::{FpuState, LapicState}; + use hypervisor::{HypervisorVmConfig, StandardRegisters}; use linux_loader::loader::bootparam::setup_header; #[test] fn test_setlint() { let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().expect("new VM fd creation failed"); + let vm = hv + .create_vm(HypervisorVmConfig::default()) + .expect("new VM fd creation failed"); hv.check_required_extensions().unwrap(); // Calling get_lapic will fail if there is no irqchip before hand. vm.create_irq_chip().unwrap(); @@ -2894,7 +2896,9 @@ mod tests { #[test] fn test_setup_fpu() { let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().expect("new VM fd creation failed"); + let vm = hv + .create_vm(HypervisorVmConfig::default()) + .expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0, None).unwrap(); setup_fpu(&vcpu).unwrap(); @@ -2918,7 +2922,9 @@ mod tests { use hypervisor::arch::x86::{MsrEntry, msr_index}; let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().expect("new VM fd creation failed"); + let vm = hv + .create_vm(HypervisorVmConfig::default()) + .expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0, None).unwrap(); setup_msrs(&vcpu).unwrap(); @@ -2944,7 +2950,9 @@ mod tests { #[test] fn test_setup_regs_for_pvh() { let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().expect("new VM fd creation failed"); + let vm = hv + .create_vm(HypervisorVmConfig::default()) + .expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0, None).unwrap(); let mut expected_regs: StandardRegisters = vcpu.create_standard_regs(); @@ -2968,7 +2976,9 @@ mod tests { #[test] fn test_setup_regs_for_bzimage() { let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().expect("new VM fd creation failed"); + let vm = hv + .create_vm(HypervisorVmConfig::default()) + .expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0, None).unwrap(); let mut expected_regs: StandardRegisters = vcpu.create_standard_regs(); @@ -3000,7 +3010,6 @@ mod tests { use std::{mem, mem::offset_of}; use arch::layout; - use hypervisor::HypervisorCpuError; use hypervisor::arch::aarch64::regs::MPIDR_EL1; #[cfg(feature = "kvm")] use hypervisor::arm64_core_reg_id; @@ -3010,11 +3019,12 @@ mod tests { use hypervisor::kvm::kvm_bindings::{ KVM_REG_ARM_CORE, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_SIZE_U64, user_pt_regs, }; + use hypervisor::{HypervisorCpuError, HypervisorVmConfig}; #[test] fn test_setup_regs() { let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let vcpu = vm.create_vcpu(0, None).unwrap(); // Must fail when vcpu is not initialized yet. @@ -3030,7 +3040,7 @@ mod tests { #[test] fn test_read_mpidr() { let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let vcpu = vm.create_vcpu(0, None).unwrap(); let mut kvi = vcpu.create_vcpu_init(); vm.get_preferred_target(&mut kvi).unwrap(); @@ -3055,7 +3065,7 @@ mod tests { #[test] fn test_save_restore_core_regs() { let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let vcpu = vm.create_vcpu(0, None).unwrap(); let mut kvi = vcpu.create_vcpu_init(); vm.get_preferred_target(&mut kvi).unwrap(); @@ -3105,7 +3115,7 @@ mod tests { #[test] fn test_get_set_mpstate() { let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let vcpu = vm.create_vcpu(0, None).unwrap(); let mut kvi = vcpu.create_vcpu_init(); vm.get_preferred_target(&mut kvi).unwrap(); diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 836feb470..f6199fdf1 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -45,7 +45,7 @@ use gdbstub_arch::aarch64::reg::AArch64CoreRegs as CoreRegs; use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs; #[cfg(target_arch = "aarch64")] use hypervisor::arch::aarch64::regs::AARCH64_PMU_IRQ; -use hypervisor::{HypervisorVmError, VmOps}; +use hypervisor::{HypervisorVmConfig, HypervisorVmError, VmOps}; use libc::{SIGWINCH, termios}; use linux_loader::cmdline::Cmdline; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] @@ -1084,26 +1084,16 @@ impl Vm { #[cfg(feature = "sev_snp")] mem_size: u64, ) -> Result> { hypervisor.check_required_extensions().unwrap(); + let config = HypervisorVmConfig { + #[cfg(feature = "tdx")] + tdx_enabled, + #[cfg(feature = "sev_snp")] + sev_snp_enabled, + #[cfg(feature = "sev_snp")] + mem_size, + }; - cfg_if::cfg_if! { - if #[cfg(feature = "tdx")] { - // Passing KVM_X86_TDX_VM: 1 if tdx_enabled is true - // Otherwise KVM_X86_LEGACY_VM: 0 - // value of tdx_enabled is mapped to KVM_X86_TDX_VM or KVM_X86_LEGACY_VM - let vm = hypervisor - .create_vm_with_type(u64::from(tdx_enabled)) - .unwrap(); - } else if #[cfg(feature = "sev_snp")] { - // Passing SEV_SNP_ENABLED: 1 if sev_snp_enabled is true - // Otherwise SEV_SNP_DISABLED: 0 - // value of sev_snp_enabled is mapped to SEV_SNP_ENABLED for true or SEV_SNP_DISABLED for false - let vm = hypervisor - .create_vm_with_type_and_memory(u64::from(sev_snp_enabled), mem_size) - .unwrap(); - } else { - let vm = hypervisor.create_vm().unwrap(); - } - } + let vm = hypervisor.create_vm(config).unwrap(); #[cfg(target_arch = "x86_64")] { @@ -3497,7 +3487,7 @@ mod tests { .collect(); let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().unwrap(); + let vm = hv.create_vm(HypervisorVmConfig::default()).unwrap(); let gic = vm .create_vgic(Gic::create_default_config(1)) .expect("Cannot create gic"); @@ -3539,7 +3529,9 @@ pub fn test_vm() { let mem = GuestMemoryMmap::from_ranges(&[(load_addr, mem_size)]).unwrap(); let hv = hypervisor::new().unwrap(); - let vm = hv.create_vm().expect("new VM creation failed"); + let vm = hv + .create_vm(HypervisorVmConfig::default()) + .expect("new VM creation failed"); for (index, region) in mem.iter().enumerate() { let mem_region = vm.make_user_memory_region(