@@ -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" ) ]
@@ -252,6 +254,17 @@ pub fn build_microvm_for_boot(
252
254
) ?;
253
255
}
254
256
257
+ // Attach virtio-mem device if configured
258
+ if let Some ( memory_hotplug) = & vm_resources. memory_hotplug {
259
+ attach_virtio_mem_device (
260
+ & mut device_manager,
261
+ & vm,
262
+ & mut boot_cmdline,
263
+ memory_hotplug,
264
+ event_manager,
265
+ ) ?;
266
+ }
267
+
255
268
#[ cfg( target_arch = "aarch64" ) ]
256
269
device_manager. attach_legacy_devices_aarch64 (
257
270
& vm,
@@ -576,6 +589,29 @@ fn attach_entropy_device(
576
589
device_manager. attach_virtio_device ( vm, id, entropy_device. clone ( ) , cmdline, false )
577
590
}
578
591
592
+ fn attach_virtio_mem_device (
593
+ device_manager : & mut DeviceManager ,
594
+ vm : & Arc < Vm > ,
595
+ cmdline : & mut LoaderKernelCmdline ,
596
+ config : & MemoryHotplugConfig ,
597
+ event_manager : & mut EventManager ,
598
+ ) -> Result < ( ) , StartMicrovmError > {
599
+ let virtio_mem = Arc :: new ( Mutex :: new (
600
+ VirtioMem :: new (
601
+ Arc :: clone ( vm) ,
602
+ config. total_size_mib ,
603
+ config. block_size_mib ,
604
+ config. slot_size_mib ,
605
+ )
606
+ . map_err ( |e| StartMicrovmError :: Internal ( VmmError :: VirtioMem ( e) ) ) ?,
607
+ ) ) ;
608
+
609
+ let id = virtio_mem. lock ( ) . expect ( "Poisoned lock" ) . id ( ) . to_string ( ) ;
610
+ event_manager. add_subscriber ( virtio_mem. clone ( ) ) ;
611
+ device_manager. attach_virtio_device ( vm, id, virtio_mem. clone ( ) , cmdline, false ) ?;
612
+ Ok ( ( ) )
613
+ }
614
+
579
615
fn attach_block_devices < ' a , I : Iterator < Item = & ' a Arc < Mutex < Block > > > + Debug > (
580
616
device_manager : & mut DeviceManager ,
581
617
vm : & Arc < Vm > ,
@@ -1200,4 +1236,42 @@ pub(crate) mod tests {
1200
1236
"virtio_mmio.device=4K@0xc0001000:5"
1201
1237
) ) ;
1202
1238
}
1239
+
1240
+ pub ( crate ) fn insert_virtio_mem_device (
1241
+ vmm : & mut Vmm ,
1242
+ cmdline : & mut Cmdline ,
1243
+ event_manager : & mut EventManager ,
1244
+ config : MemoryHotplugConfig ,
1245
+ ) {
1246
+ attach_virtio_mem_device (
1247
+ & mut vmm. device_manager ,
1248
+ & vmm. vm ,
1249
+ cmdline,
1250
+ & config,
1251
+ event_manager,
1252
+ )
1253
+ . unwrap ( ) ;
1254
+ }
1255
+
1256
+ #[ test]
1257
+ fn test_attach_virtio_mem_device ( ) {
1258
+ let mut event_manager = EventManager :: new ( ) . expect ( "Unable to create EventManager" ) ;
1259
+ let mut vmm = default_vmm ( ) ;
1260
+
1261
+ let config = MemoryHotplugConfig {
1262
+ total_size_mib : 1024 ,
1263
+ block_size_mib : 2 ,
1264
+ slot_size_mib : 128 ,
1265
+ } ;
1266
+
1267
+ let mut cmdline = default_kernel_cmdline ( ) ;
1268
+ insert_virtio_mem_device ( & mut vmm, & mut cmdline, & mut event_manager, config) ;
1269
+
1270
+ // Check if the vsock device is described in kernel_cmdline.
1271
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1272
+ assert ! ( cmdline_contains(
1273
+ & cmdline,
1274
+ "virtio_mmio.device=4K@0xc0001000:5"
1275
+ ) ) ;
1276
+ }
1203
1277
}
0 commit comments