From 043bab3d3e0be7982713380bb56dfdcec9640856 Mon Sep 17 00:00:00 2001 From: "alex.lyn" Date: Tue, 20 May 2025 11:18:46 +0800 Subject: [PATCH] runtime-rs: Handle port allocation in PCIe topology for vfio devices It's import to handle port allocation in a PCIe topology before vfio deivce hotplug via QMP. The code ensures that VFIO devices are properly allocated to available ports (either root ports or switch ports) and updates the device's bus and port information accordingly. It'll first retrieves the PCIe port type from the topology using pcie_topo.get_pcie_port(). And then, searches for an available node in the PCIe topology with RootPort or SwitchPort type and allocates the VFIO device to the found available port. Finally, Updates the device's bus with the allocated port's ID and type. Fixes # 10361 Signed-off-by: alex.lyn --- .../hypervisor/src/device/driver/vfio.rs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/runtime-rs/crates/hypervisor/src/device/driver/vfio.rs b/src/runtime-rs/crates/hypervisor/src/device/driver/vfio.rs index c3834878e9..63cea42e85 100644 --- a/src/runtime-rs/crates/hypervisor/src/device/driver/vfio.rs +++ b/src/runtime-rs/crates/hypervisor/src/device/driver/vfio.rs @@ -20,7 +20,7 @@ use kata_sys_util::fs::get_base_name; use crate::{ device::{ pci_path::PciPath, - topology::{do_add_pcie_endpoint, PCIePort, PCIeTopology}, + topology::{do_add_pcie_endpoint, AvailableNode, PCIePort, PCIeTopology}, util::{do_decrease_count, do_increase_count}, Device, DeviceType, PCIeDevice, }, @@ -561,6 +561,34 @@ impl PCIeDevice for VfioDevice { return Ok(()); } + // handle port devices + if !self.allocated { + let (port_type, _) = pcie_topo + .get_pcie_port() + .ok_or_else(|| anyhow!("No validated port type supported."))?; + let avail_port = match port_type { + PCIePort::RootPort | PCIePort::SwitchPort => pcie_topo.find_available_node(), + _ => { + info!( + sl!(), + "There's no need to set ports used to hot-plug vfio devices" + ); + None + } + }; + // vfio device attached onto port(root port | switch port) + let port_device = avail_port + .ok_or_else(|| anyhow!("No available node found for {:?} device", port_type))?; + self.bus = match port_device { + AvailableNode::TopologyPortDevice(root_port) => root_port.port_id(), + AvailableNode::SwitchDownPort(swdown_port) => swdown_port.port_id(), + }; + + self.port = port_type; + self.allocated = true; + info!(sl!(), "bus: {:?}, port type: {:?}", &self.bus, &self.port); + } + self.device_options.clear(); for hostdev in self.devices.iter_mut() { let pci_path = do_add_pcie_endpoint(