@@ -32,6 +32,7 @@ use crate::device_manager::{
32
32
use crate :: devices:: acpi:: vmgenid:: VmGenIdError ;
33
33
use crate :: devices:: virtio:: balloon:: Balloon ;
34
34
use crate :: devices:: virtio:: block:: device:: Block ;
35
+ use crate :: devices:: virtio:: mem:: VirtioMem ;
35
36
use crate :: devices:: virtio:: net:: Net ;
36
37
use crate :: devices:: virtio:: rng:: Entropy ;
37
38
use crate :: devices:: virtio:: vsock:: { Vsock , VsockUnixBackend } ;
@@ -45,6 +46,7 @@ use crate::seccomp::BpfThreadMap;
45
46
use crate :: snapshot:: Persist ;
46
47
use crate :: vmm_config:: instance_info:: InstanceInfo ;
47
48
use crate :: vmm_config:: machine_config:: MachineConfigError ;
49
+ use crate :: vmm_config:: memory_hotplug:: MemoryHotplugConfig ;
48
50
use crate :: vstate:: kvm:: { Kvm , KvmError } ;
49
51
use crate :: vstate:: memory:: GuestRegionMmap ;
50
52
#[ cfg( target_arch = "aarch64" ) ]
@@ -240,6 +242,17 @@ pub fn build_microvm_for_boot(
240
242
) ?;
241
243
}
242
244
245
+ // Attach virtio-mem device if configured
246
+ if let Some ( memory_hotplug) = & vm_resources. memory_hotplug {
247
+ attach_virtio_mem_device (
248
+ & mut device_manager,
249
+ & vm,
250
+ & mut boot_cmdline,
251
+ memory_hotplug,
252
+ event_manager,
253
+ ) ?;
254
+ }
255
+
243
256
#[ cfg( target_arch = "aarch64" ) ]
244
257
device_manager. attach_legacy_devices_aarch64 (
245
258
& vm,
@@ -563,6 +576,29 @@ fn attach_entropy_device(
563
576
device_manager. attach_virtio_device ( vm, id, entropy_device. clone ( ) , cmdline, false )
564
577
}
565
578
579
+ fn attach_virtio_mem_device (
580
+ device_manager : & mut DeviceManager ,
581
+ vm : & Arc < Vm > ,
582
+ cmdline : & mut LoaderKernelCmdline ,
583
+ config : & MemoryHotplugConfig ,
584
+ event_manager : & mut EventManager ,
585
+ ) -> Result < ( ) , StartMicrovmError > {
586
+ let virtio_mem = Arc :: new ( Mutex :: new (
587
+ VirtioMem :: new (
588
+ Arc :: clone ( vm) ,
589
+ config. total_size_mib ,
590
+ config. block_size_mib ,
591
+ config. slot_size_mib ,
592
+ )
593
+ . map_err ( |e| StartMicrovmError :: Internal ( VmmError :: VirtioMem ( e) ) ) ?,
594
+ ) ) ;
595
+
596
+ let id = virtio_mem. lock ( ) . expect ( "Poisoned lock" ) . id ( ) . to_string ( ) ;
597
+ event_manager. add_subscriber ( virtio_mem. clone ( ) ) ;
598
+ device_manager. attach_virtio_device ( vm, id, virtio_mem. clone ( ) , cmdline, false ) ?;
599
+ Ok ( ( ) )
600
+ }
601
+
566
602
fn attach_block_devices < ' a , I : Iterator < Item = & ' a Arc < Mutex < Block > > > + Debug > (
567
603
device_manager : & mut DeviceManager ,
568
604
vm : & Arc < Vm > ,
@@ -1187,4 +1223,42 @@ pub(crate) mod tests {
1187
1223
"virtio_mmio.device=4K@0xc0001000:5"
1188
1224
) ) ;
1189
1225
}
1226
+
1227
+ pub ( crate ) fn insert_virtio_mem_device (
1228
+ vmm : & mut Vmm ,
1229
+ cmdline : & mut Cmdline ,
1230
+ event_manager : & mut EventManager ,
1231
+ config : MemoryHotplugConfig ,
1232
+ ) {
1233
+ attach_virtio_mem_device (
1234
+ & mut vmm. device_manager ,
1235
+ & vmm. vm ,
1236
+ cmdline,
1237
+ & config,
1238
+ event_manager,
1239
+ )
1240
+ . unwrap ( ) ;
1241
+ }
1242
+
1243
+ #[ test]
1244
+ fn test_attach_virtio_mem_device ( ) {
1245
+ let mut event_manager = EventManager :: new ( ) . expect ( "Unable to create EventManager" ) ;
1246
+ let mut vmm = default_vmm ( ) ;
1247
+
1248
+ let config = MemoryHotplugConfig {
1249
+ total_size_mib : 1024 ,
1250
+ block_size_mib : 2 ,
1251
+ slot_size_mib : 128 ,
1252
+ } ;
1253
+
1254
+ let mut cmdline = default_kernel_cmdline ( ) ;
1255
+ insert_virtio_mem_device ( & mut vmm, & mut cmdline, & mut event_manager, config) ;
1256
+
1257
+ // Check if the vsock device is described in kernel_cmdline.
1258
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1259
+ assert ! ( cmdline_contains(
1260
+ & cmdline,
1261
+ "virtio_mmio.device=4K@0xc0001000:5"
1262
+ ) ) ;
1263
+ }
1190
1264
}
0 commit comments