From 56ca26e72c63b2dfa7d3df32e37f5c2e7d79b9cc Mon Sep 17 00:00:00 2001 From: Julian Stecklina Date: Thu, 10 Apr 2025 13:46:53 +0200 Subject: [PATCH] pci: only parse capabilities if the device claims to have some Currently, the code tries to follow the PCI capabilities list in offset 0x34 in the config space regardless of whether the status registers says this is valid. Fix by adding the appropriate check. Signed-off-by: Julian Stecklina --- pci/src/vfio.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pci/src/vfio.rs b/pci/src/vfio.rs index 4cf99de63..460f064e1 100644 --- a/pci/src/vfio.rs +++ b/pci/src/vfio.rs @@ -876,7 +876,17 @@ impl VfioCommon { }); } + /// Returns true, if the device claims to have a PCI capability list. + pub(crate) fn has_capabilities(&self) -> bool { + let status = self.vfio_wrapper.read_config_word(PCI_CONFIG_STATUS_OFFSET); + status & PCI_CONFIG_STATUS_CAPABILITIES_LIST != 0 + } + pub(crate) fn get_msix_cap_idx(&self) -> Option { + if !self.has_capabilities() { + return None; + } + let mut cap_next = self .vfio_wrapper .read_config_byte(PCI_CONFIG_CAPABILITY_OFFSET); @@ -894,6 +904,10 @@ impl VfioCommon { } pub(crate) fn parse_capabilities(&mut self, bdf: PciBdf) { + if !self.has_capabilities() { + return; + } + let mut cap_iter = self .vfio_wrapper .read_config_byte(PCI_CONFIG_CAPABILITY_OFFSET); @@ -1777,6 +1791,10 @@ impl BusDevice for VfioPciDevice { } } +// Offset of the 16-bit status register in the PCI configuration space. +const PCI_CONFIG_STATUS_OFFSET: u32 = 0x06; +// Status bit indicating the presence of a capabilities list. +const PCI_CONFIG_STATUS_CAPABILITIES_LIST: u16 = 1 << 4; // First BAR offset in the PCI config space. const PCI_CONFIG_BAR_OFFSET: u32 = 0x10; // Capability register offset in the PCI config space.