devices: vfio_pci: identify intel-lpss devices via cmdline
intel-lpss devices need special handling during BAR accesses due to PV
operations in the guest (when compiled with the direct feature). Allow
identification of such devices via a new vfio parameter, intel-lpss, so
that it can tag them for PV handling.
BUG=b:232887201
TEST=crosvm accepts the intel-lpss parameter in --vfio
Change-Id: I6ce710b112e7d286e43014d7dc55ec4e68939731
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3764936
Tested-by: Peter Fang <peter.fang@intel.corp-partner.google.com>
Commit-Queue: Tomasz Nowicki <tnowicki@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
diff --git a/devices/src/pci/vfio_pci.rs b/devices/src/pci/vfio_pci.rs
index 852eb31..47b68c2 100644
--- a/devices/src/pci/vfio_pci.rs
+++ b/devices/src/pci/vfio_pci.rs
@@ -587,6 +587,9 @@
header_type_reg: Option<u32>,
// PCI Express Extended Capabilities
ext_caps: Vec<ExtCap>,
+ #[cfg(feature = "direct")]
+ #[allow(dead_code)]
+ is_intel_lpss: bool,
mapped_mmio_bars: BTreeMap<PciBarIndex, (u64, Vec<MemSlot>)>,
}
@@ -602,6 +605,7 @@
vfio_device_socket_msix: Tube,
vfio_device_socket_mem: Tube,
vfio_device_socket_vm: Option<Tube>,
+ #[cfg(feature = "direct")] is_intel_lpss: bool,
) -> Result<Self, PciDeviceError> {
let preferred_address = if let Some(bus_num) = hotplug_bus_number {
debug!("hotplug bus {}", bus_num);
@@ -766,6 +770,8 @@
#[cfg(feature = "direct")]
header_type_reg,
ext_caps,
+ #[cfg(feature = "direct")]
+ is_intel_lpss,
mapped_mmio_bars: BTreeMap::new(),
})
}
diff --git a/src/crosvm/sys/unix.rs b/src/crosvm/sys/unix.rs
index c22eec5..f2909aa 100644
--- a/src/crosvm/sys/unix.rs
+++ b/src/crosvm/sys/unix.rs
@@ -687,6 +687,8 @@
vfio_dev.guest_address(),
Some(&mut coiommu_attached_endpoints),
vfio_dev.iommu_dev_type(),
+ #[cfg(feature = "direct")]
+ vfio_dev.is_intel_lpss(),
)?;
*iova_max_addr = Some(max(
@@ -1915,6 +1917,8 @@
} else {
IommuDevType::NoIommu
},
+ #[cfg(feature = "direct")]
+ false,
)?;
let pci_address = Arch::register_pci_device(
linux,
diff --git a/src/crosvm/sys/unix/config.rs b/src/crosvm/sys/unix/config.rs
index f30af7d..0a0cc22 100644
--- a/src/crosvm/sys/unix/config.rs
+++ b/src/crosvm/sys/unix/config.rs
@@ -280,6 +280,17 @@
))
}
}
+ #[cfg(feature = "direct")]
+ "intel-lpss" => {
+ if value.parse::<bool>().is_ok() {
+ Ok(())
+ } else {
+ Err(invalid_value_err(
+ format!("{}={}", kind, value),
+ "option must be `intel-lpss=true|false`",
+ ))
+ }
+ }
_ => Err(invalid_value_err(
format!("{}={}", kind, value),
"option must be `guest-address=<val>` and/or `iommu=<val>`",
@@ -305,6 +316,14 @@
}
IommuDevType::NoIommu
}
+
+ #[cfg(feature = "direct")]
+ pub fn is_intel_lpss(&self) -> bool {
+ if let Some(lpss) = self.params.get("intel-lpss") {
+ return lpss.parse::<bool>().unwrap_or(false);
+ }
+ false
+ }
}
#[cfg(test)]
diff --git a/src/crosvm/sys/unix/device_helpers.rs b/src/crosvm/sys/unix/device_helpers.rs
index 58f9c67..c1f403f 100644
--- a/src/crosvm/sys/unix/device_helpers.rs
+++ b/src/crosvm/sys/unix/device_helpers.rs
@@ -1433,6 +1433,7 @@
guest_address: Option<PciAddress>,
coiommu_endpoints: Option<&mut Vec<u16>>,
iommu_dev: IommuDevType,
+ #[cfg(feature = "direct")] is_intel_lpss: bool,
) -> DeviceResult<(Box<VfioPciDevice>, Option<Minijail>, Option<VfioWrapper>)> {
let vfio_container = VfioCommonSetup::vfio_get_container(iommu_dev, Some(vfio_path))
.context("failed to get vfio container")?;
@@ -1476,6 +1477,8 @@
vfio_device_tube_msix,
vfio_device_tube_mem,
vfio_device_tube_vm,
+ #[cfg(feature = "direct")]
+ is_intel_lpss,
)?);
// early reservation for pass-through PCI devices.
let endpoint_addr = vfio_pci_device