DmaMap () operations of type MapOperationBusMasterCommonBuffer should return a mapping that is coherent between the CPU and the device. For this reason, the API only allows DmaMap () to be called with this operation type if the memory to be mapped was allocated by DmaAllocateBuffer (), which in this implementation guarantees the coherency by using uncached mappings on the CPU side.
This means that, if we encounter a cached mapping in DmaMap () with this operation type, the code is either broken, or someone is violating the API, but simply proceeding with a double buffer makes no sense at all, and can only cause problems. So instead, actively reject this operation type for cached memory mappings. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <[email protected]> --- ArmPkg/Library/ArmDmaLib/ArmDmaLib.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c b/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c index 7f6598318a91..7e518ed3b83e 100644 --- a/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c +++ b/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c @@ -103,6 +103,18 @@ DmaMap ( // If the mapped buffer is not an uncached buffer if ((GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) != 0) { // + // Operations of type MapOperationBusMasterCommonBuffer are only allowed + // on uncached buffers. + // + if (Operation == MapOperationBusMasterCommonBuffer) { + DEBUG ((EFI_D_ERROR, + "%a: Operation type 'MapOperationBusMasterCommonBuffer' is only supported\n" + "on memory regions that were allocated using DmaAllocateBuffer ()\n", + __FUNCTION__)); + return EFI_UNSUPPORTED; + } + + // // If the buffer does not fill entire cache lines we must double buffer into // uncached memory. Device (PCI) address becomes uncached page. // @@ -112,7 +124,7 @@ DmaMap ( return Status; } - if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) { + if (Operation == MapOperationBusMasterRead) { CopyMem (Buffer, HostAddress, *NumberOfBytes); } @@ -168,7 +180,9 @@ DmaUnmap ( Map = (MAP_INFO_INSTANCE *)Mapping; if (Map->DoubleBuffer) { - if ((Map->Operation == MapOperationBusMasterWrite) || (Map->Operation == MapOperationBusMasterCommonBuffer)) { + ASSERT (Map->Operation != MapOperationBusMasterCommonBuffer); + + if (Map->Operation == MapOperationBusMasterWrite) { CopyMem ((VOID *)(UINTN)Map->HostAddress, (VOID *)(UINTN)Map->DeviceAddress, Map->NumberOfBytes); } -- 2.5.0 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

