hypervisor: use memory size during VM creation

For SEV-SNP VM on MSHV we need to request page access during
IO, we want to avoid such request for the page that have already
been requested. In order to maintain the bitmap we need the memory size
during bitmap creation.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2024-09-05 15:25:53 -07:00 committed by Wei Liu
parent 1001d807ff
commit 4054a49e2d
3 changed files with 114 additions and 47 deletions

View File

@ -118,6 +118,17 @@ pub trait Hypervisor: Send + Sync {
fn create_vm_with_type(&self, _vm_type: u64) -> Result<Arc<dyn Vm>> { fn create_vm_with_type(&self, _vm_type: u64) -> Result<Arc<dyn Vm>> {
unreachable!() 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<Arc<dyn Vm>> {
unreachable!()
}
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
/// ///
/// Get the supported CpuID /// Get the supported CpuID

View File

@ -1076,6 +1076,26 @@ impl hypervisor::Hypervisor for KvmHypervisor {
HypervisorType::Kvm 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<Arc<dyn vm::Vm>> {
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 /// Create a KVM vm object of a specific VM type and return the object as Vm trait object
/// ///
/// # Examples /// # Examples

View File

@ -205,48 +205,12 @@ impl MshvHypervisor {
.get_msr_index_list() .get_msr_index_list()
.map_err(|e| hypervisor::HypervisorError::GetMsrList(e.into())) .map_err(|e| hypervisor::HypervisorError::GetMsrList(e.into()))
} }
}
impl MshvHypervisor { fn create_vm_with_type_and_memory_int(
/// Create a hypervisor based on Mshv &self,
#[allow(clippy::new_ret_no_self)] vm_type: u64,
pub fn new() -> hypervisor::Result<Arc<dyn hypervisor::Hypervisor>> { #[cfg(feature = "sev_snp")] _mem_size: Option<u64>,
let mshv_obj = ) -> hypervisor::Result<Arc<dyn crate::Vm>> {
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<bool> {
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
}
fn create_vm_with_type(&self, vm_type: u64) -> hypervisor::Result<Arc<dyn crate::Vm>> {
let mshv_vm_type: VmType = match VmType::try_from(vm_type) { let mshv_vm_type: VmType = match VmType::try_from(vm_type) {
Ok(vm_type) => vm_type, Ok(vm_type) => vm_type,
Err(_) => return Err(hypervisor::HypervisorError::UnsupportedVmType()), Err(_) => return Err(hypervisor::HypervisorError::UnsupportedVmType()),
@ -350,6 +314,78 @@ impl hypervisor::Hypervisor for MshvHypervisor {
})) }))
} }
} }
}
impl MshvHypervisor {
/// Create a hypervisor based on Mshv
#[allow(clippy::new_ret_no_self)]
pub fn new() -> hypervisor::Result<Arc<dyn hypervisor::Hypervisor>> {
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<bool> {
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<Arc<dyn vm::Vm>> {
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<Arc<dyn crate::Vm>> {
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 /// Create a mshv vm object and return the object as Vm trait object
/// ///
@ -357,7 +393,7 @@ impl hypervisor::Hypervisor for MshvHypervisor {
/// ///
/// ``` /// ```
/// # extern crate hypervisor; /// # extern crate hypervisor;
/// # use hypervisor::mshv::MshvHypervisor; /// use hypervisor::mshv::MshvHypervisor;
/// use hypervisor::mshv::MshvVm; /// use hypervisor::mshv::MshvVm;
/// let hypervisor = MshvHypervisor::new().unwrap(); /// let hypervisor = MshvHypervisor::new().unwrap();
/// let vm = hypervisor.create_vm().unwrap(); /// let vm = hypervisor.create_vm().unwrap();
@ -428,8 +464,8 @@ pub struct MshvVcpu {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # use hypervisor::mshv::MshvHypervisor; /// use hypervisor::mshv::MshvHypervisor;
/// # use std::sync::Arc; /// use std::sync::Arc;
/// let mshv = MshvHypervisor::new().unwrap(); /// let mshv = MshvHypervisor::new().unwrap();
/// let hypervisor = Arc::new(mshv); /// let hypervisor = Arc::new(mshv);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed"); /// let vm = hypervisor.create_vm().expect("new VM fd creation failed");
@ -1572,9 +1608,9 @@ impl MshvVm {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate hypervisor; /// extern crate hypervisor;
/// # use hypervisor::mshv::MshvHypervisor; /// use hypervisor::mshv::MshvHypervisor;
/// # use std::sync::Arc; /// use std::sync::Arc;
/// let mshv = MshvHypervisor::new().unwrap(); /// let mshv = MshvHypervisor::new().unwrap();
/// let hypervisor = Arc::new(mshv); /// let hypervisor = Arc::new(mshv);
/// let vm = hypervisor.create_vm().expect("new VM fd creation failed"); /// let vm = hypervisor.create_vm().expect("new VM fd creation failed");