vfio: Add support for memory hotplug

Whenever the guest memory is extended, the IOMMU mappings related to
each VFIO device must be updated. This allows subsequent RAM accesses
to be authorized by the physical IOMMU for the newly added RAM region.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-03-26 14:05:27 +01:00
parent 8fc7bf2953
commit e4a034aef9
2 changed files with 22 additions and 2 deletions

View File

@ -25,7 +25,7 @@ use vfio_ioctls::*;
use vm_device::{get_host_address_range, ExternalDmaMapping};
use vm_memory::{
Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestMemoryMmap,
GuestMemoryRegion,
GuestMemoryRegion, GuestRegionMmap,
};
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::fam::FamStruct;
@ -873,6 +873,18 @@ impl VfioDevice {
Ok(())
}
pub fn extend_dma_map(&self, new_region: &Arc<GuestRegionMmap>) -> Result<()> {
if !self.iommu_attached {
self.vfio_dma_map(
new_region.start_addr().raw_value(),
new_region.len() as u64,
new_region.as_ptr() as u64,
)
} else {
Ok(())
}
}
/// Return the maximum numner of interrupts a VFIO device can request.
/// This is used for pre-allocating the VFIO PCI routes.
pub fn max_interrupts(&self) -> u32 {

View File

@ -27,7 +27,7 @@ use vm_allocator::SystemAllocator;
use vm_device::interrupt::{
InterruptIndex, InterruptManager, InterruptSourceGroup, MsiIrqGroupConfig,
};
use vm_memory::{Address, GuestAddress, GuestUsize};
use vm_memory::{Address, GuestAddress, GuestRegionMmap, GuestUsize};
use vmm_sys_util::eventfd::EventFd;
#[derive(Debug)]
@ -41,6 +41,7 @@ pub enum VfioPciError {
SetGsiRouting(kvm_ioctls::Error),
MsiNotConfigured,
MsixNotConfigured,
UpdateMemory(crate::VfioError),
UpdateMsiEventFd,
UpdateMsixEventFd,
}
@ -62,6 +63,7 @@ impl fmt::Display for VfioPciError {
VfioPciError::SetGsiRouting(e) => write!(f, "failed to set GSI routes for KVM: {}", e),
VfioPciError::MsiNotConfigured => write!(f, "MSI interrupt not yet configured"),
VfioPciError::MsixNotConfigured => write!(f, "MSI-X interrupt not yet configured"),
VfioPciError::UpdateMemory(e) => write!(f, "failed to update memory: {}", e),
VfioPciError::UpdateMsiEventFd => write!(f, "failed to update MSI eventfd"),
VfioPciError::UpdateMsixEventFd => write!(f, "failed to update MSI-X eventfd"),
}
@ -610,6 +612,12 @@ impl VfioPciDevice {
}
}
}
pub fn update_memory(&self, new_region: &Arc<GuestRegionMmap>) -> Result<()> {
self.device
.extend_dma_map(new_region)
.map_err(VfioPciError::UpdateMemory)
}
}
impl Drop for VfioPciDevice {