Skip to content

Commit 89461db

Browse files
wensmszyprow
authored andcommitted
dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask
When a reserved memory region described in the device tree is attached to a device, it is expected that the device's limitations are correctly included in that description. However, if the device driver failed to implement DMA address masking or addressing beyond the default 32 bits (on arm64), then bad things could happen because the DMA address was truncated, such as playing back audio with no actual audio coming out, or DMA overwriting random blocks of kernel memory. Check against the coherent DMA mask when the memory regions are attached to the device. Give a warning when the memory region can not be covered by the mask. A warning instead of a hard error was chosen, because it is possible that existing drivers could be working fine even if they forgot to extend the coherent DMA mask. Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Link: https://lore.kernel.org/r/20250421083930.374173-1-wenst@chromium.org
1 parent cae5572 commit 89461db

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

kernel/dma/coherent.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,16 +336,22 @@ static phys_addr_t dma_reserved_default_memory_size __initdata;
336336

337337
static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
338338
{
339-
if (!rmem->priv) {
340-
struct dma_coherent_mem *mem;
339+
struct dma_coherent_mem *mem = rmem->priv;
341340

341+
if (!mem) {
342342
mem = dma_init_coherent_memory(rmem->base, rmem->base,
343343
rmem->size, true);
344344
if (IS_ERR(mem))
345345
return PTR_ERR(mem);
346346
rmem->priv = mem;
347347
}
348-
dma_assign_coherent_memory(dev, rmem->priv);
348+
349+
/* Warn if the device potentially can't use the reserved memory */
350+
if (mem->device_base + rmem->size - 1 >
351+
min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit))
352+
dev_warn(dev, "reserved memory is beyond device's set DMA address range\n");
353+
354+
dma_assign_coherent_memory(dev, mem);
349355
return 0;
350356
}
351357

0 commit comments

Comments
 (0)