Page MenuHomeFreeBSD

D60098.id187906.diff
No OneTemporary

D60098.id187906.diff

diff --git a/FreeBSD/sys/arm64/arm64/busdma_bounce.c b/FreeBSD/sys/arm64/arm64/busdma_bounce.c
--- a/FreeBSD/sys/arm64/arm64/busdma_bounce.c
+++ b/FreeBSD/sys/arm64/arm64/busdma_bounce.c
@@ -69,6 +69,7 @@
BF_KMEM_ALLOC_CONTIG = 0x08,
BF_KMEM_ALLOC = BF_KMEM_ALLOC_PAGES | BF_KMEM_ALLOC_CONTIG,
BF_COHERENT = 0x10,
+ BF_FORCE_MAP = 0x20,
};
struct bounce_page;
@@ -115,6 +116,10 @@
struct sync_list slist[];
};
+static struct bus_dmamap nobounce_dmamap = {
+ .flags = DMAMAP_COHERENT,
+};
+
static bool _bus_dmamap_pagesneeded(bus_dma_tag_t dmat, bus_dmamap_t map,
vm_paddr_t buf, bus_size_t buflen, int *pagesneeded);
static void _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
@@ -278,6 +283,11 @@
newtag->map_count = 0;
newtag->segments = NULL;
+#ifdef KMSAN
+ /* KMSAN stores the memory descriptor in the map. */
+ newtag->bounce_flags |= BF_FORCE_MAP;
+#endif
+
if ((flags & BUS_DMA_COHERENT) != 0) {
newtag->bounce_flags |= BF_COHERENT;
}
@@ -412,13 +422,22 @@
}
}
- *mapp = alloc_dmamap(dmat, M_NOWAIT);
- if (*mapp == NULL) {
- CTR3(KTR_BUSDMA, "%s: tag %p error %d",
- __func__, dmat, ENOMEM);
- return (ENOMEM);
+ if ((dmat->bounce_flags &
+ (BF_COULD_BOUNCE | BF_COHERENT | BF_FORCE_MAP)) == BF_COHERENT &&
+ !in_realm()) {
+ *mapp = NULL;
+ } else {
+ *mapp = alloc_dmamap(dmat, M_NOWAIT);
+ if (*mapp == NULL) {
+ CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+ __func__, dmat, ENOMEM);
+ return (ENOMEM);
+ }
}
+ if (*mapp == NULL)
+ goto out;
+
/*
* Bouncing might be required if the driver asks for an active
* exclusion region, a data alignment that is stricter than 1, and/or
@@ -459,9 +478,11 @@
}
bz->map_count++;
+out:
if (error == 0) {
dmat->map_count++;
- if ((dmat->bounce_flags & BF_COHERENT) != 0)
+ if (*mapp != NULL &&
+ (dmat->bounce_flags & BF_COHERENT) != 0)
(*mapp)->flags |= DMAMAP_COHERENT;
} else {
free(*mapp, M_DEVBUF);
@@ -479,17 +500,19 @@
bounce_bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
{
- /* Check we are destroying the correct map type */
- if ((map->flags & DMAMAP_FROM_DMAMEM) != 0)
- panic("bounce_bus_dmamap_destroy: Invalid map freed\n");
-
- if (STAILQ_FIRST(&map->bpages) != NULL || map->sync_count != 0) {
- CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, EBUSY);
- return (EBUSY);
+ if (map != NULL && map != &nobounce_dmamap) {
+ if ((map->flags & DMAMAP_FROM_DMAMEM) != 0)
+ panic("bounce_bus_dmamap_destroy: Invalid map freed\n");
+ if (STAILQ_FIRST(&map->bpages) != NULL ||
+ map->sync_count != 0) {
+ CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__,
+ dmat, EBUSY);
+ return (EBUSY);
+ }
+ if (dmat->bounce_zone != NULL)
+ dmat->bounce_zone->map_count--;
+ free(map, M_DEVBUF);
}
- if (dmat->bounce_zone)
- dmat->bounce_zone->map_count--;
- free(map, M_DEVBUF);
dmat->map_count--;
CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
return (0);
@@ -748,6 +771,14 @@
bus_addr_t curaddr, sl_end;
int error;
+ if (map == NULL) {
+ KASSERT((dmat->bounce_flags &
+ (BF_COULD_BOUNCE | BF_COHERENT | BF_FORCE_MAP)) ==
+ BF_COHERENT && !in_realm(),
+ ("%s: invalid NULL map for tag %p", __func__, dmat));
+ map = &nobounce_dmamap;
+ }
+
if (segs == NULL)
segs = dmat->segments;
@@ -831,6 +862,14 @@
char *kvaddr, *vaddr, *sl_vend;
int error;
+ if (map == NULL) {
+ KASSERT((dmat->bounce_flags &
+ (BF_COULD_BOUNCE | BF_COHERENT | BF_FORCE_MAP)) ==
+ BF_COHERENT && !in_realm(),
+ ("%s: invalid NULL map for tag %p", __func__, dmat));
+ map = &nobounce_dmamap;
+ }
+
KASSERT((map->flags & DMAMAP_FROM_DMAMEM) != 0 ||
dmat->common.alignment <= PAGE_SIZE,
("loading user buffer with alignment bigger than PAGE_SIZE is not "
@@ -839,7 +878,7 @@
if (segs == NULL)
segs = dmat->segments;
- if (flags & BUS_DMA_LOAD_MBUF)
+ if ((flags & BUS_DMA_LOAD_MBUF) != 0 && map != &nobounce_dmamap)
map->flags |= DMAMAP_MBUF;
if (might_bounce(dmat, map, (bus_addr_t)buf, buflen)) {
@@ -938,6 +977,8 @@
struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg)
{
+ if (map == NULL)
+ return;
map->mem = *mem;
map->dmat = dmat;
map->callback = callback;
@@ -960,6 +1001,9 @@
static void
bounce_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
{
+ if (map == NULL || map == &nobounce_dmamap)
+ return;
+
free_bounce_pages(dmat, map);
map->sync_count = 0;
map->flags &= ~DMAMAP_MBUF;
@@ -1057,6 +1101,8 @@
*/
dsb(sy);
}
+ if (map == NULL)
+ goto out;
if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
@@ -1127,6 +1173,7 @@
dma_dcache_sync(sl, op);
}
+out:
if ((op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)) != 0) {
/*
* Wait for the bcopy to complete before any DMA operations.
@@ -1134,7 +1181,8 @@
dsb(sy);
}
- kmsan_bus_dmamap_sync(&map->kmsan_mem, op);
+ if (map != NULL)
+ kmsan_bus_dmamap_sync(&map->kmsan_mem, op);
}
#ifdef KMSAN

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 29, 10:17 PM (2 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39888758
Default Alt Text
D60098.id187906.diff (4 KB)

Event Timeline