]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmMmuLib: Reuse XIP MMU routines when splitting entries
authorArd Biesheuvel <ardb@kernel.org>
Sat, 24 Sep 2022 20:31:44 +0000 (22:31 +0200)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 19 Oct 2022 09:07:13 +0000 (09:07 +0000)
In order to reduce the likelihood that we will need to rely on the logic
that disables and re-enables the MMU for updating a page table entry
safely, expose the XIP version of the helper routine via a HOB and use
it instead of the one that is copied into DRAM. Since the XIP copy is
already clean to the PoC, and will never end up getting unmapped during
a block entry split, we can use it safely without any cache maintenance,
and without running the risk of pulling the rug from under our feet when
updating an entry by going through an invalid mapping.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Leif Lindholm <quic_llindhol@quicinc.com>
ArmPkg/ArmPkg.dec
ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c
ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf

index 9da1bbc9f2166dc8ae93f96a34d3165fffed34dc..cfb6fe602485aa7bc3e91f48caf5bbbbe9b7a761 100644 (file)
@@ -99,6 +99,8 @@
   # Include/Guid/ArmMpCoreInfo.h\r
   gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5,  {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }\r
 \r
+  gArmMmuReplaceLiveTranslationEntryFuncGuid = { 0xa8b50ff3, 0x08ec, 0x4dd3, {0xbf, 0x04, 0x28, 0xbf, 0x71, 0x75, 0xc7, 0x4a} }\r
+\r
 [Protocols.common]\r
   ## Arm System Control and Management Interface(SCMI) Base protocol\r
   ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h\r
index ae59e9a7d04e34ba2e328b8afb246e668aea5493..764c7d362e2e480ab6f9aec538dff43f2e7e1aff 100644 (file)
@@ -10,6 +10,7 @@
 **/\r
 \r
 #include <Uefi.h>\r
+#include <Pi/PiMultiPhase.h>\r
 #include <Chipset/AArch64.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/CacheMaintenanceLib.h>\r
@@ -120,14 +121,14 @@ ReplaceTableEntry (
     // use an ordinary break before make. Otherwise, we will need to\r
     // temporarily disable the MMU.\r
     DisableMmu = FALSE;\r
-    if ((((RegionStart ^ (UINTN)ArmReplaceLiveTranslationEntry) & ~BlockMask) == 0) ||\r
+    if ((((RegionStart ^ (UINTN)mReplaceLiveEntryFunc) & ~BlockMask) == 0) ||\r
         (((RegionStart ^ (UINTN)Entry) & ~BlockMask) == 0))\r
     {\r
       DisableMmu = TRUE;\r
       DEBUG ((DEBUG_WARN, "%a: splitting block entry with MMU disabled\n", __FUNCTION__));\r
     }\r
 \r
-    ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart, DisableMmu);\r
+    mReplaceLiveEntryFunc (Entry, Value, RegionStart, DisableMmu);\r
   }\r
 }\r
 \r
@@ -747,15 +748,21 @@ ArmMmuBaseLibConstructor (
   )\r
 {\r
   extern UINT32  ArmReplaceLiveTranslationEntrySize;\r
+  VOID           *Hob;\r
 \r
-  //\r
-  // The ArmReplaceLiveTranslationEntry () helper function may be invoked\r
-  // with the MMU off so we have to ensure that it gets cleaned to the PoC\r
-  //\r
-  WriteBackDataCacheRange (\r
-    (VOID *)(UINTN)ArmReplaceLiveTranslationEntry,\r
-    ArmReplaceLiveTranslationEntrySize\r
-    );\r
+  Hob = GetFirstGuidHob (&gArmMmuReplaceLiveTranslationEntryFuncGuid);\r
+  if (Hob != NULL) {\r
+    mReplaceLiveEntryFunc = *(VOID **)GET_GUID_HOB_DATA (Hob);\r
+  } else {\r
+    //\r
+    // The ArmReplaceLiveTranslationEntry () helper function may be invoked\r
+    // with the MMU off so we have to ensure that it gets cleaned to the PoC\r
+    //\r
+    WriteBackDataCacheRange (\r
+      (VOID *)(UINTN)ArmReplaceLiveTranslationEntry,\r
+      ArmReplaceLiveTranslationEntrySize\r
+      );\r
+  }\r
 \r
   return RETURN_SUCCESS;\r
 }\r
index caace2c17cdc47a9b48e49586d2aa833da3eee47..5f50a605a338d75e33a72849ca6712592bdf3dd7 100644 (file)
@@ -12,6 +12,7 @@
 #include <Library/ArmMmuLib.h>\r
 #include <Library/CacheMaintenanceLib.h>\r
 #include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
 \r
 EFI_STATUS\r
 EFIAPI\r
@@ -21,6 +22,8 @@ ArmMmuPeiLibConstructor (
   )\r
 {\r
   extern UINT32  ArmReplaceLiveTranslationEntrySize;\r
+  VOID           *ArmReplaceLiveTranslationEntryFunc;\r
+  VOID           *Hob;\r
 \r
   EFI_FV_FILE_INFO  FileInfo;\r
   EFI_STATUS        Status;\r
@@ -42,6 +45,20 @@ ArmMmuPeiLibConstructor (
        (UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize))\r
   {\r
     DEBUG ((DEBUG_INFO, "ArmMmuLib: skipping cache maintenance on XIP PEIM\n"));\r
+\r
+    //\r
+    // Expose the XIP version of the ArmReplaceLiveTranslationEntry() routine\r
+    // via a HOB so we can fall back to it later when we need to split block\r
+    // mappings in a way that adheres to break-before-make requirements.\r
+    //\r
+    ArmReplaceLiveTranslationEntryFunc = ArmReplaceLiveTranslationEntry;\r
+\r
+    Hob = BuildGuidDataHob (\r
+            &gArmMmuReplaceLiveTranslationEntryFuncGuid,\r
+            &ArmReplaceLiveTranslationEntryFunc,\r
+            sizeof ArmReplaceLiveTranslationEntryFunc\r
+            );\r
+    ASSERT (Hob != NULL);\r
   } else {\r
     DEBUG ((DEBUG_INFO, "ArmMmuLib: performing cache maintenance on shadowed PEIM\n"));\r
     //\r
index 3d78e7dabf476864bc795f5942a7e4a952651d21..57cb71f90ee3a0d4201f2870b6526ec7c1006830 100644 (file)
 [LibraryClasses]\r
   ArmLib\r
   CacheMaintenanceLib\r
+  HobLib\r
   MemoryAllocationLib\r
 \r
+[Guids]\r
+  gArmMmuReplaceLiveTranslationEntryFuncGuid\r
+\r
 [Pcd.ARM]\r
   gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride\r
index ce9674ea99efb9aaaff0089a48d3fac28ebef612..02f874a1a994c7c44c29107fb4ea3c1b8bb67dff 100644 (file)
@@ -29,4 +29,8 @@
 [LibraryClasses]\r
   ArmLib\r
   CacheMaintenanceLib\r
+  HobLib\r
   MemoryAllocationLib\r
+\r
+[Guids]\r
+  gArmMmuReplaceLiveTranslationEntryFuncGuid\r