Skip to content

Commit 078871b

Browse files
committed
dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask
commit 89461db Author: Chen-Yu Tsai <[email protected]> Date: Mon Apr 21 16:39:29 2025 +0800 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 <[email protected]> Signed-off-by: Marek Szyprowski <[email protected]> Link: https://lore.kernel.org/r/[email protected] (cherry picked from commit 89461db) Signed-off-by: Jerry Snitselaar <[email protected]> Upstream-Status: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git JIRA: https://issues.redhat.com/browse/RHEL-89891
1 parent 7bf4b2e commit 078871b

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
@@ -335,16 +335,22 @@ static struct reserved_mem *dma_reserved_default_memory __initdata;
335335

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

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

0 commit comments

Comments
 (0)