diff options
| author | Leon Romanovsky <leonro@nvidia.com> | 2026-05-01 09:35:10 +0300 |
|---|---|---|
| committer | Marek Szyprowski <m.szyprowski@samsung.com> | 2026-05-08 23:28:19 +0300 |
| commit | a34bd60bdaebb1db4631cad45ff87dcabf4fc962 (patch) | |
| tree | fb67e61d903a8d7aaa6a10db98cfc334fd4a4b78 | |
| parent | c8411b1d1e524cbe4a12aacad7bf2163fb2be062 (diff) | |
| download | linux-a34bd60bdaebb1db4631cad45ff87dcabf4fc962.tar.xz | |
dma-debug: Ensure mappings are created and released with matching attributes
The DMA API expects that callers use the same attributes when mapping
and unmapping. Add tracking to verify this and catch mismatches.
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20260501-dma-attrs-debug-v2-6-8dbac75cd501@nvidia.com
| -rw-r--r-- | kernel/dma/debug.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index 3dfed51c3d9a..c38efc1ac8d6 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -1074,6 +1074,29 @@ static void check_unmap(struct dma_debug_entry *ref) type2name[entry->type]); } + /* + * This may be no bug in reality - but DMA API still expects + * that entry is unmapped with same attributes as it was mapped. + * + * DMA_ATTR_UNMAP_VALID lists the attributes that must be identical + * between map and unmap. Any attribute outside this set (e.g. + * DMA_ATTR_NO_WARN, DMA_ATTR_SKIP_CPU_SYNC) is allowed to differ. + */ +#define DMA_ATTR_UNMAP_VALID \ + (DMA_ATTR_NO_KERNEL_MAPPING | DMA_ATTR_FORCE_CONTIGUOUS | \ + DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT | DMA_ATTR_PRIVILEGED | \ + DMA_ATTR_CC_SHARED) + if ((ref->attrs & DMA_ATTR_UNMAP_VALID) != + (entry->attrs & DMA_ATTR_UNMAP_VALID)) { + err_printk(ref->dev, entry, + "device driver frees " + "DMA memory with different attributes " + "[device address=0x%016llx] [size=%llu bytes] " + "[mapped with 0x%lx] [unmapped with 0x%lx]\n", + ref->dev_addr, ref->size, entry->attrs, ref->attrs); + } +#undef DMA_ATTR_UNMAP_VALID + hash_bucket_del(entry); put_hash_bucket(bucket, flags); |
