]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/DxeCapsuleLibFmp: clone ESRT for runtime access
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sat, 20 Apr 2019 10:34:54 +0000 (12:34 +0200)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 23 Apr 2019 16:15:00 +0000 (18:15 +0200)
The DxeCapsuleLibFmp code accesses the ESRT table to decide whether
a certain capsule is an FMP capsule. Since the UEFI spec mandates
that the ESRT resides in EfiBootServicesData memory, this results
in problems at OS runtime, since the firmware implementation itself
cannot access memory that has not been virtually remapped.

So let's take a private copy of the ESRT at ReadyToBoot, and store
it in EfiRuntimeServicesData memory. The ESRT's size is order 10s
of bytes so the memory footprint is going to be negligigble.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c
MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf

index 602921d13c06fd4d65e6546b52881d3fd79f74a8..f94044a409185fb1def509f6f9eb31c5b3e1ba99 100644 (file)
@@ -23,6 +23,7 @@
 extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable;\r
 extern BOOLEAN                   mIsVirtualAddrConverted;\r
 EFI_EVENT                 mDxeRuntimeCapsuleLibVirtualAddressChangeEvent  = NULL;\r
+EFI_EVENT                 mDxeRuntimeCapsuleLibReadyToBootEvent  = NULL;\r
 \r
 /**\r
   Convert EsrtTable physical address to virtual address.\r
@@ -38,8 +39,28 @@ DxeCapsuleLibVirtualAddressChangeEvent (
   IN  VOID        *Context\r
   )\r
 {\r
-  UINTN                    Index;\r
-  EFI_CONFIGURATION_TABLE  *ConfigEntry;\r
+  gRT->ConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mEsrtTable);\r
+  mIsVirtualAddrConverted = TRUE;\r
+}\r
+\r
+/**\r
+  Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT.\r
+\r
+  @param[in]  Event   The Event that is being processed.\r
+  @param[in]  Context The Event Context.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+DxeCapsuleLibReadyToBootEventNotify (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+{\r
+  UINTN                       Index;\r
+  EFI_CONFIGURATION_TABLE     *ConfigEntry;\r
+  EFI_SYSTEM_RESOURCE_TABLE   *EsrtTable;\r
 \r
   //\r
   // Get Esrt table first\r
@@ -59,16 +80,19 @@ DxeCapsuleLibVirtualAddressChangeEvent (
     //\r
     // Search Esrt to check given capsule is qualified\r
     //\r
-    mEsrtTable = (EFI_SYSTEM_RESOURCE_TABLE *) ConfigEntry->VendorTable;\r
+    EsrtTable = (EFI_SYSTEM_RESOURCE_TABLE *) ConfigEntry->VendorTable;\r
+\r
+    mEsrtTable = AllocateRuntimeCopyPool (\r
+                   sizeof (EFI_SYSTEM_RESOURCE_TABLE) +\r
+                   EsrtTable->FwResourceCount * sizeof (EFI_SYSTEM_RESOURCE_ENTRY),\r
+                   EsrtTable);\r
+    ASSERT (mEsrtTable != NULL);\r
 \r
     //\r
-    // Update protocol pointer to Esrt Table.\r
+    // Set FwResourceCountMax to a sane value.\r
     //\r
-    gRT->ConvertPointer (0x00, (VOID**) &(mEsrtTable));\r
+    mEsrtTable->FwResourceCountMax = mEsrtTable->FwResourceCount;\r
   }\r
-\r
-  mIsVirtualAddrConverted = TRUE;\r
-\r
 }\r
 \r
 /**\r
@@ -101,6 +125,19 @@ DxeRuntimeCapsuleLibConstructor (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Register notify function to cache the FMP capsule GUIDs at ReadyToBoot.\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  DxeCapsuleLibReadyToBootEventNotify,\r
+                  NULL,\r
+                  &gEfiEventReadyToBootGuid,\r
+                  &mDxeRuntimeCapsuleLibReadyToBootEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -127,5 +164,11 @@ DxeRuntimeCapsuleLibDestructor (
   Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibVirtualAddressChangeEvent);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Close the ReadyToBoot event.\r
+  //\r
+  Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibReadyToBootEvent);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   return EFI_SUCCESS;\r
 }\r
index 700d0d5dcdddce84081c1227b55ffbea1afa7694..2c93e6870023333afd786c29e85850febb56ec95 100644 (file)
@@ -66,6 +66,7 @@
   gEfiCapsuleReportGuid\r
   gEfiCapsuleVendorGuid                   ## SOMETIMES_CONSUMES ## Variable:L"CapsuleUpdateData"\r
   gEfiEndOfDxeEventGroupGuid              ## CONSUMES ## Event\r
+  gEfiEventReadyToBootGuid                ## CONSUMES ## Event\r
   gEfiEventVirtualAddressChangeGuid       ## CONSUMES ## Event\r
 \r
 [Depex]\r