Skip to content

Commit b9a6232

Browse files
committed
Merge tag 'dma-mapping-6.17-2025-09-09' into HEAD
dma-mapping fix for Linux 6.17 - one more fix for DMA API debugging infrastructure (Baochen Qiang)
2 parents 110aa2c + 7e2368a commit b9a6232

7 files changed

Lines changed: 86 additions & 11 deletions

File tree

drivers/of/of_reserved_mem.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/memblock.h>
2626
#include <linux/kmemleak.h>
2727
#include <linux/cma.h>
28+
#include <linux/dma-map-ops.h>
2829

2930
#include "of_private.h"
3031

@@ -175,13 +176,17 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
175176
base = dt_mem_next_cell(dt_root_addr_cells, &prop);
176177
size = dt_mem_next_cell(dt_root_size_cells, &prop);
177178

178-
if (size &&
179-
early_init_dt_reserve_memory(base, size, nomap) == 0)
179+
if (size && early_init_dt_reserve_memory(base, size, nomap) == 0) {
180+
/* Architecture specific contiguous memory fixup. */
181+
if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
182+
of_get_flat_dt_prop(node, "reusable", NULL))
183+
dma_contiguous_early_fixup(base, size);
180184
pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
181185
uname, &base, (unsigned long)(size / SZ_1M));
182-
else
186+
} else {
183187
pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
184188
uname, &base, (unsigned long)(size / SZ_1M));
189+
}
185190

186191
len -= t_len;
187192
}
@@ -472,7 +477,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
472477
uname, (unsigned long)(size / SZ_1M));
473478
return -ENOMEM;
474479
}
475-
480+
/* Architecture specific contiguous memory fixup. */
481+
if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
482+
of_get_flat_dt_prop(node, "reusable", NULL))
483+
dma_contiguous_early_fixup(base, size);
476484
/* Save region in the reserved_mem array */
477485
fdt_reserved_mem_save_node(node, uname, base, size);
478486
return 0;

include/linux/dma-map-ops.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ static inline void dma_free_contiguous(struct device *dev, struct page *page,
153153
{
154154
__free_pages(page, get_order(size));
155155
}
156+
static inline void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
157+
{
158+
}
156159
#endif /* CONFIG_DMA_CMA*/
157160

158161
#ifdef CONFIG_DMA_DECLARE_COHERENT

kernel/dma/contiguous.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
483483
pr_err("Reserved memory: unable to setup CMA region\n");
484484
return err;
485485
}
486-
/* Architecture specific contiguous memory fixup. */
487-
dma_contiguous_early_fixup(rmem->base, rmem->size);
488486

489487
if (default_cma)
490488
dma_contiguous_default_area = cma;

kernel/dma/debug.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum {
3939
dma_debug_sg,
4040
dma_debug_coherent,
4141
dma_debug_resource,
42+
dma_debug_noncoherent,
4243
};
4344

4445
enum map_err_types {
@@ -141,6 +142,7 @@ static const char *type2name[] = {
141142
[dma_debug_sg] = "scatter-gather",
142143
[dma_debug_coherent] = "coherent",
143144
[dma_debug_resource] = "resource",
145+
[dma_debug_noncoherent] = "noncoherent",
144146
};
145147

146148
static const char *dir2name[] = {
@@ -993,7 +995,8 @@ static void check_unmap(struct dma_debug_entry *ref)
993995
"[mapped as %s] [unmapped as %s]\n",
994996
ref->dev_addr, ref->size,
995997
type2name[entry->type], type2name[ref->type]);
996-
} else if (entry->type == dma_debug_coherent &&
998+
} else if ((entry->type == dma_debug_coherent ||
999+
entry->type == dma_debug_noncoherent) &&
9971000
ref->paddr != entry->paddr) {
9981001
err_printk(ref->dev, entry, "device driver frees "
9991002
"DMA memory with different CPU address "
@@ -1581,6 +1584,49 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
15811584
}
15821585
}
15831586

1587+
void debug_dma_alloc_pages(struct device *dev, struct page *page,
1588+
size_t size, int direction,
1589+
dma_addr_t dma_addr,
1590+
unsigned long attrs)
1591+
{
1592+
struct dma_debug_entry *entry;
1593+
1594+
if (unlikely(dma_debug_disabled()))
1595+
return;
1596+
1597+
entry = dma_entry_alloc();
1598+
if (!entry)
1599+
return;
1600+
1601+
entry->type = dma_debug_noncoherent;
1602+
entry->dev = dev;
1603+
entry->paddr = page_to_phys(page);
1604+
entry->size = size;
1605+
entry->dev_addr = dma_addr;
1606+
entry->direction = direction;
1607+
1608+
add_dma_entry(entry, attrs);
1609+
}
1610+
1611+
void debug_dma_free_pages(struct device *dev, struct page *page,
1612+
size_t size, int direction,
1613+
dma_addr_t dma_addr)
1614+
{
1615+
struct dma_debug_entry ref = {
1616+
.type = dma_debug_noncoherent,
1617+
.dev = dev,
1618+
.paddr = page_to_phys(page),
1619+
.dev_addr = dma_addr,
1620+
.size = size,
1621+
.direction = direction,
1622+
};
1623+
1624+
if (unlikely(dma_debug_disabled()))
1625+
return;
1626+
1627+
check_unmap(&ref);
1628+
}
1629+
15841630
static int __init dma_debug_driver_setup(char *str)
15851631
{
15861632
int i;

kernel/dma/debug.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ extern void debug_dma_sync_sg_for_cpu(struct device *dev,
5454
extern void debug_dma_sync_sg_for_device(struct device *dev,
5555
struct scatterlist *sg,
5656
int nelems, int direction);
57+
extern void debug_dma_alloc_pages(struct device *dev, struct page *page,
58+
size_t size, int direction,
59+
dma_addr_t dma_addr,
60+
unsigned long attrs);
61+
extern void debug_dma_free_pages(struct device *dev, struct page *page,
62+
size_t size, int direction,
63+
dma_addr_t dma_addr);
5764
#else /* CONFIG_DMA_API_DEBUG */
5865
static inline void debug_dma_map_page(struct device *dev, struct page *page,
5966
size_t offset, size_t size,
@@ -126,5 +133,18 @@ static inline void debug_dma_sync_sg_for_device(struct device *dev,
126133
int nelems, int direction)
127134
{
128135
}
136+
137+
static inline void debug_dma_alloc_pages(struct device *dev, struct page *page,
138+
size_t size, int direction,
139+
dma_addr_t dma_addr,
140+
unsigned long attrs)
141+
{
142+
}
143+
144+
static inline void debug_dma_free_pages(struct device *dev, struct page *page,
145+
size_t size, int direction,
146+
dma_addr_t dma_addr)
147+
{
148+
}
129149
#endif /* CONFIG_DMA_API_DEBUG */
130150
#endif /* _KERNEL_DMA_DEBUG_H */

kernel/dma/mapping.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ struct page *dma_alloc_pages(struct device *dev, size_t size,
712712
if (page) {
713713
trace_dma_alloc_pages(dev, page_to_virt(page), *dma_handle,
714714
size, dir, gfp, 0);
715-
debug_dma_map_page(dev, page, 0, size, dir, *dma_handle, 0);
715+
debug_dma_alloc_pages(dev, page, size, dir, *dma_handle, 0);
716716
} else {
717717
trace_dma_alloc_pages(dev, NULL, 0, size, dir, gfp, 0);
718718
}
@@ -738,7 +738,7 @@ void dma_free_pages(struct device *dev, size_t size, struct page *page,
738738
dma_addr_t dma_handle, enum dma_data_direction dir)
739739
{
740740
trace_dma_free_pages(dev, page_to_virt(page), dma_handle, size, dir, 0);
741-
debug_dma_unmap_page(dev, dma_handle, size, dir);
741+
debug_dma_free_pages(dev, page, size, dir, dma_handle);
742742
__dma_free_pages(dev, size, page, dma_handle, dir);
743743
}
744744
EXPORT_SYMBOL_GPL(dma_free_pages);

kernel/dma/pool.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
102102

103103
#ifdef CONFIG_DMA_DIRECT_REMAP
104104
addr = dma_common_contiguous_remap(page, pool_size,
105-
pgprot_dmacoherent(PAGE_KERNEL),
106-
__builtin_return_address(0));
105+
pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
106+
__builtin_return_address(0));
107107
if (!addr)
108108
goto free_page;
109109
#else

0 commit comments

Comments
 (0)