Hi! I am having an issue with capabilities (hopefully the chunk formatting won't break).
The problem is that when virtio_pci_find_capability() reads pci_find_capability(dev, PCI_CAP_ID_VNDR), 0 is returned; if repeated, it returns a valid number (0x84). Timing seems to matter. pci_cfg_read trace shows that that first time read does not reach QEMU but others do reach QEMU and return what is expected. How to debug this, any quick ideas? The config space is not a MMIO BAR or KVM memory slot or anything like this, right? :) Thanks, [ 3.489492] ___K___ (0) virtio_pci_modern_probe 642 [ 3.489697] ___K___ (0) virtio_pci_find_capability 492: FIND a cap [ 3.490070] ___K___ (0) virtio_pci_find_capability 494: cap is at 0 [ 3.490335] ___K___ (0) virtio_pci_find_capability 492: FIND a cap 10909@1576216763.643271:pci_cfg_read virtio-net-pci 00:0 @0x6 -> 0x10 10909@1576216763.643431:pci_cfg_read virtio-net-pci 00:0 @0x34 -> 0x98 10909@1576216763.643591:pci_cfg_read virtio-net-pci 00:0 @0x98 -> 0x8411 10909@1576216763.643747:pci_cfg_read virtio-net-pci 00:0 @0x84 -> 0x7009 [ 3.491264] ___K___ (0) virtio_pci_find_capability 494: cap is at 132 10909@1576216763.644140:pci_cfg_read virtio-net-pci 00:0 @0x87 -> 0x5 10909@1576216763.644287:pci_cfg_read virtio-net-pci 00:0 @0x88 -> 0x0 [ 3.491803] ___K___ (0) virtio_pci_find_capability 506: 5 0 10909@1576216763.644632:pci_cfg_read virtio-net-pci 00:0 @0x85 -> 0x70 10909@1576216763.644786:pci_cfg_read virtio-net-pci 00:0 @0x70 -> 0x6009 10909@1576216763.644942:pci_cfg_read virtio-net-pci 00:0 @0x73 -> 0x2 10909@1576216763.645092:pci_cfg_read virtio-net-pci 00:0 @0x74 -> 0x4 [ 3.492607] ___K___ (0) virtio_pci_find_capability 506: 2 4 diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 7abcc50838b8..85b2a7ce96e9 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -486,9 +486,14 @@ static const struct virtio_config_ops virtio_pci_config_ops = { static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 cfg_type, u32 ioresource_types, int *bars) { - int pos; + int pos = 0;// = pci_find_capability(dev, PCI_CAP_ID_VNDR); - for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); + while (!pos) { + pr_err("___K___ (%u) %s %u: FIND a cap\n", smp_processor_id(), __func__, __LINE__); + pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); + pr_err("___K___ (%u) %s %u: cap is at %d\n", smp_processor_id(), __func__, __LINE__, pos); + } + for (; pos > 0; pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) { u8 type, bar; -- Alexey