Thank you for your contribution! Sashiko AI review found 1 potential issue to consider: - [Medium] dma-mapping: linux,cma-default lendable pool bypassed in dma_alloc_contiguous() --
commit b8e3981ec38ba68b29bb5ed6b932c6f83a300db4 Author: Vincent Donnefort vdonnefort@google.com
dma-mapping: Introduce lendable-dma-pool
This commit introduces the "lendable-dma-pool" reserved-memory CMA driver along with dma_zap_direct_map() and dma_restore_direct_map() to unmap DMA pages from the kernel direct map before lending them to a secure world and restore them upon reclaim.
diff --git a/kernel/dma/lendable.c b/kernel/dma/lendable.c new file mode 100644 index 0000000000000..85ac3ad10df03 --- /dev/null +++ b/kernel/dma/lendable.c @@ -0,0 +1,243 @@
[ ... ]
+int dma_zap_direct_map(struct device *dev, struct page *page, size_t size) +{
- unsigned int nr_pages = size >> PAGE_SHIFT;
- bool from_lendable, has_lendable;
- struct cma *cma;
- int ret;
- if (!size || !PAGE_ALIGNED(size))
return -EINVAL;- cma = dev_get_cma_area(dev);
- has_lendable = cma_is_lendable(cma);
- from_lendable = has_lendable && cma_has_range(cma, page, nr_pages);
- if (!from_lendable && !can_set_direct_map())
return has_lendable ? -EFAULT : -ENODEV;
[Severity: Medium] Can dma_zap_direct_map() fail with -EFAULT for pages allocated via dma_alloc_pages() or dma_alloc_coherent() when a lendable pool is configured as "linux,cma-default" without a per-device memory-region?
When dev->cma_area is NULL, dev_get_cma_area(dev) returns dma_contiguous_default_area, so has_lendable is true. However, dma_alloc_contiguous() skips dma_contiguous_default_area for single-page allocations (returning NULL so the caller falls back to the buddy allocator) and prefers dma_contiguous_numa_area[nid] when CONFIG_DMA_NUMA_CMA is enabled:
kernel/dma/contiguous.c:dma_alloc_contiguous() { ... if (dev->cma_area) return cma_alloc_aligned(dev->cma_area, size, gfp); if (size <= PAGE_SIZE) return NULL;
#ifdef CONFIG_DMA_NUMA_CMA if (nid != NUMA_NO_NODE && !(gfp & (GFP_DMA | GFP_DMA32))) { struct cma *cma = dma_contiguous_numa_area[nid]; ... }
As a result, those pages do not come from dma_contiguous_default_area, cma_has_range() returns false, and dma_zap_direct_map() returns -EFAULT whenever can_set_direct_map() is false.