diff --git a/Cargo.lock b/Cargo.lock index 1af0cc786..cc40dac95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1150,7 +1150,7 @@ dependencies = [ [[package]] name = "vfio-ioctls" version = "0.1.0" -source = "git+https://github.com/rust-vmm/vfio-ioctls?branch=main#adbc9444387a9276e568fd2e31ed19bd0cd96611" +source = "git+https://github.com/rust-vmm/vfio-ioctls?branch=main#8f7f2210ebe71660938b05b2ed7eec9253478bc5" dependencies = [ "byteorder", "kvm-bindings", diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index b2db5251b..666c46e26 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -705,7 +705,7 @@ dependencies = [ [[package]] name = "vfio-ioctls" version = "0.1.0" -source = "git+https://github.com/rust-vmm/vfio-ioctls?branch=main#d51c1fad37be30c20385c55a217e2d90972ea31d" +source = "git+https://github.com/rust-vmm/vfio-ioctls?branch=main#8f7f2210ebe71660938b05b2ed7eec9253478bc5" dependencies = [ "byteorder", "kvm-bindings", diff --git a/pci/src/vfio.rs b/pci/src/vfio.rs index 9c813c3f2..90a0d92b7 100644 --- a/pci/src/vfio.rs +++ b/pci/src/vfio.rs @@ -18,7 +18,7 @@ use std::ptr::null_mut; use std::sync::{Arc, Barrier}; use thiserror::Error; use vfio_bindings::bindings::vfio::*; -use vfio_ioctls::{VfioContainer, VfioDevice, VfioIrq}; +use vfio_ioctls::{VfioContainer, VfioDevice, VfioIrq, VfioRegionInfoCap}; use vm_allocator::{AddressAllocator, SystemAllocator}; use vm_device::interrupt::{ InterruptIndex, InterruptManager, InterruptSourceGroup, MsiIrqGroupConfig, @@ -1120,11 +1120,25 @@ impl VfioPciDevice { prot |= libc::PROT_WRITE; } - // We ignore the mmap offset because we only support running on - // host with VFIO newer than 4.16. That's because sparse mmap - // has been deprecated and instead MSI-X regions can now be - // entirely mapped. - let (_, mmap_size) = self.device.get_region_mmap(region.index); + // Retrieve the list of capabilities found on the region + let caps = if region_flags & VFIO_REGION_INFO_FLAG_CAPS != 0 { + self.device.get_region_caps(region.index) + } else { + Vec::new() + }; + + // Don't try to mmap the region if it contains MSI-X table or + // MSI-X PBA subregion, and if we couldn't find MSIX_MAPPABLE + // in the list of supported capabilities. + if let Some(msix) = self.common.interrupt.msix.as_ref() { + if (region.index == msix.cap.table_bir() || region.index == msix.cap.pba_bir()) + && !caps.contains(&VfioRegionInfoCap::MsixMappable) + { + continue; + } + } + + let mmap_size = self.device.get_region_size(region.index); let offset = self.device.get_region_offset(region.index); let host_addr = unsafe { @@ -1139,7 +1153,7 @@ impl VfioPciDevice { }; if host_addr == libc::MAP_FAILED { - warn!( + error!( "Could not mmap region index {}: {}", region.index, io::Error::last_os_error()