]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmDmaLib: reject consistent DMA mappings of cached memory
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 19 Apr 2016 14:26:00 +0000 (16:26 +0200)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 10 May 2016 12:44:39 +0000 (14:44 +0200)
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 <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
ArmPkg/Library/ArmDmaLib/ArmDmaLib.c

index 2144699c08b94008f5cd20d56c79b74bb024720a..0e6fdce8ab52e3a05baba5e63d3a4b2ab387fc88 100644 (file)
@@ -103,6 +103,18 @@ DmaMap (
 \r
     // If the mapped buffer is not an uncached buffer\r
     if ((GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) != 0) {\r
+      //\r
+      // Operations of type MapOperationBusMasterCommonBuffer are only allowed\r
+      // on uncached buffers.\r
+      //\r
+      if (Operation == MapOperationBusMasterCommonBuffer) {\r
+        DEBUG ((EFI_D_ERROR,\r
+          "%a: Operation type 'MapOperationBusMasterCommonBuffer' is only supported\n"\r
+          "on memory regions that were allocated using DmaAllocateBuffer ()\n",\r
+          __FUNCTION__));\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
       //\r
       // If the buffer does not fill entire cache lines we must double buffer into\r
       // uncached memory. Device (PCI) address becomes uncached page.\r
@@ -113,7 +125,7 @@ DmaMap (
         return Status;\r
       }\r
 \r
-      if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {\r
+      if (Operation == MapOperationBusMasterRead) {\r
         CopyMem (Buffer, HostAddress, *NumberOfBytes);\r
       }\r
 \r
@@ -151,6 +163,8 @@ DmaMap (
 \r
   @retval EFI_SUCCESS           The range was unmapped.\r
   @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.\r
+  @retval EFI_INVALID_PARAMETER An inconsistency was detected between the mapping type\r
+                                and the DoubleBuffer field\r
 \r
 **/\r
 EFI_STATUS\r
@@ -160,6 +174,7 @@ DmaUnmap (
   )\r
 {\r
   MAP_INFO_INSTANCE *Map;\r
+  EFI_STATUS        Status;\r
 \r
   if (Mapping == NULL) {\r
     ASSERT (FALSE);\r
@@ -168,8 +183,13 @@ DmaUnmap (
 \r
   Map = (MAP_INFO_INSTANCE *)Mapping;\r
 \r
+  Status = EFI_SUCCESS;\r
   if (Map->DoubleBuffer) {\r
-    if ((Map->Operation == MapOperationBusMasterWrite) || (Map->Operation == MapOperationBusMasterCommonBuffer)) {\r
+    ASSERT (Map->Operation != MapOperationBusMasterCommonBuffer);\r
+\r
+    if (Map->Operation == MapOperationBusMasterCommonBuffer) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+    } else if (Map->Operation == MapOperationBusMasterWrite) {\r
       CopyMem ((VOID *)(UINTN)Map->HostAddress, (VOID *)(UINTN)Map->DeviceAddress, Map->NumberOfBytes);\r
     }\r
 \r
@@ -186,7 +206,7 @@ DmaUnmap (
 \r
   FreePool (Map);\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
 /**\r