diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index 1899d282b..77e1f9a43 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -170,6 +170,7 @@ pub struct HypervisorVmConfig { pub sev_snp_enabled: bool, #[cfg(feature = "sev_snp")] pub mem_size: u64, + pub nested: bool, } #[derive(Copy, Clone)] diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index fd2ddd127..90173d011 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -14,7 +14,10 @@ use log::{debug, warn}; use mshv_bindings::*; #[cfg(target_arch = "x86_64")] use mshv_ioctls::InterruptRequest; -use mshv_ioctls::{Mshv, NoDatamatch, VcpuFd, VmFd, VmType, set_registers_64}; +use mshv_ioctls::{ + Mshv, NoDatamatch, VcpuFd, VmFd, VmType, make_default_partition_create_arg, + make_default_synthetic_features_mask, set_registers_64, +}; use vfio_ioctls::VfioDeviceFd; use vm::DataMatch; #[cfg(feature = "sev_snp")] @@ -292,10 +295,37 @@ impl hypervisor::Hypervisor for MshvHypervisor { VmType::Normal }; } - + let mut create_args = make_default_partition_create_arg(mshv_vm_type); + let mut disable_proc_features = hv_partition_processor_features::default(); + // SAFETY: Accessing a union element from bindgen generated bindings. + unsafe { + for i in 0..create_args.pt_num_cpu_fbanks { + disable_proc_features.as_uint64[i as usize] = create_args.pt_cpu_fbanks[i as usize]; + } + #[cfg(target_arch = "x86_64")] + { + // Modify create_args based on user configuration + // For now we only handle nested virtualization, but more features can be added here + if _config.nested { + create_args.pt_flags |= 1 << MSHV_PT_BIT_NESTED_VIRTUALIZATION; + disable_proc_features + .__bindgen_anon_1 + .set_nested_virt_support(0u64); + } else { + disable_proc_features + .__bindgen_anon_1 + .set_nested_virt_support(1u64); + } + } + // Modified feature bit fields are written back to create_args + for i in 0..create_args.pt_num_cpu_fbanks { + create_args.pt_cpu_fbanks[i as usize] = disable_proc_features.as_uint64[i as usize]; + } + } + let synthetic_features_mask = make_default_synthetic_features_mask(); let fd: VmFd; loop { - match self.mshv.create_vm_with_type(mshv_vm_type) { + match self.mshv.create_vm_with_args(&create_args) { Ok(res) => fd = res, Err(e) => { if e.errno() == libc::EINTR { @@ -309,7 +339,11 @@ impl hypervisor::Hypervisor for MshvHypervisor { } break; } - + fd.set_partition_property( + hv_partition_property_code_HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES, + synthetic_features_mask, + ) + .map_err(|e| hypervisor::HypervisorError::SetPartitionProperty(e.into()))?; let vm_fd = Arc::new(fd); #[cfg(target_arch = "x86_64")] diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index f4b46dc4b..0298efc06 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -220,6 +220,7 @@ impl From<&VmConfig> for hypervisor::HypervisorVmConfig { sev_snp_enabled: _value.is_sev_snp_enabled(), #[cfg(feature = "sev_snp")] mem_size: _value.memory.total_size(), + nested: _value.cpus.nested, } } }