vm-device: Move ExternalDmaMapping trait out of vfio-ioctls

By moving the trait and its VFIO implementation out of vfio-ioctls, we
give anticipate for the move to the vfio-ioctls from rust-vmm.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-02-23 14:47:56 +01:00 committed by Samuel Ortiz
parent 727287b69d
commit 5bd05b1af0
5 changed files with 93 additions and 0 deletions

1
Cargo.lock generated
View File

@ -1449,6 +1449,7 @@ dependencies = [
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"thiserror", "thiserror",
"vfio-ioctls",
"vm-memory", "vm-memory",
"vmm-sys-util", "vmm-sys-util",
] ]

View File

@ -10,6 +10,7 @@ thiserror = "1.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"
vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" }
vm-memory = { version = "0.5.0", features = ["backend-mmap"] } vm-memory = { version = "0.5.0", features = ["backend-mmap"] }
vmm-sys-util = ">=0.3.1" vmm-sys-util = ">=0.3.1"

View File

@ -0,0 +1,17 @@
// Copyright © 2021 Intel Corporation
//
// 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
/// 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
/// guest.
pub trait ExternalDmaMapping: Send + Sync {
/// Map a memory range
fn map(&self, iova: u64, gpa: u64, size: u64) -> std::result::Result<(), std::io::Error>;
/// Unmap a memory range
fn unmap(&self, iova: u64, size: u64) -> std::result::Result<(), std::io::Error>;
}

View File

@ -0,0 +1,73 @@
// 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{:x} into \
host user virtual address",
gpa
),
));
};
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{:x}, gpa 0x{:x}, size 0x{:x}: {:?}",
iova, gpa, size, 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{:x}, size 0x{:x}: {:?}",
iova, size, e
),
)
})
}
}

View File

@ -10,6 +10,7 @@ extern crate vm_memory;
use std::io; use std::io;
mod bus; mod bus;
pub mod dma_mapping;
pub mod interrupt; pub mod interrupt;
pub use self::bus::{Bus, BusDevice, Error as BusError}; pub use self::bus::{Bus, BusDevice, Error as BusError};