aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorStephen Boyd <swboyd@chromium.org>2018-10-08 03:20:07 -0400
committerChristoph Hellwig <hch@lst.de>2018-10-08 03:44:17 -0400
commit99c65fa7c59ff558e70db8aa61bbdece5d3a9588 (patch)
tree5a72a54e4d6d2104b3aeedd86d84563d2d545af5 /kernel
parent1fc8e6423edb4bba365b0780c2fcddfb921b24b2 (diff)
dma-debug: Check for drivers mapping invalid addresses in dma_map_single()
I recently debugged a DMA mapping oops where a driver was trying to map a buffer returned from request_firmware() with dma_map_single(). Memory returned from request_firmware() is mapped into the vmalloc region and this isn't a valid region to map with dma_map_single() per the DMA documentation's "What memory is DMA'able?" section. Unfortunately, we don't really check that in the DMA debugging code, so enabling DMA debugging doesn't help catch this problem. Let's add a new DMA debug function to check for a vmalloc address or an invalid virtual address and print a warning if this happens. This makes it a little easier to debug these sorts of problems, instead of seeing odd behavior or crashes when drivers attempt to map the vmalloc space for DMA. Cc: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Stephen Boyd <swboyd@chromium.org> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/dma/debug.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
index c007d25bee09..231ca4628062 100644
--- a/kernel/dma/debug.c
+++ b/kernel/dma/debug.c
@@ -1312,6 +1312,22 @@ static void check_sg_segment(struct device *dev, struct scatterlist *sg)
1312#endif 1312#endif
1313} 1313}
1314 1314
1315void debug_dma_map_single(struct device *dev, const void *addr,
1316 unsigned long len)
1317{
1318 if (unlikely(dma_debug_disabled()))
1319 return;
1320
1321 if (!virt_addr_valid(addr))
1322 err_printk(dev, NULL, "DMA-API: device driver maps memory from invalid area [addr=%p] [len=%lu]\n",
1323 addr, len);
1324
1325 if (is_vmalloc_addr(addr))
1326 err_printk(dev, NULL, "DMA-API: device driver maps memory from vmalloc area [addr=%p] [len=%lu]\n",
1327 addr, len);
1328}
1329EXPORT_SYMBOL(debug_dma_map_single);
1330
1315void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, 1331void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
1316 size_t size, int direction, dma_addr_t dma_addr, 1332 size_t size, int direction, dma_addr_t dma_addr,
1317 bool map_single) 1333 bool map_single)