vmm: Remove mmio and pci differentiation

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-10-15 17:34:35 +02:00 committed by Rob Bradford
parent d2741fdc84
commit af3c6c34c3
6 changed files with 155 additions and 486 deletions

View File

@ -49,10 +49,8 @@ serde_json = "1.0.59"
net_util = { path = "net_util" } net_util = { path = "net_util" }
[features] [features]
default = ["acpi", "pci", "cmos", "kvm"] default = ["acpi", "cmos", "kvm"]
acpi = ["vmm/acpi"] acpi = ["vmm/acpi"]
pci = ["vmm/pci_support"]
mmio = ["vmm/mmio_support"]
cmos = ["vmm/cmos"] cmos = ["vmm/cmos"]
fwdebug = ["vmm/fwdebug"] fwdebug = ["vmm/fwdebug"]
kvm = ["vmm/kvm"] kvm = ["vmm/kvm"]

View File

@ -7,8 +7,6 @@ edition = "2018"
[features] [features]
default = [] default = []
acpi = ["acpi_tables","devices/acpi", "arch/acpi"] 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"] cmos = ["devices/cmos"]
fwdebug = ["devices/fwdebug"] fwdebug = ["devices/fwdebug"]
kvm = ["hypervisor/kvm"] kvm = ["hypervisor/kvm"]
@ -31,15 +29,15 @@ log = "0.4.11"
micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "master" } micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "master" }
net_util = { path = "../net_util" } net_util = { path = "../net_util" }
option_parser = { path = "../option_parser" } option_parser = { path = "../option_parser" }
pci = {path = "../pci", optional = true} pci = { path = "../pci" }
qcow = { path = "../qcow" } qcow = { path = "../qcow" }
seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v0.22.0" } seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v0.22.0" }
serde = {version = ">=1.0.27", features = ["rc"] } serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27" serde_derive = ">=1.0.27"
serde_json = ">=1.0.9" serde_json = ">=1.0.9"
url = "2.1.1" url = "2.1.1"
vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch", optional = true } vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" }
virtio-devices = {path = "../virtio-devices"} virtio-devices = { path = "../virtio-devices", features = ["pci_support"]}
vm-allocator = { path = "../vm-allocator" } vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" } vm-device = { path = "../vm-device" }
vm-memory = { version = "0.3.0", features = ["backend-mmap", "backend-atomic"] } vm-memory = { version = "0.3.0", features = ["backend-mmap", "backend-atomic"] }

View File

@ -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 let Some(t) = &self.cpus.topology {
if t.threads_per_core == 0 if t.threads_per_core == 0
|| t.cores_per_die == 0 || t.cores_per_die == 0

View File

@ -10,7 +10,6 @@
// //
use crate::config::ConsoleOutputMode; use crate::config::ConsoleOutputMode;
#[cfg(feature = "pci_support")]
use crate::config::DeviceConfig; use crate::config::DeviceConfig;
use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, VsockConfig}; use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, VsockConfig};
use crate::device_tree::{DeviceNode, DeviceTree}; use crate::device_tree::{DeviceNode, DeviceTree};
@ -20,7 +19,6 @@ use crate::interrupt::LegacyUserspaceInterruptManager;
use crate::memory_manager::{Error as MemoryManagerError, MemoryManager}; use crate::memory_manager::{Error as MemoryManagerError, MemoryManager};
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
use crate::vm::NumaNodes; use crate::vm::NumaNodes;
#[cfg(feature = "pci_support")]
use crate::PciDeviceInfo; use crate::PciDeviceInfo;
use crate::{device_node, DEVICE_MANAGER_SNAPSHOT_ID}; use crate::{device_node, DEVICE_MANAGER_SNAPSHOT_ID};
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
@ -47,39 +45,33 @@ use devices::{
}; };
use hypervisor::kvm_ioctls; use hypervisor::kvm_ioctls;
use hypervisor::kvm_ioctls::*; use hypervisor::kvm_ioctls::*;
#[cfg(feature = "mmio_support")]
use hypervisor::vm::DataMatch;
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
use hypervisor::CpuState; use hypervisor::CpuState;
use libc::TIOCGWINSZ; use libc::TIOCGWINSZ;
use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE}; use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE};
#[cfg(feature = "pci_support")]
use pci::{ use pci::{
DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot, DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot,
VfioPciDevice, VfioPciDevice,
}; };
use qcow::{self, ImageType, QcowFile}; use qcow::{self, ImageType, QcowFile};
use seccomp::SeccompAction; use seccomp::SeccompAction;
#[cfg(feature = "pci_support")]
use std::any::Any; use std::any::Any;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{self, sink, stdout, Seek, SeekFrom}; use std::io::{self, sink, stdout, Seek, SeekFrom};
use std::num::Wrapping; use std::num::Wrapping;
use std::os::unix::fs::OpenOptionsExt; use std::os::unix::fs::OpenOptionsExt;
#[cfg(all(feature = "pci_support", feature = "kvm"))] #[cfg(feature = "kvm")]
use std::os::unix::io::FromRawFd; use std::os::unix::io::FromRawFd;
use std::path::PathBuf; use std::path::PathBuf;
use std::result; use std::result;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
#[cfg(all(feature = "pci_support", feature = "kvm"))] #[cfg(feature = "kvm")]
use vfio_ioctls::{VfioContainer, VfioDevice, VfioDmaMapping}; use vfio_ioctls::{VfioContainer, VfioDevice, VfioDmaMapping};
#[cfg(feature = "pci_support")]
use virtio_devices::transport::VirtioPciDevice; use virtio_devices::transport::VirtioPciDevice;
use virtio_devices::transport::VirtioTransport; use virtio_devices::transport::VirtioTransport;
use virtio_devices::vhost_user::VhostUserConfig; use virtio_devices::vhost_user::VhostUserConfig;
#[cfg(feature = "pci_support")]
use virtio_devices::{DmaRemapping, IommuMapping}; use virtio_devices::{DmaRemapping, IommuMapping};
use virtio_devices::{VirtioSharedMemory, VirtioSharedMemoryList}; use virtio_devices::{VirtioSharedMemory, VirtioSharedMemoryList};
use vm_allocator::SystemAllocator; use vm_allocator::SystemAllocator;
@ -95,14 +87,13 @@ use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable, Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable, Transportable,
}; };
#[cfg(feature = "pci_support")]
use vm_virtio::{VirtioDeviceType, VirtioIommuRemapping}; use vm_virtio::{VirtioDeviceType, VirtioIommuRemapping};
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
#[cfg(any(feature = "mmio_support", target_arch = "aarch64"))] #[cfg(target_arch = "aarch64")]
const MMIO_LEN: u64 = 0x1000; const MMIO_LEN: u64 = 0x1000;
#[cfg(all(feature = "pci_support", feature = "kvm"))] #[cfg(feature = "kvm")]
const VFIO_DEVICE_NAME_PREFIX: &str = "_vfio"; const VFIO_DEVICE_NAME_PREFIX: &str = "_vfio";
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
@ -120,12 +111,8 @@ const PMEM_DEVICE_NAME_PREFIX: &str = "_pmem";
const RNG_DEVICE_NAME: &str = "_rng"; const RNG_DEVICE_NAME: &str = "_rng";
const VSOCK_DEVICE_NAME_PREFIX: &str = "_vsock"; const VSOCK_DEVICE_NAME_PREFIX: &str = "_vsock";
#[cfg(feature = "pci_support")]
const IOMMU_DEVICE_NAME: &str = "_iommu"; 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"; const VIRTIO_PCI_DEVICE_NAME_PREFIX: &str = "_virtio-pci";
/// Errors associated with device manager /// Errors associated with device manager
@ -195,11 +182,9 @@ pub enum DeviceManagerError {
Irq(kvm_ioctls::Error), Irq(kvm_ioctls::Error),
/// Cannot allocate PCI BARs /// Cannot allocate PCI BARs
#[cfg(feature = "pci_support")]
AllocateBars(pci::PciDeviceError), AllocateBars(pci::PciDeviceError),
/// Could not free the BARs associated with a PCI device. /// Could not free the BARs associated with a PCI device.
#[cfg(feature = "pci_support")]
FreePciBars(pci::PciDeviceError), FreePciBars(pci::PciDeviceError),
/// Cannot register ioevent. /// Cannot register ioevent.
@ -212,7 +197,6 @@ pub enum DeviceManagerError {
VirtioDevice(vmm_sys_util::errno::Error), VirtioDevice(vmm_sys_util::errno::Error),
/// Cannot add PCI device /// Cannot add PCI device
#[cfg(feature = "pci_support")]
AddPciDevice(pci::PciRootError), AddPciDevice(pci::PciRootError),
/// Cannot open persistent memory file /// Cannot open persistent memory file
@ -234,15 +218,12 @@ pub enum DeviceManagerError {
ConsoleOutputFileOpen(io::Error), ConsoleOutputFileOpen(io::Error),
/// Cannot create a VFIO device /// Cannot create a VFIO device
#[cfg(feature = "pci_support")]
VfioCreate(vfio_ioctls::VfioError), VfioCreate(vfio_ioctls::VfioError),
/// Cannot create a VFIO PCI device /// Cannot create a VFIO PCI device
#[cfg(feature = "pci_support")]
VfioPciCreate(pci::VfioPciError), VfioPciCreate(pci::VfioPciError),
/// Failed to map VFIO MMIO region. /// Failed to map VFIO MMIO region.
#[cfg(feature = "pci_support")]
VfioMapRegion(pci::VfioPciError), VfioMapRegion(pci::VfioPciError),
/// Failed to create the passthrough device. /// Failed to create the passthrough device.
@ -297,7 +278,6 @@ pub enum DeviceManagerError {
MissingPciDevice, MissingPciDevice,
/// Failed removing a PCI device from the PCI bus. /// Failed removing a PCI device from the PCI bus.
#[cfg(feature = "pci_support")]
RemoveDeviceFromPciBus(pci::PciRootError), RemoveDeviceFromPciBus(pci::PciRootError),
/// Failed removing a bus device from the IO bus. /// Failed removing a bus device from the IO bus.
@ -307,27 +287,21 @@ pub enum DeviceManagerError {
RemoveDeviceFromMmioBus(vm_device::BusError), RemoveDeviceFromMmioBus(vm_device::BusError),
/// Failed to find the device corresponding to a specific PCI b/d/f. /// Failed to find the device corresponding to a specific PCI b/d/f.
#[cfg(feature = "pci_support")]
UnknownPciBdf(u32), UnknownPciBdf(u32),
/// Not allowed to remove this type of device from the VM. /// Not allowed to remove this type of device from the VM.
#[cfg(feature = "pci_support")]
RemovalNotAllowed(vm_virtio::VirtioDeviceType), RemovalNotAllowed(vm_virtio::VirtioDeviceType),
/// Failed to find device corresponding to the given identifier. /// Failed to find device corresponding to the given identifier.
#[cfg(feature = "pci_support")]
UnknownDeviceId(String), UnknownDeviceId(String),
/// Failed to find an available PCI device ID. /// Failed to find an available PCI device ID.
#[cfg(feature = "pci_support")]
NextPciDeviceId(pci::PciRootError), NextPciDeviceId(pci::PciRootError),
/// Could not reserve the PCI device ID. /// Could not reserve the PCI device ID.
#[cfg(feature = "pci_support")]
GetPciDeviceId(pci::PciRootError), GetPciDeviceId(pci::PciRootError),
/// Could not give the PCI device ID back. /// Could not give the PCI device ID back.
#[cfg(feature = "pci_support")]
PutPciDeviceId(pci::PciRootError), PutPciDeviceId(pci::PciRootError),
/// Incorrect device ID as it is already used by another device. /// Incorrect device ID as it is already used by another device.
@ -349,7 +323,6 @@ pub enum DeviceManagerError {
VirtioMemRangeAllocation, VirtioMemRangeAllocation,
/// Failed updating guest memory for VFIO PCI device. /// Failed updating guest memory for VFIO PCI device.
#[cfg(feature = "pci_support")]
UpdateMemoryForVfioPciDevice(pci::VfioPciError), UpdateMemoryForVfioPciDevice(pci::VfioPciError),
/// Trying to use a directory for pmem but no size specified /// Trying to use a directory for pmem but no size specified
@ -377,7 +350,6 @@ pub enum DeviceManagerError {
MissingVirtioFsResources, MissingVirtioFsResources,
/// Missing PCI b/d/f from the DeviceNode. /// Missing PCI b/d/f from the DeviceNode.
#[cfg(feature = "pci_support")]
MissingDeviceNodePciBdf, MissingDeviceNodePciBdf,
/// No support for device passthrough /// No support for device passthrough
@ -465,11 +437,9 @@ struct AddressManager {
io_bus: Arc<Bus>, io_bus: Arc<Bus>,
mmio_bus: Arc<Bus>, mmio_bus: Arc<Bus>,
vm: Arc<dyn hypervisor::Vm>, vm: Arc<dyn hypervisor::Vm>,
#[cfg(feature = "pci_support")]
device_tree: Arc<Mutex<DeviceTree>>, device_tree: Arc<Mutex<DeviceTree>>,
} }
#[cfg(feature = "pci_support")]
impl DeviceRelocation for AddressManager { impl DeviceRelocation for AddressManager {
fn move_bar( fn move_bar(
&self, &self,
@ -763,7 +733,6 @@ pub struct DeviceManager {
device_id_cnt: Wrapping<usize>, device_id_cnt: Wrapping<usize>,
// Keep a reference to the PCI bus // Keep a reference to the PCI bus
#[cfg(feature = "pci_support")]
pci_bus: Option<Arc<Mutex<PciBus>>>, pci_bus: Option<Arc<Mutex<PciBus>>>,
#[cfg_attr(target_arch = "aarch64", allow(dead_code))] #[cfg_attr(target_arch = "aarch64", allow(dead_code))]
@ -771,27 +740,21 @@ pub struct DeviceManager {
msi_interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>, msi_interrupt_manager: Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
// Passthrough device handle // Passthrough device handle
#[cfg(feature = "pci_support")]
passthrough_device: Option<Arc<dyn hypervisor::Device>>, passthrough_device: Option<Arc<dyn hypervisor::Device>>,
// Paravirtualized IOMMU // Paravirtualized IOMMU
#[cfg(feature = "pci_support")]
iommu_device: Option<Arc<Mutex<virtio_devices::Iommu>>>, iommu_device: Option<Arc<Mutex<virtio_devices::Iommu>>>,
// Bitmap of PCI devices to hotplug. // Bitmap of PCI devices to hotplug.
#[cfg(feature = "pci_support")]
pci_devices_up: u32, pci_devices_up: u32,
// Bitmap of PCI devices to hotunplug. // Bitmap of PCI devices to hotunplug.
#[cfg(feature = "pci_support")]
pci_devices_down: u32, pci_devices_down: u32,
// Hashmap of device's name to their corresponding PCI b/d/f. // Hashmap of device's name to their corresponding PCI b/d/f.
#[cfg(feature = "pci_support")]
pci_id_list: HashMap<String, u32>, pci_id_list: HashMap<String, u32>,
// Hashmap of PCI b/d/f to their corresponding Arc<Mutex<dyn PciDevice>>. // Hashmap of PCI b/d/f to their corresponding Arc<Mutex<dyn PciDevice>>.
#[cfg(feature = "pci_support")]
pci_devices: HashMap<u32, Arc<dyn Any + Send + Sync>>, pci_devices: HashMap<u32, Arc<dyn Any + Send + Sync>>,
// Tree of devices, representing the dependencies between devices. // Tree of devices, representing the dependencies between devices.
@ -837,7 +800,6 @@ impl DeviceManager {
io_bus: Arc::new(Bus::new()), io_bus: Arc::new(Bus::new()),
mmio_bus: Arc::new(Bus::new()), mmio_bus: Arc::new(Bus::new()),
vm: vm.clone(), vm: vm.clone(),
#[cfg(feature = "pci_support")]
device_tree: Arc::clone(&device_tree), device_tree: Arc::clone(&device_tree),
}); });
@ -869,20 +831,13 @@ impl DeviceManager {
vmm_path, vmm_path,
vhost_user_backends: Vec::new(), vhost_user_backends: Vec::new(),
device_id_cnt: Wrapping(0), device_id_cnt: Wrapping(0),
#[cfg(feature = "pci_support")]
pci_bus: None, pci_bus: None,
msi_interrupt_manager, msi_interrupt_manager,
#[cfg(feature = "pci_support")]
passthrough_device: None, passthrough_device: None,
#[cfg(feature = "pci_support")]
iommu_device: None, iommu_device: None,
#[cfg(feature = "pci_support")]
pci_devices_up: 0, pci_devices_up: 0,
#[cfg(feature = "pci_support")]
pci_devices_down: 0, pci_devices_down: 0,
#[cfg(feature = "pci_support")]
pci_id_list: HashMap::new(), pci_id_list: HashMap::new(),
#[cfg(feature = "pci_support")]
pci_devices: HashMap::new(), pci_devices: HashMap::new(),
device_tree, device_tree,
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
@ -975,14 +930,9 @@ impl DeviceManager {
self.console = self.add_console_device(&legacy_interrupt_manager, &mut virtio_devices)?; 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()?); virtio_devices.append(&mut self.make_virtio_devices()?);
if cfg!(feature = "pci_support") {
self.add_pci_devices(virtio_devices.clone())?; self.add_pci_devices(virtio_devices.clone())?;
} else if cfg!(feature = "mmio_support") {
self.add_mmio_devices(virtio_devices.clone(), &legacy_interrupt_manager)?;
}
self.virtio_devices = virtio_devices; self.virtio_devices = virtio_devices;
@ -1014,8 +964,6 @@ impl DeviceManager {
&mut self, &mut self,
virtio_devices: Vec<(VirtioDeviceArc, bool, String)>, virtio_devices: Vec<(VirtioDeviceArc, bool, String)>,
) -> DeviceManagerResult<()> { ) -> DeviceManagerResult<()> {
#[cfg(feature = "pci_support")]
{
let pci_root = PciRoot::new(None); let pci_root = PciRoot::new(None);
let mut pci_bus = PciBus::new( let mut pci_bus = PciBus::new(
pci_root, pci_root,
@ -1055,21 +1003,15 @@ impl DeviceManager {
&None &None
}; };
let dev_id = self.add_virtio_pci_device( let dev_id =
device, self.add_virtio_pci_device(device, &mut pci_bus, mapping, &interrupt_manager, id)?;
&mut pci_bus,
mapping,
&interrupt_manager,
id,
)?;
if iommu_attached { if iommu_attached {
iommu_attached_devices.push(dev_id); iommu_attached_devices.push(dev_id);
} }
} }
let mut vfio_iommu_device_ids = let mut vfio_iommu_device_ids = self.add_vfio_devices(&mut pci_bus, &interrupt_manager)?;
self.add_vfio_devices(&mut pci_bus, &interrupt_manager)?;
iommu_attached_devices.append(&mut vfio_iommu_device_ids); iommu_attached_devices.append(&mut vfio_iommu_device_ids);
@ -1113,23 +1055,6 @@ impl DeviceManager {
.map_err(DeviceManagerError::BusError)?; .map_err(DeviceManagerError::BusError)?;
self.pci_bus = Some(pci_bus); 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<dyn InterruptManager<GroupConfig = LegacyIrqGroupConfig>>,
) -> DeviceManagerResult<()> {
#[cfg(feature = "mmio_support")]
{
for (device, _, id) in virtio_devices {
self.add_virtio_mmio_device(id, device, interrupt_manager)?;
}
}
Ok(()) Ok(())
} }
@ -2543,17 +2468,6 @@ impl DeviceManager {
Ok(devices) Ok(devices)
} }
#[cfg(not(feature = "pci_support"))]
fn next_device_name(&mut self, prefix: &str) -> DeviceManagerResult<String> {
// 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<String> { fn next_device_name(&mut self, prefix: &str) -> DeviceManagerResult<String> {
let start_id = self.device_id_cnt; let start_id = self.device_id_cnt;
loop { loop {
@ -2575,7 +2489,6 @@ impl DeviceManager {
Err(DeviceManagerError::NoAvailableDeviceName) Err(DeviceManagerError::NoAvailableDeviceName)
} }
#[cfg(feature = "pci_support")]
#[cfg_attr(not(feature = "kvm"), allow(unused_variables))] #[cfg_attr(not(feature = "kvm"), allow(unused_variables))]
fn add_passthrough_device( fn add_passthrough_device(
&mut self, &mut self,
@ -2590,7 +2503,7 @@ impl DeviceManager {
Err(DeviceManagerError::NoDevicePassthroughSupport) Err(DeviceManagerError::NoDevicePassthroughSupport)
} }
#[cfg(all(feature = "pci_support", feature = "kvm"))] #[cfg(feature = "kvm")]
fn add_vfio_device( fn add_vfio_device(
&mut self, &mut self,
pci: &mut PciBus, pci: &mut PciBus,
@ -2700,7 +2613,6 @@ impl DeviceManager {
Ok((pci_device_bdf, vfio_name)) Ok((pci_device_bdf, vfio_name))
} }
#[cfg(feature = "pci_support")]
fn add_pci_device( fn add_pci_device(
&mut self, &mut self,
pci_bus: &mut PciBus, pci_bus: &mut PciBus,
@ -2740,7 +2652,6 @@ impl DeviceManager {
Ok(bars) Ok(bars)
} }
#[cfg(feature = "pci_support")]
fn add_vfio_devices( fn add_vfio_devices(
&mut self, &mut self,
pci: &mut PciBus, pci: &mut PciBus,
@ -2775,7 +2686,6 @@ impl DeviceManager {
Ok(iommu_attached_device_ids) Ok(iommu_attached_device_ids)
} }
#[cfg(feature = "pci_support")]
fn add_virtio_pci_device( fn add_virtio_pci_device(
&mut self, &mut self,
virtio_device: VirtioDeviceArc, virtio_device: VirtioDeviceArc,
@ -2914,160 +2824,6 @@ impl DeviceManager {
Ok(pci_device_bdf) 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<dyn InterruptManager<GroupConfig = LegacyIrqGroupConfig>>,
) -> 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<u32> = 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<Mutex<dyn BusDevice>>);
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<Mutex<dyn Migratable>>);
self.device_tree.lock().unwrap().insert(id, node);
Ok(())
}
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub fn io_bus(&self) -> &Arc<Bus> { pub fn io_bus(&self) -> &Arc<Bus> {
&self.address_manager.io_bus &self.address_manager.io_bus
@ -3108,12 +2864,8 @@ impl DeviceManager {
} }
// Take care of updating the memory for VFIO PCI devices. // Take care of updating the memory for VFIO PCI devices.
#[cfg(feature = "pci_support")]
{
for (_, any_device) in self.pci_devices.iter() { for (_, any_device) in self.pci_devices.iter() {
if let Ok(vfio_pci_device) = if let Ok(vfio_pci_device) = Arc::clone(any_device).downcast::<Mutex<VfioPciDevice>>() {
Arc::clone(any_device).downcast::<Mutex<VfioPciDevice>>()
{
vfio_pci_device vfio_pci_device
.lock() .lock()
.unwrap() .unwrap()
@ -3121,7 +2873,6 @@ impl DeviceManager {
.map_err(DeviceManagerError::UpdateMemoryForVfioPciDevice)?; .map_err(DeviceManagerError::UpdateMemoryForVfioPciDevice)?;
} }
} }
}
Ok(()) Ok(())
} }
@ -3143,7 +2894,6 @@ impl DeviceManager {
return Ok(()); return Ok(());
} }
#[cfg(feature = "pci_support")]
pub fn add_device( pub fn add_device(
&mut self, &mut self,
device_cfg: &mut DeviceConfig, device_cfg: &mut DeviceConfig,
@ -3179,7 +2929,6 @@ impl DeviceManager {
}) })
} }
#[cfg(feature = "pci_support")]
pub fn remove_device(&mut self, id: String) -> DeviceManagerResult<()> { pub fn remove_device(&mut self, id: String) -> DeviceManagerResult<()> {
if let Some(pci_device_bdf) = self.pci_id_list.get(&id) { if let Some(pci_device_bdf) = self.pci_id_list.get(&id) {
if let Some(any_device) = self.pci_devices.get(&pci_device_bdf) { 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<()> { pub fn eject_device(&mut self, device_id: u8) -> DeviceManagerResult<()> {
// Retrieve the PCI bus. // Retrieve the PCI bus.
let pci = if let Some(pci_bus) = &self.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( fn hotplug_virtio_pci_device(
&mut self, &mut self,
device: VirtioDeviceArc, device: VirtioDeviceArc,
@ -3376,31 +3123,26 @@ impl DeviceManager {
Ok(PciDeviceInfo { id, bdf: device_id }) Ok(PciDeviceInfo { id, bdf: device_id })
} }
#[cfg(feature = "pci_support")]
pub fn add_disk(&mut self, disk_cfg: &mut DiskConfig) -> DeviceManagerResult<PciDeviceInfo> { pub fn add_disk(&mut self, disk_cfg: &mut DiskConfig) -> DeviceManagerResult<PciDeviceInfo> {
let (device, iommu_attached, id) = self.make_virtio_block_device(disk_cfg)?; let (device, iommu_attached, id) = self.make_virtio_block_device(disk_cfg)?;
self.hotplug_virtio_pci_device(device, iommu_attached, id) self.hotplug_virtio_pci_device(device, iommu_attached, id)
} }
#[cfg(feature = "pci_support")]
pub fn add_fs(&mut self, fs_cfg: &mut FsConfig) -> DeviceManagerResult<PciDeviceInfo> { pub fn add_fs(&mut self, fs_cfg: &mut FsConfig) -> DeviceManagerResult<PciDeviceInfo> {
let (device, iommu_attached, id) = self.make_virtio_fs_device(fs_cfg)?; let (device, iommu_attached, id) = self.make_virtio_fs_device(fs_cfg)?;
self.hotplug_virtio_pci_device(device, iommu_attached, id) self.hotplug_virtio_pci_device(device, iommu_attached, id)
} }
#[cfg(feature = "pci_support")]
pub fn add_pmem(&mut self, pmem_cfg: &mut PmemConfig) -> DeviceManagerResult<PciDeviceInfo> { pub fn add_pmem(&mut self, pmem_cfg: &mut PmemConfig) -> DeviceManagerResult<PciDeviceInfo> {
let (device, iommu_attached, id) = self.make_virtio_pmem_device(pmem_cfg)?; let (device, iommu_attached, id) = self.make_virtio_pmem_device(pmem_cfg)?;
self.hotplug_virtio_pci_device(device, iommu_attached, id) self.hotplug_virtio_pci_device(device, iommu_attached, id)
} }
#[cfg(feature = "pci_support")]
pub fn add_net(&mut self, net_cfg: &mut NetConfig) -> DeviceManagerResult<PciDeviceInfo> { pub fn add_net(&mut self, net_cfg: &mut NetConfig) -> DeviceManagerResult<PciDeviceInfo> {
let (device, iommu_attached, id) = self.make_virtio_net_device(net_cfg)?; let (device, iommu_attached, id) = self.make_virtio_net_device(net_cfg)?;
self.hotplug_virtio_pci_device(device, iommu_attached, id) self.hotplug_virtio_pci_device(device, iommu_attached, id)
} }
#[cfg(feature = "pci_support")]
pub fn add_vsock(&mut self, vsock_cfg: &mut VsockConfig) -> DeviceManagerResult<PciDeviceInfo> { pub fn add_vsock(&mut self, vsock_cfg: &mut VsockConfig) -> DeviceManagerResult<PciDeviceInfo> {
let (device, iommu_attached, id) = self.make_virtio_vsock_device(vsock_cfg)?; let (device, iommu_attached, id) = self.make_virtio_vsock_device(vsock_cfg)?;
self.hotplug_virtio_pci_device(device, iommu_attached, id) self.hotplug_virtio_pci_device(device, iommu_attached, id)
@ -3792,23 +3534,16 @@ impl Snapshottable for DeviceManager {
impl Transportable for DeviceManager {} impl Transportable for DeviceManager {}
impl Migratable for DeviceManager {} impl Migratable for DeviceManager {}
#[cfg(feature = "pci_support")]
const PCIU_FIELD_OFFSET: u64 = 0; const PCIU_FIELD_OFFSET: u64 = 0;
#[cfg(feature = "pci_support")]
const PCID_FIELD_OFFSET: u64 = 4; const PCID_FIELD_OFFSET: u64 = 4;
#[cfg(feature = "pci_support")]
const B0EJ_FIELD_OFFSET: u64 = 8; const B0EJ_FIELD_OFFSET: u64 = 8;
#[cfg(feature = "pci_support")]
const PCIU_FIELD_SIZE: usize = 4; const PCIU_FIELD_SIZE: usize = 4;
#[cfg(feature = "pci_support")]
const PCID_FIELD_SIZE: usize = 4; const PCID_FIELD_SIZE: usize = 4;
#[cfg(feature = "pci_support")]
const B0EJ_FIELD_SIZE: usize = 4; const B0EJ_FIELD_SIZE: usize = 4;
impl BusDevice for DeviceManager { impl BusDevice for DeviceManager {
fn read(&mut self, base: u64, offset: u64, data: &mut [u8]) { fn read(&mut self, base: u64, offset: u64, data: &mut [u8]) {
#[cfg(feature = "pci_support")]
match offset { match offset {
PCIU_FIELD_OFFSET => { PCIU_FIELD_OFFSET => {
assert!(data.len() == PCIU_FIELD_SIZE); assert!(data.len() == PCIU_FIELD_SIZE);
@ -3835,7 +3570,6 @@ impl BusDevice for DeviceManager {
} }
fn write(&mut self, base: u64, offset: u64, data: &[u8]) { fn write(&mut self, base: u64, offset: u64, data: &[u8]) {
#[cfg(feature = "pci_support")]
match offset { match offset {
B0EJ_FIELD_OFFSET => { B0EJ_FIELD_OFFSET => {
assert!(data.len() == B0EJ_FIELD_SIZE); assert!(data.len() == B0EJ_FIELD_SIZE);

View File

@ -15,7 +15,6 @@ pub struct DeviceNode {
pub children: Vec<String>, pub children: Vec<String>,
#[serde(skip)] #[serde(skip)]
pub migratable: Option<Arc<Mutex<dyn Migratable>>>, pub migratable: Option<Arc<Mutex<dyn Migratable>>>,
#[cfg(feature = "pci_support")]
pub pci_bdf: Option<u32>, pub pci_bdf: Option<u32>,
} }
@ -27,7 +26,6 @@ impl DeviceNode {
parent: None, parent: None,
children: Vec::new(), children: Vec::new(),
migratable, migratable,
#[cfg(feature = "pci_support")]
pci_bdf: None, pci_bdf: None,
} }
} }

View File

@ -19,7 +19,6 @@ extern crate libc;
extern crate linux_loader; extern crate linux_loader;
extern crate net_util; extern crate net_util;
extern crate signal_hook; extern crate signal_hook;
#[cfg(feature = "pci_support")]
extern crate vm_allocator; extern crate vm_allocator;
extern crate vm_memory; extern crate vm_memory;
@ -945,7 +944,6 @@ impl Vm {
.get_device_info() .get_device_info()
.clone(); .clone();
let pci_space: Option<(u64, u64)> = if cfg!(feature = "pci_support") {
let pci_space_start: GuestAddress = self let pci_space_start: GuestAddress = self
.memory_manager .memory_manager
.lock() .lock()
@ -965,10 +963,7 @@ impl Vm {
.ok_or(Error::MemOverflow)? .ok_or(Error::MemOverflow)?
+ 1; + 1;
Some((pci_space_start.0, pci_space_size)) let pci_space = Some((pci_space_start.0, pci_space_size));
} else {
None
};
// Call `configure_system` and pass the GIC devices out, so that // Call `configure_system` and pass the GIC devices out, so that
// we can register the GIC device to the device manager. // we can register the GIC device to the device manager.
@ -1158,12 +1153,6 @@ impl Vm {
Err(Error::ResizeZone) Err(Error::ResizeZone)
} }
#[cfg(not(feature = "pci_support"))]
pub fn add_device(&mut self, mut _device_cfg: DeviceConfig) -> Result<PciDeviceInfo> {
Err(Error::NoPciSupport)
}
#[cfg(feature = "pci_support")]
pub fn add_device(&mut self, mut _device_cfg: DeviceConfig) -> Result<PciDeviceInfo> { pub fn add_device(&mut self, mut _device_cfg: DeviceConfig) -> Result<PciDeviceInfo> {
let pci_device_info = self let pci_device_info = self
.device_manager .device_manager
@ -1193,9 +1182,6 @@ impl Vm {
} }
pub fn remove_device(&mut self, _id: String) -> Result<()> { pub fn remove_device(&mut self, _id: String) -> Result<()> {
if cfg!(feature = "pci_support") {
#[cfg(feature = "pci_support")]
{
self.device_manager self.device_manager
.lock() .lock()
.unwrap() .unwrap()
@ -1204,7 +1190,6 @@ impl Vm {
// Update VmConfig by removing the device. This is important to // Update VmConfig by removing the device. This is important to
// ensure the device would not be created in case of a reboot. // ensure the device would not be created in case of a reboot.
{
let mut config = self.config.lock().unwrap(); let mut config = self.config.lock().unwrap();
// Remove if VFIO device // Remove if VFIO device
@ -1233,26 +1218,15 @@ impl Vm {
config.vsock = None; config.vsock = None;
} }
} }
}
self.device_manager self.device_manager
.lock() .lock()
.unwrap() .unwrap()
.notify_hotplug(HotPlugNotificationFlags::PCI_DEVICES_CHANGED) .notify_hotplug(HotPlugNotificationFlags::PCI_DEVICES_CHANGED)
.map_err(Error::DeviceManager)?; .map_err(Error::DeviceManager)?;
}
Ok(()) Ok(())
} else {
Err(Error::NoPciSupport)
}
} }
#[cfg(not(feature = "pci_support"))]
pub fn add_disk(&mut self, mut _disk_cfg: DiskConfig) -> Result<PciDeviceInfo> {
Err(Error::NoPciSupport)
}
#[cfg(feature = "pci_support")]
pub fn add_disk(&mut self, mut _disk_cfg: DiskConfig) -> Result<PciDeviceInfo> { pub fn add_disk(&mut self, mut _disk_cfg: DiskConfig) -> Result<PciDeviceInfo> {
let pci_device_info = self let pci_device_info = self
.device_manager .device_manager
@ -1281,12 +1255,6 @@ impl Vm {
Ok(pci_device_info) Ok(pci_device_info)
} }
#[cfg(not(feature = "pci_support"))]
pub fn add_fs(&mut self, mut _fs_cfg: FsConfig) -> Result<PciDeviceInfo> {
Err(Error::NoPciSupport)
}
#[cfg(feature = "pci_support")]
pub fn add_fs(&mut self, mut _fs_cfg: FsConfig) -> Result<PciDeviceInfo> { pub fn add_fs(&mut self, mut _fs_cfg: FsConfig) -> Result<PciDeviceInfo> {
let pci_device_info = self let pci_device_info = self
.device_manager .device_manager
@ -1315,12 +1283,6 @@ impl Vm {
Ok(pci_device_info) Ok(pci_device_info)
} }
#[cfg(not(feature = "pci_support"))]
pub fn add_pmem(&mut self, mut _pmem_cfg: PmemConfig) -> Result<PciDeviceInfo> {
Err(Error::NoPciSupport)
}
#[cfg(feature = "pci_support")]
pub fn add_pmem(&mut self, mut _pmem_cfg: PmemConfig) -> Result<PciDeviceInfo> { pub fn add_pmem(&mut self, mut _pmem_cfg: PmemConfig) -> Result<PciDeviceInfo> {
let pci_device_info = self let pci_device_info = self
.device_manager .device_manager
@ -1349,12 +1311,6 @@ impl Vm {
Ok(pci_device_info) Ok(pci_device_info)
} }
#[cfg(not(feature = "pci_support"))]
pub fn add_net(&mut self, mut _net_cfg: NetConfig) -> Result<PciDeviceInfo> {
Err(Error::NoPciSupport)
}
#[cfg(feature = "pci_support")]
pub fn add_net(&mut self, mut _net_cfg: NetConfig) -> Result<PciDeviceInfo> { pub fn add_net(&mut self, mut _net_cfg: NetConfig) -> Result<PciDeviceInfo> {
let pci_device_info = self let pci_device_info = self
.device_manager .device_manager
@ -1383,12 +1339,6 @@ impl Vm {
Ok(pci_device_info) Ok(pci_device_info)
} }
#[cfg(not(feature = "pci_support"))]
pub fn add_vsock(&mut self, mut _vsock_cfg: VsockConfig) -> Result<PciDeviceInfo> {
Err(Error::NoPciSupport)
}
#[cfg(feature = "pci_support")]
pub fn add_vsock(&mut self, mut _vsock_cfg: VsockConfig) -> Result<PciDeviceInfo> { pub fn add_vsock(&mut self, mut _vsock_cfg: VsockConfig) -> Result<PciDeviceInfo> {
if self.config.lock().unwrap().vsock.is_some() { if self.config.lock().unwrap().vsock.is_some() {
return Err(Error::TooManyVsockDevices); return Err(Error::TooManyVsockDevices);