MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / parse_capabilities

Method parse_capabilities

pci/src/vfio.rs:948–1011  ·  view source on GitHub ↗
(&mut self, bdf: PciBdf)

Source from the content-addressed store, hash-verified

946 }
947
948 fn parse_capabilities(&mut self, bdf: PciBdf) {
949 if !self.has_capabilities() {
950 return;
951 }
952
953 let mut cap_iter = self
954 .vfio_wrapper
955 .read_config_byte(PCI_CONFIG_CAPABILITY_OFFSET)
956 & PCI_CONFIG_CAPABILITY_PTR_MASK;
957
958 let mut pci_express_cap_found = false;
959 let mut power_management_cap_found = false;
960
961 while cap_iter != 0 {
962 let cap_id = self.vfio_wrapper.read_config_byte(cap_iter.into());
963
964 match PciCapabilityId::from(cap_id) {
965 PciCapabilityId::MessageSignalledInterrupts => {
966 if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_MSI_IRQ_INDEX)
967 && irq_info.count > 0
968 {
969 // Parse capability only if the VFIO device
970 // supports MSI.
971 let msg_ctl = self.parse_msi_capabilities(cap_iter);
972 self.initialize_msi(msg_ctl, cap_iter as u32, None);
973 }
974 }
975 PciCapabilityId::MsiX => {
976 if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_MSIX_IRQ_INDEX)
977 && irq_info.count > 0
978 {
979 // Parse capability only if the VFIO device
980 // supports MSI-X.
981 let msix_cap = self.parse_msix_capabilities(cap_iter);
982 self.initialize_msix(msix_cap, cap_iter as u32, bdf, None);
983 }
984 }
985 PciCapabilityId::PciExpress => pci_express_cap_found = true,
986 PciCapabilityId::PowerManagement => power_management_cap_found = true,
987 _ => {}
988 }
989
990 let cap_next = self.vfio_wrapper.read_config_byte((cap_iter + 1).into())
991 & PCI_CONFIG_CAPABILITY_PTR_MASK;
992
993 // Break out of the loop, if we either find the end or we have a broken device. This
994 // doesn't handle all cases where a device might send us in a loop here, but it
995 // handles case of a device returning 0xFF instead of implementing a real
996 // capabilities list.
997 if cap_next == 0 || cap_next == cap_iter {
998 break;
999 }
1000
1001 cap_iter = cap_next;
1002 }
1003
1004 if let Some(clique_id) = self.x_nv_gpudirect_clique {
1005 self.add_nv_gpudirect_clique_cap(cap_iter, clique_id);

Callers 1

newMethod · 0.80

Calls 9

has_capabilitiesMethod · 0.80
read_config_byteMethod · 0.80
initialize_msiMethod · 0.80
initialize_msixMethod · 0.80
get_irq_infoMethod · 0.45

Tested by

no test coverage detected