git: f59128775636 - main - iommu_gas: make placeholder entry at the start of the GAS zero size

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 26 Dec 2023 01:28:56 UTC
The branch main has been updated by kib:

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

commit f59128775636846574e092c68e849a56f74577e6
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-12-22 22:19:05 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-12-26 01:28:22 +0000

    iommu_gas: make placeholder entry at the start of the GAS zero size
    
    same as the placeholder at the end.  This is required to allow GAS to
    start at zero, for integration with vmm.
    
    Also, in iommu_gas_remove(), accept placeholders after remove op.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 sys/dev/iommu/iommu_gas.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/sys/dev/iommu/iommu_gas.c b/sys/dev/iommu/iommu_gas.c
index 9a74854f926f..cfd375c658c3 100644
--- a/sys/dev/iommu/iommu_gas.c
+++ b/sys/dev/iommu/iommu_gas.c
@@ -118,7 +118,7 @@ static int
 iommu_gas_cmp_entries(struct iommu_map_entry *a, struct iommu_map_entry *b)
 {
 
-	/* Last entry have zero size, so <= */
+	/* First and last entries have zero size, so <= */
 	KASSERT(a->start <= a->end, ("inverted entry %p (%jx, %jx)",
 	    a, (uintmax_t)a->start, (uintmax_t)a->end));
 	KASSERT(b->start <= b->end, ("inverted entry %p (%jx, %jx)",
@@ -244,25 +244,17 @@ iommu_gas_init_domain(struct iommu_domain *domain)
 	KASSERT(RB_EMPTY(&domain->rb_root),
 	    ("non-empty entries %p", domain));
 
-	/*
-	 * The end entry must be inserted first because it has a zero-length gap
-	 * between start and end.  Initially, all augmentation data for a new
-	 * entry is zero.  Function iommu_gas_augment_entry will compute no
-	 * change in the value of (start-end) and no change in the value of
-	 * free_down, so it will return false to suggest that nothing changed in
-	 * the entry.  Thus, inserting the end entry second prevents
-	 * augmentation information to be propogated to the begin entry at the
-	 * tree root.  So it is inserted first.
-	 */
 	end->start = domain->end;
 	end->end = domain->end;
 	end->flags = IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED;
 	RB_INSERT(iommu_gas_entries_tree, &domain->rb_root, end);
 
 	begin->start = 0;
-	begin->end = IOMMU_PAGE_SIZE;
+	begin->end = 0;
 	begin->flags = IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED;
 	RB_INSERT_PREV(iommu_gas_entries_tree, &domain->rb_root, end, begin);
+	iommu_gas_augment_entry(end);
+	iommu_gas_augment_entry(begin);
 
 	domain->start_gap = begin;
 	domain->first_place = begin;
@@ -739,7 +731,8 @@ iommu_gas_remove_locked(struct iommu_domain *domain,
 
 #ifdef INVARIANTS
 	RB_FOREACH(entry, iommu_gas_entries_tree, &domain->rb_root) {
-		if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0)
+		if ((entry->flags & (IOMMU_MAP_ENTRY_RMRR |
+		    IOMMU_MAP_ENTRY_PLACE)) != 0)
 			continue;
 		KASSERT(entry->end <= start || entry->start >= end,
 		    ("iommu_gas_remove leftover entry (%#jx, %#jx) range "