Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F116025300
D35440.id106788.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D35440.id106788.diff
View Options
Index: sys/dev/iommu/iommu_gas.c
===================================================================
--- sys/dev/iommu/iommu_gas.c
+++ sys/dev/iommu/iommu_gas.c
@@ -301,61 +301,45 @@
iommu_gas_match_one(struct iommu_gas_match_args *a, iommu_gaddr_t beg,
iommu_gaddr_t end, iommu_gaddr_t maxaddr)
{
- iommu_gaddr_t bs, start;
-
- a->entry->start = roundup2(beg + IOMMU_PAGE_SIZE,
- a->common->alignment);
- if (a->entry->start + a->offset + a->size > maxaddr)
- return (false);
+ iommu_gaddr_t first, start;
+ bool found __diagused;
- /* IOMMU_PAGE_SIZE to create gap after new entry. */
- if (a->entry->start < beg + IOMMU_PAGE_SIZE ||
- a->entry->start + a->size + a->offset + IOMMU_PAGE_SIZE > end)
+ /* IOMMU_PAGE_SIZE to create gaps before, after new entry. */
+ beg += IOMMU_PAGE_SIZE;
+ first = start = roundup2(beg, a->common->alignment);
+ end = ummin(end - IOMMU_PAGE_SIZE, maxaddr);
+ if (start + a->size + a->offset > end)
return (false);
- /* No boundary crossing. */
- if (vm_addr_bound_ok(a->entry->start + a->offset, a->size,
- a->common->boundary))
- return (true);
-
- /*
- * The start + offset to start + offset + size region crosses
- * the boundary. Check if there is enough space after the
- * next boundary after the beg.
- */
- bs = rounddown2(a->entry->start + a->offset + a->common->boundary,
- a->common->boundary);
- start = roundup2(bs, a->common->alignment);
- /* IOMMU_PAGE_SIZE to create gap after new entry. */
- if (start + a->offset + a->size + IOMMU_PAGE_SIZE <= end &&
- start + a->offset + a->size <= maxaddr &&
- vm_addr_bound_ok(start + a->offset, a->size,
+ /* Check for and try to skip past boundary crossing. */
+ if (!vm_addr_bound_ok(start + a->offset, a->size,
a->common->boundary)) {
- a->entry->start = start;
- return (true);
+ /*
+ * The start + offset to start + offset + size region crosses
+ * the boundary. Check if there is enough space after the next
+ * boundary after the beg.
+ */
+ beg = roundup2(start + a->offset + 1, a->common->boundary);
+ start = roundup2(beg, a->common->alignment);
}
- /*
- * Not enough space to align at the requested boundary, or
- * boundary is smaller than the size, but allowed to split.
- * We already checked that start + size does not overlap maxaddr.
- *
- * XXXKIB. It is possible that bs is exactly at the start of
- * the next entry, then we do not have gap. Ignore for now.
- */
- if ((a->gas_flags & IOMMU_MF_CANSPLIT) != 0) {
- a->size = bs - a->entry->start;
- return (true);
+ if (start + a->offset + a->size > end ||
+ !vm_addr_bound_ok(start + a->offset, a->size,
+ a->common->boundary)) {
+ /*
+ * Not enough space to align at the requested boundary, or
+ * boundary is smaller than the size, but allowed to split. We
+ * already checked that start + size does not overlap maxaddr.
+ *
+ * XXXKIB. It is possible that beg is exactly at the start of
+ * the next entry, then we do not have gap. Ignore for now.
+ */
+ if ((a->gas_flags & IOMMU_MF_CANSPLIT) == 0)
+ return (false);
+ a->size = beg - first;
+ start = first;
}
- return (false);
-}
-
-static void
-iommu_gas_match_insert(struct iommu_gas_match_args *a)
-{
- bool found __diagused;
-
/*
* The prev->end is always aligned on the page size, which
* causes page alignment for the entry->start too. The size
@@ -364,12 +348,14 @@
* 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->start = start;
+ a->entry->end = start + a->size;
found = iommu_gas_rb_insert(a->domain, a->entry);
KASSERT(found, ("found dup %p start %jx size %jx",
- a->domain, (uintmax_t)a->entry->start, (uintmax_t)a->size));
+ a->domain, (uintmax_t)start, (uintmax_t)a->size));
a->entry->flags = IOMMU_MAP_ENTRY_MAP;
+ return (true);
}
static int
@@ -390,17 +376,13 @@
return (0);
if (child != NULL && entry->end < a->common->lowaddr &&
iommu_gas_match_one(a, entry->end, child->first,
- a->common->lowaddr)) {
- iommu_gas_match_insert(a);
+ a->common->lowaddr))
return (0);
- }
child = RB_LEFT(entry, rb_entry);
if (child != NULL && child->last < a->common->lowaddr &&
iommu_gas_match_one(a, child->last, entry->start,
- a->common->lowaddr)) {
- iommu_gas_match_insert(a);
+ a->common->lowaddr))
return (0);
- }
if (child != NULL && 0 == iommu_gas_lowermatch(a, child))
return (0);
return (ENOMEM);
@@ -424,17 +406,13 @@
return (0);
if (child != NULL && child->last >= a->common->highaddr &&
iommu_gas_match_one(a, child->last, entry->start,
- a->domain->end)) {
- iommu_gas_match_insert(a);
+ a->domain->end))
return (0);
- }
child = RB_RIGHT(entry, rb_entry);
if (child != NULL && entry->end >= a->common->highaddr &&
iommu_gas_match_one(a, entry->end, child->first,
- a->domain->end)) {
- iommu_gas_match_insert(a);
+ a->domain->end))
return (0);
- }
if (child != NULL && 0 == iommu_gas_uppermatch(a, child))
return (0);
return (ENOMEM);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, May 2, 6:37 PM (11 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17910017
Default Alt Text
D35440.id106788.diff (5 KB)
Attached To
Mode
D35440: iommu_gas: simplify match_one, merge insert into it, drop uppermatch
Attached
Detach File
Event Timeline
Log In to Comment