mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-07-09 22:24:51 +00:00
runtime-rs: drop non-passthrough functions from VFIO groups
A discrete GPU usually shares its IOMMU group with an audio function (e.g. NVIDIA 02:00.1). Cold-plugging every function in the group made QEMU emit a vfio-pci/pcie-root-port/iommufd triple per function while reusing the GPU's root-port and IOMMUFD object ids, so QEMU aborted with a duplicate-id error before it was reachable over QMP. Apply the existing IOMMU_IGNORE classification while discovering the group so audio controllers and bridges are pruned, leaving only the passthrough-capable device(s). Also fix filter_bridge_device to parse the sysfs class attribute as hex; the previous decimal parse always failed, which is why the filter never removed anything. Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com> Assisted-by: Cursor <noreply@cursor.com>
This commit is contained in:
@@ -380,8 +380,11 @@ fn filter_bridge_device(bdf: &str, bitmasks: &[u64]) -> Option<u64> {
|
||||
return None;
|
||||
}
|
||||
|
||||
match device_class.parse::<u32>() {
|
||||
Ok(cid_u32) => {
|
||||
// The sysfs `class` attribute is a hex string (e.g. "0x040300"), so it must
|
||||
// be parsed base-16. Parsing it as decimal always fails, which previously
|
||||
// caused every device to be treated as passthrough-capable.
|
||||
match parse_class_code_u32(&device_class) {
|
||||
Some(cid_u32) => {
|
||||
// PCI class code is 24 bits, shift right 8 to get base+sub class
|
||||
let class_code = u64::from(cid_u32) >> 8;
|
||||
for &bitmask in bitmasks {
|
||||
@@ -391,7 +394,7 @@ fn filter_bridge_device(bdf: &str, bitmasks: &[u64]) -> Option<u64> {
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,6 +608,24 @@ fn discover_vfio_device_for_iommu_group(gid: u32, group_devnode: PathBuf) -> Res
|
||||
}
|
||||
}
|
||||
|
||||
// Drop functions that only share the GPU's IOMMU group but must not be
|
||||
// passed through (audio controllers, bridges), reusing the same
|
||||
// IOMMU_IGNORE classification as validate_group_basic. Everything derived
|
||||
// below (vfio_cdevs, the IOMMUFD backend cdevs and the primary device) is
|
||||
// built from this filtered list. Passing such a function would otherwise
|
||||
// emit an extra vfio-pci entry reusing the GPU's cold-plug root-port and
|
||||
// IOMMUFD object ids, making QEMU abort with a duplicate-id error.
|
||||
devices.retain(|d| match &d.addr {
|
||||
DeviceAddress::Pci(bdf) => filter_bridge_device(&bdf.to_string(), IOMMU_IGNORE).is_none(),
|
||||
_ => true,
|
||||
});
|
||||
if devices.is_empty() {
|
||||
return Err(anyhow!(
|
||||
"IOMMU group {} has no passthrough-capable devices",
|
||||
gid
|
||||
));
|
||||
}
|
||||
|
||||
let labels = build_group_labels(&devices);
|
||||
let is_viable = validate_group_basic(&devices);
|
||||
let primary_device = select_primary_device(&devices);
|
||||
|
||||
Reference in New Issue
Block a user