Skip to content

Commit fe46199

Browse files
committed
feat(virtio-mem): add static allocation of hotpluggable memory
Allocate the memory that will be used for hotplugging. Initially, this memory will be registered with KVM, but that will change later when we add dynamic slot support. Signed-off-by: Riccardo Mancini <[email protected]>
1 parent ddb9041 commit fe46199

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

src/vmm/src/builder.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::device_manager::{
3232
use crate::devices::acpi::vmgenid::VmGenIdError;
3333
use crate::devices::virtio::balloon::Balloon;
3434
use crate::devices::virtio::block::device::Block;
35-
use crate::devices::virtio::mem::VirtioMem;
35+
use crate::devices::virtio::mem::{VIRTIO_MEM_GUEST_ADDRESS, VirtioMem};
3636
use crate::devices::virtio::net::Net;
3737
use crate::devices::virtio::rng::Entropy;
3838
use crate::devices::virtio::vsock::{Vsock, VsockUnixBackend};
@@ -44,6 +44,7 @@ use crate::persist::{MicrovmState, MicrovmStateError};
4444
use crate::resources::VmResources;
4545
use crate::seccomp::BpfThreadMap;
4646
use crate::snapshot::Persist;
47+
use crate::utils::mib_to_bytes;
4748
use crate::vmm_config::instance_info::InstanceInfo;
4849
use crate::vmm_config::machine_config::MachineConfigError;
4950
use crate::vmm_config::memory_hotplug::MemoryHotplugConfig;
@@ -172,6 +173,18 @@ pub fn build_microvm_for_boot(
172173
let (mut vcpus, vcpus_exit_evt) = vm.create_vcpus(vm_resources.machine_config.vcpu_count)?;
173174
vm.register_dram_memory_regions(guest_memory)?;
174175

176+
// Allocate memory as soon as possible to make hotpluggable memory available to all consumers,
177+
// before they clone the GuestMemoryMmap object
178+
if let Some(memory_hotplug) = &vm_resources.memory_hotplug {
179+
let hotplug_memory_region = vm_resources
180+
.allocate_memory_region(
181+
VIRTIO_MEM_GUEST_ADDRESS,
182+
mib_to_bytes(memory_hotplug.total_size_mib),
183+
)
184+
.map_err(StartMicrovmError::GuestMemory)?;
185+
vm.register_hotpluggable_memory_region(hotplug_memory_region)?;
186+
}
187+
175188
let mut device_manager = DeviceManager::new(
176189
event_manager,
177190
&vcpus_exit_evt,

src/vmm/src/resources.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,18 @@ impl VmResources {
536536
crate::arch::arch_memory_regions(mib_to_bytes(self.machine_config.mem_size_mib));
537537
self.allocate_memory_regions(&regions)
538538
}
539+
540+
/// Allocates a single guest memory region.
541+
pub fn allocate_memory_region(
542+
&self,
543+
start: GuestAddress,
544+
size: usize,
545+
) -> Result<GuestRegionMmap, MemoryError> {
546+
Ok(self
547+
.allocate_memory_regions(&[(start, size)])?
548+
.pop()
549+
.unwrap())
550+
}
539551
}
540552

541553
impl From<&VmResources> for VmmConfig {

src/vmm/src/vstate/memory.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ pub enum MemoryError {
5757
pub enum GuestRegionType {
5858
/// Guest DRAM
5959
Dram,
60+
/// Hotpluggable memory
61+
Hotpluggable,
6062
}
6163

6264
/// An extension to GuestMemoryRegion that stores the type of region, and the KVM slot
@@ -80,6 +82,14 @@ impl GuestRegionMmapExt {
8082
}
8183
}
8284

85+
pub(crate) fn hotpluggable_from_mmap_region(region: GuestRegionMmap, slot: u32) -> Self {
86+
GuestRegionMmapExt {
87+
inner: region,
88+
region_type: GuestRegionType::Hotpluggable,
89+
slot,
90+
}
91+
}
92+
8393
pub(crate) fn from_state(
8494
region: GuestRegionMmap,
8595
state: &GuestMemoryRegionState,

src/vmm/src/vstate/vm.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,19 @@ impl Vm {
222222
Ok(())
223223
}
224224

225+
/// Register a new hotpluggable region to this [`Vm`].
226+
pub fn register_hotpluggable_memory_region(
227+
&mut self,
228+
region: GuestRegionMmap,
229+
) -> Result<(), VmError> {
230+
let arcd_region = Arc::new(GuestRegionMmapExt::hotpluggable_from_mmap_region(
231+
region,
232+
self.allocate_slot_ids(1)?,
233+
));
234+
235+
self._register_memory_region(arcd_region)
236+
}
237+
225238
/// Register a list of new memory regions to this [`Vm`].
226239
///
227240
/// Note: regions and state.regions need to be in the same order.

0 commit comments

Comments
 (0)