On Tue, Nov 10, 2026 at 1:48 AM Marek Szyprowski <[email protected]> wrote: > > arch_dma_prep_coherent() performs the cache maintenance on the address > returned by page_address(). xtensa with CONFIG_HIGHMEM uses > HASHED_PAGE_VIRTUAL, so page_address() returns NULL for a highmem page > that is not kmapped, and the cache operation then works on the virtual > range starting at 0 instead of the buffer, leaving any dirty cache lines > of the buffer in place. > > Highmem pages do reach this function: dma_alloc_contiguous() can return > a highmem CMA page, which dma_direct_alloc() handles by forcing the remap > path and calling arch_dma_prep_coherent() on that page before creating > the uncached mapping. > > Fix this by reusing do_cache_op(), which the arch_sync_dma_for_*() hooks > already use and which maps highmem pages one page at a time with > kmap_atomic(). For lowmem pages it does a single cache operation over > the whole range, so the behaviour is unchanged there. A small wrapper > is needed because __flush_invalidate_dcache_range() is a macro on cores > with a write-through data cache. > > Fixes: 0f665b9e2a6d ("xtensa: use the generic uncached segment support") > Signed-off-by: Marek Szyprowski <[email protected]> > --- > arch/xtensa/kernel/pci-dma.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-)
Reviewed-by: Max Filippov <[email protected]> -- Thanks. -- Max
