mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vfio: Create VFIO implementation of ExternalDmaMapping
With this implementation of the trait ExternalDmaMapping, we now have the tool to provide to the virtual IOMMU to trigger the map/unmap on behalf of the guest. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
committed by
Samuel Ortiz
parent
3598e603d5
commit
837bcbc6ba
@@ -14,6 +14,7 @@ extern crate log;
|
||||
extern crate pci;
|
||||
extern crate vfio_bindings;
|
||||
extern crate vm_allocator;
|
||||
extern crate vm_device;
|
||||
extern crate vm_memory;
|
||||
#[macro_use]
|
||||
extern crate vmm_sys_util;
|
||||
@@ -24,7 +25,7 @@ mod vfio_pci;
|
||||
|
||||
use std::mem::size_of;
|
||||
|
||||
pub use vfio_device::{VfioDevice, VfioError};
|
||||
pub use vfio_device::{VfioContainer, VfioDevice, VfioDmaMapping, VfioError};
|
||||
pub use vfio_pci::{VfioPciDevice, VfioPciError};
|
||||
|
||||
// Returns a `Vec<T>` with a size in bytes at least as large as `size_in_bytes`.
|
||||
|
||||
@@ -14,11 +14,13 @@ use std::mem;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||
use std::os::unix::prelude::FileExt;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::result;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::u32;
|
||||
use vfio_bindings::bindings::vfio::*;
|
||||
use vfio_ioctls::*;
|
||||
use vm_memory::{Address, GuestMemory, GuestMemoryMmap, GuestMemoryRegion};
|
||||
use vm_device::ExternalDmaMapping;
|
||||
use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion};
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
use vmm_sys_util::ioctl::*;
|
||||
|
||||
@@ -506,6 +508,68 @@ impl VfioDeviceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
container: Arc<VfioContainer>,
|
||||
memory: Arc<RwLock<GuestMemoryMmap>>,
|
||||
}
|
||||
|
||||
impl VfioDmaMapping {
|
||||
pub fn new(container: Arc<VfioContainer>, memory: Arc<RwLock<GuestMemoryMmap>>) -> Self {
|
||||
VfioDmaMapping { container, memory }
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternalDmaMapping for VfioDmaMapping {
|
||||
fn map(&self, iova: u64, gpa: u64, size: u64) -> result::Result<(), io::Error> {
|
||||
let user_addr = if let Some(addr) = self
|
||||
.memory
|
||||
.read()
|
||||
.unwrap()
|
||||
.get_host_address(GuestAddress(gpa))
|
||||
{
|
||||
addr 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) -> 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
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Vfio device for exposing regions which could be read/write to kernel vfio device.
|
||||
pub struct VfioDevice {
|
||||
device: File,
|
||||
|
||||
Reference in New Issue
Block a user