git: 60662799b126 - stable/14 - pci: Only add special VF handling for direct children in bus methods
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 27 Feb 2025 14:17:31 UTC
The branch stable/14 has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=60662799b1268ddbed2896223a77493b8def436c
commit 60662799b1268ddbed2896223a77493b8def436c
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-06-05 16:50:05 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-02-27 13:09:23 +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
(cherry picked from commit 56b822a17cde5940909633c50623d463191a7852)
---
sys/dev/pci/pci.c | 48 ++++++++++++++++++++++++++++++++----------------
1 file changed, 32 insertions(+), 16 deletions(-)
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 8ff31beca696..4be3210840fc 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -5702,6 +5702,10 @@ pci_activate_resource(device_t dev, device_t child, int type, int rid,
struct pci_devinfo *dinfo;
int error;
+ if (device_get_parent(child) != dev)
+ return (bus_generic_activate_resource(dev, child, type, rid,
+ r));
+
dinfo = device_get_ivars(child);
#ifdef PCI_IOV
if (dinfo->cfg.flags & PCICFG_VF) {
@@ -5724,18 +5728,17 @@ pci_activate_resource(device_t dev, device_t child, int type, int rid,
if (error)
return (error);
+ /* 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. */
- 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);
}
@@ -5747,6 +5750,10 @@ pci_deactivate_resource(device_t dev, device_t child, int type,
struct pci_devinfo *dinfo;
int error;
+ if (device_get_parent(child) != dev)
+ return (bus_generic_deactivate_resource(dev, child, type, rid,
+ r));
+
dinfo = device_get_ivars(child);
#ifdef PCI_IOV
if (dinfo->cfg.flags & PCICFG_VF) {
@@ -5771,11 +5778,9 @@ pci_deactivate_resource(device_t dev, device_t child, int type,
return (error);
/* Disable decoding for device ROMs. */
- if (device_get_parent(child) == dev) {
- if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid))
- pci_write_bar(child, pci_find_bar(child, rid),
- rman_get_start(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);
}
@@ -5786,6 +5791,10 @@ pci_adjust_resource(device_t dev, device_t child, int type, struct resource *r,
{
struct pci_devinfo *dinfo;
+ if (device_get_parent(child) != dev)
+ return (bus_generic_adjust_resource(dev, child, type, r, start,
+ end));
+
dinfo = device_get_ivars(child);
if (dinfo->cfg.flags & PCICFG_VF) {
switch (rman_get_type(r)) {
@@ -5809,6 +5818,10 @@ pci_map_resource(device_t dev, device_t child, int type, struct resource *r,
{
struct pci_devinfo *dinfo;
+ if (device_get_parent(child) != dev)
+ return (bus_generic_map_resource(dev, child, type, r, argsp,
+ map));
+
dinfo = device_get_ivars(child);
if (dinfo->cfg.flags & PCICFG_VF) {
switch (rman_get_type(r)) {
@@ -5832,6 +5845,9 @@ pci_unmap_resource(device_t dev, device_t child, int type, struct resource *r,
{
struct pci_devinfo *dinfo;
+ if (device_get_parent(child) != dev)
+ return (bus_generic_unmap_resource(dev, child, type, r, map));
+
dinfo = device_get_ivars(child);
if (dinfo->cfg.flags & PCICFG_VF) {
switch (rman_get_type(r)) {