hypervisor: Implement start/stop_dirty_log for MSHV

This patch modify the existing live migration code
to support MSHV. Adds couple of new functions to enable
and disable dirty page tracking. Add missing IOCTL
to the seccomp rules for live migration.
Adds necessary flags for MSHV.
This changes don't affect KVM functionality at all.

In order to get better performance it is good to
enable dirty page tracking when we start live migration
and disable it when the migration is done.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2021-07-08 10:07:18 -07:00 committed by LIU Wei
parent 6492496cc2
commit 81895b9b40
2 changed files with 26 additions and 6 deletions

View File

@ -34,6 +34,7 @@ use std::fs::File;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
const DIRTY_BITMAP_CLEAR_DIRTY: u64 = 0x4; const DIRTY_BITMAP_CLEAR_DIRTY: u64 = 0x4;
const DIRTY_BITMAP_SET_DIRTY: u64 = 0x8;
pub const PAGE_SHIFT: usize = 12; pub const PAGE_SHIFT: usize = 12;
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)] #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
@ -905,17 +906,27 @@ impl vm::Vm for MshvVm {
/// Start logging dirty pages /// Start logging dirty pages
/// ///
fn start_dirty_log(&self) -> vm::Result<()> { fn start_dirty_log(&self) -> vm::Result<()> {
Err(vm::HypervisorVmError::StartDirtyLog(anyhow!( self.fd
"functionality not implemented" .enable_dirty_page_tracking()
))) .map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))
} }
/// ///
/// Stop logging dirty pages /// Stop logging dirty pages
/// ///
fn stop_dirty_log(&self) -> vm::Result<()> { fn stop_dirty_log(&self) -> vm::Result<()> {
Err(vm::HypervisorVmError::StopDirtyLog(anyhow!( let dirty_log_slots = self.dirty_log_slots.read().unwrap();
"functionality not implemented" // 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) /// Get dirty pages bitmap (one bit per page)

View File

@ -141,6 +141,8 @@ mod mshv {
pub const MSHV_RUN_VP: u64 = 0x8100_b807; pub const MSHV_RUN_VP: u64 = 0x8100_b807;
pub const MSHV_GET_VP_STATE: u64 = 0xc028_b80a; pub const MSHV_GET_VP_STATE: u64 = 0xc028_b80a;
pub const MSHV_SET_VP_STATE: u64 = 0xc028_b80b; 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")] #[cfg(feature = "mshv")]
use mshv::*; use mshv::*;
@ -161,6 +163,13 @@ fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result<Vec<SeccompRule>, Error
and![Cond::new(1, ArgLen::DWORD, Eq, MSHV_RUN_VP)?], 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_GET_VP_STATE)?],
and![Cond::new(1, ArgLen::DWORD, Eq, MSHV_SET_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)?],
]) ])
} }