Skip to content

Commit 72a65f2

Browse files
committed
vmm: handle uniformly GSIs and memory of a guest
Right now we handle guest interrupt lines (GSIs) and physical memory inside the MMIO device manager. With ACPI we will add a new device type for which we will need to allocate GSIs and memory. With the current way we do things, this means that we would need an extra pair of GSI and memory allocators. This commit introduces a resource manager at the VMM level for handling GSIs and guest physical memory allocations. Each device manager will get a reference to this object for handling resources globally. Signed-off-by: Babis Chalios <[email protected]>
1 parent 138a189 commit 72a65f2

File tree

6 files changed

+264
-116
lines changed

6 files changed

+264
-116
lines changed

src/vmm/src/builder.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use crate::cpu_config::templates::{
3838
use crate::device_manager::legacy::PortIODeviceManager;
3939
use crate::device_manager::mmio::MMIODeviceManager;
4040
use crate::device_manager::persist::MMIODevManagerConstructorArgs;
41+
use crate::device_manager::resources::ResourceAllocator;
4142
use crate::devices::legacy::serial::SerialOut;
4243
#[cfg(target_arch = "aarch64")]
4344
use crate::devices::legacy::RTCDevice;
@@ -105,13 +106,15 @@ pub enum StartMicrovmError {
105106
/// Cannot open the block device backing file: {0}
106107
OpenBlockDevice(io::Error),
107108
/// Cannot initialize a MMIO Device or add a device to the MMIO Bus or cmdline: {0}
108-
RegisterMmioDevice(device_manager::mmio::MmioError),
109+
RegisterMmioDevice(#[from] device_manager::mmio::MmioError),
109110
/// Cannot restore microvm state: {0}
110111
RestoreMicrovmState(MicrovmStateError),
111112
/// Cannot set vm resources: {0}
112113
SetVmResources(VmConfigError),
113114
/// Cannot create the entropy device: {0}
114115
CreateEntropyDevice(crate::devices::virtio::rng::EntropyError),
116+
/// Failed to allocate guest resource: {0}
117+
AllocateResources(#[from] vm_allocator::Error),
115118
}
116119

117120
/// It's convenient to automatically convert `linux_loader::cmdline::Error`s
@@ -147,15 +150,10 @@ fn create_vmm_and_vcpus(
147150
.map_err(VmmError::EventFd)
148151
.map_err(Internal)?;
149152

153+
let resource_allocator = ResourceAllocator::new()?;
154+
150155
// Instantiate the MMIO device manager.
151-
// 'mmio_base' address has to be an address which is protected by the kernel
152-
// and is architectural specific.
153-
let mmio_device_manager = MMIODeviceManager::new(
154-
crate::arch::MMIO_MEM_START,
155-
crate::arch::MMIO_MEM_SIZE,
156-
(crate::arch::IRQ_BASE, crate::arch::IRQ_MAX),
157-
)
158-
.map_err(StartMicrovmError::RegisterMmioDevice)?;
156+
let mmio_device_manager = MMIODeviceManager::new();
159157

160158
// For x86_64 we need to create the interrupt controller before calling `KVM_CREATE_VCPUS`
161159
// while on aarch64 we need to do it the other way around.
@@ -208,6 +206,7 @@ fn create_vmm_and_vcpus(
208206
uffd,
209207
vcpus_handles: Vec::new(),
210208
vcpus_exit_evt,
209+
resource_allocator,
211210
mmio_device_manager,
212211
#[cfg(target_arch = "x86_64")]
213212
pio_device_manager,
@@ -497,6 +496,7 @@ pub fn build_microvm_from_snapshot(
497496
mem: guest_memory,
498497
vm: vmm.vm.fd(),
499498
event_manager,
499+
resource_allocator: &mut vmm.resource_allocator,
500500
vm_resources,
501501
instance_id: &instance_info.id,
502502
};
@@ -681,7 +681,7 @@ fn attach_legacy_devices_aarch64(
681681
set_stdout_nonblocking();
682682
let serial = setup_serial_device(event_manager, std::io::stdin(), std::io::stdout())?;
683683
vmm.mmio_device_manager
684-
.register_mmio_serial(vmm.vm.fd(), serial, None)
684+
.register_mmio_serial(vmm.vm.fd(), &mut vmm.resource_allocator, serial, None)
685685
.map_err(VmmError::RegisterMMIODevice)?;
686686
vmm.mmio_device_manager
687687
.add_mmio_serial_to_cmdline(cmdline)
@@ -692,7 +692,7 @@ fn attach_legacy_devices_aarch64(
692692
&crate::devices::legacy::rtc_pl031::METRICS,
693693
));
694694
vmm.mmio_device_manager
695-
.register_mmio_rtc(rtc, None)
695+
.register_mmio_rtc(&mut vmm.resource_allocator, rtc, None)
696696
.map_err(VmmError::RegisterMMIODevice)
697697
}
698698

@@ -827,7 +827,13 @@ fn attach_virtio_device<T: 'static + VirtioDevice + MutEventSubscriber + Debug>(
827827
// The device mutex mustn't be locked here otherwise it will deadlock.
828828
let device = MmioTransport::new(vmm.guest_memory().clone(), device, is_vhost_user);
829829
vmm.mmio_device_manager
830-
.register_mmio_virtio_for_boot(vmm.vm.fd(), id, device, cmdline)
830+
.register_mmio_virtio_for_boot(
831+
vmm.vm.fd(),
832+
&mut vmm.resource_allocator,
833+
id,
834+
device,
835+
cmdline,
836+
)
831837
.map_err(RegisterMmioDevice)
832838
.map(|_| ())
833839
}
@@ -841,7 +847,7 @@ pub(crate) fn attach_boot_timer_device(
841847
let boot_timer = crate::devices::pseudo::BootTimer::new(request_ts);
842848

843849
vmm.mmio_device_manager
844-
.register_mmio_boot_timer(boot_timer)
850+
.register_mmio_boot_timer(&mut vmm.resource_allocator, boot_timer)
845851
.map_err(RegisterMmioDevice)?;
846852

847853
Ok(())
@@ -964,6 +970,7 @@ pub mod tests {
964970

965971
use super::*;
966972
use crate::arch::DeviceType;
973+
use crate::device_manager::resources::ResourceAllocator;
967974
use crate::devices::virtio::block::CacheType;
968975
use crate::devices::virtio::rng::device::ENTROPY_DEV_ID;
969976
use crate::devices::virtio::vsock::{TYPE_VSOCK, VSOCK_DEV_ID};
@@ -1006,15 +1013,6 @@ pub mod tests {
10061013
}
10071014
}
10081015

1009-
fn default_mmio_device_manager() -> MMIODeviceManager {
1010-
MMIODeviceManager::new(
1011-
crate::arch::MMIO_MEM_START,
1012-
crate::arch::MMIO_MEM_SIZE,
1013-
(crate::arch::IRQ_BASE, crate::arch::IRQ_MAX),
1014-
)
1015-
.unwrap()
1016-
}
1017-
10181016
fn cmdline_contains(cmdline: &Cmdline, slug: &str) -> bool {
10191017
// The following unwraps can never fail; the only way any of these methods
10201018
// would return an `Err` is if one of the following conditions is met:
@@ -1051,7 +1049,7 @@ pub mod tests {
10511049

10521050
let mut vm = Vm::new(vec![]).unwrap();
10531051
vm.memory_init(&guest_memory, false).unwrap();
1054-
let mmio_device_manager = default_mmio_device_manager();
1052+
let mmio_device_manager = MMIODeviceManager::new();
10551053
#[cfg(target_arch = "x86_64")]
10561054
let pio_device_manager = PortIODeviceManager::new(
10571055
Arc::new(Mutex::new(BusDevice::Serial(SerialWrapper {
@@ -1087,6 +1085,7 @@ pub mod tests {
10871085
uffd: None,
10881086
vcpus_handles: Vec::new(),
10891087
vcpus_exit_evt,
1088+
resource_allocator: ResourceAllocator::new().unwrap(),
10901089
mmio_device_manager,
10911090
#[cfg(target_arch = "x86_64")]
10921091
pio_device_manager,

0 commit comments

Comments
 (0)