vfio: Don't map guest memory for VFIO devices attached to vIOMMU

In case a VFIO devices is being attached behind a virtual IOMMU, we
should not automatically map the entire guest memory for the specific
device.

A VFIO device attached to the virtual IOMMU will be driven with IOVAs,
hence we should simply wait for the requests coming from the virtual
IOMMU.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2019-10-08 12:50:05 -07:00
committed by Samuel Ortiz
parent 63c30a6e79
commit 3acf9dfcf3
2 changed files with 24 additions and 13 deletions

View File

@@ -578,6 +578,7 @@ pub struct VfioDevice {
regions: Vec<VfioRegion>,
irqs: HashMap<u32, VfioIrq>,
mem: Arc<RwLock<GuestMemoryMmap>>,
iommu_attached: bool,
}
impl VfioDevice {
@@ -588,6 +589,7 @@ impl VfioDevice {
sysfspath: &Path,
device_fd: Arc<DeviceFd>,
mem: Arc<RwLock<GuestMemoryMmap>>,
iommu_attached: bool,
) -> Result<Self> {
let uuid_path: PathBuf = [sysfspath, Path::new("iommu_group")].iter().collect();
let group_path = uuid_path.read_link().map_err(|_| VfioError::InvalidPath)?;
@@ -609,6 +611,7 @@ impl VfioDevice {
regions,
irqs,
mem,
iommu_attached,
})
}
@@ -841,22 +844,26 @@ impl VfioDevice {
/// Add all guest memory regions into vfio container's iommu table,
/// then vfio kernel driver could access guest memory from gfn
pub fn setup_dma_map(&self) -> Result<()> {
self.mem.read().unwrap().with_regions(|_index, region| {
self.vfio_dma_map(
region.start_addr().raw_value(),
region.len() as u64,
region.as_ptr() as u64,
)
})?;
if !self.iommu_attached {
self.mem.read().unwrap().with_regions(|_index, region| {
self.vfio_dma_map(
region.start_addr().raw_value(),
region.len() as u64,
region.as_ptr() as u64,
)
})?;
}
Ok(())
}
/// remove all guest memory regions from vfio containers iommu table
/// then vfio kernel driver couldn't access this guest memory
pub fn unset_dma_map(&self) -> Result<()> {
self.mem.read().unwrap().with_regions(|_index, region| {
self.vfio_dma_unmap(region.start_addr().raw_value(), region.len() as u64)
})?;
if !self.iommu_attached {
self.mem.read().unwrap().with_regions(|_index, region| {
self.vfio_dma_unmap(region.start_addr().raw_value(), region.len() as u64)
})?;
}
Ok(())
}