Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Feb 2025 14:17:28 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 1c3996e87f09 - stable/14 - acpi/pci/vmd: Fix a nit with nested resource mapping requests
Message-ID:  <202502271417.51REHSl1017430@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=1c3996e87f09a5e67ebbd4e7e73a38848127c99e

commit 1c3996e87f09a5e67ebbd4e7e73a38848127c99e
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-06-04 23:50:56 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-02-27 13:09:23 +0000

    acpi/pci/vmd: Fix a nit with nested resource mapping requests
    
    Some bus drivers use rmans to suballocate resources to child devices.
    When the driver for a child device requests a mapping for a
    suballocated resource, the bus driver translates this into a mapping
    request for a suitable subrange of the original resource the bus
    driver allocated from its parent.  This nested mapping request should
    look like any other resource mapping request being made by the bus
    device (i.e. as if the bus device had called bus_map_resource() or
    bus_alloc_resource() with RF_ACTIVE).
    
    I had slightly flubbed this last bit though since the direct use of
    bus_generic_map/unmap_resource passed up the original child device
    (second argument to the underlying kobj interface).  While this is
    currently harmless, it is not strictly correct as the resource being
    mapped is owned by the bus device, not the child and can break for
    other bus drivers in the future.
    
    Instead, use bus_map/unmap_resource for the nested request where the
    requesting device is now the bus device that owns the parent resource.
    
    Reviewed by:    imp
    Fixes:          0e1246e33461 acpi: Cleanup handling of suballocated resources
    Fixes:          b377ff8110e3 pcib: Refine handling of resources allocated from bridge windows
    Fixes:          d79b6b8ec267 pci_host_generic: Don't rewrite resource start address for translation
    Fixes:          d714e73f7895 vmd: Use bus_generic_rman_* for PCI bus and memory resources
    Differential Revision:  https://reviews.freebsd.org/D45433
    (cherry picked from commit 98056127ddfa36720bcf46edc09843c867784bcb)
---
 sys/dev/acpica/acpi.c          | 17 ++++++++++-------
 sys/dev/pci/pci_host_generic.c | 17 ++++++++---------
 sys/dev/pci/pci_pci.c          | 16 +++++++++-------
 sys/dev/vmd/vmd.c              |  9 +++++----
 4 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index de6520331644..2ba2b2c8c642 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -1671,19 +1671,22 @@ acpi_map_resource(device_t bus, device_t child, int type, struct resource *r,
 
 	args.offset = start - rman_get_start(sysres);
 	args.length = length;
-	return (bus_generic_map_resource(bus, child, type, sysres, &args, map));
+	return (bus_map_resource(bus, sysres, &args, map));
 }
 
 static int
 acpi_unmap_resource(device_t bus, device_t child, int type, struct resource *r,
     struct resource_map *map)
 {
-	if (acpi_is_resource_managed(bus, r)) {
-		r = acpi_managed_resource(bus, type, r);
-		if (r == NULL)
-			return (ENOENT);
-	}
-	return (bus_generic_unmap_resource(bus, child, type, r, map));
+	struct resource *sysres;
+
+	if (!acpi_is_resource_managed(bus, r))
+		return (bus_generic_unmap_resource(bus, child, type, r, map));
+
+	sysres = acpi_managed_resource(bus, type, r);
+	if (sysres == NULL)
+		return (ENOENT);
+	return (bus_unmap_resource(bus, sysres, map));
 }
 
 /* Allocate an IO port or memory resource, given its GAS. */
diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c
index 4b7a1cb8ab39..4fd8c3b42250 100644
--- a/sys/dev/pci/pci_host_generic.c
+++ b/sys/dev/pci/pci_host_generic.c
@@ -654,8 +654,7 @@ generic_pcie_map_resource(device_t dev, device_t child, int type,
 
 	args.offset = start - range->pci_base;
 	args.length = length;
-	return (bus_generic_map_resource(dev, child, type, range->res, &args,
-	    map));
+	return (bus_map_resource(dev, range->res, &args, map));
 }
 
 static int
@@ -671,16 +670,16 @@ generic_pcie_unmap_resource(device_t dev, device_t child, int type,
 #endif
 	case SYS_RES_IOPORT:
 	case SYS_RES_MEMORY:
-		range = generic_pcie_containing_range(dev, type,
-		    rman_get_start(r), rman_get_end(r));
-		if (range == NULL || range->res == NULL)
-			return (ENOENT);
-		r = range->res;
 		break;
 	default:
-		break;
+		return (bus_generic_unmap_resource(dev, child, type, r, argsp, map));
 	}
-	return (bus_generic_unmap_resource(dev, child, type, r, map));
+
+	range = generic_pcie_containing_range(dev, type, rman_get_start(r),
+	    rman_get_end(r));
+	if (range == NULL || range->res == NULL)
+		return (ENOENT);
+	return (bus_unmap_resource(dev, range->res, map));
 }
 
 static bus_dma_tag_t
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index da09a917b9bc..06e8c2bc8433 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -2553,7 +2553,7 @@ pcib_map_resource(device_t dev, device_t child, int type, struct resource *r,
 
 	args.offset = start - rman_get_start(pres);
 	args.length = length;
-	return (bus_generic_map_resource(dev, child, type, pres, &args, map));
+	return (bus_map_resource(dev, pres, &args, map));
 }
 
 static int
@@ -2562,14 +2562,16 @@ pcib_unmap_resource(device_t dev, device_t child, int type, struct resource *r,
 {
 	struct pcib_softc *sc = device_get_softc(dev);
 	struct pcib_window *w;
+	struct resource *pres;
 
 	w = pcib_get_resource_window(sc, r);
-	if (w != NULL) {
-		r = pcib_find_parent_resource(w, r);
-		if (r == NULL)
-			return (ENOENT);
-	}
-	return (bus_generic_unmap_resource(dev, child, type, r, map));
+	if (w == NULL)
+		return (bus_generic_unmap_resource(dev, child, type, r, map));
+
+	pres = pcib_find_parent_resource(w, r);
+	if (pres == NULL)
+		return (ENOENT);
+	return (bus_unmap_resource(dev, pres, map));
 }
 #else
 /*
diff --git a/sys/dev/vmd/vmd.c b/sys/dev/vmd/vmd.c
index d513d3ea5a5a..b5a77cd5ad4e 100644
--- a/sys/dev/vmd/vmd.c
+++ b/sys/dev/vmd/vmd.c
@@ -552,7 +552,7 @@ vmd_map_resource(device_t dev, device_t child, int type, struct resource *r,
 
 	args.offset = start - rman_get_start(pres);
 	args.length = length;
-	return (bus_generic_map_resource(dev, child, type, pres, &args, map));
+	return (bus_map_resource(dev, pres, &args, map));
 }
 
 static int
@@ -560,11 +560,12 @@ vmd_unmap_resource(device_t dev, device_t child, int type, struct resource *r,
     struct resource_map *map)
 {
 	struct vmd_softc *sc = device_get_softc(dev);
+	struct resource *pres;
 
-	r = vmd_find_parent_resource(sc, r);
-	if (r == NULL)
+	pres = vmd_find_parent_resource(sc, r);
+	if (pres == NULL)
 		return (ENOENT);
-	return (bus_generic_unmap_resource(dev, child, type, r, map));
+	return (bus_unmap_resource(dev, pres, map));
 }
 
 static int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502271417.51REHSl1017430>