diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 40d8796e9..8ef150294 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -69,6 +69,7 @@ pub use x86_64::{VcpuMshvState, emulator}; /// Export generically-named wrappers of mshv-bindings for Unix-based platforms /// pub use { + mshv_bindings::hv_partition_property_code_HV_PARTITION_PROPERTY_PROCESSORS_PER_SOCKET as HV_PARTITION_PROPERTY_PROCESSORS_PER_SOCKET, mshv_bindings::mshv_create_device as CreateDevice, mshv_bindings::mshv_device_attr as DeviceAttr, mshv_ioctls, mshv_ioctls::DeviceFd, }; @@ -1712,6 +1713,16 @@ impl MshvVm { .map_err(|e| vm::HypervisorVmError::CreateDevice(e.into()))?; Ok(VfioDeviceFd::new_from_mshv(device_fd)) } + + /// + /// Sets a partition property. + /// + /// This allows runtime configuration of partition properties. + pub fn set_partition_property(&self, code: u32, value: u64) -> anyhow::Result<()> { + self.fd + .set_partition_property(code, value) + .map_err(|e| anyhow!("Failed to set partition property: {e:?}")) + } } /// diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index ea030fb0c..bba78e642 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -216,6 +216,10 @@ pub enum Error { #[cfg(target_arch = "x86_64")] #[error("Failed to inject NMI")] NmiError(#[source] hypervisor::HypervisorCpuError), + + #[cfg(feature = "mshv")] + #[error("Failed to set partition property")] + SetPartitionProperty(#[source] anyhow::Error), } pub type Result = result::Result; @@ -1374,6 +1378,25 @@ impl CpuManager { self.activate_vcpus(self.boot_vcpus(), false, Some(paused)) } + #[cfg(feature = "mshv")] + pub fn set_processors_per_socket_property(&self) -> Result<()> { + if let Some(mshv_vm) = self.vm.as_any().downcast_ref::() { + let threads_per_core = if let Some(ref topology) = self.config.topology { + topology.threads_per_core as u64 + } else { + 1u64 + }; + + mshv_vm + .set_partition_property( + hypervisor::mshv::HV_PARTITION_PROPERTY_PROCESSORS_PER_SOCKET, + threads_per_core, + ) + .map_err(Error::SetPartitionProperty)?; + } + Ok(()) + } + pub fn start_restored_vcpus(&mut self) -> Result<()> { self.activate_vcpus(self.vcpus.len() as u32, false, Some(true)) .map_err(|e| { diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 536481885..441d0bcaf 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -2415,6 +2415,15 @@ impl Vm { .map_err(Error::CpuManager)?; } + #[cfg(feature = "mshv")] + { + self.cpu_manager + .lock() + .unwrap() + .set_processors_per_socket_property() + .ok(); + } + #[cfg(feature = "tdx")] let (sections, guid_found) = if tdx_enabled { self.extract_tdvf_sections()?