aboutsummaryrefslogtreecommitdiff
path: root/src/interface
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2020-11-28 22:44:09 +0000
committerMichael Brown <mcb30@ipxe.org>2020-11-29 11:25:40 +0000
commita8442750e6059335f1f7f5ce8b2fb803a6953789 (patch)
tree897b92cd4e24427d11c95f342004e77f630b0e58 /src/interface
parenta2e5cf1a3fb7bbffb4136a12daea9145577a3241 (diff)
downloadipxe-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.c28
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;