]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Avoid requesting zero-length DMA mappings
authorMichael Brown <mcb30@ipxe.org>
Sat, 28 Nov 2020 22:44:09 +0000 (22:44 +0000)
committerMichael Brown <mcb30@ipxe.org>
Sun, 29 Nov 2020 11:25:40 +0000 (11:25 +0000)
The UEFI specification does not prohibit zero-length DMA mappings.
However, there is a reasonable chance that at least one implementation
will treat it as an invalid parameter.  As a precaution, avoid calling
EFI_PCI_IO_PROTOCOL.Map() with a length of zero.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/interface/efi/efi_pci.c

index 8c30c95148c0f27898214fbf56613b0db73b99c3..9f6bf952bde30be85be79ad91d9b4aa14acf23ec 100644 (file)
@@ -352,14 +352,20 @@ static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map,
                break;
        }
 
-       /* Map buffer */
+       /* Map buffer (if non-zero length) */
        count = len;
-       if ( ( efirc = pci_io->Map ( pci_io, op, phys_to_virt ( addr ), &count,
-                                    &bus, &mapping ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( pci, "EFIPCI " PCI_FMT " cannot map %08lx+%zx: %s\n",
-                      PCI_ARGS ( pci ), addr, len, strerror ( rc ) );
-               goto err_map;
+       if ( len ) {
+               if ( ( efirc = pci_io->Map ( pci_io, op, phys_to_virt ( addr ),
+                                            &count, &bus, &mapping ) ) != 0 ) {
+                       rc = -EEFI ( efirc );
+                       DBGC ( pci, "EFIPCI " PCI_FMT " cannot map %08lx+%zx: "
+                              "%s\n", PCI_ARGS ( pci ), addr, len,
+                              strerror ( rc ) );
+                       goto err_map;
+               }
+       } else {
+               bus = addr;
+               mapping = NULL;
        }
 
        /* Check that full length was mapped.  The UEFI specification
@@ -403,11 +409,9 @@ static void efipci_dma_unmap ( struct dma_device *dma,
                container_of ( dma, struct efi_pci_device, pci.dma );
        EFI_PCI_IO_PROTOCOL *pci_io = efipci->io;
 
-       /* Sanity check */
-       assert ( map->token != NULL );
-
-       /* Unmap buffer */
-       pci_io->Unmap ( pci_io, map->token );
+       /* Unmap buffer (if non-zero length) */
+       if ( map->token )
+               pci_io->Unmap ( pci_io, map->token );
 
        /* Clear mapping */
        map->dma = NULL;