]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[riscv] Ensure coherent DMA allocations do not cross cacheline boundaries coverity_scan master
authorMichael Brown <mcb30@ipxe.org>
Fri, 11 Jul 2025 12:50:41 +0000 (13:50 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 11 Jul 2025 12:50:41 +0000 (13:50 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/riscv/core/riscv_dma.c

index 0a0107bd12b727bd6c72ed3f100eb5514899945c..7b48b1bddaec7fd89c851c8a3828d5741a62c82a 100644 (file)
@@ -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 );