Skip to content
74 changes: 74 additions & 0 deletions src/vmm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::device_manager::{
use crate::devices::acpi::vmgenid::VmGenIdError;
use crate::devices::virtio::balloon::Balloon;
use crate::devices::virtio::block::device::Block;
use crate::devices::virtio::mem::VirtioMem;
use crate::devices::virtio::net::Net;
use crate::devices::virtio::rng::Entropy;
use crate::devices::virtio::vsock::{Vsock, VsockUnixBackend};
Expand All @@ -45,6 +46,7 @@ use crate::seccomp::BpfThreadMap;
use crate::snapshot::Persist;
use crate::vmm_config::instance_info::InstanceInfo;
use crate::vmm_config::machine_config::MachineConfigError;
use crate::vmm_config::memory_hotplug::MemoryHotplugConfig;
use crate::vstate::kvm::{Kvm, KvmError};
use crate::vstate::memory::GuestRegionMmap;
#[cfg(target_arch = "aarch64")]
Expand Down Expand Up @@ -252,6 +254,17 @@ pub fn build_microvm_for_boot(
)?;
}

// Attach virtio-mem device if configured
if let Some(memory_hotplug) = &vm_resources.memory_hotplug {
attach_virtio_mem_device(
&mut device_manager,
&vm,
&mut boot_cmdline,
memory_hotplug,
event_manager,
)?;
}

#[cfg(target_arch = "aarch64")]
device_manager.attach_legacy_devices_aarch64(
&vm,
Expand Down Expand Up @@ -576,6 +589,29 @@ fn attach_entropy_device(
device_manager.attach_virtio_device(vm, id, entropy_device.clone(), cmdline, false)
}

fn attach_virtio_mem_device(
device_manager: &mut DeviceManager,
vm: &Arc<Vm>,
cmdline: &mut LoaderKernelCmdline,
config: &MemoryHotplugConfig,
event_manager: &mut EventManager,
) -> Result<(), StartMicrovmError> {
let virtio_mem = Arc::new(Mutex::new(
VirtioMem::new(
Arc::clone(vm),
config.total_size_mib,
config.block_size_mib,
config.slot_size_mib,
)
.map_err(|e| StartMicrovmError::Internal(VmmError::VirtioMem(e)))?,
));

let id = virtio_mem.lock().expect("Poisoned lock").id().to_string();
event_manager.add_subscriber(virtio_mem.clone());
device_manager.attach_virtio_device(vm, id, virtio_mem.clone(), cmdline, false)?;
Ok(())
}

fn attach_block_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Block>>> + Debug>(
device_manager: &mut DeviceManager,
vm: &Arc<Vm>,
Expand Down Expand Up @@ -1200,4 +1236,42 @@ pub(crate) mod tests {
"virtio_mmio.device=4K@0xc0001000:5"
));
}

pub(crate) fn insert_virtio_mem_device(
vmm: &mut Vmm,
cmdline: &mut Cmdline,
event_manager: &mut EventManager,
config: MemoryHotplugConfig,
) {
attach_virtio_mem_device(
&mut vmm.device_manager,
&vmm.vm,
cmdline,
&config,
event_manager,
)
.unwrap();
}

#[test]
fn test_attach_virtio_mem_device() {
let mut event_manager = EventManager::new().expect("Unable to create EventManager");
let mut vmm = default_vmm();

let config = MemoryHotplugConfig {
total_size_mib: 1024,
block_size_mib: 2,
slot_size_mib: 128,
};

let mut cmdline = default_kernel_cmdline();
insert_virtio_mem_device(&mut vmm, &mut cmdline, &mut event_manager, config);

// Check if the vsock device is described in kernel_cmdline.
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
assert!(cmdline_contains(
&cmdline,
"virtio_mmio.device=4K@0xc0001000:5"
));
}
}
Loading