From af3c6c34c3d8840e6c7c78021dfc87f675489977 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 15 Oct 2020 17:34:35 +0200 Subject: [PATCH] vmm: Remove mmio and pci differentiation Signed-off-by: Sebastien Boeuf --- Cargo.toml | 4 +- vmm/Cargo.toml | 8 +- vmm/src/config.rs | 9 - vmm/src/device_manager.rs | 454 ++++++++------------------------------ vmm/src/device_tree.rs | 2 - vmm/src/vm.rs | 164 +++++--------- 6 files changed, 155 insertions(+), 486 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index efebedb7c..8444d3b0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,10 +49,8 @@ serde_json = "1.0.59" net_util = { path = "net_util" } [features] -default = ["acpi", "pci", "cmos", "kvm"] +default = ["acpi", "cmos", "kvm"] acpi = ["vmm/acpi"] -pci = ["vmm/pci_support"] -mmio = ["vmm/mmio_support"] cmos = ["vmm/cmos"] fwdebug = ["vmm/fwdebug"] kvm = ["vmm/kvm"] diff --git a/vmm/Cargo.toml b/vmm/Cargo.toml index e1daed5ad..76f6b3a6d 100644 --- a/vmm/Cargo.toml +++ b/vmm/Cargo.toml @@ -7,8 +7,6 @@ edition = "2018" [features] default = [] acpi = ["acpi_tables","devices/acpi", "arch/acpi"] -pci_support = ["pci", "vfio-ioctls", "virtio-devices/pci_support"] -mmio_support = ["virtio-devices/mmio_support"] cmos = ["devices/cmos"] fwdebug = ["devices/fwdebug"] kvm = ["hypervisor/kvm"] @@ -31,15 +29,15 @@ log = "0.4.11" micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "master" } net_util = { path = "../net_util" } option_parser = { path = "../option_parser" } -pci = {path = "../pci", optional = true} +pci = { path = "../pci" } qcow = { path = "../qcow" } seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v0.22.0" } serde = {version = ">=1.0.27", features = ["rc"] } serde_derive = ">=1.0.27" serde_json = ">=1.0.9" url = "2.1.1" -vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch", optional = true } -virtio-devices = {path = "../virtio-devices"} +vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" } +virtio-devices = { path = "../virtio-devices", features = ["pci_support"]} vm-allocator = { path = "../vm-allocator" } vm-device = { path = "../vm-device" } vm-memory = { version = "0.3.0", features = ["backend-mmap", "backend-atomic"] } diff --git a/vmm/src/config.rs b/vmm/src/config.rs index bc5a5d3ef..636719595 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -1449,15 +1449,6 @@ impl VmConfig { } } - if cfg!(not(feature = "pci_support")) { - if self.iommu { - return Err(ValidationError::IommuUnsupported); - } - if self.devices.is_some() { - return Err(ValidationError::VfioUnsupported); - } - } - if let Some(t) = &self.cpus.topology { if t.threads_per_core == 0 || t.cores_per_die == 0 diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 45601b88b..b3adc3861 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -10,7 +10,6 @@ // use crate::config::ConsoleOutputMode; -#[cfg(feature = "pci_support")] use crate::config::DeviceConfig; use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, VsockConfig}; use crate::device_tree::{DeviceNode, DeviceTree}; @@ -20,7 +19,6 @@ use crate::interrupt::LegacyUserspaceInterruptManager; use crate::memory_manager::{Error as MemoryManagerError, MemoryManager}; #[cfg(feature = "acpi")] use crate::vm::NumaNodes; -#[cfg(feature = "pci_support")] use crate::PciDeviceInfo; use crate::{device_node, DEVICE_MANAGER_SNAPSHOT_ID}; #[cfg(feature = "acpi")] @@ -47,39 +45,33 @@ use devices::{ }; use hypervisor::kvm_ioctls; use hypervisor::kvm_ioctls::*; -#[cfg(feature = "mmio_support")] -use hypervisor::vm::DataMatch; #[cfg(target_arch = "aarch64")] use hypervisor::CpuState; use libc::TIOCGWINSZ; use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE}; -#[cfg(feature = "pci_support")] use pci::{ DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot, VfioPciDevice, }; use qcow::{self, ImageType, QcowFile}; use seccomp::SeccompAction; -#[cfg(feature = "pci_support")] use std::any::Any; use std::collections::HashMap; use std::fs::{File, OpenOptions}; use std::io::{self, sink, stdout, Seek, SeekFrom}; use std::num::Wrapping; use std::os::unix::fs::OpenOptionsExt; -#[cfg(all(feature = "pci_support", feature = "kvm"))] +#[cfg(feature = "kvm")] use std::os::unix::io::FromRawFd; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; use tempfile::NamedTempFile; -#[cfg(all(feature = "pci_support", feature = "kvm"))] +#[cfg(feature = "kvm")] use vfio_ioctls::{VfioContainer, VfioDevice, VfioDmaMapping}; -#[cfg(feature = "pci_support")] use virtio_devices::transport::VirtioPciDevice; use virtio_devices::transport::VirtioTransport; use virtio_devices::vhost_user::VhostUserConfig; -#[cfg(feature = "pci_support")] use virtio_devices::{DmaRemapping, IommuMapping}; use virtio_devices::{VirtioSharedMemory, VirtioSharedMemoryList}; use vm_allocator::SystemAllocator; @@ -95,14 +87,13 @@ use vm_migration::{ Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable, Transportable, }; -#[cfg(feature = "pci_support")] use vm_virtio::{VirtioDeviceType, VirtioIommuRemapping}; use vmm_sys_util::eventfd::EventFd; -#[cfg(any(feature = "mmio_support", target_arch = "aarch64"))] +#[cfg(target_arch = "aarch64")] const MMIO_LEN: u64 = 0x1000; -#[cfg(all(feature = "pci_support", feature = "kvm"))] +#[cfg(feature = "kvm")] const VFIO_DEVICE_NAME_PREFIX: &str = "_vfio"; #[cfg(target_arch = "x86_64")] @@ -120,12 +111,8 @@ const PMEM_DEVICE_NAME_PREFIX: &str = "_pmem"; const RNG_DEVICE_NAME: &str = "_rng"; const VSOCK_DEVICE_NAME_PREFIX: &str = "_vsock"; -#[cfg(feature = "pci_support")] const IOMMU_DEVICE_NAME: &str = "_iommu"; -#[cfg(feature = "mmio_support")] -const VIRTIO_MMIO_DEVICE_NAME_PREFIX: &str = "_virtio-mmio"; -#[cfg(feature = "pci_support")] const VIRTIO_PCI_DEVICE_NAME_PREFIX: &str = "_virtio-pci"; /// Errors associated with device manager @@ -195,11 +182,9 @@ pub enum DeviceManagerError { Irq(kvm_ioctls::Error), /// Cannot allocate PCI BARs - #[cfg(feature = "pci_support")] AllocateBars(pci::PciDeviceError), /// Could not free the BARs associated with a PCI device. - #[cfg(feature = "pci_support")] FreePciBars(pci::PciDeviceError), /// Cannot register ioevent. @@ -212,7 +197,6 @@ pub enum DeviceManagerError { VirtioDevice(vmm_sys_util::errno::Error), /// Cannot add PCI device - #[cfg(feature = "pci_support")] AddPciDevice(pci::PciRootError), /// Cannot open persistent memory file @@ -234,15 +218,12 @@ pub enum DeviceManagerError { ConsoleOutputFileOpen(io::Error), /// Cannot create a VFIO device - #[cfg(feature = "pci_support")] VfioCreate(vfio_ioctls::VfioError), /// Cannot create a VFIO PCI device - #[cfg(feature = "pci_support")] VfioPciCreate(pci::VfioPciError), /// Failed to map VFIO MMIO region. - #[cfg(feature = "pci_support")] VfioMapRegion(pci::VfioPciError), /// Failed to create the passthrough device. @@ -297,7 +278,6 @@ pub enum DeviceManagerError { MissingPciDevice, /// Failed removing a PCI device from the PCI bus. - #[cfg(feature = "pci_support")] RemoveDeviceFromPciBus(pci::PciRootError), /// Failed removing a bus device from the IO bus. @@ -307,27 +287,21 @@ pub enum DeviceManagerError { RemoveDeviceFromMmioBus(vm_device::BusError), /// Failed to find the device corresponding to a specific PCI b/d/f. - #[cfg(feature = "pci_support")] UnknownPciBdf(u32), /// Not allowed to remove this type of device from the VM. - #[cfg(feature = "pci_support")] RemovalNotAllowed(vm_virtio::VirtioDeviceType), /// Failed to find device corresponding to the given identifier. - #[cfg(feature = "pci_support")] UnknownDeviceId(String), /// Failed to find an available PCI device ID. - #[cfg(feature = "pci_support")] NextPciDeviceId(pci::PciRootError), /// Could not reserve the PCI device ID. - #[cfg(feature = "pci_support")] GetPciDeviceId(pci::PciRootError), /// Could not give the PCI device ID back. - #[cfg(feature = "pci_support")] PutPciDeviceId(pci::PciRootError), /// Incorrect device ID as it is already used by another device. @@ -349,7 +323,6 @@ pub enum DeviceManagerError { VirtioMemRangeAllocation, /// Failed updating guest memory for VFIO PCI device. - #[cfg(feature = "pci_support")] UpdateMemoryForVfioPciDevice(pci::VfioPciError), /// Trying to use a directory for pmem but no size specified @@ -377,7 +350,6 @@ pub enum DeviceManagerError { MissingVirtioFsResources, /// Missing PCI b/d/f from the DeviceNode. - #[cfg(feature = "pci_support")] MissingDeviceNodePciBdf, /// No support for device passthrough @@ -465,11 +437,9 @@ struct AddressManager { io_bus: Arc, mmio_bus: Arc, vm: Arc, - #[cfg(feature = "pci_support")] device_tree: Arc>, } -#[cfg(feature = "pci_support")] impl DeviceRelocation for AddressManager { fn move_bar( &self, @@ -763,7 +733,6 @@ pub struct DeviceManager { device_id_cnt: Wrapping, // Keep a reference to the PCI bus - #[cfg(feature = "pci_support")] pci_bus: Option>>, #[cfg_attr(target_arch = "aarch64", allow(dead_code))] @@ -771,27 +740,21 @@ pub struct DeviceManager { msi_interrupt_manager: Arc>, // Passthrough device handle - #[cfg(feature = "pci_support")] passthrough_device: Option>, // Paravirtualized IOMMU - #[cfg(feature = "pci_support")] iommu_device: Option>>, // Bitmap of PCI devices to hotplug. - #[cfg(feature = "pci_support")] pci_devices_up: u32, // Bitmap of PCI devices to hotunplug. - #[cfg(feature = "pci_support")] pci_devices_down: u32, // Hashmap of device's name to their corresponding PCI b/d/f. - #[cfg(feature = "pci_support")] pci_id_list: HashMap, // Hashmap of PCI b/d/f to their corresponding Arc>. - #[cfg(feature = "pci_support")] pci_devices: HashMap>, // Tree of devices, representing the dependencies between devices. @@ -837,7 +800,6 @@ impl DeviceManager { io_bus: Arc::new(Bus::new()), mmio_bus: Arc::new(Bus::new()), vm: vm.clone(), - #[cfg(feature = "pci_support")] device_tree: Arc::clone(&device_tree), }); @@ -869,20 +831,13 @@ impl DeviceManager { vmm_path, vhost_user_backends: Vec::new(), device_id_cnt: Wrapping(0), - #[cfg(feature = "pci_support")] pci_bus: None, msi_interrupt_manager, - #[cfg(feature = "pci_support")] passthrough_device: None, - #[cfg(feature = "pci_support")] iommu_device: None, - #[cfg(feature = "pci_support")] pci_devices_up: 0, - #[cfg(feature = "pci_support")] pci_devices_down: 0, - #[cfg(feature = "pci_support")] pci_id_list: HashMap::new(), - #[cfg(feature = "pci_support")] pci_devices: HashMap::new(), device_tree, #[cfg(feature = "acpi")] @@ -975,14 +930,9 @@ impl DeviceManager { self.console = self.add_console_device(&legacy_interrupt_manager, &mut virtio_devices)?; - #[cfg(any(feature = "pci_support", feature = "mmio_support"))] virtio_devices.append(&mut self.make_virtio_devices()?); - if cfg!(feature = "pci_support") { - self.add_pci_devices(virtio_devices.clone())?; - } else if cfg!(feature = "mmio_support") { - self.add_mmio_devices(virtio_devices.clone(), &legacy_interrupt_manager)?; - } + self.add_pci_devices(virtio_devices.clone())?; self.virtio_devices = virtio_devices; @@ -1014,123 +964,98 @@ impl DeviceManager { &mut self, virtio_devices: Vec<(VirtioDeviceArc, bool, String)>, ) -> DeviceManagerResult<()> { - #[cfg(feature = "pci_support")] - { - let pci_root = PciRoot::new(None); - let mut pci_bus = PciBus::new( - pci_root, - Arc::clone(&self.address_manager) as Arc, - ); + let pci_root = PciRoot::new(None); + let mut pci_bus = PciBus::new( + pci_root, + Arc::clone(&self.address_manager) as Arc, + ); - let iommu_id = String::from(IOMMU_DEVICE_NAME); + let iommu_id = String::from(IOMMU_DEVICE_NAME); - let (iommu_device, iommu_mapping) = if self.config.lock().unwrap().iommu { - let (device, mapping) = - virtio_devices::Iommu::new(iommu_id.clone(), self.seccomp_action.clone()) - .map_err(DeviceManagerError::CreateVirtioIommu)?; - let device = Arc::new(Mutex::new(device)); - self.iommu_device = Some(Arc::clone(&device)); + let (iommu_device, iommu_mapping) = if self.config.lock().unwrap().iommu { + let (device, mapping) = + virtio_devices::Iommu::new(iommu_id.clone(), self.seccomp_action.clone()) + .map_err(DeviceManagerError::CreateVirtioIommu)?; + let device = Arc::new(Mutex::new(device)); + self.iommu_device = Some(Arc::clone(&device)); - // Fill the device tree with a new node. In case of restore, we - // know there is nothing to do, so we can simply override the - // existing entry. - self.device_tree - .lock() - .unwrap() - .insert(iommu_id.clone(), device_node!(iommu_id, device)); + // Fill the device tree with a new node. In case of restore, we + // know there is nothing to do, so we can simply override the + // existing entry. + self.device_tree + .lock() + .unwrap() + .insert(iommu_id.clone(), device_node!(iommu_id, device)); - (Some(device), Some(mapping)) + (Some(device), Some(mapping)) + } else { + (None, None) + }; + + let interrupt_manager = Arc::clone(&self.msi_interrupt_manager); + + let mut iommu_attached_devices = Vec::new(); + + for (device, iommu_attached, id) in virtio_devices { + let mapping: &Option> = if iommu_attached { + &iommu_mapping } else { - (None, None) + &None }; - let interrupt_manager = Arc::clone(&self.msi_interrupt_manager); + let dev_id = + self.add_virtio_pci_device(device, &mut pci_bus, mapping, &interrupt_manager, id)?; - let mut iommu_attached_devices = Vec::new(); - - for (device, iommu_attached, id) in virtio_devices { - let mapping: &Option> = if iommu_attached { - &iommu_mapping - } else { - &None - }; - - let dev_id = self.add_virtio_pci_device( - device, - &mut pci_bus, - mapping, - &interrupt_manager, - id, - )?; - - if iommu_attached { - iommu_attached_devices.push(dev_id); - } - } - - let mut vfio_iommu_device_ids = - self.add_vfio_devices(&mut pci_bus, &interrupt_manager)?; - - iommu_attached_devices.append(&mut vfio_iommu_device_ids); - - if let Some(iommu_device) = iommu_device { - iommu_device - .lock() - .unwrap() - .attach_pci_devices(0, iommu_attached_devices); - - // Because we determined the virtio-iommu b/d/f, we have to - // add the device to the PCI topology now. Otherwise, the - // b/d/f won't match the virtio-iommu device as expected. - self.add_virtio_pci_device( - iommu_device, - &mut pci_bus, - &None, - &interrupt_manager, - iommu_id, - )?; - } - - let pci_bus = Arc::new(Mutex::new(pci_bus)); - let pci_config_io = Arc::new(Mutex::new(PciConfigIo::new(Arc::clone(&pci_bus)))); - self.bus_devices - .push(Arc::clone(&pci_config_io) as Arc>); - #[cfg(target_arch = "x86_64")] - self.address_manager - .io_bus - .insert(pci_config_io, 0xcf8, 0x8) - .map_err(DeviceManagerError::BusError)?; - let pci_config_mmio = Arc::new(Mutex::new(PciConfigMmio::new(Arc::clone(&pci_bus)))); - self.bus_devices - .push(Arc::clone(&pci_config_mmio) as Arc>); - self.address_manager - .mmio_bus - .insert( - pci_config_mmio, - arch::layout::PCI_MMCONFIG_START.0, - arch::layout::PCI_MMCONFIG_SIZE, - ) - .map_err(DeviceManagerError::BusError)?; - - self.pci_bus = Some(pci_bus); - } - - Ok(()) - } - - #[allow(unused_variables, unused_mut)] - fn add_mmio_devices( - &mut self, - virtio_devices: Vec<(VirtioDeviceArc, bool, String)>, - interrupt_manager: &Arc>, - ) -> DeviceManagerResult<()> { - #[cfg(feature = "mmio_support")] - { - for (device, _, id) in virtio_devices { - self.add_virtio_mmio_device(id, device, interrupt_manager)?; + if iommu_attached { + iommu_attached_devices.push(dev_id); } } + let mut vfio_iommu_device_ids = self.add_vfio_devices(&mut pci_bus, &interrupt_manager)?; + + iommu_attached_devices.append(&mut vfio_iommu_device_ids); + + if let Some(iommu_device) = iommu_device { + iommu_device + .lock() + .unwrap() + .attach_pci_devices(0, iommu_attached_devices); + + // Because we determined the virtio-iommu b/d/f, we have to + // add the device to the PCI topology now. Otherwise, the + // b/d/f won't match the virtio-iommu device as expected. + self.add_virtio_pci_device( + iommu_device, + &mut pci_bus, + &None, + &interrupt_manager, + iommu_id, + )?; + } + + let pci_bus = Arc::new(Mutex::new(pci_bus)); + let pci_config_io = Arc::new(Mutex::new(PciConfigIo::new(Arc::clone(&pci_bus)))); + self.bus_devices + .push(Arc::clone(&pci_config_io) as Arc>); + #[cfg(target_arch = "x86_64")] + self.address_manager + .io_bus + .insert(pci_config_io, 0xcf8, 0x8) + .map_err(DeviceManagerError::BusError)?; + let pci_config_mmio = Arc::new(Mutex::new(PciConfigMmio::new(Arc::clone(&pci_bus)))); + self.bus_devices + .push(Arc::clone(&pci_config_mmio) as Arc>); + self.address_manager + .mmio_bus + .insert( + pci_config_mmio, + arch::layout::PCI_MMCONFIG_START.0, + arch::layout::PCI_MMCONFIG_SIZE, + ) + .map_err(DeviceManagerError::BusError)?; + + self.pci_bus = Some(pci_bus); + Ok(()) } @@ -2543,17 +2468,6 @@ impl DeviceManager { Ok(devices) } - #[cfg(not(feature = "pci_support"))] - fn next_device_name(&mut self, prefix: &str) -> DeviceManagerResult { - // Generate the temporary name. - let name = format!("{}{}", prefix, self.device_id_cnt); - // Increment the counter. - self.device_id_cnt += Wrapping(1); - - Ok(name) - } - - #[cfg(feature = "pci_support")] fn next_device_name(&mut self, prefix: &str) -> DeviceManagerResult { let start_id = self.device_id_cnt; loop { @@ -2575,7 +2489,6 @@ impl DeviceManager { Err(DeviceManagerError::NoAvailableDeviceName) } - #[cfg(feature = "pci_support")] #[cfg_attr(not(feature = "kvm"), allow(unused_variables))] fn add_passthrough_device( &mut self, @@ -2590,7 +2503,7 @@ impl DeviceManager { Err(DeviceManagerError::NoDevicePassthroughSupport) } - #[cfg(all(feature = "pci_support", feature = "kvm"))] + #[cfg(feature = "kvm")] fn add_vfio_device( &mut self, pci: &mut PciBus, @@ -2700,7 +2613,6 @@ impl DeviceManager { Ok((pci_device_bdf, vfio_name)) } - #[cfg(feature = "pci_support")] fn add_pci_device( &mut self, pci_bus: &mut PciBus, @@ -2740,7 +2652,6 @@ impl DeviceManager { Ok(bars) } - #[cfg(feature = "pci_support")] fn add_vfio_devices( &mut self, pci: &mut PciBus, @@ -2775,7 +2686,6 @@ impl DeviceManager { Ok(iommu_attached_device_ids) } - #[cfg(feature = "pci_support")] fn add_virtio_pci_device( &mut self, virtio_device: VirtioDeviceArc, @@ -2914,160 +2824,6 @@ impl DeviceManager { Ok(pci_device_bdf) } - #[cfg(feature = "mmio_support")] - fn add_virtio_mmio_device( - &mut self, - virtio_device_id: String, - virtio_device: VirtioDeviceArc, - interrupt_manager: &Arc>, - ) -> DeviceManagerResult<()> { - let id = format!("{}-{}", VIRTIO_MMIO_DEVICE_NAME_PREFIX, virtio_device_id); - - // Create the new virtio-mmio node that will be added later to the - // device tree. - let mut node = device_node!(id); - node.children = vec![virtio_device_id.clone()]; - - // Look for the id in the device tree. If it can be found, that means - // the device is being restored, otherwise it's created from scratch. - let (mmio_range, mmio_irq) = if let Some(node) = self.device_tree.lock().unwrap().get(&id) { - debug!("Restoring virtio-mmio {} resources", id); - - let mut mmio_range: Option<(u64, u64)> = None; - let mut mmio_irq: Option = None; - for resource in node.resources.iter() { - match resource { - Resource::MmioAddressRange { base, size } => { - if mmio_range.is_some() { - return Err(DeviceManagerError::ResourceAlreadyExists); - } - - mmio_range = Some((*base, *size)); - } - Resource::LegacyIrq(irq) => { - if mmio_irq.is_some() { - return Err(DeviceManagerError::ResourceAlreadyExists); - } - - mmio_irq = Some(*irq); - } - _ => { - error!("Unexpected resource {:?} for {}", resource, id); - } - } - } - - if mmio_range.is_none() || mmio_irq.is_none() { - return Err(DeviceManagerError::MissingVirtioMmioResources); - } - - (mmio_range, mmio_irq) - } else { - (None, None) - }; - - // Update the existing virtio node by setting the parent. - if let Some(node) = self.device_tree.lock().unwrap().get_mut(&virtio_device_id) { - node.parent = Some(id.clone()); - } else { - return Err(DeviceManagerError::MissingNode); - } - - let (mmio_base, mmio_size) = if let Some((base, size)) = mmio_range { - self.address_manager - .allocator - .lock() - .unwrap() - .allocate_mmio_addresses(Some(GuestAddress(base)), size, Some(size)) - .ok_or(DeviceManagerError::MmioRangeAllocation)?; - - (base, size) - } else { - let size = MMIO_LEN; - let base = self - .address_manager - .allocator - .lock() - .unwrap() - .allocate_mmio_addresses(None, size, Some(size)) - .ok_or(DeviceManagerError::MmioRangeAllocation)?; - - (base.raw_value(), size) - }; - - let irq_num = if let Some(irq) = mmio_irq { - irq - } else { - self.address_manager - .allocator - .lock() - .unwrap() - .allocate_irq() - .ok_or(DeviceManagerError::AllocateIrq)? - }; - - #[cfg(target_arch = "aarch64")] - { - let device_type = virtio_device.lock().unwrap().device_type(); - self.id_to_dev_info.insert( - (DeviceType::Virtio(device_type), virtio_device_id), - MMIODeviceInfo { - addr: mmio_base, - len: mmio_size, - irq: irq_num, - }, - ); - } - - let memory = self.memory_manager.lock().unwrap().guest_memory(); - let mut mmio_device = - virtio_devices::transport::MmioDevice::new(id.clone(), memory, virtio_device) - .map_err(DeviceManagerError::VirtioDevice)?; - - for (i, (event, addr)) in mmio_device.ioeventfds(mmio_base).iter().enumerate() { - let io_addr = IoEventAddress::Mmio(*addr); - self.address_manager - .vm - .register_ioevent(event, &io_addr, Some(DataMatch::DataMatch32(i as u32))) - .map_err(|e| DeviceManagerError::RegisterIoevent(e.into()))?; - } - - let interrupt_group = interrupt_manager - .create_group(LegacyIrqGroupConfig { - irq: irq_num as InterruptIndex, - }) - .map_err(DeviceManagerError::CreateInterruptGroup)?; - - mmio_device.assign_interrupt(interrupt_group); - - let mmio_device_arc = Arc::new(Mutex::new(mmio_device)); - self.bus_devices - .push(Arc::clone(&mmio_device_arc) as Arc>); - self.address_manager - .mmio_bus - .insert(mmio_device_arc.clone(), mmio_base, MMIO_LEN) - .map_err(DeviceManagerError::BusError)?; - - #[cfg(target_arch = "x86_64")] - self.cmdline_additions.push(format!( - "virtio_mmio.device={}K@0x{:08x}:{}", - mmio_size / 1024, - mmio_base, - irq_num - )); - - // Update the device tree with correct resource information. - node.resources.push(Resource::MmioAddressRange { - base: mmio_base, - size: mmio_size, - }); - node.resources.push(Resource::LegacyIrq(irq_num)); - node.migratable = Some(Arc::clone(&mmio_device_arc) as Arc>); - self.device_tree.lock().unwrap().insert(id, node); - - Ok(()) - } - #[cfg(target_arch = "x86_64")] pub fn io_bus(&self) -> &Arc { &self.address_manager.io_bus @@ -3108,18 +2864,13 @@ impl DeviceManager { } // Take care of updating the memory for VFIO PCI devices. - #[cfg(feature = "pci_support")] - { - for (_, any_device) in self.pci_devices.iter() { - if let Ok(vfio_pci_device) = - Arc::clone(any_device).downcast::>() - { - vfio_pci_device - .lock() - .unwrap() - .update_memory(_new_region) - .map_err(DeviceManagerError::UpdateMemoryForVfioPciDevice)?; - } + for (_, any_device) in self.pci_devices.iter() { + if let Ok(vfio_pci_device) = Arc::clone(any_device).downcast::>() { + vfio_pci_device + .lock() + .unwrap() + .update_memory(_new_region) + .map_err(DeviceManagerError::UpdateMemoryForVfioPciDevice)?; } } @@ -3143,7 +2894,6 @@ impl DeviceManager { return Ok(()); } - #[cfg(feature = "pci_support")] pub fn add_device( &mut self, device_cfg: &mut DeviceConfig, @@ -3179,7 +2929,6 @@ impl DeviceManager { }) } - #[cfg(feature = "pci_support")] pub fn remove_device(&mut self, id: String) -> DeviceManagerResult<()> { if let Some(pci_device_bdf) = self.pci_id_list.get(&id) { if let Some(any_device) = self.pci_devices.get(&pci_device_bdf) { @@ -3225,7 +2974,6 @@ impl DeviceManager { } } - #[cfg(feature = "pci_support")] pub fn eject_device(&mut self, device_id: u8) -> DeviceManagerResult<()> { // Retrieve the PCI bus. let pci = if let Some(pci_bus) = &self.pci_bus { @@ -3337,7 +3085,6 @@ impl DeviceManager { } } - #[cfg(feature = "pci_support")] fn hotplug_virtio_pci_device( &mut self, device: VirtioDeviceArc, @@ -3376,31 +3123,26 @@ impl DeviceManager { Ok(PciDeviceInfo { id, bdf: device_id }) } - #[cfg(feature = "pci_support")] pub fn add_disk(&mut self, disk_cfg: &mut DiskConfig) -> DeviceManagerResult { let (device, iommu_attached, id) = self.make_virtio_block_device(disk_cfg)?; self.hotplug_virtio_pci_device(device, iommu_attached, id) } - #[cfg(feature = "pci_support")] pub fn add_fs(&mut self, fs_cfg: &mut FsConfig) -> DeviceManagerResult { let (device, iommu_attached, id) = self.make_virtio_fs_device(fs_cfg)?; self.hotplug_virtio_pci_device(device, iommu_attached, id) } - #[cfg(feature = "pci_support")] pub fn add_pmem(&mut self, pmem_cfg: &mut PmemConfig) -> DeviceManagerResult { let (device, iommu_attached, id) = self.make_virtio_pmem_device(pmem_cfg)?; self.hotplug_virtio_pci_device(device, iommu_attached, id) } - #[cfg(feature = "pci_support")] pub fn add_net(&mut self, net_cfg: &mut NetConfig) -> DeviceManagerResult { let (device, iommu_attached, id) = self.make_virtio_net_device(net_cfg)?; self.hotplug_virtio_pci_device(device, iommu_attached, id) } - #[cfg(feature = "pci_support")] pub fn add_vsock(&mut self, vsock_cfg: &mut VsockConfig) -> DeviceManagerResult { let (device, iommu_attached, id) = self.make_virtio_vsock_device(vsock_cfg)?; self.hotplug_virtio_pci_device(device, iommu_attached, id) @@ -3792,23 +3534,16 @@ impl Snapshottable for DeviceManager { impl Transportable for DeviceManager {} impl Migratable for DeviceManager {} -#[cfg(feature = "pci_support")] const PCIU_FIELD_OFFSET: u64 = 0; -#[cfg(feature = "pci_support")] const PCID_FIELD_OFFSET: u64 = 4; -#[cfg(feature = "pci_support")] const B0EJ_FIELD_OFFSET: u64 = 8; -#[cfg(feature = "pci_support")] const PCIU_FIELD_SIZE: usize = 4; -#[cfg(feature = "pci_support")] const PCID_FIELD_SIZE: usize = 4; -#[cfg(feature = "pci_support")] const B0EJ_FIELD_SIZE: usize = 4; impl BusDevice for DeviceManager { fn read(&mut self, base: u64, offset: u64, data: &mut [u8]) { - #[cfg(feature = "pci_support")] match offset { PCIU_FIELD_OFFSET => { assert!(data.len() == PCIU_FIELD_SIZE); @@ -3835,7 +3570,6 @@ impl BusDevice for DeviceManager { } fn write(&mut self, base: u64, offset: u64, data: &[u8]) { - #[cfg(feature = "pci_support")] match offset { B0EJ_FIELD_OFFSET => { assert!(data.len() == B0EJ_FIELD_SIZE); diff --git a/vmm/src/device_tree.rs b/vmm/src/device_tree.rs index 3610f2938..c0afad4bd 100644 --- a/vmm/src/device_tree.rs +++ b/vmm/src/device_tree.rs @@ -15,7 +15,6 @@ pub struct DeviceNode { pub children: Vec, #[serde(skip)] pub migratable: Option>>, - #[cfg(feature = "pci_support")] pub pci_bdf: Option, } @@ -27,7 +26,6 @@ impl DeviceNode { parent: None, children: Vec::new(), migratable, - #[cfg(feature = "pci_support")] pci_bdf: None, } } diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 22afab496..505b1d1cc 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -19,7 +19,6 @@ extern crate libc; extern crate linux_loader; extern crate net_util; extern crate signal_hook; -#[cfg(feature = "pci_support")] extern crate vm_allocator; extern crate vm_memory; @@ -945,30 +944,26 @@ impl Vm { .get_device_info() .clone(); - let pci_space: Option<(u64, u64)> = if cfg!(feature = "pci_support") { - let pci_space_start: GuestAddress = self - .memory_manager - .lock() - .as_ref() - .unwrap() - .start_of_device_area(); + let pci_space_start: GuestAddress = self + .memory_manager + .lock() + .as_ref() + .unwrap() + .start_of_device_area(); - let pci_space_end: GuestAddress = self - .memory_manager - .lock() - .as_ref() - .unwrap() - .end_of_device_area(); + let pci_space_end: GuestAddress = self + .memory_manager + .lock() + .as_ref() + .unwrap() + .end_of_device_area(); - let pci_space_size = pci_space_end - .checked_offset_from(pci_space_start) - .ok_or(Error::MemOverflow)? - + 1; + let pci_space_size = pci_space_end + .checked_offset_from(pci_space_start) + .ok_or(Error::MemOverflow)? + + 1; - Some((pci_space_start.0, pci_space_size)) - } else { - None - }; + let pci_space = Some((pci_space_start.0, pci_space_size)); // Call `configure_system` and pass the GIC devices out, so that // we can register the GIC device to the device manager. @@ -1158,12 +1153,6 @@ impl Vm { Err(Error::ResizeZone) } - #[cfg(not(feature = "pci_support"))] - pub fn add_device(&mut self, mut _device_cfg: DeviceConfig) -> Result { - Err(Error::NoPciSupport) - } - - #[cfg(feature = "pci_support")] pub fn add_device(&mut self, mut _device_cfg: DeviceConfig) -> Result { let pci_device_info = self .device_manager @@ -1193,66 +1182,51 @@ impl Vm { } pub fn remove_device(&mut self, _id: String) -> Result<()> { - if cfg!(feature = "pci_support") { - #[cfg(feature = "pci_support")] - { - self.device_manager - .lock() - .unwrap() - .remove_device(_id.clone()) - .map_err(Error::DeviceManager)?; + self.device_manager + .lock() + .unwrap() + .remove_device(_id.clone()) + .map_err(Error::DeviceManager)?; - // Update VmConfig by removing the device. This is important to - // ensure the device would not be created in case of a reboot. - { - let mut config = self.config.lock().unwrap(); + // Update VmConfig by removing the device. This is important to + // ensure the device would not be created in case of a reboot. + let mut config = self.config.lock().unwrap(); - // Remove if VFIO device - if let Some(devices) = config.devices.as_mut() { - devices.retain(|dev| dev.id.as_ref() != Some(&_id)); - } - - // Remove if disk device - if let Some(disks) = config.disks.as_mut() { - disks.retain(|dev| dev.id.as_ref() != Some(&_id)); - } - - // Remove if net device - if let Some(net) = config.net.as_mut() { - net.retain(|dev| dev.id.as_ref() != Some(&_id)); - } - - // Remove if pmem device - if let Some(pmem) = config.pmem.as_mut() { - pmem.retain(|dev| dev.id.as_ref() != Some(&_id)); - } - - // Remove if vsock device - if let Some(vsock) = config.vsock.as_ref() { - if vsock.id.as_ref() == Some(&_id) { - config.vsock = None; - } - } - } - - self.device_manager - .lock() - .unwrap() - .notify_hotplug(HotPlugNotificationFlags::PCI_DEVICES_CHANGED) - .map_err(Error::DeviceManager)?; - } - Ok(()) - } else { - Err(Error::NoPciSupport) + // Remove if VFIO device + if let Some(devices) = config.devices.as_mut() { + devices.retain(|dev| dev.id.as_ref() != Some(&_id)); } + + // Remove if disk device + if let Some(disks) = config.disks.as_mut() { + disks.retain(|dev| dev.id.as_ref() != Some(&_id)); + } + + // Remove if net device + if let Some(net) = config.net.as_mut() { + net.retain(|dev| dev.id.as_ref() != Some(&_id)); + } + + // Remove if pmem device + if let Some(pmem) = config.pmem.as_mut() { + pmem.retain(|dev| dev.id.as_ref() != Some(&_id)); + } + + // Remove if vsock device + if let Some(vsock) = config.vsock.as_ref() { + if vsock.id.as_ref() == Some(&_id) { + config.vsock = None; + } + } + + self.device_manager + .lock() + .unwrap() + .notify_hotplug(HotPlugNotificationFlags::PCI_DEVICES_CHANGED) + .map_err(Error::DeviceManager)?; + Ok(()) } - #[cfg(not(feature = "pci_support"))] - pub fn add_disk(&mut self, mut _disk_cfg: DiskConfig) -> Result { - Err(Error::NoPciSupport) - } - - #[cfg(feature = "pci_support")] pub fn add_disk(&mut self, mut _disk_cfg: DiskConfig) -> Result { let pci_device_info = self .device_manager @@ -1281,12 +1255,6 @@ impl Vm { Ok(pci_device_info) } - #[cfg(not(feature = "pci_support"))] - pub fn add_fs(&mut self, mut _fs_cfg: FsConfig) -> Result { - Err(Error::NoPciSupport) - } - - #[cfg(feature = "pci_support")] pub fn add_fs(&mut self, mut _fs_cfg: FsConfig) -> Result { let pci_device_info = self .device_manager @@ -1315,12 +1283,6 @@ impl Vm { Ok(pci_device_info) } - #[cfg(not(feature = "pci_support"))] - pub fn add_pmem(&mut self, mut _pmem_cfg: PmemConfig) -> Result { - Err(Error::NoPciSupport) - } - - #[cfg(feature = "pci_support")] pub fn add_pmem(&mut self, mut _pmem_cfg: PmemConfig) -> Result { let pci_device_info = self .device_manager @@ -1349,12 +1311,6 @@ impl Vm { Ok(pci_device_info) } - #[cfg(not(feature = "pci_support"))] - pub fn add_net(&mut self, mut _net_cfg: NetConfig) -> Result { - Err(Error::NoPciSupport) - } - - #[cfg(feature = "pci_support")] pub fn add_net(&mut self, mut _net_cfg: NetConfig) -> Result { let pci_device_info = self .device_manager @@ -1383,12 +1339,6 @@ impl Vm { Ok(pci_device_info) } - #[cfg(not(feature = "pci_support"))] - pub fn add_vsock(&mut self, mut _vsock_cfg: VsockConfig) -> Result { - Err(Error::NoPciSupport) - } - - #[cfg(feature = "pci_support")] pub fn add_vsock(&mut self, mut _vsock_cfg: VsockConfig) -> Result { if self.config.lock().unwrap().vsock.is_some() { return Err(Error::TooManyVsockDevices);