diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index e377663db..b365e4e77 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -34,6 +34,7 @@ use std::fs::File; use std::os::unix::io::AsRawFd; const DIRTY_BITMAP_CLEAR_DIRTY: u64 = 0x4; +const DIRTY_BITMAP_SET_DIRTY: u64 = 0x8; pub const PAGE_SHIFT: usize = 12; #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)] @@ -905,17 +906,27 @@ impl vm::Vm for MshvVm { /// Start logging dirty pages /// fn start_dirty_log(&self) -> vm::Result<()> { - Err(vm::HypervisorVmError::StartDirtyLog(anyhow!( - "functionality not implemented" - ))) + self.fd + .enable_dirty_page_tracking() + .map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into())) } /// /// Stop logging dirty pages /// fn stop_dirty_log(&self) -> vm::Result<()> { - Err(vm::HypervisorVmError::StopDirtyLog(anyhow!( - "functionality not implemented" - ))) + let dirty_log_slots = self.dirty_log_slots.read().unwrap(); + // Before disabling the dirty page tracking we need + // to set the dirty bits in the Hypervisor + // This is a requirement from Microsoft Hypervisor + for (_, s) in dirty_log_slots.iter() { + self.fd + .get_dirty_log(s.guest_pfn, s.memory_size as usize, DIRTY_BITMAP_SET_DIRTY) + .map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))?; + } + self.fd + .disable_dirty_page_tracking() + .map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))?; + Ok(()) } /// /// Get dirty pages bitmap (one bit per page) diff --git a/vmm/src/seccomp_filters.rs b/vmm/src/seccomp_filters.rs index 67fdbc4a3..ce7b328b8 100644 --- a/vmm/src/seccomp_filters.rs +++ b/vmm/src/seccomp_filters.rs @@ -141,6 +141,8 @@ mod mshv { pub const MSHV_RUN_VP: u64 = 0x8100_b807; pub const MSHV_GET_VP_STATE: u64 = 0xc028_b80a; pub const MSHV_SET_VP_STATE: u64 = 0xc028_b80b; + pub const MSHV_SET_PARTITION_PROPERTY: u64 = 0x4010_b80c; + pub const MSHV_GET_GPA_ACCESS_STATES: u64 = 0xc01c_b812; } #[cfg(feature = "mshv")] use mshv::*; @@ -161,6 +163,13 @@ fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result, Error and![Cond::new(1, ArgLen::DWORD, Eq, MSHV_RUN_VP)?], and![Cond::new(1, ArgLen::DWORD, Eq, MSHV_GET_VP_STATE)?], and![Cond::new(1, ArgLen::DWORD, Eq, MSHV_SET_VP_STATE)?], + and![Cond::new( + 1, + ArgLen::DWORD, + Eq, + MSHV_SET_PARTITION_PROPERTY + )?], + and![Cond::new(1, ArgLen::DWORD, Eq, MSHV_GET_GPA_ACCESS_STATES)?], ]) }