mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-05 21:15:45 +00:00
vmm: device_manager: Remove the need for Any
We define a new enum in order to classify PCI device under virtio or VFIO. This is a cleaner approach than using the Any trait, and downcasting it to find the object back. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
fbd624d816
commit
e311fd66cd
@ -64,12 +64,12 @@ use libc::{
|
|||||||
isatty, tcgetattr, tcsetattr, termios, ECHO, ICANON, ISIG, MAP_NORESERVE, MAP_PRIVATE,
|
isatty, tcgetattr, tcsetattr, termios, ECHO, ICANON, ISIG, MAP_NORESERVE, MAP_PRIVATE,
|
||||||
MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE, TCSANOW, TIOCGWINSZ,
|
MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE, TCSANOW, TIOCGWINSZ,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
use pci::VfioPciDevice;
|
||||||
use pci::{
|
use pci::{
|
||||||
DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot,
|
DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot,
|
||||||
VfioPciDevice,
|
|
||||||
};
|
};
|
||||||
use seccomp::SeccompAction;
|
use seccomp::SeccompAction;
|
||||||
use std::any::Any;
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::fs::{read_link, File, OpenOptions};
|
use std::fs::{read_link, File, OpenOptions};
|
||||||
@ -96,9 +96,9 @@ use vm_device::interrupt::{
|
|||||||
};
|
};
|
||||||
use vm_device::{Bus, BusDevice, Resource};
|
use vm_device::{Bus, BusDevice, Resource};
|
||||||
use vm_memory::guest_memory::FileOffset;
|
use vm_memory::guest_memory::FileOffset;
|
||||||
use vm_memory::{
|
#[cfg(feature = "kvm")]
|
||||||
Address, GuestAddress, GuestMemoryRegion, GuestRegionMmap, GuestUsize, MmapRegion,
|
use vm_memory::GuestMemoryRegion;
|
||||||
};
|
use vm_memory::{Address, GuestAddress, GuestRegionMmap, GuestUsize, MmapRegion};
|
||||||
#[cfg(feature = "cmos")]
|
#[cfg(feature = "cmos")]
|
||||||
use vm_memory::{GuestAddressSpace, GuestMemory};
|
use vm_memory::{GuestAddressSpace, GuestMemory};
|
||||||
use vm_migration::{
|
use vm_migration::{
|
||||||
@ -825,6 +825,12 @@ impl PtyPair {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PciDeviceHandle {
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
Vfio(Arc<Mutex<VfioPciDevice>>),
|
||||||
|
Virtio(Arc<Mutex<VirtioPciDevice>>),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct DeviceManager {
|
pub struct DeviceManager {
|
||||||
// Manage address space related to devices
|
// Manage address space related to devices
|
||||||
address_manager: Arc<AddressManager>,
|
address_manager: Arc<AddressManager>,
|
||||||
@ -895,7 +901,7 @@ pub struct DeviceManager {
|
|||||||
pci_devices_down: u32,
|
pci_devices_down: u32,
|
||||||
|
|
||||||
// BTreeMap of PCI b/d/f to their corresponding MetaPciDevice.
|
// BTreeMap of PCI b/d/f to their corresponding MetaPciDevice.
|
||||||
pci_devices: BTreeMap<u32, (String, Arc<dyn Any + Send + Sync>)>,
|
pci_devices: BTreeMap<u32, (String, PciDeviceHandle)>,
|
||||||
|
|
||||||
// BTreeMap of PCI b/d/f to their allocated IRQ.
|
// BTreeMap of PCI b/d/f to their allocated IRQ.
|
||||||
pci_device_irqs: BTreeMap<u32, u32>,
|
pci_device_irqs: BTreeMap<u32, u32>,
|
||||||
@ -2907,7 +2913,7 @@ impl DeviceManager {
|
|||||||
pci,
|
pci,
|
||||||
vfio_pci_device.clone(),
|
vfio_pci_device.clone(),
|
||||||
vfio_pci_device.clone(),
|
vfio_pci_device.clone(),
|
||||||
vfio_pci_device,
|
PciDeviceHandle::Vfio(vfio_pci_device),
|
||||||
pci_device_bdf,
|
pci_device_bdf,
|
||||||
vfio_name.clone(),
|
vfio_name.clone(),
|
||||||
)?;
|
)?;
|
||||||
@ -2924,7 +2930,7 @@ impl DeviceManager {
|
|||||||
pci_bus: &mut PciBus,
|
pci_bus: &mut PciBus,
|
||||||
bus_device: Arc<Mutex<dyn BusDevice>>,
|
bus_device: Arc<Mutex<dyn BusDevice>>,
|
||||||
pci_device: Arc<Mutex<dyn PciDevice>>,
|
pci_device: Arc<Mutex<dyn PciDevice>>,
|
||||||
any_device: Arc<dyn Any + Send + Sync>,
|
pci_device_handle: PciDeviceHandle,
|
||||||
bdf: u32,
|
bdf: u32,
|
||||||
device_id: String,
|
device_id: String,
|
||||||
) -> DeviceManagerResult<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> {
|
) -> DeviceManagerResult<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> {
|
||||||
@ -2938,8 +2944,7 @@ impl DeviceManager {
|
|||||||
.add_device(bdf, pci_device)
|
.add_device(bdf, pci_device)
|
||||||
.map_err(DeviceManagerError::AddPciDevice)?;
|
.map_err(DeviceManagerError::AddPciDevice)?;
|
||||||
|
|
||||||
self.pci_devices
|
self.pci_devices.insert(bdf, (device_id, pci_device_handle));
|
||||||
.insert(bdf, (device_id.clone(), any_device));
|
|
||||||
self.bus_devices.push(Arc::clone(&bus_device));
|
self.bus_devices.push(Arc::clone(&bus_device));
|
||||||
|
|
||||||
pci_bus
|
pci_bus
|
||||||
@ -3096,7 +3101,7 @@ impl DeviceManager {
|
|||||||
pci,
|
pci,
|
||||||
virtio_pci_device.clone(),
|
virtio_pci_device.clone(),
|
||||||
virtio_pci_device.clone(),
|
virtio_pci_device.clone(),
|
||||||
virtio_pci_device.clone(),
|
PciDeviceHandle::Virtio(Arc::clone(&virtio_pci_device)),
|
||||||
pci_device_bdf,
|
pci_device_bdf,
|
||||||
virtio_device_id,
|
virtio_device_id,
|
||||||
)?;
|
)?;
|
||||||
@ -3163,9 +3168,9 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Take care of updating the memory for VFIO PCI devices.
|
// Take care of updating the memory for VFIO PCI devices.
|
||||||
for (_, (_, any_device)) in self.pci_devices.iter() {
|
#[cfg(feature = "kvm")]
|
||||||
if let Ok(vfio_pci_device) = Arc::clone(&any_device).downcast::<Mutex<VfioPciDevice>>()
|
for (_, (_, pci_device_handle)) in self.pci_devices.iter() {
|
||||||
{
|
if let PciDeviceHandle::Vfio(vfio_pci_device) = pci_device_handle {
|
||||||
vfio_pci_device
|
vfio_pci_device
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -3183,10 +3188,9 @@ impl DeviceManager {
|
|||||||
|
|
||||||
pub fn activate_virtio_devices(&self) -> DeviceManagerResult<()> {
|
pub fn activate_virtio_devices(&self) -> DeviceManagerResult<()> {
|
||||||
// Find virtio pci devices and activate any pending ones
|
// Find virtio pci devices and activate any pending ones
|
||||||
for (_, (_, any_device)) in self.pci_devices.iter() {
|
for (_, (_, pci_device_handle)) in self.pci_devices.iter() {
|
||||||
if let Ok(virtio_pci_device) =
|
#[allow(irrefutable_let_patterns)]
|
||||||
Arc::clone(&any_device).downcast::<Mutex<VirtioPciDevice>>()
|
if let PciDeviceHandle::Virtio(virtio_pci_device) = pci_device_handle {
|
||||||
{
|
|
||||||
virtio_pci_device.lock().unwrap().maybe_activate();
|
virtio_pci_device.lock().unwrap().maybe_activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3244,11 +3248,10 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_device(&mut self, id: String) -> DeviceManagerResult<()> {
|
pub fn remove_device(&mut self, id: String) -> DeviceManagerResult<()> {
|
||||||
for (pci_device_bdf, (device_id, any_device)) in self.pci_devices.iter() {
|
for (pci_device_bdf, (device_id, pci_device_handle)) in self.pci_devices.iter() {
|
||||||
if *device_id == id {
|
if *device_id == id {
|
||||||
if let Ok(virtio_pci_device) =
|
#[allow(irrefutable_let_patterns)]
|
||||||
Arc::clone(&any_device).downcast::<Mutex<VirtioPciDevice>>()
|
if let PciDeviceHandle::Virtio(virtio_pci_device) = pci_device_handle {
|
||||||
{
|
|
||||||
let device_type = VirtioDeviceType::from(
|
let device_type = VirtioDeviceType::from(
|
||||||
virtio_pci_device
|
virtio_pci_device
|
||||||
.lock()
|
.lock()
|
||||||
@ -3303,10 +3306,10 @@ impl DeviceManager {
|
|||||||
.put_device_id(device_id as usize)
|
.put_device_id(device_id as usize)
|
||||||
.map_err(DeviceManagerError::PutPciDeviceId)?;
|
.map_err(DeviceManagerError::PutPciDeviceId)?;
|
||||||
|
|
||||||
if let Some((_, any_device)) = self.pci_devices.remove(&pci_device_bdf) {
|
if let Some((_, pci_device_handle)) = self.pci_devices.remove(&pci_device_bdf) {
|
||||||
let (pci_device, bus_device, virtio_device) = if let Ok(vfio_pci_device) =
|
let (pci_device, bus_device, virtio_device) = match pci_device_handle {
|
||||||
any_device.clone().downcast::<Mutex<VfioPciDevice>>()
|
#[cfg(feature = "kvm")]
|
||||||
{
|
PciDeviceHandle::Vfio(vfio_pci_device) => {
|
||||||
{
|
{
|
||||||
// Unregister DMA mapping in IOMMU.
|
// Unregister DMA mapping in IOMMU.
|
||||||
// Do not unregister the virtio-mem region, as it is
|
// Do not unregister the virtio-mem region, as it is
|
||||||
@ -3327,7 +3330,9 @@ impl DeviceManager {
|
|||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.remove_dma_mapping_handler(pci_device_bdf)
|
.remove_dma_mapping_handler(pci_device_bdf)
|
||||||
.map_err(DeviceManagerError::RemoveDmaMappingHandlerVirtioMem)?;
|
.map_err(
|
||||||
|
DeviceManagerError::RemoveDmaMappingHandlerVirtioMem,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3337,7 +3342,8 @@ impl DeviceManager {
|
|||||||
Arc::clone(&vfio_pci_device) as Arc<Mutex<dyn BusDevice>>,
|
Arc::clone(&vfio_pci_device) as Arc<Mutex<dyn BusDevice>>,
|
||||||
None as Option<VirtioDeviceArc>,
|
None as Option<VirtioDeviceArc>,
|
||||||
)
|
)
|
||||||
} else if let Ok(virtio_pci_device) = any_device.downcast::<Mutex<VirtioPciDevice>>() {
|
}
|
||||||
|
PciDeviceHandle::Virtio(virtio_pci_device) => {
|
||||||
let bar_addr = virtio_pci_device.lock().unwrap().config_bar_addr();
|
let bar_addr = virtio_pci_device.lock().unwrap().config_bar_addr();
|
||||||
for (event, addr) in virtio_pci_device.lock().unwrap().ioeventfds(bar_addr) {
|
for (event, addr) in virtio_pci_device.lock().unwrap().ioeventfds(bar_addr) {
|
||||||
let io_addr = IoEventAddress::Mmio(addr);
|
let io_addr = IoEventAddress::Mmio(addr);
|
||||||
@ -3352,8 +3358,7 @@ impl DeviceManager {
|
|||||||
Arc::clone(&virtio_pci_device) as Arc<Mutex<dyn BusDevice>>,
|
Arc::clone(&virtio_pci_device) as Arc<Mutex<dyn BusDevice>>,
|
||||||
Some(virtio_pci_device.lock().unwrap().virtio_device()),
|
Some(virtio_pci_device.lock().unwrap().virtio_device()),
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
return Ok(());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Free the allocated BARs
|
// Free the allocated BARs
|
||||||
|
Loading…
Reference in New Issue
Block a user