git: 2d8b9313f47e - stable/13 - iommu_gas: pass size to iommu_map without rounding

From: Doug Moore <dougm_at_FreeBSD.org>
Date: Wed, 06 Jul 2022 17:05:01 UTC
The branch stable/13 has been updated by dougm:

URL: https://cgit.FreeBSD.org/src/commit/?id=2d8b9313f47e0ae9223f060b8363e18eb7ff1908

commit 2d8b9313f47e0ae9223f060b8363e18eb7ff1908
Author:     Doug Moore <dougm@FreeBSD.org>
AuthorDate: 2022-06-10 18:56:54 +0000
Commit:     Doug Moore <dougm@FreeBSD.org>
CommitDate: 2022-07-06 16:41:50 +0000

    iommu_gas: pass size to iommu_map without rounding
    
    Let the caller to iommu_map pass the size parameter without rounding
    it up to a multiple of page size.  Let iommu_map round it up when
    necessary, which is not all of the time, so that in some cases less
    space is reserved.
    
    Reviewed by:    alc, kib (previous version)
    Tested by:      pho, br
    Discussed with: andrew
    MFC after:      3 weeks
    Differential Revision:  https://reviews.freebsd.org/D35424
    
    (cherry picked from commit 19bb5a7244ff0374f44068a20df9393a1c88de5d)
---
 sys/arm64/arm64/gicv3_its.c  |  3 ++-
 sys/dev/iommu/busdma_iommu.c |  3 +--
 sys/dev/iommu/iommu_gas.c    | 10 ++++++----
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/sys/arm64/arm64/gicv3_its.c b/sys/arm64/arm64/gicv3_its.c
index 35a5642a95dc..2af20e5d03fc 100644
--- a/sys/arm64/arm64/gicv3_its.c
+++ b/sys/arm64/arm64/gicv3_its.c
@@ -1457,7 +1457,8 @@ gicv3_iommu_init(device_t dev, device_t child, struct iommu_domain **domain)
 	ctx = iommu_get_dev_ctx(child);
 	if (ctx == NULL)
 		return (ENXIO);
-	error = iommu_map_msi(ctx, PAGE_SIZE, GITS_TRANSLATER,
+	/* Map the page containing the GITS_TRANSLATER register. */
+	error = iommu_map_msi(ctx, PAGE_SIZE, 0,
 	    IOMMU_MAP_ENTRY_WRITE, IOMMU_MF_CANWAIT, &sc->ma);
 	*domain = iommu_get_ctx_domain(ctx);
 
diff --git a/sys/dev/iommu/busdma_iommu.c b/sys/dev/iommu/busdma_iommu.c
index 89e5e1bcff39..da2318eac393 100644
--- a/sys/dev/iommu/busdma_iommu.c
+++ b/sys/dev/iommu/busdma_iommu.c
@@ -593,8 +593,7 @@ iommu_bus_dmamap_load_something1(struct bus_dma_tag_iommu *tag,
 		if (seg + 1 < tag->common.nsegments)
 			gas_flags |= IOMMU_MF_CANSPLIT;
 
-		error = iommu_map(domain, &tag->common,
-		    round_page(offset + buflen1),
+		error = iommu_map(domain, &tag->common, buflen1,
 		    offset, e_flags, gas_flags, ma + idx, &entry);
 		if (error != 0)
 			break;
diff --git a/sys/dev/iommu/iommu_gas.c b/sys/dev/iommu/iommu_gas.c
index d1a46ab6ee8f..f7c38e8d65e8 100644
--- a/sys/dev/iommu/iommu_gas.c
+++ b/sys/dev/iommu/iommu_gas.c
@@ -364,7 +364,8 @@ iommu_gas_match_insert(struct iommu_gas_match_args *a)
 	 * The page sized gap is created between consequent
 	 * allocations to ensure that out-of-bounds accesses fault.
 	 */
-	a->entry->end = a->entry->start + a->size;
+	a->entry->end = a->entry->start +
+	    roundup2(a->size + a->offset, IOMMU_PAGE_SIZE);
 
 	found = iommu_gas_rb_insert(a->domain, a->entry);
 	KASSERT(found, ("found dup %p start %jx size %jx",
@@ -381,7 +382,8 @@ iommu_gas_lowermatch(struct iommu_gas_match_args *a, struct iommu_map_entry *ent
 	 * If the subtree doesn't have free space for the requested allocation
 	 * plus two guard pages, give up.
 	 */
-	if (entry->free_down < a->size + a->offset + 2 * IOMMU_PAGE_SIZE)
+	if (entry->free_down < 2 * IOMMU_PAGE_SIZE +
+	    roundup2(a->size + a->offset, IOMMU_PAGE_SIZE))
 		return (ENOMEM);
 	if (entry->first >= a->common->lowaddr)
 		return (ENOMEM);
@@ -415,7 +417,8 @@ iommu_gas_uppermatch(struct iommu_gas_match_args *a, struct iommu_map_entry *ent
 	 * If the subtree doesn't have free space for the requested allocation
 	 * plus two guard pages, give up.
 	 */
-	if (entry->free_down < a->size + a->offset + 2 * IOMMU_PAGE_SIZE)
+	if (entry->free_down < 2 * IOMMU_PAGE_SIZE +
+	    roundup2(a->size + a->offset, IOMMU_PAGE_SIZE))
 		return (ENOMEM);
 	if (entry->last < a->common->highaddr)
 		return (ENOMEM);
@@ -450,7 +453,6 @@ iommu_gas_find_space(struct iommu_domain *domain,
 
 	IOMMU_DOMAIN_ASSERT_LOCKED(domain);
 	KASSERT(entry->flags == 0, ("dirty entry %p %p", domain, entry));
-	KASSERT((size & IOMMU_PAGE_MASK) == 0, ("size %jx", (uintmax_t)size));
 
 	a.domain = domain;
 	a.size = size;