@@ -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" ) ]
@@ -247,6 +249,17 @@ pub fn build_microvm_for_boot(
247
249
) ?;
248
250
}
249
251
252
+ // Attach virtio-mem device if configured
253
+ if let Some ( memory_hotplug) = & vm_resources. memory_hotplug {
254
+ attach_virtio_mem_device (
255
+ & mut device_manager,
256
+ & vm,
257
+ & mut boot_cmdline,
258
+ memory_hotplug,
259
+ event_manager,
260
+ ) ?;
261
+ }
262
+
250
263
#[ cfg( target_arch = "aarch64" ) ]
251
264
device_manager. attach_legacy_devices_aarch64 ( & vm, event_manager, & mut boot_cmdline) ?;
252
265
@@ -568,6 +581,29 @@ fn attach_entropy_device(
568
581
device_manager. attach_virtio_device ( vm, id, entropy_device. clone ( ) , cmdline, false )
569
582
}
570
583
584
+ fn attach_virtio_mem_device (
585
+ device_manager : & mut DeviceManager ,
586
+ vm : & Arc < Vm > ,
587
+ cmdline : & mut LoaderKernelCmdline ,
588
+ config : & MemoryHotplugConfig ,
589
+ event_manager : & mut EventManager ,
590
+ ) -> Result < ( ) , StartMicrovmError > {
591
+ let virtio_mem = Arc :: new ( Mutex :: new (
592
+ VirtioMem :: new (
593
+ vm. clone ( ) ,
594
+ config. total_size_mib ,
595
+ config. block_size_mib ,
596
+ config. slot_size_mib ,
597
+ )
598
+ . map_err ( |e| StartMicrovmError :: Internal ( VmmError :: VirtioMem ( e) ) ) ?,
599
+ ) ) ;
600
+
601
+ let id = virtio_mem. lock ( ) . expect ( "Poisoned lock" ) . id ( ) . to_string ( ) ;
602
+ event_manager. add_subscriber ( virtio_mem. clone ( ) ) ;
603
+ device_manager. attach_virtio_device ( vm, id, virtio_mem. clone ( ) , cmdline, false ) ?;
604
+ Ok ( ( ) )
605
+ }
606
+
571
607
fn attach_block_devices < ' a , I : Iterator < Item = & ' a Arc < Mutex < Block > > > + Debug > (
572
608
device_manager : & mut DeviceManager ,
573
609
vm : & Arc < Vm > ,
@@ -1193,4 +1229,42 @@ pub(crate) mod tests {
1193
1229
"virtio_mmio.device=4K@0xc0001000:5"
1194
1230
) ) ;
1195
1231
}
1232
+
1233
+ pub ( crate ) fn insert_virtio_mem_device (
1234
+ vmm : & mut Vmm ,
1235
+ cmdline : & mut Cmdline ,
1236
+ event_manager : & mut EventManager ,
1237
+ config : MemoryHotplugConfig ,
1238
+ ) {
1239
+ attach_virtio_mem_device (
1240
+ & mut vmm. device_manager ,
1241
+ & vmm. vm ,
1242
+ cmdline,
1243
+ & config,
1244
+ event_manager,
1245
+ )
1246
+ . unwrap ( ) ;
1247
+ }
1248
+
1249
+ #[ test]
1250
+ fn test_attach_virtio_mem_device ( ) {
1251
+ let mut event_manager = EventManager :: new ( ) . expect ( "Unable to create EventManager" ) ;
1252
+ let mut vmm = default_vmm ( ) ;
1253
+
1254
+ let config = MemoryHotplugConfig {
1255
+ total_size_mib : 1024 ,
1256
+ block_size_mib : 2 ,
1257
+ slot_size_mib : 128 ,
1258
+ } ;
1259
+
1260
+ let mut cmdline = default_kernel_cmdline ( ) ;
1261
+ insert_virtio_mem_device ( & mut vmm, & mut cmdline, & mut event_manager, config) ;
1262
+
1263
+ // Check if the vsock device is described in kernel_cmdline.
1264
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1265
+ assert ! ( cmdline_contains(
1266
+ & cmdline,
1267
+ "virtio_mmio.device=4K@0xc0001000:5"
1268
+ ) ) ;
1269
+ }
1196
1270
}
0 commit comments