@@ -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 ;
33+ use crate :: vmm_config:: meminfo:: { MemoryMapingsResponse , MemoryResponse } ;
3434use crate :: vmm_config:: memory_hotplug:: {
3535 MemoryHotplugConfig , MemoryHotplugConfigError , MemoryHotplugSizeUpdate ,
3636} ;
@@ -149,6 +149,8 @@ pub enum VmmAction {
149149 UpdateMachineConfiguration ( MachineConfigUpdate ) ,
150150 /// Get the guest memory mappings to host memory
151151 GetMemoryMappings ,
152+ /// Get guest memory resident and empty pages information
153+ GetMemory ,
152154}
153155
154156/// Wrapper for all errors associated with VMM actions.
@@ -200,6 +202,8 @@ pub enum VmmActionError {
200202 OperationNotSupportedPostBoot ,
201203 /// The requested operation is not supported before starting the microVM.
202204 OperationNotSupportedPreBoot ,
205+ /// The requested operation is not supported while the microVM is running.
206+ OperationNotSupportedWhileRunning ,
203207 /// Start microvm error: {0}
204208 StartMicrovm ( #[ from] StartMicrovmError ) ,
205209 /// Vsock config error: {0}
@@ -233,6 +237,8 @@ pub enum VmmData {
233237 HintingStatus ( HintingStatus ) ,
234238 /// The guest memory mapping information.
235239 MemoryMappings ( MemoryMapingsResponse ) ,
240+ /// The guest memory resident and empty pages information
241+ Memory ( MemoryResponse ) ,
236242}
237243
238244/// Trait used for deduplicating the MMDS request handling across the two ApiControllers.
@@ -501,7 +507,8 @@ impl<'a> PrebootApiController<'a> {
501507 | StartFreePageHinting ( _)
502508 | GetFreePageHintingStatus
503509 | StopFreePageHinting
504- | GetMemoryMappings => Err ( VmmActionError :: OperationNotSupportedPreBoot ) ,
510+ | GetMemoryMappings
511+ | GetMemory => Err ( VmmActionError :: OperationNotSupportedPreBoot ) ,
505512 #[ cfg( target_arch = "x86_64" ) ]
506513 SendCtrlAltDel => Err ( VmmActionError :: OperationNotSupportedPreBoot ) ,
507514 }
@@ -778,6 +785,7 @@ impl RuntimeApiController {
778785 . map ( |_| VmmData :: Empty )
779786 . map_err ( VmmActionError :: MemoryHotplugUpdate ) ,
780787 GetMemoryMappings => self . get_guest_memory_mappings ( ) ,
788+ GetMemory => self . get_guest_memory_info ( ) ,
781789 // Operations not allowed post-boot.
782790 ConfigureBootSource ( _)
783791 | ConfigureLogger ( _)
@@ -957,6 +965,25 @@ impl RuntimeApiController {
957965 info ! ( "'get memory mappings' VMM action took {elapsed_time_us} us." ) ;
958966 Ok ( VmmData :: MemoryMappings ( MemoryMapingsResponse { mappings } ) )
959967 }
968+
969+ /// Get resident and empty pages information for guest memory
970+ fn get_guest_memory_info ( & self ) -> Result < VmmData , VmmActionError > {
971+ let start_us = get_time_us ( ClockType :: Monotonic ) ;
972+ let vmm = self . vmm . lock ( ) . expect ( "Poisoned lock" ) ;
973+
974+ // Check if VM is paused
975+ if vmm. instance_info . state != VmState :: Paused {
976+ return Err ( VmmActionError :: OperationNotSupportedWhileRunning ) ;
977+ }
978+
979+ let page_size = self . vm_resources . machine_config . huge_pages . page_size ( ) ;
980+ let ( resident, empty) = vmm. guest_memory_info ( page_size) ?;
981+
982+ let elapsed_time_us = get_time_us ( ClockType :: Monotonic ) - start_us;
983+ info ! ( "'get memory info' VMM action took {elapsed_time_us} us." ) ;
984+
985+ Ok ( VmmData :: Memory ( MemoryResponse { resident, empty } ) )
986+ }
960987}
961988
962989#[ cfg( test) ]
0 commit comments