@@ -26,7 +26,9 @@ use crate::vmm_config::balloon::{
2626use crate :: vmm_config:: boot_source:: { BootSourceConfig , BootSourceConfigError } ;
2727use crate :: vmm_config:: drive:: { BlockDeviceConfig , BlockDeviceUpdateConfig , DriveError } ;
2828use crate :: vmm_config:: entropy:: { EntropyDeviceConfig , EntropyDeviceError } ;
29- use crate :: vmm_config:: instance_info:: { InstanceInfo , MemoryMappingsResponse , MemoryResponse } ;
29+ use crate :: vmm_config:: instance_info:: {
30+ InstanceInfo , MemoryDirty , MemoryMappingsResponse , MemoryResponse , VmState ,
31+ } ;
3032use crate :: vmm_config:: machine_config:: { MachineConfig , MachineConfigError , MachineConfigUpdate } ;
3133use crate :: vmm_config:: metrics:: { MetricsConfig , MetricsConfigError } ;
3234use crate :: vmm_config:: mmds:: { MmdsConfig , MmdsConfigError } ;
@@ -69,6 +71,8 @@ pub enum VmmAction {
6971 GetMemoryMappings ,
7072 /// Get memory info (resident and empty pages).
7173 GetMemory ,
74+ /// Get guest memory dirty pages information.
75+ GetMemoryDirty ,
7276 /// Get microVM version.
7377 GetVmmVersion ,
7478 /// Flush the metrics. This action can only be called after the logger has been configured.
@@ -168,6 +172,8 @@ pub enum VmmActionError {
168172 OperationNotSupportedPostBoot ,
169173 /// The requested operation is not supported before starting the microVM.
170174 OperationNotSupportedPreBoot ,
175+ /// The requested operation is not supported while the microVM is running.
176+ OperationNotSupportedWhileRunning ,
171177 /// Start microvm error: {0}
172178 StartMicrovm ( #[ from] StartMicrovmError ) ,
173179 /// Vsock config error: {0}
@@ -197,6 +203,8 @@ pub enum VmmData {
197203 MemoryMappings ( MemoryMappingsResponse ) ,
198204 /// Memory info (resident and empty pages).
199205 Memory ( MemoryResponse ) ,
206+ /// The guest memory dirty pages information.
207+ MemoryDirty ( MemoryDirty ) ,
200208 /// The microVM version.
201209 VmmVersion ( String ) ,
202210}
@@ -427,7 +435,9 @@ impl<'a> PrebootApiController<'a> {
427435 self . vm_resources . machine_config . clone ( ) ,
428436 ) ) ,
429437 GetVmInstanceInfo => Ok ( VmmData :: InstanceInformation ( self . instance_info . clone ( ) ) ) ,
430- GetMemoryMappings | GetMemory => Err ( VmmActionError :: OperationNotSupportedPreBoot ) ,
438+ GetMemoryMappings | GetMemory | GetMemoryDirty => {
439+ Err ( VmmActionError :: OperationNotSupportedPreBoot )
440+ }
431441 GetVmmVersion => Ok ( VmmData :: VmmVersion ( self . instance_info . vmm_version . clone ( ) ) ) ,
432442 InsertBlockDevice ( config) => self . insert_block_device ( config) ,
433443 InsertNetworkDevice ( config) => self . insert_net_device ( config) ,
@@ -680,6 +690,7 @@ impl RuntimeApiController {
680690 empty : empty_bitmap,
681691 } ) )
682692 }
693+ GetMemoryDirty => self . get_dirty_memory_info ( ) ,
683694 GetVmmVersion => Ok ( VmmData :: VmmVersion (
684695 self . vmm . lock ( ) . expect ( "Poisoned lock" ) . version ( ) ,
685696 ) ) ,
@@ -825,6 +836,27 @@ impl RuntimeApiController {
825836 Ok ( VmmData :: Empty )
826837 }
827838
839+ /// Get dirty pages information for guest memory.
840+ fn get_dirty_memory_info ( & self ) -> Result < VmmData , VmmActionError > {
841+ let start_us = get_time_us ( ClockType :: Monotonic ) ;
842+ let vmm = self . vmm . lock ( ) . expect ( "Poisoned lock" ) ;
843+
844+ // Dirty memory can only be queried while the VM is paused
845+ if vmm. instance_info . state != VmState :: Paused {
846+ return Err ( VmmActionError :: OperationNotSupportedWhileRunning ) ;
847+ }
848+
849+ let page_size = self . vm_resources . machine_config . huge_pages . page_size ( ) ;
850+ let bitmap = vmm
851+ . get_dirty_memory ( page_size)
852+ . map_err ( VmmActionError :: InternalVmm ) ?;
853+
854+ let elapsed_time_us = get_time_us ( ClockType :: Monotonic ) - start_us;
855+ info ! ( "'get dirty memory' VMM action took {elapsed_time_us} us." ) ;
856+
857+ Ok ( VmmData :: MemoryDirty ( MemoryDirty { bitmap } ) )
858+ }
859+
828860 /// Updates block device properties:
829861 /// - path of the host file backing the emulated block device, update the disk image on the
830862 /// device and its virtio configuration
0 commit comments