diff options
author | Michael Brown <mcb30@ipxe.org> | 2020-11-28 22:44:09 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2020-11-29 11:25:40 +0000 |
commit | a8442750e6059335f1f7f5ce8b2fb803a6953789 (patch) | |
tree | 897b92cd4e24427d11c95f342004e77f630b0e58 /src/interface | |
parent | a2e5cf1a3fb7bbffb4136a12daea9145577a3241 (diff) | |
download | ipxe-a8442750e6059335f1f7f5ce8b2fb803a6953789.zip ipxe-a8442750e6059335f1f7f5ce8b2fb803a6953789.tar.gz ipxe-a8442750e6059335f1f7f5ce8b2fb803a6953789.tar.bz2 |
[efi] Avoid requesting zero-length DMA mappings
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>
Diffstat (limited to 'src/interface')
-rw-r--r-- | src/interface/efi/efi_pci.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/src/interface/efi/efi_pci.c b/src/interface/efi/efi_pci.c index 8c30c95..9f6bf95 100644 --- a/src/interface/efi/efi_pci.c +++ b/src/interface/efi/efi_pci.c @@ -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; |