Skip to content

Commit 8c81152

Browse files
committed
refactor(vm): move ResourceAllocator inside Vm
ResourceAllocator object was part of DeviceManager since it is (mainly) devices that use it. ResourceAllocator is as well the object that implements (in a dummy way, for the moment) the DeviceRelocation trait which PciDevices use to move the address space of a PciDevice when triggered from the guest. Problem with DeviceRelocation is that it also needs the Vm file descriptor to perform the relocation, because we need to move register the new IO event fd for VirtIO devices. To make things simpler, move ResourceAllocator inside the Vm object. In subsequent commit we will remove the DeviceRelocation from ResourceAllocator and move it to Vm instead. This has the nice secondary effect that we were able to simplify the signature of many device-related methods that received Vm and ResourceAllocator arguments. Signed-off-by: Babis Chalios <[email protected]>
1 parent 172a293 commit 8c81152

File tree

18 files changed

+113
-204
lines changed

18 files changed

+113
-204
lines changed

src/vmm/src/acpi/mod.rs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use crate::acpi::x86_64::{
1212
};
1313
use crate::arch::x86_64::layout;
1414
use crate::device_manager::DeviceManager;
15-
use crate::device_manager::resources::ResourceAllocator;
1615
use crate::vstate::memory::{GuestAddress, GuestMemoryMmap};
16+
use crate::vstate::resources::ResourceAllocator;
1717

1818
mod x86_64;
1919

@@ -80,7 +80,11 @@ impl AcpiTableWriter<'_> {
8080
}
8181

8282
/// Build the DSDT table for the guest
83-
fn build_dsdt(&mut self, device_manager: &mut DeviceManager) -> Result<u64, AcpiError> {
83+
fn build_dsdt(
84+
&mut self,
85+
device_manager: &mut DeviceManager,
86+
resource_allocator: &ResourceAllocator,
87+
) -> Result<u64, AcpiError> {
8488
let mut dsdt_data = Vec::new();
8589

8690
// Virtio-devices DSDT data
@@ -99,7 +103,7 @@ impl AcpiTableWriter<'_> {
99103
setup_arch_dsdt(&mut dsdt_data)?;
100104

101105
let mut dsdt = Dsdt::new(OEM_ID, *b"FCVMDSDT", OEM_REVISION, dsdt_data);
102-
self.write_acpi_table(&device_manager.resource_allocator, &mut dsdt)
106+
self.write_acpi_table(resource_allocator, &mut dsdt)
103107
}
104108

105109
/// Build the FADT table for the guest
@@ -193,26 +197,16 @@ impl AcpiTableWriter<'_> {
193197
pub(crate) fn create_acpi_tables(
194198
mem: &GuestMemoryMmap,
195199
device_manager: &mut DeviceManager,
200+
resource_allocator: &ResourceAllocator,
196201
vcpus: &[Vcpu],
197202
) -> Result<(), AcpiError> {
198203
let mut writer = AcpiTableWriter { mem };
199-
let dsdt_addr = writer.build_dsdt(device_manager)?;
200-
201-
let fadt_addr = writer.build_fadt(&device_manager.resource_allocator, dsdt_addr)?;
202-
let madt_addr = writer.build_madt(
203-
&device_manager.resource_allocator,
204-
vcpus.len().try_into().unwrap(),
205-
)?;
206-
let mcfg_addr = writer.build_mcfg(
207-
&device_manager.resource_allocator,
208-
layout::PCI_MMCONFIG_START,
209-
)?;
210-
let xsdt_addr = writer.build_xsdt(
211-
&device_manager.resource_allocator,
212-
fadt_addr,
213-
madt_addr,
214-
mcfg_addr,
215-
)?;
204+
let dsdt_addr = writer.build_dsdt(device_manager, resource_allocator)?;
205+
206+
let fadt_addr = writer.build_fadt(resource_allocator, dsdt_addr)?;
207+
let madt_addr = writer.build_madt(resource_allocator, vcpus.len().try_into().unwrap())?;
208+
let mcfg_addr = writer.build_mcfg(resource_allocator, layout::PCI_MMCONFIG_START)?;
209+
let xsdt_addr = writer.build_xsdt(resource_allocator, fadt_addr, madt_addr, mcfg_addr)?;
216210
writer.build_rsdp(xsdt_addr)
217211
}
218212

@@ -224,8 +218,8 @@ mod tests {
224218
use crate::acpi::{AcpiError, AcpiTableWriter};
225219
use crate::arch::x86_64::layout::{SYSTEM_MEM_SIZE, SYSTEM_MEM_START};
226220
use crate::builder::tests::default_vmm;
227-
use crate::device_manager::resources::ResourceAllocator;
228221
use crate::utils::u64_to_usize;
222+
use crate::vstate::resources::ResourceAllocator;
229223
use crate::vstate::vm::tests::setup_vm_with_memory;
230224

231225
struct MockSdt(Vec<u8>);
@@ -259,14 +253,14 @@ mod tests {
259253
// This should succeed
260254
let mut sdt = MockSdt(vec![0; 4096]);
261255
let addr = writer
262-
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
256+
.write_acpi_table(&vmm.vm.common.resource_allocator, &mut sdt)
263257
.unwrap();
264258
assert_eq!(addr, SYSTEM_MEM_START);
265259

266260
// Let's try to write two 4K pages plus one byte
267261
let mut sdt = MockSdt(vec![0; usize::try_from(SYSTEM_MEM_SIZE + 1).unwrap()]);
268262
let err = writer
269-
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
263+
.write_acpi_table(&vmm.vm.common.resource_allocator, &mut sdt)
270264
.unwrap_err();
271265
assert!(
272266
matches!(
@@ -281,27 +275,27 @@ mod tests {
281275
// succeed.
282276
let mut sdt = MockSdt(vec![0; 5]);
283277
let addr = writer
284-
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
278+
.write_acpi_table(&vmm.vm.common.resource_allocator, &mut sdt)
285279
.unwrap();
286280
assert_eq!(addr, SYSTEM_MEM_START + 4096);
287281
let mut sdt = MockSdt(vec![0; 2]);
288282
let addr = writer
289-
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
283+
.write_acpi_table(&vmm.vm.common.resource_allocator, &mut sdt)
290284
.unwrap();
291285
assert_eq!(addr, SYSTEM_MEM_START + 4101);
292286
let mut sdt = MockSdt(vec![0; 4]);
293287
let addr = writer
294-
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
288+
.write_acpi_table(&vmm.vm.common.resource_allocator, &mut sdt)
295289
.unwrap();
296290
assert_eq!(addr, SYSTEM_MEM_START + 4103);
297291
let mut sdt = MockSdt(vec![0; 8]);
298292
let addr = writer
299-
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
293+
.write_acpi_table(&vmm.vm.common.resource_allocator, &mut sdt)
300294
.unwrap();
301295
assert_eq!(addr, SYSTEM_MEM_START + 4107);
302296
let mut sdt = MockSdt(vec![0; 16]);
303297
let addr = writer
304-
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
298+
.write_acpi_table(&vmm.vm.common.resource_allocator, &mut sdt)
305299
.unwrap();
306300
assert_eq!(addr, SYSTEM_MEM_START + 4115);
307301
}

src/vmm/src/arch/aarch64/fdt.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -536,14 +536,7 @@ mod tests {
536536
let dummy = Arc::new(Mutex::new(DummyDevice::new()));
537537
device_manager
538538
.mmio_devices
539-
.register_virtio_test_device(
540-
&vm,
541-
mem.clone(),
542-
&device_manager.resource_allocator,
543-
dummy,
544-
&mut cmdline,
545-
"dummy",
546-
)
539+
.register_virtio_test_device(&vm, mem.clone(), dummy, &mut cmdline, "dummy")
547540
.unwrap();
548541

549542
create_fdt(

src/vmm/src/arch/x86_64/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ pub fn configure_system_for_boot(
217217
// Note that this puts the mptable at the last 1k of Linux's 640k base RAM
218218
mptable::setup_mptable(
219219
vm.guest_memory(),
220-
&device_manager.resource_allocator,
220+
&vm.common.resource_allocator,
221221
vcpu_config.vcpu_count,
222222
)
223223
.map_err(ConfigurationError::MpTableSetup)?;
@@ -238,7 +238,12 @@ pub fn configure_system_for_boot(
238238

239239
// Create ACPI tables and write them in guest memory
240240
// For the time being we only support ACPI in x86_64
241-
create_acpi_tables(vm.guest_memory(), device_manager, vcpus)?;
241+
create_acpi_tables(
242+
vm.guest_memory(),
243+
device_manager,
244+
&vm.common.resource_allocator,
245+
vcpus,
246+
)?;
242247
Ok(())
243248
}
244249

@@ -568,9 +573,9 @@ mod tests {
568573
use linux_loader::loader::bootparam::boot_e820_entry;
569574

570575
use super::*;
571-
use crate::device_manager::resources::ResourceAllocator;
572576
use crate::test_utils::{arch_mem, single_region_mem};
573577
use crate::utils::mib_to_bytes;
578+
use crate::vstate::resources::ResourceAllocator;
574579

575580
#[test]
576581
fn regions_lt_4gb() {

src/vmm/src/arch/x86_64/mptable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ use vm_allocator::AllocPolicy;
1515

1616
use crate::arch::IRQ_MAX;
1717
use crate::arch::x86_64::generated::mpspec;
18-
use crate::device_manager::resources::ResourceAllocator;
1918
use crate::vstate::memory::{
2019
Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap,
2120
};
21+
use crate::vstate::resources::ResourceAllocator;
2222

2323
// These `mpspec` wrapper types are only data, reading them from data is a safe initialization.
2424
// SAFETY: POD

src/vmm/src/arch/x86_64/vm.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ use kvm_ioctls::Cap;
1111
use serde::{Deserialize, Serialize};
1212

1313
use crate::arch::x86_64::msr::MsrError;
14+
use crate::snapshot::Persist;
1415
use crate::utils::u64_to_usize;
1516
use crate::vstate::memory::{GuestMemoryExtension, GuestMemoryState};
17+
use crate::vstate::resources::ResourceAllocatorState;
1618
use crate::vstate::vm::{VmCommon, VmError};
1719

1820
/// Error type for [`Vm::restore_state`]
@@ -187,6 +189,7 @@ impl ArchVm {
187189

188190
Ok(VmState {
189191
memory: self.common.guest_memory.describe(),
192+
resource_allocator: self.common.resource_allocator.save(),
190193
pitstate,
191194
clock,
192195
pic_master,
@@ -211,6 +214,8 @@ impl ArchVm {
211214
pub struct VmState {
212215
/// guest memory state
213216
pub memory: GuestMemoryState,
217+
/// resource allocator
218+
pub resource_allocator: ResourceAllocatorState,
214219
pitstate: kvm_pit_state2,
215220
clock: kvm_clock_data,
216221
// TODO: rename this field to adopt inclusive language once Linux updates it, too.

src/vmm/src/builder.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ use crate::vmm_config::instance_info::InstanceInfo;
4747
use crate::vmm_config::machine_config::MachineConfigError;
4848
use crate::vstate::kvm::{Kvm, KvmError};
4949
use crate::vstate::memory::GuestRegionMmap;
50+
#[cfg(target_arch = "aarch64")]
51+
use crate::vstate::resources::ResourceAllocator;
5052
use crate::vstate::vcpu::VcpuError;
5153
use crate::vstate::vm::{Vm, VmError};
5254
use crate::{EventManager, Vmm, VmmError};
@@ -188,7 +190,7 @@ pub fn build_microvm_for_boot(
188190
.collect::<Result<Vec<_>, _>>()?;
189191

190192
if vm_resources.pci_enabled {
191-
device_manager.enable_pci()?;
193+
device_manager.enable_pci(&vm)?;
192194
} else {
193195
boot_cmdline.insert("pci", "off")?;
194196
}
@@ -197,7 +199,7 @@ pub fn build_microvm_for_boot(
197199
// to maintain the same MMIO address referenced in the documentation
198200
// and tests.
199201
if vm_resources.boot_timer {
200-
device_manager.attach_boot_timer_device(request_ts)?;
202+
device_manager.attach_boot_timer_device(&vm, request_ts)?;
201203
}
202204

203205
if let Some(balloon) = vm_resources.balloon.get() {
@@ -252,7 +254,7 @@ pub fn build_microvm_for_boot(
252254

253255
#[cfg(target_arch = "aarch64")]
254256
if vcpus[0].kvm_vcpu.supports_pvtime() {
255-
setup_pvtime(&mut device_manager, &mut vcpus)?;
257+
setup_pvtime(&vm.common.resource_allocator, &mut vcpus)?;
256258
} else {
257259
log::warn!("Vcpus do not support pvtime, steal time will not be reported to guest");
258260
}
@@ -513,13 +515,12 @@ const STEALTIME_STRUCT_MEM_SIZE: u64 = 64;
513515
/// Helper method to allocate steal time region
514516
#[cfg(target_arch = "aarch64")]
515517
fn allocate_pvtime_region(
516-
device_manager: &mut DeviceManager,
518+
resource_allocator: &ResourceAllocator,
517519
vcpu_count: usize,
518520
policy: vm_allocator::AllocPolicy,
519521
) -> Result<GuestAddress, StartMicrovmError> {
520522
let size = STEALTIME_STRUCT_MEM_SIZE * vcpu_count as u64;
521-
let addr = device_manager
522-
.resource_allocator
523+
let addr = resource_allocator
523524
.allocate_system_memory(size, STEALTIME_STRUCT_MEM_SIZE, policy)
524525
.map_err(StartMicrovmError::AllocateResources)?;
525526
Ok(GuestAddress(addr))
@@ -528,12 +529,12 @@ fn allocate_pvtime_region(
528529
/// Sets up pvtime for all vcpus
529530
#[cfg(target_arch = "aarch64")]
530531
fn setup_pvtime(
531-
device_manager: &mut DeviceManager,
532+
resource_allocator: &ResourceAllocator,
532533
vcpus: &mut [Vcpu],
533534
) -> Result<(), StartMicrovmError> {
534535
// Alloc sys mem for steal time region
535536
let pvtime_mem: GuestAddress = allocate_pvtime_region(
536-
device_manager,
537+
resource_allocator,
537538
vcpus.len(),
538539
vm_allocator::AllocPolicy::LastMatch,
539540
)?;
@@ -1141,7 +1142,9 @@ pub(crate) mod tests {
11411142
let mut vmm = default_vmm();
11421143
let request_ts = TimestampUs::default();
11431144

1144-
let res = vmm.device_manager.attach_boot_timer_device(request_ts);
1145+
let res = vmm
1146+
.device_manager
1147+
.attach_boot_timer_device(&vmm.vm, request_ts);
11451148
res.unwrap();
11461149
assert!(vmm.device_manager.mmio_devices.boot_timer.is_some());
11471150
}

src/vmm/src/device_manager/legacy.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,7 @@ impl PortIODeviceManager {
9797
}
9898

9999
/// Register supported legacy devices.
100-
pub fn register_devices(
101-
&mut self,
102-
io_bus: &vm_device::Bus,
103-
vm: &Vm,
104-
) -> Result<(), LegacyDeviceError> {
100+
pub fn register_devices(&mut self, vm: &Vm) -> Result<(), LegacyDeviceError> {
105101
let serial_2_4 = Arc::new(Mutex::new(SerialDevice {
106102
serial: Serial::with_events(
107103
self.com_evt_2_4.try_clone()?.try_clone()?,
@@ -122,6 +118,8 @@ impl PortIODeviceManager {
122118
),
123119
input: None,
124120
}));
121+
122+
let io_bus = &vm.common.resource_allocator.pio_bus;
125123
io_bus.insert(
126124
self.stdio_serial.clone(),
127125
Self::SERIAL_PORT_ADDRESSES[0],
@@ -243,7 +241,6 @@ mod tests {
243241
#[test]
244242
fn test_register_legacy_devices() {
245243
let (_, vm) = setup_vm_with_memory(0x1000);
246-
let io_bus = vm_device::Bus::new();
247244
vm.setup_irqchip().unwrap();
248245
let mut ldm = PortIODeviceManager::new(
249246
Arc::new(Mutex::new(SerialDevice {
@@ -261,6 +258,6 @@ mod tests {
261258
)),
262259
)
263260
.unwrap();
264-
ldm.register_devices(&io_bus, &vm).unwrap();
261+
ldm.register_devices(&vm).unwrap();
265262
}
266263
}

0 commit comments

Comments
 (0)