The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=56b822a17cde5940909633c50623d463191a7852
commit 56b822a17cde5940909633c50623d463191a7852 Author: John Baldwin <j...@freebsd.org> AuthorDate: 2024-06-05 16:50:05 +0000 Commit: John Baldwin <j...@freebsd.org> CommitDate: 2024-06-05 16:50:05 +0000 pci: Only add special VF handling for direct children in bus methods For activate/deactivate resource, use a more standard check at the start of the function since the addition of the PCI_IOV code made this more complex. For the three recently added methods, just add the typical check at the beginning that I missed. This wasn't always fatal as if your system only had PCI device_t's as children of PCI bus devices it would happen to work ok, but if you have a non-PCI child device (e.g. an ATA channel) then dereferencing ivars for non-direct-children could fault. Reported by: Cirrus-CI (via emaste) Reviewed by: emaste Fixes: 871b33ad65ba pci: Consistently use pci_vf_* for suballocated VF memory resources Differential Revision: https://reviews.freebsd.org/D45499 --- sys/dev/pci/pci.c | 55 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 2093d6a8b5ef..9661cfd19db7 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -5695,6 +5695,9 @@ pci_activate_resource(device_t dev, device_t child, struct resource *r) struct pci_devinfo *dinfo; int error, rid, type; + if (device_get_parent(child) != dev) + return (bus_generic_activate_resource(dev, child, r)); + dinfo = device_get_ivars(child); #ifdef PCI_IOV if (dinfo->cfg.flags & PCICFG_VF) { @@ -5716,20 +5719,20 @@ pci_activate_resource(device_t dev, device_t child, struct resource *r) if (error) return (error); + rid = rman_get_rid(r); + type = rman_get_type(r); + + /* Device ROMs need their decoding explicitly enabled. */ + if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid)) + pci_write_bar(child, pci_find_bar(child, rid), + rman_get_start(r) | PCIM_BIOS_ENABLE); + /* Enable decoding in the command register when activating BARs. */ - if (device_get_parent(child) == dev) { - /* Device ROMs need their decoding explicitly enabled. */ - rid = rman_get_rid(r); - type = rman_get_type(r); - if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid)) - pci_write_bar(child, pci_find_bar(child, rid), - rman_get_start(r) | PCIM_BIOS_ENABLE); - switch (type) { - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - error = PCI_ENABLE_IO(dev, child, type); - break; - } + switch (type) { + case SYS_RES_IOPORT: + case SYS_RES_MEMORY: + error = PCI_ENABLE_IO(dev, child, type); + break; } return (error); } @@ -5740,6 +5743,9 @@ pci_deactivate_resource(device_t dev, device_t child, struct resource *r) struct pci_devinfo *dinfo; int error, rid, type; + if (device_get_parent(child) != dev) + return (bus_generic_deactivate_resource(dev, child, r)); + dinfo = device_get_ivars(child); #ifdef PCI_IOV if (dinfo->cfg.flags & PCICFG_VF) { @@ -5762,13 +5768,11 @@ pci_deactivate_resource(device_t dev, device_t child, struct resource *r) return (error); /* Disable decoding for device ROMs. */ - if (device_get_parent(child) == dev) { - rid = rman_get_rid(r); - type = rman_get_type(r); - if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid)) - pci_write_bar(child, pci_find_bar(child, rid), - rman_get_start(r)); - } + rid = rman_get_rid(r); + type = rman_get_type(r); + if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid)) + pci_write_bar(child, pci_find_bar(child, rid), + rman_get_start(r)); return (0); } @@ -5779,6 +5783,10 @@ pci_adjust_resource(device_t dev, device_t child, struct resource *r, { struct pci_devinfo *dinfo; + if (device_get_parent(child) != dev) + return (bus_generic_adjust_resource(dev, child, r, start, + end)); + dinfo = device_get_ivars(child); if (dinfo->cfg.flags & PCICFG_VF) { switch (rman_get_type(r)) { @@ -5802,6 +5810,10 @@ pci_map_resource(device_t dev, device_t child, struct resource *r, { struct pci_devinfo *dinfo; + if (device_get_parent(child) != dev) + return (bus_generic_map_resource(dev, child, r, argsp, + map)); + dinfo = device_get_ivars(child); if (dinfo->cfg.flags & PCICFG_VF) { switch (rman_get_type(r)) { @@ -5825,6 +5837,9 @@ pci_unmap_resource(device_t dev, device_t child, struct resource *r, { struct pci_devinfo *dinfo; + if (device_get_parent(child) != dev) + return (bus_generic_unmap_resource(dev, child, r, map)); + dinfo = device_get_ivars(child); if (dinfo->cfg.flags & PCICFG_VF) { switch (rman_get_type(r)) {