diff --git a/vmm_core/virt_mshv/src/aarch64/mod.rs b/vmm_core/virt_mshv/src/aarch64/mod.rs index 79f5f5e2aa6..8baec652b98 100644 --- a/vmm_core/virt_mshv/src/aarch64/mod.rs +++ b/vmm_core/virt_mshv/src/aarch64/mod.rs @@ -266,6 +266,7 @@ impl virt::ResetPartition for MshvPartition { type Error = Error; fn reset(&self) -> Result<(), Error> { + self.inner.scrub_partition()?; self.inner.freeze_time()?; Ok(()) } diff --git a/vmm_core/virt_mshv/src/lib.rs b/vmm_core/virt_mshv/src/lib.rs index f6bbde76d0a..fbf964d09ac 100644 --- a/vmm_core/virt_mshv/src/lib.rs +++ b/vmm_core/virt_mshv/src/lib.rs @@ -312,6 +312,19 @@ impl MshvPartitionInner { &self.vps[vp_index.index() as usize] } + fn scrub_partition(&self) -> Result<(), Error> { + const HVCALL_SCRUB_PARTITION: libc::c_ulong = 0x008d; + + // SAFETY: `vmfd` is a valid MSHV partition fd. The private MSHV ABI + // exposes HvCallScrubPartition directly as an argument-less ioctl. + let ret = unsafe { libc::ioctl(self.vmfd.as_raw_fd(), HVCALL_SCRUB_PARTITION) }; + if ret < 0 { + return Err(ErrorInner::ScrubPartition(io::Error::last_os_error()).into()); + } + + Ok(()) + } + /// Freezes partition time. Time will remain frozen until [`thaw_time`] is /// called (typically on the first VP run after reset). fn freeze_time(&self) -> Result<(), Error> { @@ -608,13 +621,6 @@ impl virt::Processor for MshvProcessor<'_> { } fn reset(&mut self) -> Result<(), impl std::error::Error + Send + Sync + 'static> { - use virt::vp::AccessVpState; - - let vp_info = self.inner.vp_info; - self.access_state(Vtl::Vtl0) - .reset_all(&vp_info) - .map_err(|e| ErrorInner::ResetState(Box::new(e)))?; - self.reset_synic_state(); Ok::<(), Error>(()) @@ -670,6 +676,8 @@ enum ErrorInner { GetPartitionProperty(#[source] KernelError), #[error("failed to set partition property")] SetPartitionProperty(#[source] KernelError), + #[error("failed to scrub partition")] + ScrubPartition(#[source] io::Error), #[error("register access error")] Register(#[source] KernelError), #[cfg(guest_arch = "x86_64")] diff --git a/vmm_core/virt_mshv/src/x86_64/mod.rs b/vmm_core/virt_mshv/src/x86_64/mod.rs index 351b7ea4faf..5fee6744b44 100644 --- a/vmm_core/virt_mshv/src/x86_64/mod.rs +++ b/vmm_core/virt_mshv/src/x86_64/mod.rs @@ -411,6 +411,8 @@ impl virt::ResetPartition for MshvPartition { fn reset(&self) -> Result<(), Error> { use virt::x86::vm::AccessVmState; + self.inner.scrub_partition()?; + for irq in 0..virt::irqcon::IRQ_LINES as u8 { self.inner.irq_routes.set_irq_route(irq, None); }