From 8746c16593a338e35ade70bfda8240175c8adb59 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 23 Oct 2019 15:14:13 -0700 Subject: [PATCH] vmm: Create AddressManager to own SystemAllocator In order to reuse the SystemAllocator later at runtime, it is moved into the new structure AddressManager. The goal is to have a hold onto the SystemAllocator and both IO and MMIO buses so that we can use them later. Signed-off-by: Sebastien Boeuf --- vmm/src/device_manager.rs | 119 +++++++++++++++++++------------------- vmm/src/vm.rs | 2 +- 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index c5ed15902..c04679dbb 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -167,11 +167,6 @@ pub enum DeviceManagerError { } pub type DeviceManagerResult = result::Result; -struct BusInfo<'a> { - io: &'a Arc, - mmio: &'a Arc, -} - struct InterruptInfo<'a> { _msi_capable: bool, ioapic: &'a Option>>, @@ -275,9 +270,15 @@ impl Console { } } -pub struct DeviceManager { +struct AddressManager { + allocator: Arc>, io_bus: Arc, mmio_bus: Arc, +} + +pub struct DeviceManager { + // Manage address space related to devices + address_manager: Arc, // Console abstraction console: Arc, @@ -299,20 +300,15 @@ pub struct DeviceManager { impl DeviceManager { pub fn new( vm_info: &VmInfo, - allocator: &mut SystemAllocator, + mut allocator: SystemAllocator, _msi_capable: bool, userspace_ioapic: bool, mut mem_slots: u32, _exit_evt: &EventFd, reset_evt: &EventFd, ) -> DeviceManagerResult { - let mut io_bus = Arc::new(devices::Bus::new()); - let mut mmio_bus = Arc::new(devices::Bus::new()); - - let mut buses = BusInfo { - io: &mut io_bus, - mmio: &mut mmio_bus, - }; + let io_bus = devices::Bus::new(); + let mmio_bus = devices::Bus::new(); let ioapic = if userspace_ioapic { // Create IOAPIC @@ -320,8 +316,7 @@ impl DeviceManager { vm_info.vm_fd.clone(), APIC_START, ))); - buses - .mmio + mmio_bus .insert(ioapic.clone(), IOAPIC_START.0, IOAPIC_SIZE) .map_err(DeviceManagerError::BusError)?; Some(ioapic) @@ -362,8 +357,7 @@ impl DeviceManager { serial_writer, ))); - buses - .io + io_bus .insert(serial.clone(), 0x3f8, 0x8) .map_err(DeviceManagerError::BusError)?; @@ -376,8 +370,7 @@ impl DeviceManager { let i8042 = Arc::new(Mutex::new(devices::legacy::I8042Device::new( reset_evt.try_clone().map_err(DeviceManagerError::EventFd)?, ))); - buses - .io + io_bus .insert(i8042.clone(), 0x61, 0x4) .map_err(DeviceManagerError::BusError)?; #[cfg(feature = "cmos")] @@ -391,8 +384,7 @@ impl DeviceManager { mem_below_4g, mem_above_4g, ))); - buses - .io + io_bus .insert(cmos.clone(), 0x70, 0x2) .map_err(DeviceManagerError::BusError)?; } @@ -402,8 +394,7 @@ impl DeviceManager { _exit_evt.try_clone().map_err(DeviceManagerError::EventFd)?, reset_evt.try_clone().map_err(DeviceManagerError::EventFd)?, ))); - buses - .io + io_bus .insert(acpi_device.clone(), 0x3c0, 0x4) .map_err(DeviceManagerError::BusError)?; } @@ -446,7 +437,7 @@ impl DeviceManager { virtio_devices.append(&mut DeviceManager::make_virtio_devices( vm_info, - allocator, + &mut allocator, &mut mem_slots, &mut mmap_regions, )?); @@ -457,6 +448,12 @@ impl DeviceManager { #[allow(unused_mut)] let mut virt_iommu: Option<(u32, Vec)> = None; + let address_manager = Arc::new(AddressManager { + allocator: Arc::new(Mutex::new(allocator)), + io_bus: Arc::new(io_bus), + mmio_bus: Arc::new(mmio_bus), + }); + if cfg!(feature = "pci_support") { #[cfg(feature = "pci_support")] { @@ -483,10 +480,9 @@ impl DeviceManager { let virtio_iommu_attach_dev = DeviceManager::add_virtio_pci_device( device, vm_info.memory, - allocator, + &address_manager, vm_info.vm_fd, &mut pci_bus, - &mut buses, &interrupt_info, mapping, )?; @@ -498,9 +494,8 @@ impl DeviceManager { let mut vfio_iommu_device_ids = DeviceManager::add_vfio_devices( vm_info, - allocator, + &address_manager, &mut pci_bus, - &mut buses, mem_slots, &mut iommu_device, )?; @@ -521,10 +516,9 @@ impl DeviceManager { DeviceManager::add_virtio_pci_device( Box::new(iommu_device), vm_info.memory, - allocator, + &address_manager, vm_info.vm_fd, &mut pci_bus, - &mut buses, &interrupt_info, &None, )?; @@ -534,11 +528,13 @@ impl DeviceManager { let pci_bus = Arc::new(Mutex::new(pci_bus)); let pci_config_io = Arc::new(Mutex::new(PciConfigIo::new(pci_bus.clone()))); - io_bus + address_manager + .io_bus .insert(pci_config_io, 0xcf8, 0x8) .map_err(DeviceManagerError::BusError)?; let pci_config_mmio = Arc::new(Mutex::new(PciConfigMmio::new(pci_bus))); - mmio_bus + address_manager + .mmio_bus .insert( pci_config_mmio, arch::layout::PCI_MMCONFIG_START.0, @@ -550,15 +546,17 @@ impl DeviceManager { #[cfg(feature = "mmio_support")] { for (device, _) in virtio_devices { - if let Some(addr) = - allocator.allocate_mmio_addresses(None, MMIO_LEN, Some(MMIO_LEN)) - { + let mmio_addr = address_manager + .allocator + .lock() + .unwrap() + .allocate_mmio_addresses(None, MMIO_LEN, Some(MMIO_LEN)); + if let Some(addr) = mmio_addr { DeviceManager::add_virtio_mmio_device( device, vm_info.memory, - allocator, + &address_manager, vm_info.vm_fd, - &mut buses, &interrupt_info, addr, &mut cmdline_additions, @@ -571,8 +569,7 @@ impl DeviceManager { } Ok(DeviceManager { - io_bus, - mmio_bus, + address_manager, console, ioapic, mmap_regions, @@ -978,14 +975,14 @@ impl DeviceManager { #[cfg(feature = "pci_support")] fn add_vfio_devices( vm_info: &VmInfo, - allocator: &mut SystemAllocator, + address_manager: &Arc, pci: &mut PciBus, - buses: &mut BusInfo, mem_slots: u32, iommu_device: &mut Option, ) -> DeviceManagerResult> { let mut mem_slot = mem_slots; let mut iommu_attached_device_ids = Vec::new(); + let mut allocator = address_manager.allocator.lock().unwrap(); if let Some(device_list_cfg) = &vm_info.vm_cfg.devices { // Create the KVM VFIO device let device_fd = DeviceManager::create_kvm_device(vm_info.vm_fd)?; @@ -1019,11 +1016,12 @@ impl DeviceManager { } } - let mut vfio_pci_device = VfioPciDevice::new(vm_info.vm_fd, allocator, vfio_device) - .map_err(DeviceManagerError::VfioPciCreate)?; + let mut vfio_pci_device = + VfioPciDevice::new(vm_info.vm_fd, &mut allocator, vfio_device) + .map_err(DeviceManagerError::VfioPciCreate)?; let bars = vfio_pci_device - .allocate_bars(allocator) + .allocate_bars(&mut allocator) .map_err(DeviceManagerError::AllocateBars)?; mem_slot = vfio_pci_device @@ -1037,8 +1035,8 @@ impl DeviceManager { pci.register_mapping( vfio_pci_device.clone(), - buses.io.as_ref(), - buses.mmio.as_ref(), + address_manager.io_bus.as_ref(), + address_manager.mmio_bus.as_ref(), bars, ) .map_err(DeviceManagerError::AddPciDevice)?; @@ -1052,10 +1050,9 @@ impl DeviceManager { fn add_virtio_pci_device( virtio_device: Box, memory: &Arc>, - allocator: &mut SystemAllocator, + address_manager: &Arc, vm_fd: &Arc, pci: &mut PciBus, - buses: &mut BusInfo, interrupt_info: &InterruptInfo, iommu_mapping: &Option>, ) -> DeviceManagerResult> { @@ -1099,8 +1096,10 @@ impl DeviceManager { VirtioPciDevice::new(memory.clone(), virtio_device, msix_num, iommu_mapping_cb) .map_err(DeviceManagerError::VirtioDevice)?; + let mut allocator = address_manager.allocator.lock().unwrap(); + let bars = virtio_pci_device - .allocate_bars(allocator) + .allocate_bars(&mut allocator) .map_err(DeviceManagerError::AllocateBars)?; for (event, addr, _) in virtio_pci_device.ioeventfds() { @@ -1183,8 +1182,8 @@ impl DeviceManager { pci.register_mapping( virtio_pci_device.clone(), - buses.io.as_ref(), - buses.mmio.as_ref(), + address_manager.io_bus.as_ref(), + address_manager.mmio_bus.as_ref(), bars, ) .map_err(DeviceManagerError::AddPciDevice)?; @@ -1203,9 +1202,8 @@ impl DeviceManager { fn add_virtio_mmio_device( virtio_device: Box, memory: &Arc>, - allocator: &mut SystemAllocator, + address_manager: &Arc, vm_fd: &Arc, - buses: &mut BusInfo, interrupt_info: &InterruptInfo, mmio_base: GuestAddress, cmdline_additions: &mut Vec, @@ -1222,7 +1220,10 @@ impl DeviceManager { .map_err(DeviceManagerError::RegisterIoevent)?; } - let irq_num = allocator + let irq_num = address_manager + .allocator + .lock() + .unwrap() .allocate_irq() .ok_or(DeviceManagerError::AllocateIrq)?; @@ -1240,8 +1241,8 @@ impl DeviceManager { mmio_device.assign_interrupt(interrupt); - buses - .mmio + address_manager + .mmio_bus .insert(Arc::new(Mutex::new(mmio_device)), mmio_base.0, MMIO_LEN) .map_err(DeviceManagerError::BusError)?; @@ -1256,11 +1257,11 @@ impl DeviceManager { } pub fn io_bus(&self) -> &Arc { - &self.io_bus + &self.address_manager.io_bus } pub fn mmio_bus(&self) -> &Arc { - &self.mmio_bus + &self.address_manager.mmio_bus } pub fn ioapic(&self) -> &Option>> { diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 3cf733ea9..b8ff57ac1 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -701,7 +701,7 @@ impl Vm { let device_manager = DeviceManager::new( &vm_info, - &mut allocator, + allocator, msi_capable, userspace_ioapic, ram_regions.len() as u32,