[edk2-devel] [PATCH v10 1/4] OvmfPkg: Add memory acceptance event in AmdSevDxe

Dionna Glaze via groups.io dionnaglaze=google.com at groups.io
Thu Jan 26 00:56:44 UTC 2023


The added behavior is to accept all unaccepted memory at
ExitBootServices if the behavior is not disabled. This allows safe
upgrades for OS loaders to affirm their support for the unaccepted
memory type.

Cc: Gerd Hoffmann <kraxel at redhat.com>
Cc: James Bottomley <jejb at linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: "Min M. Xu" <min.m.xu at intel.com>
Cc: Andrew Fish <afish at apple.com>
Cc: "Michael D. Kinney" <michael.d.kinney at intel.com>

Signed-off-by: Dionna Glaze <dionnaglaze at google.com>
---
 OvmfPkg/AmdSevDxe/AmdSevDxe.c   | 109 ++++++++++++++++++++
 OvmfPkg/AmdSevDxe/AmdSevDxe.inf |   1 +
 2 files changed, 110 insertions(+)

diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
index f7600c3c81..5eec76fea2 100644
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
@@ -20,6 +20,7 @@
 #include <Library/UefiBootServicesTableLib.h>
 #include <Guid/ConfidentialComputingSevSnpBlob.h>
 #include <Library/PcdLib.h>
+#include <Pi/PrePiDxeCis.h>
 #include <Protocol/MemoryAccept.h>
 
 STATIC CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION  mSnpBootDxeTable = {
@@ -34,6 +35,10 @@ STATIC CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION  mSnpBootDxeTable = {
 
 STATIC EFI_HANDLE  mAmdSevDxeHandle = NULL;
 
+STATIC BOOLEAN  mAcceptAllMemoryAtEBS = TRUE;
+
+STATIC EFI_EVENT  mAcceptAllMemoryEvent = NULL;
+
 #define IS_ALIGNED(x, y)  ((((x) & ((y) - 1)) == 0))
 
 STATIC
@@ -62,6 +67,94 @@ AmdSevMemoryAccept (
   return EFI_SUCCESS;
 }
 
+STATIC
+EFI_STATUS
+AcceptAllMemory (
+  IN EDKII_MEMORY_ACCEPT_PROTOCOL  *AcceptMemory
+  )
+{
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *AllDescMap;
+  UINTN                            NumEntries;
+  UINTN                            Index;
+  EFI_STATUS                       Status;
+
+  DEBUG ((DEBUG_INFO, "Accepting all memory\n"));
+
+  /*
+   * Get a copy of the memory space map to iterate over while
+   * changing the map.
+   */
+  Status = gDS->GetMemorySpaceMap (&NumEntries, &AllDescMap);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < NumEntries; Index++) {
+    CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Desc;
+
+    Desc = &AllDescMap[Index];
+    if (Desc->GcdMemoryType != EFI_GCD_MEMORY_TYPE_UNACCEPTED) {
+      continue;
+    }
+
+    Status = AcceptMemory->AcceptMemory (
+                             AcceptMemory,
+                             Desc->BaseAddress,
+                             Desc->Length
+                             );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    Status = gDS->RemoveMemorySpace (Desc->BaseAddress, Desc->Length);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    Status = gDS->AddMemorySpace (
+                    EfiGcdMemoryTypeSystemMemory,
+                    Desc->BaseAddress,
+                    Desc->Length,
+                    EFI_MEMORY_CPU_CRYPTO | EFI_MEMORY_XP | EFI_MEMORY_RO | EFI_MEMORY_RP
+                    );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+  }
+
+  gBS->FreePool (AllDescMap);
+  return Status;
+}
+
+VOID
+EFIAPI
+ResolveUnacceptedMemory (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EDKII_MEMORY_ACCEPT_PROTOCOL  *AcceptMemory;
+  EFI_STATUS                    Status;
+
+  if (!mAcceptAllMemoryAtEBS) {
+    return;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEdkiiMemoryAcceptProtocolGuid,
+                  NULL,
+                  (VOID **)&AcceptMemory
+                  );
+  if (Status == EFI_NOT_FOUND) {
+    return;
+  }
+
+  ASSERT_EFI_ERROR (Status);
+
+  Status = AcceptAllMemory (AcceptMemory);
+  ASSERT_EFI_ERROR (Status);
+}
+
 STATIC EDKII_MEMORY_ACCEPT_PROTOCOL  mMemoryAcceptProtocol = {
   AmdSevMemoryAccept
 };
@@ -195,6 +288,22 @@ AmdSevDxeEntryPoint (
                     );
     ASSERT_EFI_ERROR (Status);
 
+    // SEV-SNP support does not automatically imply unaccepted memory support,
+    // so make ExitBootServices accept all unaccepted memory if support is
+    // not communicated.
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    ResolveUnacceptedMemory,
+                    NULL,
+                    &gEfiEventBeforeExitBootServicesGuid,
+                    &mAcceptAllMemoryEvent
+                    );
+
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "AllowUnacceptedMemory event creation for EventBeforeExitBootServices failed.\n"));
+    }
+
     //
     // If its SEV-SNP active guest then install the CONFIDENTIAL_COMPUTING_SEV_SNP_BLOB.
     // It contains the location for both the Secrets and CPUID page.
diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
index cd1b686c53..5b443d45bc 100644
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
@@ -52,6 +52,7 @@
 
 [Guids]
   gConfidentialComputingSevSnpBlobGuid
+  gEfiEventBeforeExitBootServicesGuid
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
-- 
2.39.1.456.gfc5497dd1b-goog



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#99050): https://edk2.groups.io/g/devel/message/99050
Mute This Topic: https://groups.io/mt/96534752/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list