]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[dma] Use virtual addresses for dma_map()
authorMichael Brown <mcb30@ipxe.org>
Tue, 8 Jul 2025 11:38:05 +0000 (12:38 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 8 Jul 2025 14:13:19 +0000 (15:13 +0100)
Cache management operations must generally be performed on virtual
addresses rather than physical addresses.

Change the address parameter in dma_map() to be a virtual address, and
make dma() the API-level primitive instead of dma_phys().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/dma.c
src/drivers/net/intelxl.c
src/include/ipxe/dma.h
src/include/ipxe/iobuf.h
src/interface/efi/efi_pci.c

index cf4b20379926271bec928ea1ce2a19d093d6e423..cbc9b8d10f6a80d56f4f5fcaf39cf32a18f5264a 100644 (file)
@@ -47,7 +47,7 @@ PROVIDE_DMAAPI_INLINE ( flat, dma_free );
 PROVIDE_DMAAPI_INLINE ( flat, dma_umalloc );
 PROVIDE_DMAAPI_INLINE ( flat, dma_ufree );
 PROVIDE_DMAAPI_INLINE ( flat, dma_set_mask );
-PROVIDE_DMAAPI_INLINE ( flat, dma_phys );
+PROVIDE_DMAAPI_INLINE ( flat, dma );
 
 /******************************************************************************
  *
@@ -67,7 +67,7 @@ PROVIDE_DMAAPI_INLINE ( flat, dma_phys );
  * @ret rc             Return status code
  */
 static int dma_op_map ( struct dma_device *dma, struct dma_mapping *map,
-                       physaddr_t addr, size_t len, int flags ) {
+                       void *addr, size_t len, int flags ) {
        struct dma_operations *op = dma->op;
 
        if ( ! op )
@@ -175,4 +175,4 @@ PROVIDE_DMAAPI ( op, dma_free, dma_op_free );
 PROVIDE_DMAAPI ( op, dma_umalloc, dma_op_umalloc );
 PROVIDE_DMAAPI ( op, dma_ufree, dma_op_ufree );
 PROVIDE_DMAAPI ( op, dma_set_mask, dma_op_set_mask );
-PROVIDE_DMAAPI_INLINE ( op, dma_phys );
+PROVIDE_DMAAPI_INLINE ( op, dma );
index 82b07833c81e558b301b310ce9f5dcfb32dbf051..1d4c22a09773500aaf3e62d5ca8be226cbf66bf0 100644 (file)
@@ -65,8 +65,8 @@ int intelxl_msix_enable ( struct intelxl_nic *intelxl,
 
        /* Map dummy target location */
        if ( ( rc = dma_map ( intelxl->dma, &intelxl->msix.map,
-                             virt_to_phys ( &intelxl->msix.msg ),
-                             sizeof ( intelxl->msix.msg ), DMA_RX ) ) != 0 ) {
+                             &intelxl->msix.msg, sizeof ( intelxl->msix.msg ),
+                             DMA_RX ) ) != 0 ) {
                DBGC ( intelxl, "INTELXL %p could not map MSI-X target: %s\n",
                       intelxl, strerror ( rc ) );
                goto err_map;
index 6e5c43289fb2f2d32a355ddefb576a699b87a61b..d450ef523f65feb04c37ab59575f31c401d44224 100644 (file)
@@ -68,7 +68,7 @@ struct dma_operations {
         * @ret rc              Return status code
         */
        int ( * map ) ( struct dma_device *dma, struct dma_mapping *map,
-                       physaddr_t addr, size_t len, int flags );
+                       void *addr, size_t len, int flags );
        /**
         * Unmap buffer
         *
@@ -178,8 +178,7 @@ struct dma_operations {
  */
 static inline __always_inline int
 DMAAPI_INLINE ( flat, dma_map ) ( struct dma_device *dma,
-                                 struct dma_mapping *map,
-                                 physaddr_t addr __unused,
+                                 struct dma_mapping *map, void *addr __unused,
                                  size_t len __unused, int flags __unused ) {
 
        /* Increment mapping count (for debugging) */
@@ -319,32 +318,31 @@ DMAAPI_INLINE ( flat, dma_set_mask ) ( struct dma_device *dma __unused,
 }
 
 /**
- * Get DMA address from physical address
+ * Get DMA address from virtual address
  *
  * @v map              DMA mapping
- * @v addr             Physical address within the mapped region
+ * @v addr             Address within the mapped region
  * @ret addr           Device-side DMA address
  */
 static inline __always_inline physaddr_t
-DMAAPI_INLINE ( flat, dma_phys ) ( struct dma_mapping *map __unused,
-                                  physaddr_t addr ) {
+DMAAPI_INLINE ( flat, dma ) ( struct dma_mapping *map __unused, void *addr ) {
 
        /* Use physical address as device address */
-       return addr;
+       return virt_to_phys ( addr );
 }
 
 /**
- * Get DMA address from physical address
+ * Get DMA address from virtual address
  *
  * @v map              DMA mapping
- * @v addr             Physical address within the mapped region
+ * @v addr             Address within the mapped region
  * @ret addr           Device-side DMA address
  */
 static inline __always_inline physaddr_t
-DMAAPI_INLINE ( op, dma_phys ) ( struct dma_mapping *map, physaddr_t addr ) {
+DMAAPI_INLINE ( op, dma ) ( struct dma_mapping *map, void *addr ) {
 
        /* Adjust physical address using mapping offset */
-       return ( addr + map->offset );
+       return ( virt_to_phys ( addr ) + map->offset );
 }
 
 /**
@@ -358,7 +356,7 @@ DMAAPI_INLINE ( op, dma_phys ) ( struct dma_mapping *map, physaddr_t addr ) {
  * @ret rc             Return status code
  */
 int dma_map ( struct dma_device *dma, struct dma_mapping *map,
-             physaddr_t addr, size_t len, int flags );
+             void *addr, size_t len, int flags );
 
 /**
  * Unmap buffer
@@ -417,28 +415,14 @@ void dma_ufree ( struct dma_mapping *map, void *addr, size_t len );
  */
 void dma_set_mask ( struct dma_device *dma, physaddr_t mask );
 
-/**
- * Get DMA address from physical address
- *
- * @v map              DMA mapping
- * @v addr             Physical address within the mapped region
- * @ret addr           Device-side DMA address
- */
-physaddr_t dma_phys ( struct dma_mapping *map, physaddr_t addr );
-
 /**
  * Get DMA address from virtual address
  *
  * @v map              DMA mapping
- * @v addr             Virtual address within the mapped region
+ * @v addr             Address within the mapped region
  * @ret addr           Device-side DMA address
  */
-static inline __always_inline physaddr_t dma ( struct dma_mapping *map,
-                                              void *addr ) {
-
-       /* Get DMA address from corresponding physical address */
-       return dma_phys ( map, virt_to_phys ( addr ) );
-}
+physaddr_t dma ( struct dma_mapping *map, void *addr );
 
 /**
  * Check if DMA unmapping is required
index 2bdca6b5d395591de400dca563543ff1bbbdef86..df8d0b8544fea8354ac04202c57845c7d498b174 100644 (file)
@@ -230,8 +230,7 @@ static inline void iob_populate ( struct io_buffer *iobuf,
 static inline __always_inline int iob_map ( struct io_buffer *iobuf,
                                            struct dma_device *dma,
                                            size_t len, int flags ) {
-       return dma_map ( dma, &iobuf->map, virt_to_phys ( iobuf->data ),
-                        len, flags );
+       return dma_map ( dma, &iobuf->map, iobuf->data, len, flags );
 }
 
 /**
index 1b1f0581643a39f81ebea3197e6fbde9cfcccf32..ae0ec4264723a8a486c8f6ae36de66884a3578dc 100644 (file)
@@ -455,7 +455,7 @@ PROVIDE_PCIAPI ( efi, pci_ioremap, efipci_ioremap );
  * @ret rc             Return status code
  */
 static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map,
-                           physaddr_t addr, size_t len, int flags ) {
+                           void *addr, size_t len, int flags ) {
        struct efi_pci_device *efipci =
                container_of ( dma, struct efi_pci_device, pci.dma );
        struct pci_device *pci = &efipci->pci;
@@ -464,6 +464,7 @@ static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map,
        EFI_PHYSICAL_ADDRESS bus;
        UINTN count;
        VOID *mapping;
+       physaddr_t phys;
        EFI_STATUS efirc;
        int rc;
 
@@ -486,18 +487,19 @@ static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map,
        }
 
        /* Map buffer (if non-zero length) */
+       phys = virt_to_phys ( addr );
        count = len;
        if ( len ) {
-               if ( ( efirc = pci_io->Map ( pci_io, op, phys_to_virt ( addr ),
-                                            &count, &bus, &mapping ) ) != 0 ) {
+               if ( ( efirc = pci_io->Map ( pci_io, op, addr, &count, &bus,
+                                            &mapping ) ) != 0 ) {
                        rc = -EEFI ( efirc );
-                       DBGC ( pci, "EFIPCI " PCI_FMT " cannot map %08lx+%zx: "
+                       DBGC ( pci, "EFIPCI " PCI_FMT " cannot map %p+%zx: "
                               "%s\n", PCI_ARGS ( pci ), addr, len,
                               strerror ( rc ) );
                        goto err_map;
                }
        } else {
-               bus = addr;
+               bus = phys;
                mapping = NULL;
        }
 
@@ -508,14 +510,14 @@ static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map,
         */
        if ( count != len ) {
                DBGC ( pci, "EFIPCI " PCI_FMT " attempted split mapping for "
-                      "%08lx+%zx\n", PCI_ARGS ( pci ), addr, len );
+                      "%p+%zx\n", PCI_ARGS ( pci ), addr, len );
                rc = -ENOTSUP;
                goto err_len;
        }
 
        /* Populate mapping */
        map->dma = dma;
-       map->offset = ( bus - addr );
+       map->offset = ( bus - phys );
        map->token = mapping;
 
        /* Increment mapping count (for debugging) */
@@ -594,8 +596,7 @@ static void * efipci_dma_alloc ( struct dma_device *dma,
        memset ( addr, 0, ( pages * EFI_PAGE_SIZE ) );
 
        /* Map buffer */
-       if ( ( rc = efipci_dma_map ( dma, map, virt_to_phys ( addr ),
-                                    ( pages * EFI_PAGE_SIZE ),
+       if ( ( rc = efipci_dma_map ( dma, map, addr, ( pages * EFI_PAGE_SIZE ),
                                     DMA_BI ) ) != 0 )
                goto err_map;