/**\r
Completes the Map() operation and releases any corresponding resources.\r
\r
+ This is an internal worker function that only extends the Map() API with\r
+ the MemoryMapLocked parameter.\r
+\r
@param This The protocol instance pointer.\r
@param Mapping The mapping value returned from Map().\r
+ @param MemoryMapLocked The function is executing on the stack of\r
+ gBS->ExitBootServices(); changes to the UEFI\r
+ memory map are forbidden.\r
\r
@retval EFI_SUCCESS The range was unmapped.\r
@retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by\r
@retval EFI_DEVICE_ERROR The data was not committed to the target system\r
memory.\r
**/\r
+STATIC\r
EFI_STATUS\r
EFIAPI\r
-IoMmuUnmap (\r
+IoMmuUnmapWorker (\r
IN EDKII_IOMMU_PROTOCOL *This,\r
- IN VOID *Mapping\r
+ IN VOID *Mapping,\r
+ IN BOOLEAN MemoryMapLocked\r
)\r
{\r
MAP_INFO *MapInfo;\r
COMMON_BUFFER_HEADER *CommonBufferHeader;\r
VOID *EncryptionTarget;\r
\r
- DEBUG ((DEBUG_VERBOSE, "%a: Mapping=0x%p\n", __FUNCTION__, Mapping));\r
+ DEBUG ((\r
+ DEBUG_VERBOSE,\r
+ "%a: Mapping=0x%p MemoryMapLocked=%d\n",\r
+ __FUNCTION__,\r
+ Mapping,\r
+ MemoryMapLocked\r
+ ));\r
\r
if (Mapping == NULL) {\r
return EFI_INVALID_PARAMETER;\r
// original (now encrypted) location.\r
//\r
// For all other operations, fill the late bounce buffer (which existed as\r
- // plaintext at some point) with zeros, and then release it.\r
+ // plaintext at some point) with zeros, and then release it (unless the UEFI\r
+ // memory map is locked).\r
//\r
if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||\r
MapInfo->Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {\r
(VOID *)(UINTN)MapInfo->PlainTextAddress,\r
EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages)\r
);\r
- gBS->FreePages (MapInfo->PlainTextAddress, MapInfo->NumberOfPages);\r
+ if (!MemoryMapLocked) {\r
+ gBS->FreePages (MapInfo->PlainTextAddress, MapInfo->NumberOfPages);\r
+ }\r
}\r
\r
//\r
- // Forget and free the MAP_INFO structure.\r
+ // Forget the MAP_INFO structure, then free it (unless the UEFI memory map is\r
+ // locked).\r
//\r
RemoveEntryList (&MapInfo->Link);\r
- FreePool (MapInfo);\r
+ if (!MemoryMapLocked) {\r
+ FreePool (MapInfo);\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Completes the Map() operation and releases any corresponding resources.\r
+\r
+ @param This The protocol instance pointer.\r
+ @param Mapping The mapping value returned from Map().\r
+\r
+ @retval EFI_SUCCESS The range was unmapped.\r
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by\r
+ Map().\r
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system\r
+ memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IoMmuUnmap (\r
+ IN EDKII_IOMMU_PROTOCOL *This,\r
+ IN VOID *Mapping\r
+ )\r
+{\r
+ return IoMmuUnmapWorker (\r
+ This,\r
+ Mapping,\r
+ FALSE // MemoryMapLocked\r
+ );\r
+}\r
+\r
/**\r
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or\r
OperationBusMasterCommonBuffer64 mapping.\r