diff --git a/Cargo.lock b/Cargo.lock index 5f168d02d..10489854e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1257,9 +1257,9 @@ checksum = "9bec4598fddb13cc7b528819e697852653252b760f1228b7642679bf2ff2cd07" [[package]] name = "mshv-bindings" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577073a0abbf515d17bfe96ca2ce49c44a68454d4179e95ce1244e858a9ebd4e" +checksum = "fd7ebac759cce39aee9b81e19c8182a811161e4439a54ae47bc604e3b6a26ca7" dependencies = [ "libc", "num_enum", @@ -1271,9 +1271,9 @@ dependencies = [ [[package]] name = "mshv-ioctls" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bfcb8dfbdc1be2350d929291e88bd872dacdbeb50944ff36a7ede1de1fd3258" +checksum = "69d0777bea77576c91f7d6a6fed2e188433b3f102a38fb2b5aba259e9690e896" dependencies = [ "libc", "mshv-bindings", @@ -2253,7 +2253,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vfio-bindings" version = "0.4.0" -source = "git+https://github.com/rust-vmm/vfio?branch=main#0d6929d5242c9467c41dd41a53babd90ace7c555" +source = "git+https://github.com/rust-vmm/vfio?branch=main#21d06ceb917ffce6768edefeab02e04d5e79615d" dependencies = [ "vmm-sys-util", ] @@ -2261,7 +2261,7 @@ dependencies = [ [[package]] name = "vfio-ioctls" version = "0.2.0" -source = "git+https://github.com/rust-vmm/vfio?branch=main#0d6929d5242c9467c41dd41a53babd90ace7c555" +source = "git+https://github.com/rust-vmm/vfio?branch=main#21d06ceb917ffce6768edefeab02e04d5e79615d" dependencies = [ "byteorder", "kvm-bindings", diff --git a/Cargo.toml b/Cargo.toml index 3cb55b12e..ea2cf7338 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,8 +107,8 @@ acpi_tables = { git = "https://github.com/rust-vmm/acpi_tables", branch = "main" kvm-bindings = "0.10.0" kvm-ioctls = "0.19.1" linux-loader = "0.13.0" -mshv-bindings = "0.4.0" -mshv-ioctls = "0.4.0" +mshv-bindings = "0.5.0" +mshv-ioctls = "0.5.0" seccompiler = "0.5.0" vfio-bindings = { git = "https://github.com/rust-vmm/vfio", branch = "main" } vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false } diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 7be9913c6..49ff6b394 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -24,7 +24,7 @@ libc = "0.2.155" libfuzzer-sys = "0.4.7" linux-loader = { version = "0.13.0", features = ["bzimage", "elf", "pe"] } micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" } -mshv-bindings = "0.4.0" +mshv-bindings = "0.5.0" net_util = { path = "../net_util" } once_cell = "1.19.0" seccompiler = "0.5.0" diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 9a7b5515d..e8a07903b 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -295,53 +295,6 @@ impl MshvHypervisor { break; } - // Set additional partition property for SEV-SNP partition. - #[cfg(target_arch = "x86_64")] - if mshv_vm_type == VmType::Snp { - let snp_policy = snp::get_default_snp_guest_policy(); - let vmgexit_offloads = snp::get_default_vmgexit_offload_features(); - // SAFETY: access union fields - unsafe { - debug!( - "Setting the partition isolation policy as: 0x{:x}", - snp_policy.as_uint64 - ); - fd.set_partition_property( - hv_partition_property_code_HV_PARTITION_PROPERTY_ISOLATION_POLICY, - snp_policy.as_uint64, - ) - .map_err(|e| hypervisor::HypervisorError::SetPartitionProperty(e.into()))?; - debug!( - "Setting the partition property to enable VMGEXIT offloads as : 0x{:x}", - vmgexit_offloads.as_uint64 - ); - fd.set_partition_property( - hv_partition_property_code_HV_PARTITION_PROPERTY_SEV_VMGEXIT_OFFLOADS, - vmgexit_offloads.as_uint64, - ) - .map_err(|e| hypervisor::HypervisorError::SetPartitionProperty(e.into()))?; - } - } - - // Default Microsoft Hypervisor behavior for unimplemented MSR is to - // send a fault to the guest if it tries to access it. It is possible - // to override this behavior with a more suitable option i.e., ignore - // writes from the guest and return zero in attempt to read unimplemented - // MSR. - #[cfg(target_arch = "x86_64")] - fd.set_partition_property( - hv_partition_property_code_HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION, - hv_unimplemented_msr_action_HV_UNIMPLEMENTED_MSR_ACTION_IGNORE_WRITE_READ_ZERO as u64, - ) - .map_err(|e| hypervisor::HypervisorError::SetPartitionProperty(e.into()))?; - - // Always create a frozen partition - fd.set_partition_property( - hv_partition_property_code_HV_PARTITION_PROPERTY_TIME_FREEZE, - 1u64, - ) - .map_err(|e| hypervisor::HypervisorError::SetPartitionProperty(e.into()))?; - let vm_fd = Arc::new(fd); #[cfg(target_arch = "x86_64")] @@ -2415,4 +2368,63 @@ impl vm::Vm for MshvVm { Ok(()) } + + fn init(&self) -> vm::Result<()> { + self.fd + .initialize() + .map_err(|e| vm::HypervisorVmError::InitializeVm(e.into()))?; + + // Set additional partition property for SEV-SNP partition. + #[cfg(feature = "sev_snp")] + if self.sev_snp_enabled { + let snp_policy = snp::get_default_snp_guest_policy(); + let vmgexit_offloads = snp::get_default_vmgexit_offload_features(); + // SAFETY: access union fields + unsafe { + debug!( + "Setting the partition isolation policy as: 0x{:x}", + snp_policy.as_uint64 + ); + self.fd + .set_partition_property( + hv_partition_property_code_HV_PARTITION_PROPERTY_ISOLATION_POLICY, + snp_policy.as_uint64, + ) + .map_err(|e| vm::HypervisorVmError::InitializeVm(e.into()))?; + debug!( + "Setting the partition property to enable VMGEXIT offloads as : 0x{:x}", + vmgexit_offloads.as_uint64 + ); + self.fd + .set_partition_property( + hv_partition_property_code_HV_PARTITION_PROPERTY_SEV_VMGEXIT_OFFLOADS, + vmgexit_offloads.as_uint64, + ) + .map_err(|e| vm::HypervisorVmError::InitializeVm(e.into()))?; + } + } + // Default Microsoft Hypervisor behavior for unimplemented MSR is to + // send a fault to the guest if it tries to access it. It is possible + // to override this behavior with a more suitable option i.e., ignore + // writes from the guest and return zero in attempt to read unimplemented + // MSR. + #[cfg(target_arch = "x86_64")] + self.fd + .set_partition_property( + hv_partition_property_code_HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION, + hv_unimplemented_msr_action_HV_UNIMPLEMENTED_MSR_ACTION_IGNORE_WRITE_READ_ZERO + as u64, + ) + .map_err(|e| vm::HypervisorVmError::InitializeVm(e.into()))?; + + // Always create a frozen partition + self.fd + .set_partition_property( + hv_partition_property_code_HV_PARTITION_PROPERTY_TIME_FREEZE, + 1u64, + ) + .map_err(|e| vm::HypervisorVmError::InitializeVm(e.into()))?; + + Ok(()) + } } diff --git a/hypervisor/src/vm.rs b/hypervisor/src/vm.rs index 3ce209942..f3c193429 100644 --- a/hypervisor/src/vm.rs +++ b/hypervisor/src/vm.rs @@ -255,6 +255,11 @@ pub enum HypervisorVmError { #[cfg(feature = "sev_snp")] #[error("Failed to mmap:")] MmapToRoot, + /// + /// Failed to initialize VM + /// + #[error("Failed to initialize VM: {0}")] + InitializeVm(#[source] anyhow::Error), } /// /// Result type for returning from a function @@ -417,7 +422,10 @@ pub trait Vm: Send + Sync + Any { ) -> Result<()> { unimplemented!() } - + /// Initialize the VM + fn init(&self) -> Result<()> { + Ok(()) + } /// Pause the VM fn pause(&self) -> Result<()> { Ok(()) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index bda4a76b1..57929d108 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -142,6 +142,9 @@ pub enum Error { #[error("Error from device manager: {0:?}")] DeviceManager(DeviceManagerError), + #[error("Error initializing VM: {0:?}")] + InitializeVm(hypervisor::HypervisorVmError), + #[error("No device with id {0:?} to remove")] NoDeviceToRemove(String), @@ -604,6 +607,8 @@ impl Vm { .map_err(Error::InitializeTdxVm)?; } + vm.init().map_err(Error::InitializeVm)?; + cpu_manager .lock() .unwrap()