mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
virtio-devices: Move VfioDmaMapping to be in the pci crate
VfioUserDmaMapping is already in the pci crate, this moves VfioDmaMapping to match the behavior. This is a necessary change to allow the VfioDmaMapping trait to have access to MmioRegion memory without creating a circular dependency. The VfioDmaMapping trait needs to have access to mmio regions to map external devices over mmio (a follow-up commit). Signed-off-by: Andrew Carp <acarp@crusoeenergy.com>
This commit is contained in:
parent
44fbd60b7a
commit
f50081df00
@ -26,7 +26,7 @@ pub use self::device::{
|
|||||||
};
|
};
|
||||||
pub use self::msi::{msi_num_enabled_vectors, MsiCap, MsiConfig};
|
pub use self::msi::{msi_num_enabled_vectors, MsiCap, MsiConfig};
|
||||||
pub use self::msix::{MsixCap, MsixConfig, MsixTableEntry, MSIX_CONFIG_ID, MSIX_TABLE_ENTRY_SIZE};
|
pub use self::msix::{MsixCap, MsixConfig, MsixTableEntry, MSIX_CONFIG_ID, MSIX_TABLE_ENTRY_SIZE};
|
||||||
pub use self::vfio::{VfioPciDevice, VfioPciError};
|
pub use self::vfio::{VfioDmaMapping, VfioPciDevice, VfioPciError};
|
||||||
pub use self::vfio_user::{VfioUserDmaMapping, VfioUserPciDevice, VfioUserPciDeviceError};
|
pub use self::vfio_user::{VfioUserDmaMapping, VfioUserPciDevice, VfioUserPciDeviceError};
|
||||||
use serde::de::Visitor;
|
use serde::de::Visitor;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
@ -32,11 +32,12 @@ use vm_allocator::page_size::{
|
|||||||
align_page_size_down, align_page_size_up, is_4k_aligned, is_4k_multiple, is_page_size_aligned,
|
align_page_size_down, align_page_size_up, is_4k_aligned, is_4k_multiple, is_page_size_aligned,
|
||||||
};
|
};
|
||||||
use vm_allocator::{AddressAllocator, SystemAllocator};
|
use vm_allocator::{AddressAllocator, SystemAllocator};
|
||||||
|
use vm_device::dma_mapping::ExternalDmaMapping;
|
||||||
use vm_device::interrupt::{
|
use vm_device::interrupt::{
|
||||||
InterruptIndex, InterruptManager, InterruptSourceGroup, MsiIrqGroupConfig,
|
InterruptIndex, InterruptManager, InterruptSourceGroup, MsiIrqGroupConfig,
|
||||||
};
|
};
|
||||||
use vm_device::{BusDevice, Resource};
|
use vm_device::{BusDevice, Resource};
|
||||||
use vm_memory::{Address, GuestAddress, GuestUsize};
|
use vm_memory::{Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestUsize};
|
||||||
use vm_migration::{
|
use vm_migration::{
|
||||||
Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped,
|
Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped,
|
||||||
};
|
};
|
||||||
@ -1885,3 +1886,64 @@ impl Snapshottable for VfioPciDevice {
|
|||||||
}
|
}
|
||||||
impl Transportable for VfioPciDevice {}
|
impl Transportable for VfioPciDevice {}
|
||||||
impl Migratable for VfioPciDevice {}
|
impl Migratable for VfioPciDevice {}
|
||||||
|
|
||||||
|
/// This structure implements the ExternalDmaMapping trait. It is meant to
|
||||||
|
/// be used when the caller tries to provide a way to update the mappings
|
||||||
|
/// associated with a specific VFIO container.
|
||||||
|
pub struct VfioDmaMapping<M: GuestAddressSpace> {
|
||||||
|
container: Arc<VfioContainer>,
|
||||||
|
memory: Arc<M>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: GuestAddressSpace> VfioDmaMapping<M> {
|
||||||
|
/// Create a DmaMapping object.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// * `container`: VFIO container object.
|
||||||
|
/// * `memory·: guest memory to mmap.
|
||||||
|
pub fn new(container: Arc<VfioContainer>, memory: Arc<M>) -> Self {
|
||||||
|
VfioDmaMapping { container, memory }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VfioDmaMapping<M> {
|
||||||
|
fn map(&self, iova: u64, gpa: u64, size: u64) -> std::result::Result<(), io::Error> {
|
||||||
|
let mem = self.memory.memory();
|
||||||
|
let guest_addr = GuestAddress(gpa);
|
||||||
|
let user_addr = if mem.check_range(guest_addr, size as usize) {
|
||||||
|
mem.get_host_address(guest_addr).unwrap() as u64
|
||||||
|
} else {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"failed to convert guest address 0x{gpa:x} into \
|
||||||
|
host user virtual address"
|
||||||
|
),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
self.container
|
||||||
|
.vfio_dma_map(iova, size, user_addr)
|
||||||
|
.map_err(|e| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"failed to map memory for VFIO container, \
|
||||||
|
iova 0x{iova:x}, gpa 0x{gpa:x}, size 0x{size:x}: {e:?}"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unmap(&self, iova: u64, size: u64) -> std::result::Result<(), io::Error> {
|
||||||
|
self.container.vfio_dma_unmap(iova, size).map_err(|e| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"failed to unmap memory for VFIO container, \
|
||||||
|
iova 0x{iova:x}, size 0x{size:x}: {e:?}"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
|
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
|
||||||
|
|
||||||
pub mod vfio;
|
|
||||||
|
|
||||||
/// Trait meant for triggering the DMA mapping update related to an external
|
/// Trait meant for triggering the DMA mapping update related to an external
|
||||||
/// device not managed fully through virtio. It is dedicated to virtio-iommu
|
/// device not managed fully through virtio. It is dedicated to virtio-iommu
|
||||||
/// in order to trigger the map update anytime the mapping is updated from the
|
/// in order to trigger the map update anytime the mapping is updated from the
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
// Copyright © 2021 Intel Corporation
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
|
|
||||||
|
|
||||||
use crate::dma_mapping::ExternalDmaMapping;
|
|
||||||
use std::io;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use vfio_ioctls::VfioContainer;
|
|
||||||
use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemory};
|
|
||||||
|
|
||||||
/// This structure implements the ExternalDmaMapping trait. It is meant to
|
|
||||||
/// be used when the caller tries to provide a way to update the mappings
|
|
||||||
/// associated with a specific VFIO container.
|
|
||||||
pub struct VfioDmaMapping<M: GuestAddressSpace> {
|
|
||||||
container: Arc<VfioContainer>,
|
|
||||||
memory: Arc<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<M: GuestAddressSpace> VfioDmaMapping<M> {
|
|
||||||
/// Create a DmaMapping object.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
/// * `container`: VFIO container object.
|
|
||||||
/// * `memory·: guest memory to mmap.
|
|
||||||
pub fn new(container: Arc<VfioContainer>, memory: Arc<M>) -> Self {
|
|
||||||
VfioDmaMapping { container, memory }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VfioDmaMapping<M> {
|
|
||||||
fn map(&self, iova: u64, gpa: u64, size: u64) -> std::result::Result<(), io::Error> {
|
|
||||||
let mem = self.memory.memory();
|
|
||||||
let guest_addr = GuestAddress(gpa);
|
|
||||||
let user_addr = if mem.check_range(guest_addr, size as usize) {
|
|
||||||
mem.get_host_address(guest_addr).unwrap() as u64
|
|
||||||
} else {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!(
|
|
||||||
"failed to convert guest address 0x{gpa:x} into \
|
|
||||||
host user virtual address"
|
|
||||||
),
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
self.container
|
|
||||||
.vfio_dma_map(iova, size, user_addr)
|
|
||||||
.map_err(|e| {
|
|
||||||
io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!(
|
|
||||||
"failed to map memory for VFIO container, \
|
|
||||||
iova 0x{iova:x}, gpa 0x{gpa:x}, size 0x{size:x}: {e:?}"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unmap(&self, iova: u64, size: u64) -> std::result::Result<(), io::Error> {
|
|
||||||
self.container.vfio_dma_unmap(iova, size).map_err(|e| {
|
|
||||||
io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!(
|
|
||||||
"failed to unmap memory for VFIO container, \
|
|
||||||
iova 0x{iova:x}, size 0x{size:x}: {e:?}"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -58,8 +58,8 @@ use libc::{
|
|||||||
O_TMPFILE, PROT_READ, PROT_WRITE, TCSANOW,
|
O_TMPFILE, PROT_READ, PROT_WRITE, TCSANOW,
|
||||||
};
|
};
|
||||||
use pci::{
|
use pci::{
|
||||||
DeviceRelocation, PciBarRegionType, PciBdf, PciDevice, VfioPciDevice, VfioUserDmaMapping,
|
DeviceRelocation, PciBarRegionType, PciBdf, PciDevice, VfioDmaMapping,
|
||||||
VfioUserPciDevice, VfioUserPciDeviceError,
|
VfioPciDevice, VfioUserDmaMapping, VfioUserPciDevice, VfioUserPciDeviceError,
|
||||||
};
|
};
|
||||||
use rate_limiter::group::RateLimiterGroup;
|
use rate_limiter::group::RateLimiterGroup;
|
||||||
use seccompiler::SeccompAction;
|
use seccompiler::SeccompAction;
|
||||||
@ -85,7 +85,6 @@ use virtio_devices::{
|
|||||||
};
|
};
|
||||||
use virtio_devices::{Endpoint, IommuMapping};
|
use virtio_devices::{Endpoint, IommuMapping};
|
||||||
use vm_allocator::{AddressAllocator, SystemAllocator};
|
use vm_allocator::{AddressAllocator, SystemAllocator};
|
||||||
use vm_device::dma_mapping::vfio::VfioDmaMapping;
|
|
||||||
use vm_device::dma_mapping::ExternalDmaMapping;
|
use vm_device::dma_mapping::ExternalDmaMapping;
|
||||||
use vm_device::interrupt::{
|
use vm_device::interrupt::{
|
||||||
InterruptIndex, InterruptManager, LegacyIrqGroupConfig, MsiIrqGroupConfig,
|
InterruptIndex, InterruptManager, LegacyIrqGroupConfig, MsiIrqGroupConfig,
|
||||||
|
Loading…
Reference in New Issue
Block a user