@@ -28,9 +28,9 @@ use crate::vmm_config::balloon::{
2828use crate :: vmm_config:: boot_source:: { BootSourceConfig , BootSourceConfigError } ;
2929use crate :: vmm_config:: drive:: { BlockDeviceConfig , BlockDeviceUpdateConfig , DriveError } ;
3030use crate :: vmm_config:: entropy:: { EntropyDeviceConfig , EntropyDeviceError } ;
31- use crate :: vmm_config:: instance_info:: InstanceInfo ;
31+ use crate :: vmm_config:: instance_info:: { InstanceInfo , VmState } ;
3232use crate :: vmm_config:: machine_config:: { MachineConfig , MachineConfigError , MachineConfigUpdate } ;
33- use crate :: vmm_config:: meminfo:: { MemoryMapingsResponse , MemoryResponse } ;
33+ use crate :: vmm_config:: meminfo:: { MemoryDirty , MemoryMapingsResponse , MemoryResponse } ;
3434use crate :: vmm_config:: memory_hotplug:: {
3535 MemoryHotplugConfig , MemoryHotplugConfigError , MemoryHotplugSizeUpdate ,
3636} ;
@@ -151,6 +151,8 @@ pub enum VmmAction {
151151 GetMemoryMappings ,
152152 /// Get guest memory resident and empty pages information
153153 GetMemory ,
154+ /// Get guest memory dirty pages information
155+ GetMemoryDirty ,
154156}
155157
156158/// Wrapper for all errors associated with VMM actions.
@@ -202,6 +204,8 @@ pub enum VmmActionError {
202204 OperationNotSupportedPostBoot ,
203205 /// The requested operation is not supported before starting the microVM.
204206 OperationNotSupportedPreBoot ,
207+ /// The requested operation is not supported while the microVM is running.
208+ OperationNotSupportedWhileRunning ,
205209 /// Start microvm error: {0}
206210 StartMicrovm ( #[ from] StartMicrovmError ) ,
207211 /// Vsock config error: {0}
@@ -237,6 +241,8 @@ pub enum VmmData {
237241 MemoryMappings ( MemoryMapingsResponse ) ,
238242 /// The guest memory resident and empty pages information
239243 Memory ( MemoryResponse ) ,
244+ /// The guest memory dirty pages information
245+ MemoryDirty ( MemoryDirty ) ,
240246}
241247
242248/// Trait used for deduplicating the MMDS request handling across the two ApiControllers.
@@ -506,7 +512,8 @@ impl<'a> PrebootApiController<'a> {
506512 | GetFreePageHintingStatus
507513 | StopFreePageHinting
508514 | GetMemoryMappings
509- | GetMemory => Err ( VmmActionError :: OperationNotSupportedPreBoot ) ,
515+ | GetMemory
516+ | GetMemoryDirty => Err ( VmmActionError :: OperationNotSupportedPreBoot ) ,
510517 #[ cfg( target_arch = "x86_64" ) ]
511518 SendCtrlAltDel => Err ( VmmActionError :: OperationNotSupportedPreBoot ) ,
512519 }
@@ -784,6 +791,7 @@ impl RuntimeApiController {
784791 . map_err ( VmmActionError :: MemoryHotplugUpdate ) ,
785792 GetMemoryMappings => self . get_guest_memory_mappings ( ) ,
786793 GetMemory => self . get_guest_memory_info ( ) ,
794+ GetMemoryDirty => self . get_dirty_memory_info ( ) ,
787795 // Operations not allowed post-boot.
788796 ConfigureBootSource ( _)
789797 | ConfigureLogger ( _)
@@ -966,6 +974,20 @@ impl RuntimeApiController {
966974 let ( resident, empty) = vmm. guest_memory_info ( page_size) ?;
967975 Ok ( VmmData :: Memory ( MemoryResponse { resident, empty } ) )
968976 }
977+
978+ /// Get dirty pages information for guest memory
979+ fn get_dirty_memory_info ( & self ) -> Result < VmmData , VmmActionError > {
980+ let vmm = self . vmm . lock ( ) . expect ( "Poisoned lock" ) ;
981+
982+ // Check if VM is paused
983+ if vmm. instance_info . state != VmState :: Paused {
984+ return Err ( VmmActionError :: OperationNotSupportedWhileRunning ) ;
985+ }
986+
987+ let page_size = self . vm_resources . machine_config . huge_pages . page_size ( ) ;
988+ let bitmap = vmm. get_dirty_memory ( page_size) ?;
989+ Ok ( VmmData :: MemoryDirty ( MemoryDirty { bitmap } ) )
990+ }
969991}
970992
971993#[ cfg( test) ]
0 commit comments