Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F46028142
kib.diff
dougm (Doug Moore)
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
dougm
Aug 2 2022, 9:14 PM
2022-08-02 21:14:01 (UTC+0)
Size
3 KB
Referenced Files
None
Subscribers
None
kib.diff
View Options
diff --git a/sys/dev/iommu/iommu_gas.c b/sys/dev/iommu/iommu_gas.c
index bad56ab9140e..6cffd62d5b8c 100644
--- a/sys/dev/iommu/iommu_gas.c
+++ b/sys/dev/iommu/iommu_gas.c
@@ -600,6 +600,100 @@ iommu_gas_free_region(struct iommu_map_entry *entry)
IOMMU_DOMAIN_UNLOCK(domain);
}
+static void
+iommu_gas_remove_entry_locked(struct iommu_domain *domain,
+ struct iommu_map_entry *entry)
+{
+ if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0)
+ return;
+ iommu_gas_free_space(entry);
+ domain->ops->unmap(domain, entry->start, entry->end - entry->start,
+ IOMMU_PGF_WAITOK);
+ if ((entry->flags & IOMMU_MAP_ENTRY_PLACE) == 0)
+ iommu_gas_free_entry(entry);
+}
+
+static void
+iommu_gas_remove_locked(struct iommu_domain *domain, iommu_gaddr_t start,
+ iommu_gaddr_t end, struct iommu_map_entry **r)
+{
+ struct iommu_map_entry *entry, fentry;
+
+ IOMMU_DOMAIN_ASSERT_LOCKED(domain);
+ MPASS(start <= end);
+ MPASS(end <= domain->last_place->end);
+
+ /*
+ * Find an entry which contains the supplied guest's address
+ * start, or the first entry after the start. Since we
+ * asserted that start is below domain end, entry should
+ * exist. Then clip it if needed.
+ */
+ fentry.start = start + 1;
+ fentry.end = start + 1;
+ entry = RB_NFIND(iommu_gas_entries_tree, &domain->rb_root, &fentry);
+ MPASS(start <= entry->start || (entry->start <= start &&
+ start <= entry->end));
+
+ if (entry->start < start) {
+ if (end < entry->end)
+ **r = *entry;
+ entry->end = start;
+ RB_UPDATE_AUGMENT(entry, rb_entry);
+ if (end < entry->end) {
+ (*r)->start = end;
+ iommu_gas_rb_insert(domain, *r);
+ *r = NULL;
+ return;
+ }
+ entry = iommu_gas_entries_tree_RB_NEXT(entry);
+ }
+
+ RB_FOREACH_FROM(entry, iommu_gas_entries_tree, entry) {
+ if (entry->end >= end)
+ break;
+ KASSERT(start <= entry->start,
+ ("iommu_gas_remove entry (%#jx, %#jx) start %#jx",
+ entry->start, entry->end, start));
+ KASSERT(entry->end <= end,
+ ("iommu_gas_remove entry (%#jx, %#jx) end %#jx",
+ entry->start, entry->end, end));
+ iommu_gas_remove_entry_locked(domain, entry);
+ }
+
+ if (entry->start < end) {
+ entry->start = end;
+ RB_UPDATE_AUGMENT(entry, rb_entry);
+ }
+
+#ifdef INVARIANTS
+ RB_FOREACH(entry, iommu_gas_entries_tree, &domain->rb_root) {
+ if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0)
+ continue;
+ KASSERT(entry->end <= start || entry->start >= end,
+ ("iommu_gas_remove leftover entry (%#jx, %#jx) range "
+ "(%#jx, %#jx)",
+ entry->start, entry->end, start, end));
+ }
+#endif
+}
+
+void
+iommu_gas_remove(struct iommu_domain *domain, iommu_gaddr_t start,
+ iommu_gaddr_t size)
+{
+ struct iommu_map_entry *r;
+ iommu_gaddr_t end;
+
+ end = start + size;
+ r = iommu_gas_alloc_entry(domain, IOMMU_PGF_WAITOK);
+ IOMMU_DOMAIN_LOCK(domain);
+ iommu_gas_remove_locked(domain, start, end, &r);
+ IOMMU_DOMAIN_UNLOCK(domain);
+ if (r != NULL)
+ iommu_gas_free_entry(r);
+}
+
int
iommu_gas_map(struct iommu_domain *domain,
const struct bus_dma_tag_common *common, iommu_gaddr_t size, int offset,
File Metadata
Details
Attached
Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5026269
Default Alt Text
kib.diff (3 KB)
Attached To
Mode
D36001: iommu_gas: add iommu_gas_remove()
Attached
Detach File
Event Timeline
Log In to Comment