hypervisor, vmm: Abstract the interfaces to start/stop dirty log

Following KVM interfaces, the `hypervisor` crate now provides interfaces
to start/stop the dirty pages logging on a per region basis, and asks
its users (e.g. the `vmm` crate) to iterate over the regions that needs
dirty pages log. MSHV only has a global control to start/stop dirty
pages log on all regions at once.

This patch refactors related APIs from the `hypervisor` crate to provide
a global control to start/stop dirty pages log (following MSHV's
behaviors), and keeps tracking the regions need dirty pages log for
KVM. It avoids leaking hypervisor-specific behaviors out of the
`hypervisor` crate.

Signed-off-by: Bo Chen <chen.bo@intel.com>
This commit is contained in:
Bo Chen
2021-07-26 12:33:02 -07:00
committed by Bo Chen
parent 2723995cfa
commit e7c9954dc1
4 changed files with 89 additions and 96 deletions

View File

@@ -1541,23 +1541,14 @@ impl MemoryManager {
Ok(table)
}
// Start the dirty log on guest RAM in the hypervisor (kvm/mshv).
// Start the dirty log in the hypervisor (kvm/mshv).
// Also, reset the dirty bitmap logged by the vmm.
// Just before we do a bulk copy we want to start/clear the dirty log so that
// pages touched during our bulk copy are tracked.
pub fn start_memory_dirty_log(&self) -> std::result::Result<(), MigratableError> {
for r in &self.guest_ram_mappings {
let user_addr = self
.guest_memory()
.memory()
.get_host_address(GuestAddress(r.gpa))
.unwrap();
self.vm
.start_dirty_log(r.slot, r.gpa, r.size, user_addr as u64)
.map_err(|e| {
MigratableError::MigrateSend(anyhow!("Error starting VM dirty log {}", e))
})?;
}
self.vm.start_dirty_log().map_err(|e| {
MigratableError::MigrateSend(anyhow!("Error starting VM dirty log {}", e))
})?;
for r in self.guest_memory.memory().iter() {
r.bitmap().reset();
@@ -1567,18 +1558,9 @@ impl MemoryManager {
}
pub fn stop_memory_dirty_log(&self) -> std::result::Result<(), MigratableError> {
for r in &self.guest_ram_mappings {
let user_addr = self
.guest_memory()
.memory()
.get_host_address(GuestAddress(r.gpa))
.unwrap();
self.vm
.stop_dirty_log(r.slot, r.gpa, r.size, user_addr as u64)
.map_err(|e| {
MigratableError::MigrateSend(anyhow!("Error stopping VM dirty log {}", e))
})?;
}
self.vm.stop_dirty_log().map_err(|e| {
MigratableError::MigrateSend(anyhow!("Error stopping VM dirty log {}", e))
})?;
Ok(())
}