From: Michael Brown Date: Fri, 11 Jul 2025 12:50:41 +0000 (+0100) Subject: [riscv] Ensure coherent DMA allocations do not cross cacheline boundaries X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;p=thirdparty%2Fipxe.git [riscv] Ensure coherent DMA allocations do not cross cacheline boundaries Signed-off-by: Michael Brown --- diff --git a/src/arch/riscv/core/riscv_dma.c b/src/arch/riscv/core/riscv_dma.c index 0a0107bd1..7b48b1bdd 100644 --- a/src/arch/riscv/core/riscv_dma.c +++ b/src/arch/riscv/core/riscv_dma.c @@ -34,6 +34,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ +/** Minimum alignment for coherent DMA allocations + * + * We set this sufficiently high to ensure that we do not end up with + * both cached and uncached uses in the same cacheline. + */ +#define RISCV_DMA_ALIGN 256 + /** * Map buffer for DMA * @@ -111,6 +118,11 @@ static void * riscv_dma_alloc ( struct dma_device *dma, void *addr; void *caddr; + /* Round up length and alignment */ + len = ( ( len + RISCV_DMA_ALIGN - 1 ) & ~( RISCV_DMA_ALIGN - 1 ) ); + if ( align < RISCV_DMA_ALIGN ) + align = RISCV_DMA_ALIGN; + /* Allocate from heap */ addr = malloc_phys ( len, align ); if ( ! addr ) @@ -153,6 +165,9 @@ static void riscv_dma_free ( struct dma_mapping *map, /* Sanity check */ assert ( virt_to_phys ( addr ) == virt_to_phys ( map->token ) ); + /* Round up length to match allocation */ + len = ( ( len + RISCV_DMA_ALIGN - 1 ) & ~( RISCV_DMA_ALIGN - 1 ) ); + /* Free original allocation */ free_phys ( map->token, len );