public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v5 0/7] Add safe unaccepted memory behavior
@ 2022-09-30 23:06 Dionna Glaze
  2022-09-30 23:06 ` [PATCH v5 1/7] OvmfPkg: Realize EfiMemoryAcceptProtocol in AmdSevDxe Dionna Glaze
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Dionna Glaze @ 2022-09-30 23:06 UTC (permalink / raw)
  To: devel
  Cc: Dionna Glaze, Ard Biescheuvel, Min M. Xu, Gerd Hoffmann,
	James Bottomley, Tom Lendacky, Jiewen Yao, Erdem Aktas,
	Andrew Fish, Michael D. Kinney

These seven patches build on the lazy-accept patch series

"Introduce Lazy-accept for Tdx guest"

by adding SEV-SNP support for the MemoryAccept protocol, and
importantly making eager memory acceptance the default behavior.

We add a new protocol, ExitBootServicesCallbackProtocol, with a single
interface: TerminateMemoryMapPrehook(). We invoke all prehooks in
CoreExitBootServices after disabling the timer and before
TerminateMemoryMap. This gives hooks the chance to change the memory
map and cause ExitBootServices to fail with EFI_INVALID_PARAMETER.
The failure is specified to require the caller to update their view
of the MemoryMap and call ExitBootServices again.

To make use of this new protocol, we add a new driver that is meant to
carry behavior that is needed for all confidential compute technologies,
not just specific platforms, CocoDxe. In CocoDxe we implement the
default safe behavior to accept all unaccepted memory and invalidate
the MemoryMap on ExitBootServices.

To allow the OS loader to prevent the eager acceptance, add another
protocol, up for standardization, AcceptAllUnacceptedMemoryProtocol.
This protocol has one interface, Disable(). The OS loader can inform the
UEFI that it supports the unaccepted memory type and accepts the
responsibility to accept it.

All images that support unaccepted memory must now locate and call this
new BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL and call the Disable
function.

Changes since v4:
 - Commit message wording
 - Replaced direct change to DxeMain with a more generic callback
   protocol.
 - Implemented the direct change as an instance of the callback protocol
   from a new CocoDxe driver.
 - Replaced "enable" protocol with a "disable" protocol, since the name
   was confusing. The AcceptAllUnacceptedMemory protocol directly names
   the behavior that is disabling.

Changes since v3:
 - "DxeMain accepts all memory" patch split into 3 to make each patch
   affect only one package at a time.

Changes since v2:
 - Removed the redundant memory accept interface and added the accept
   behavior to the DXE implementation of
   MemEncryptSevSnpPreValidateSystemRam.
 - Fixed missing #include in >=4GB patch.

Changes since v1:
 - Added a patch to classify SEV-SNP memory above 4GB unaccepted.
 - Fixed style problems in EfiMemoryAcceptProtocol implementation.

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

Dionna Glaze (7):
  OvmfPkg: Realize EfiMemoryAcceptProtocol in AmdSevDxe
  MdePkg: Introduce ExitBootServicesCallbackProtocol
  MdeModulePkg: Invoke all ExitBootServicesCallback instances at
    ExitBootServices
  OvmfPkg: Introduce CocoDxe driver
  MdePkg: Introduce the AcceptAllUnacceptedMemory protocol
  OvmfPkg: Implement AcceptAllUnacceptedMemory in CocoDxe
  OvmfPkg/PlatformPei: SEV-SNP make >=4GB unaccepted

 MdeModulePkg/Core/Dxe/DxeMain.inf                                  |   1 +
 MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c                            |  62 +++++++
 MdePkg/Include/Protocol/AcceptAllUnacceptedMemory.h                |  40 +++++
 MdePkg/Include/Protocol/ExitBootServicesCallback.h                 |  38 +++++
 MdePkg/MdePkg.dec                                                  |   6 +
 OvmfPkg/AmdSev/AmdSevX64.dsc                                       |   1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf                                       |   1 +
 OvmfPkg/AmdSevDxe/AmdSevDxe.c                                      |  57 ++++++-
 OvmfPkg/AmdSevDxe/AmdSevDxe.inf                                    |   3 +
 OvmfPkg/CocoDxe/CocoDxe.c                                          | 174 ++++++++++++++++++++
 OvmfPkg/CocoDxe/CocoDxe.inf                                        |  44 +++++
 OvmfPkg/IntelTdx/IntelTdxX64.dsc                                   |   1 +
 OvmfPkg/IntelTdx/IntelTdxX64.fdf                                   |   1 +
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c |  24 ++-
 OvmfPkg/OvmfPkgIa32X64.dsc                                         |   1 +
 OvmfPkg/OvmfPkgIa32X64.fdf                                         |   1 +
 OvmfPkg/OvmfPkgX64.dsc                                             |   1 +
 OvmfPkg/OvmfPkgX64.fdf                                             |   1 +
 OvmfPkg/PlatformPei/AmdSev.c                                       |   5 +
 19 files changed, 454 insertions(+), 8 deletions(-)
 create mode 100644 MdePkg/Include/Protocol/AcceptAllUnacceptedMemory.h
 create mode 100644 MdePkg/Include/Protocol/ExitBootServicesCallback.h
 create mode 100644 OvmfPkg/CocoDxe/CocoDxe.c
 create mode 100644 OvmfPkg/CocoDxe/CocoDxe.inf

-- 
2.38.0.rc1.362.ged0d419d3c-goog


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v5 1/7] OvmfPkg: Realize EfiMemoryAcceptProtocol in AmdSevDxe
  2022-09-30 23:06 [PATCH v5 0/7] Add safe unaccepted memory behavior Dionna Glaze
@ 2022-09-30 23:06 ` Dionna Glaze
  2022-10-03 14:52   ` Lendacky, Thomas
  2022-09-30 23:06 ` [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol Dionna Glaze
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Dionna Glaze @ 2022-09-30 23:06 UTC (permalink / raw)
  To: devel
  Cc: Dionna Glaze, Gerd Hoffmann, James Bottomley, Jiewen Yao,
	Tom Lendacky

From: Sophia Wolf <phiawolf@google.com>

When a guest OS does not support unaccepted memory, the unaccepted
memory must be accepted before returning a memory map to the caller.

EfiMemoryAcceptProtocol is defined in MdePkg and is implemented /
Installed in AmdSevDxe for AMD SEV-SNP memory acceptance.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 OvmfPkg/AmdSevDxe/AmdSevDxe.c                                      | 57 ++++++++++++++++++--
 OvmfPkg/AmdSevDxe/AmdSevDxe.inf                                    |  3 ++
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c | 24 +++++++--
 3 files changed, 76 insertions(+), 8 deletions(-)

diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
index 662d3c4ccb..77d3caa833 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 <Protocol/MemoryAccept.h>
 
 STATIC CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION  mSnpBootDxeTable = {
   SIGNATURE_32 ('A',                                    'M', 'D', 'E'),
@@ -31,6 +32,38 @@ STATIC CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION  mSnpBootDxeTable = {
   FixedPcdGet32 (PcdOvmfCpuidSize),
 };
 
+STATIC EFI_HANDLE mAmdSevDxeHandle = NULL;
+
+STATIC
+EFI_STATUS
+EFIAPI
+AmdSevMemoryAccept (
+  IN EFI_MEMORY_ACCEPT_PROTOCOL *This,
+  IN EFI_PHYSICAL_ADDRESS StartAddress,
+  IN UINTN Size
+)
+{
+  //
+  // The StartAddress must be page-aligned, and the Size must be a positive
+  // multiple of SIZE_4KB. Use an assert instead of returning an erros since
+  // this is an EDK2-internal protocol.
+  //
+  ASSERT (((StartAddress & ~(SIZE_4KB - 1)) == 0) &&
+          ((Size & ~(SIZE_4KB - 1)) == 0) &&
+          (Size != 0));
+
+  MemEncryptSevSnpPreValidateSystemRam (
+    StartAddress,
+    EFI_SIZE_TO_PAGES (Size)
+    );
+
+  return EFI_SUCCESS;
+}
+
+STATIC EFI_MEMORY_ACCEPT_PROTOCOL mMemoryAcceptProtocol = {
+  AmdSevMemoryAccept
+};
+
 EFI_STATUS
 EFIAPI
 AmdSevDxeEntryPoint (
@@ -147,11 +180,27 @@ AmdSevDxeEntryPoint (
     }
   }
 
-  //
-  // 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.
-  //
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Install EfiMemoryAcceptProtocol failed.\n"));
+  }
+
   if (MemEncryptSevSnpIsEnabled ()) {
+    //
+    // Memory acceptance began being required in SEV-SNP, so install the
+    // memory accept protocol implementation for a SEV-SNP active guest.
+    //
+    Status = gBS->InstallProtocolInterface (
+                  &mAmdSevDxeHandle,
+                  &gEfiMemoryAcceptProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mMemoryAcceptProtocol
+                  );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // 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.
+    //
     return gBS->InstallConfigurationTable (
                   &gConfidentialComputingSevSnpBlobGuid,
                   &mSnpBootDxeTable
diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
index 9acf860cf2..5ddddabc32 100644
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
@@ -47,6 +47,9 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
 
+[Protocols]
+  gEfiMemoryAcceptProtocolGuid
+
 [Guids]
   gConfidentialComputingSevSnpBlobGuid
 
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
index d3a95e4913..ee3710f7b3 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
@@ -14,6 +14,7 @@
 #include <Library/MemEncryptSevLib.h>
 
 #include "SnpPageStateChange.h"
+#include "VirtualMemory.h"
 
 /**
   Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
@@ -29,12 +30,27 @@ MemEncryptSevSnpPreValidateSystemRam (
   IN UINTN             NumPages
   )
 {
+  EFI_STATUS Status;
+
   if (!MemEncryptSevSnpIsEnabled ()) {
     return;
   }
 
-  //
-  // All the pre-validation must be completed in the PEI phase.
-  //
-  ASSERT (FALSE);
+  // DXE pre-validation may happen with the memory accept protocol.
+  // The protocol should only be called outside the prevalidated ranges
+  // that the PEI stage code explicitly skips. Specifically, only memory
+  // ranges that are classified as unaccepted.
+  if (BaseAddress >= SIZE_4GB) {
+    Status = InternalMemEncryptSevCreateIdentityMap1G (
+               0,
+               BaseAddress,
+               EFI_PAGES_TO_SIZE (NumPages)
+               );
+    if (EFI_ERROR (Status)) {
+      ASSERT (FALSE);
+      CpuDeadLoop ();
+    }
+  }
+
+  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
 }
-- 
2.38.0.rc1.362.ged0d419d3c-goog


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol
  2022-09-30 23:06 [PATCH v5 0/7] Add safe unaccepted memory behavior Dionna Glaze
  2022-09-30 23:06 ` [PATCH v5 1/7] OvmfPkg: Realize EfiMemoryAcceptProtocol in AmdSevDxe Dionna Glaze
@ 2022-09-30 23:06 ` Dionna Glaze
  2022-10-01  0:15   ` [edk2-devel] " Ni, Ray
  2022-09-30 23:06 ` [PATCH v5 3/7] MdeModulePkg: Invoke all ExitBootServicesCallback instances at ExitBootServices Dionna Glaze
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Dionna Glaze @ 2022-09-30 23:06 UTC (permalink / raw)
  To: devel
  Cc: Dionna Glaze, Gerd Hoffmann, Min M. Xu, James Bottomley,
	Jiewen Yao, Tom Lendacky, Ard Biesheuvel, Andrew Fish,
	Michael D. Kinney

This introduces a callback after the time that the timer is disabled and before
the MemoryMap is finalized.

This callback is useful to make final changes to the memory map due to protocols
initiated (or not initiated) by the OS loader.

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

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 MdePkg/Include/Protocol/ExitBootServicesCallback.h | 38 ++++++++++++++++++++
 MdePkg/MdePkg.dec                                  |  3 ++
 2 files changed, 41 insertions(+)

diff --git a/MdePkg/Include/Protocol/ExitBootServicesCallback.h b/MdePkg/Include/Protocol/ExitBootServicesCallback.h
new file mode 100644
index 0000000000..d21d7700f7
--- /dev/null
+++ b/MdePkg/Include/Protocol/ExitBootServicesCallback.h
@@ -0,0 +1,38 @@
+/** @file
+  The file provides the protocol that allows callbacks in ExitBootServices
+  immediately before TerminateMemoryMap.
+
+  Copyright (c) 2022, Google LLC. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef EXIT_BOOT_SERVICES_CALLBACK_H_
+#define EXIT_BOOT_SERVICES_CALLBACK_H_
+
+/* This protocol is internal to EDK2 only */
+
+#define EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL_GUID   {0xf5684799,                                             0x9a33,                                                 0x40f7,                                                 {0xa1, 0x5c, 0x10, 0x8e, 0x0e, 0x6b, 0x45, 0x25}}
+
+typedef struct _EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL
+    EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL;
+
+/**
+  @param This A pointer to a EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_TERMINATE_MEMORY_MAP_PREHOOK)(
+  IN  EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL  *This
+  );
+
+///
+/// The EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL allows callbacks in
+/// ExitBootServices immediately before TerminateMemoryMap.
+///
+struct _EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL {
+  EDKII_TERMINATE_MEMORY_MAP_PREHOOK  TerminateMemoryMapPrehook;
+  BOOLEAN                             Disabled;
+};
+
+extern EFI_GUID  gEdkiiExitBootServicesCallbackProtocolGuid;
+
+#endif
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index de3c56758b..43b099b396 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1019,6 +1019,9 @@
   gEfiPeiDelayedDispatchPpiGuid  = { 0x869c711d, 0x649c, 0x44fe, { 0x8b, 0x9e, 0x2c, 0xbb, 0x29, 0x11, 0xc3, 0xe6 }}
 
 [Protocols]
+  ## Include/Protocol/ExitBootServicesCallback.h
+  gEdkiiExitBootServicesCallbackProtocolGuid = { 0xf5684799, 0x9a33, 0x40f7, {0xa1, 0x5c, 0x10, 0x8e, 0x0e, 0x6b, 0x45, 0x25 }}
+
   ## Include/Protocol/MemoryAccept.h
   gEfiMemoryAcceptProtocolGuid   = { 0x38c74800, 0x5590, 0x4db4, { 0xa0, 0xf3, 0x67, 0x5d, 0x9b, 0x8e, 0x80, 0x26 }}
 
-- 
2.38.0.rc1.362.ged0d419d3c-goog


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 3/7] MdeModulePkg: Invoke all ExitBootServicesCallback instances at ExitBootServices
  2022-09-30 23:06 [PATCH v5 0/7] Add safe unaccepted memory behavior Dionna Glaze
  2022-09-30 23:06 ` [PATCH v5 1/7] OvmfPkg: Realize EfiMemoryAcceptProtocol in AmdSevDxe Dionna Glaze
  2022-09-30 23:06 ` [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol Dionna Glaze
@ 2022-09-30 23:06 ` Dionna Glaze
  2022-10-03 11:33   ` Ard Biesheuvel
  2022-09-30 23:06 ` [PATCH v5 4/7] OvmfPkg: Introduce CocoDxe driver Dionna Glaze
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Dionna Glaze @ 2022-09-30 23:06 UTC (permalink / raw)
  To: devel
  Cc: Dionna Glaze, Gerd Hoffmann, James Bottomley, Jiewen Yao,
	Tom Lendacky, Ard Biesheuvel, Min M. Xu, Andrew Fish,
	Michael D. Kinney

The protocol's intent is to allow drivers to install callbacks that can
modify the memory map at ExitBootServices time, so that any changes will
lead to the EFI_INVALID_PARAMETER error. This error is specified to require
the EBS caller to call GetMemoryMap again if it already had.

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

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 MdeModulePkg/Core/Dxe/DxeMain.inf       |  1 +
 MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 62 ++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index e4bca89577..bdd9cf8222 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -153,6 +153,7 @@
   gEfiHiiPackageListProtocolGuid                ## SOMETIMES_PRODUCES
   gEfiSmmBase2ProtocolGuid                      ## SOMETIMES_CONSUMES
   gEdkiiPeCoffImageEmulatorProtocolGuid         ## SOMETIMES_CONSUMES
+  gEdkiiExitBootServicesCallbackProtocolGuid    ## CONSUMES
 
   # Arch Protocols
   gEfiBdsArchProtocolGuid                       ## CONSUMES
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
index 5733f0c8ec..8cf7d6bcbf 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -6,6 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
 
+#include <Protocol/ExitBootServicesCallback.h>
 #include "DxeMain.h"
 
 //
@@ -744,6 +745,54 @@ CalculateEfiHdrCrc (
   Hdr->CRC32 = Crc;
 }
 
+/**
+  Invokes TerminateMemoryMapPrehook from every instance of the
+  EdkiiExitBootServicesProtocol.
+**/
+STATIC
+EFI_STATUS
+InvokeTerminateMemoryMapPrehooks (
+  VOID
+  )
+{
+  UINTN       NoHandles;
+  UINTN       Index;
+  EFI_HANDLE  *HandleBuffer;
+  EFI_STATUS  Status;
+  EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL *Callback;
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEdkiiExitBootServicesCallbackProtocolGuid,
+                  NULL,
+                  &NoHandles,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status) && NoHandles == 0) {
+    return Status;
+  }
+
+  for (Index = 0; Index < NoHandles; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEdkiiExitBootServicesCallbackProtocolGuid,
+                    (VOID **)&Callback
+                    );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    Status = Callback->TerminateMemoryMapPrehook(Callback);
+    if (EFI_ERROR (Status) || Status == EFI_WARN_STALE_DATA) {
+      goto done;
+    }
+  }
+
+done:
+  FreePool(HandleBuffer);
+  return Status;
+}
+
 /**
   Terminates all boot services.
 
@@ -768,6 +817,19 @@ CoreExitBootServices (
   //
   gTimer->SetTimerPeriod (gTimer, 0);
 
+  //
+  // Invoke all protocols installed for ExitBootServices prior to
+  // CoreTerminateMemoryMap.
+  //
+  Status = InvokeTerminateMemoryMapPrehooks();
+  if (EFI_ERROR (Status)) {
+    //
+    // Notify other drivers that ExitBootServices failed
+    //
+    CoreNotifySignalList (&gEventExitBootServicesFailedGuid);
+    return Status;
+  }
+
   //
   // Terminate memory services if the MapKey matches
   //
-- 
2.38.0.rc1.362.ged0d419d3c-goog


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 4/7] OvmfPkg: Introduce CocoDxe driver
  2022-09-30 23:06 [PATCH v5 0/7] Add safe unaccepted memory behavior Dionna Glaze
                   ` (2 preceding siblings ...)
  2022-09-30 23:06 ` [PATCH v5 3/7] MdeModulePkg: Invoke all ExitBootServicesCallback instances at ExitBootServices Dionna Glaze
@ 2022-09-30 23:06 ` Dionna Glaze
  2022-09-30 23:06 ` [PATCH v5 5/7] MdePkg: Introduce the AcceptAllUnacceptedMemory protocol Dionna Glaze
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Dionna Glaze @ 2022-09-30 23:06 UTC (permalink / raw)
  To: devel
  Cc: Dionna Glaze, Gerd Hoffmann, James Bottomley, Jiewen Yao,
	Tom Lendacky, Ard Biesheuvel, Min M. Xu, Andrew Fish,
	Michael D. Kinney

This driver is meant as a join point for all Confidential Compute
technologies to put shared behavior that doesn't belong anywhere else.

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

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

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc     |   1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf     |   1 +
 OvmfPkg/CocoDxe/CocoDxe.c        | 149 ++++++++++++++++++++
 OvmfPkg/CocoDxe/CocoDxe.inf      |  43 ++++++
 OvmfPkg/IntelTdx/IntelTdxX64.dsc |   1 +
 OvmfPkg/IntelTdx/IntelTdxX64.fdf |   1 +
 OvmfPkg/OvmfPkgIa32X64.dsc       |   1 +
 OvmfPkg/OvmfPkgIa32X64.fdf       |   1 +
 OvmfPkg/OvmfPkgX64.dsc           |   1 +
 OvmfPkg/OvmfPkgX64.fdf           |   1 +
 10 files changed, 200 insertions(+)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 90e8a213ef..ad6b73ca4a 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -747,6 +747,7 @@
     <LibraryClasses>
     PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
   }
+  OvmfPkg/CocoDxe/CocoDxe.inf
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
   #
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 4658e1d30e..3717ec9094 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -302,6 +302,7 @@ INF  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
 INF  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
 INF  OvmfPkg/PlatformDxe/Platform.inf
 INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+INF  OvmfPkg/CocoDxe/CocoDxe.inf
 INF  OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
 
diff --git a/OvmfPkg/CocoDxe/CocoDxe.c b/OvmfPkg/CocoDxe/CocoDxe.c
new file mode 100644
index 0000000000..dc37c292f4
--- /dev/null
+++ b/OvmfPkg/CocoDxe/CocoDxe.c
@@ -0,0 +1,149 @@
+/** @file
+
+  Confidential Compute Dxe driver. This driver installs protocols that are
+  generic over confidential compute techonology.
+
+  Copyright (c) 2022, Google LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/MemEncryptTdxLib.h>
+#include <Protocol/ExitBootServicesCallback.h>
+#include <Protocol/MemoryAccept.h>
+
+STATIC EFI_HANDLE mCocoDxeHandle = NULL;
+
+STATIC
+EFI_STATUS
+AcceptAllUnacceptedMemory (
+  IN EFI_MEMORY_ACCEPT_PROTOCOL *AcceptMemory
+  )
+{
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *AllDescMap;
+  UINTN                            NumEntries;
+  UINTN                            Index;
+  EFI_STATUS                       Status;
+  BOOLEAN                          AcceptedAny;
+
+  DEBUG ((DEBUG_INFO, "Accepting all memory\n"));
+  AcceptedAny = FALSE;
+  /*
+   * 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 != EfiGcdMemoryTypeUnaccepted) {
+      continue;
+    }
+
+    Status = AcceptMemory->AcceptMemory (
+      AcceptMemory,
+      Desc->BaseAddress,
+      Desc->Length
+      );
+    if (EFI_ERROR(Status)) {
+      goto done;
+    }
+
+    Status = gDS->RemoveMemorySpace(Desc->BaseAddress, Desc->Length);
+    if (EFI_ERROR(Status)) {
+      goto done;
+    }
+
+    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)) {
+      goto done;
+    }
+
+    AcceptedAny = TRUE;
+  }
+
+  // If any memory is accepted, cause ExitBootServices to fail with
+  // EFI_INVALID_PARAMETER in order to force the caller to refresh
+  // their view of the MemoryMap.
+  if (AcceptedAny) {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+done:
+  gBS->FreePool (AllDescMap);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+ResolveUnacceptedMemory (
+  IN EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL  *This
+  )
+{
+  EFI_MEMORY_ACCEPT_PROTOCOL *AcceptMemory;
+  EFI_STATUS                 Status;
+
+  if (This->Disabled) {
+    return EFI_SUCCESS;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiMemoryAcceptProtocolGuid, NULL,
+    (VOID **)&AcceptMemory);
+  if (Status == EFI_NOT_FOUND) {
+    return EFI_SUCCESS;
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  return AcceptAllUnacceptedMemory(AcceptMemory);
+}
+
+STATIC EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL mExitBootServicesCallbackProcotol = {
+  ResolveUnacceptedMemory,
+  FALSE,
+};
+
+EFI_STATUS
+EFIAPI
+CocoDxeEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Do nothing when confidential compute technologies that require memory
+  // acceptance are not enabled.
+  //
+  if (!MemEncryptSevSnpIsEnabled () &&
+      !MemEncryptTdxIsEnabled ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = gBS->InstallProtocolInterface (&mCocoDxeHandle,
+                  &gEdkiiExitBootServicesCallbackProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mExitBootServicesCallbackProcotol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Install EdkiiExitBootServicesCallbackProtocol failed.\n"));
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/CocoDxe/CocoDxe.inf b/OvmfPkg/CocoDxe/CocoDxe.inf
new file mode 100644
index 0000000000..3ff2a6fade
--- /dev/null
+++ b/OvmfPkg/CocoDxe/CocoDxe.inf
@@ -0,0 +1,43 @@
+#/** @file
+#
+#  Driver installs shared protocols needed for confidential compute
+#  technologies.
+#
+#  Copyright (c) 2022, Google LLC. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 1.25
+  BASE_NAME                      = CocoDxe
+  FILE_GUID                      = 08162f1e-5147-4d3e-b5a9-fa48c9808419
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = CocoDxeEntryPoint
+
+[Sources]
+  CocoDxe.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DxeServicesTableLib
+  MemEncryptSevLib
+  MemEncryptTdxLib
+  MemoryAllocationLib
+  UefiDriverEntryPoint
+
+[Depex]
+  TRUE
+
+[Protocols]
+  gEdkiiExitBootServicesCallbackProtocolGuid
+  gEfiMemoryAcceptProtocolGuid
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index c0c1a15b09..8136d50eb2 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -753,6 +753,7 @@
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
   OvmfPkg/TdxDxe/TdxDxe.inf
+  OvmfPkg/CocoDxe/CocoDxe.inf
 
   #
   # Variable driver stack (non-SMM)
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.fdf b/OvmfPkg/IntelTdx/IntelTdxX64.fdf
index 6923eb8831..e612608c0c 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.fdf
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.fdf
@@ -269,6 +269,7 @@ INF  ShellPkg/Application/Shell/Shell.inf
 INF MdeModulePkg/Logo/LogoDxe.inf
 
 INF OvmfPkg/TdxDxe/TdxDxe.inf
+INF OvmfPkg/CocoDxe/CocoDxe.inf
 
 #
 # Usb Support
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index af566b953f..2cfb3fbc6b 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -965,6 +965,7 @@
     <LibraryClasses>
     PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
   }
+  OvmfPkg/CocoDxe/CocoDxe.inf
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
 !if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index 80de4fa2c0..2ab7f3b95b 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -343,6 +343,7 @@ INF  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
 INF  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
 INF  OvmfPkg/PlatformDxe/Platform.inf
 INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+INF  OvmfPkg/CocoDxe/CocoDxe.inf
 INF  OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
 !if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index f39d9cd117..3ead476b61 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -1036,6 +1036,7 @@
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
   OvmfPkg/TdxDxe/TdxDxe.inf
+  OvmfPkg/CocoDxe/CocoDxe.inf
 
 !if $(SMM_REQUIRE) == TRUE
   OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index c0f5a1ef3c..5dd452f42b 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -370,6 +370,7 @@ INF  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
 INF  OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
 INF  OvmfPkg/PlatformDxe/Platform.inf
 INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+INF  OvmfPkg/CocoDxe/CocoDxe.inf
 INF  OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
 !if $(SMM_REQUIRE) == TRUE
-- 
2.38.0.rc1.362.ged0d419d3c-goog


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 5/7] MdePkg: Introduce the AcceptAllUnacceptedMemory protocol
  2022-09-30 23:06 [PATCH v5 0/7] Add safe unaccepted memory behavior Dionna Glaze
                   ` (3 preceding siblings ...)
  2022-09-30 23:06 ` [PATCH v5 4/7] OvmfPkg: Introduce CocoDxe driver Dionna Glaze
@ 2022-09-30 23:06 ` Dionna Glaze
  2022-09-30 23:06 ` [PATCH v5 6/7] OvmfPkg: Implement AcceptAllUnacceptedMemory in CocoDxe Dionna Glaze
  2022-09-30 23:06 ` [PATCH v5 7/7] OvmfPkg/PlatformPei: SEV-SNP make >=4GB unaccepted Dionna Glaze
  6 siblings, 0 replies; 16+ messages in thread
From: Dionna Glaze @ 2022-09-30 23:06 UTC (permalink / raw)
  To: devel
  Cc: Dionna Glaze, Gerd Hoffmann, James Bottomley, Jiewen Yao,
	Tom Lendacky, Ard Biesheuvel, Min M. Xu, Andrew Fish,
	Michael D. Kinney

The default behavior for unaccepted memory is to accept all memory
when ExitBootServices is called. An OS loader can use this protocol to
Disable this behavior to assume responsibility for memory acceptance and
to affirm that the OS can handle the unaccepted memory type.

This is a candidate for standardization.

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

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 MdePkg/Include/Protocol/AcceptAllUnacceptedMemory.h | 40 ++++++++++++++++++++
 MdePkg/MdePkg.dec                                   |  5 ++-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/MdePkg/Include/Protocol/AcceptAllUnacceptedMemory.h b/MdePkg/Include/Protocol/AcceptAllUnacceptedMemory.h
new file mode 100644
index 0000000000..e50831836c
--- /dev/null
+++ b/MdePkg/Include/Protocol/AcceptAllUnacceptedMemory.h
@@ -0,0 +1,40 @@
+/** @file
+  The file provides the protocol that disables the behavior that all memory
+  gets accepted at ExitBootServices(). This protocol is only meant to be called
+  by the OS loader, and not EDK2 itself.
+
+  Copyright (c) 2022, Google LLC. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _ACCEPT_ALL_UNACCEPTED_MEMORY_H_
+#define _ACCEPT_ALL_UNACCEPTED_MEMORY_H_
+
+#define BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL_GUID \
+  {0xc5a010fe, \
+   0x38a7, \
+   0x4531, \
+   {0x8a, 0x4a, 0x05, 0x00, 0xd2, 0xfd, 0x16, 0x49}}
+
+typedef struct _BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL
+    BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL;
+
+/**
+  @param This A pointer to a BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *BZ3987_DISABLE_ACCEPT_ALL_UNACCEPTED_MEMORY)(
+  IN  BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL  *This
+  );
+
+///
+/// The BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL allows the OS loader to
+/// indicate to EDK2 that ExitBootServices should not accept all memory.
+///
+struct _BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL {
+  BZ3987_DISABLE_ACCEPT_ALL_UNACCEPTED_MEMORY  Disable;
+};
+
+extern EFI_GUID  gBz3987AcceptAllUnacceptedMemoryProtocolGuid;
+
+#endif
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 43b099b396..452c40683e 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1019,8 +1019,11 @@
   gEfiPeiDelayedDispatchPpiGuid  = { 0x869c711d, 0x649c, 0x44fe, { 0x8b, 0x9e, 0x2c, 0xbb, 0x29, 0x11, 0xc3, 0xe6 }}
 
 [Protocols]
+  ## Include/Protocol/AcceptAllUnacceptedMemory.h
+  gBz3987AcceptAllUnacceptedMemoryProtocolGuid = { 0xc5a010fe, 0x38a7, 0x4531, {0x8a, 0x4a, 0x05, 0x00, 0xd2, 0xfd, 0x16, 0x49 }}
+
   ## Include/Protocol/ExitBootServicesCallback.h
-  gEdkiiExitBootServicesCallbackProtocolGuid = { 0xf5684799, 0x9a33, 0x40f7, {0xa1, 0x5c, 0x10, 0x8e, 0x0e, 0x6b, 0x45, 0x25 }}
+  gEdkiiExitBootServicesCallbackProtocolGuid   = { 0xf5684799, 0x9a33, 0x40f7, {0xa1, 0x5c, 0x10, 0x8e, 0x0e, 0x6b, 0x45, 0x25 }}
 
   ## Include/Protocol/MemoryAccept.h
   gEfiMemoryAcceptProtocolGuid   = { 0x38c74800, 0x5590, 0x4db4, { 0xa0, 0xf3, 0x67, 0x5d, 0x9b, 0x8e, 0x80, 0x26 }}
-- 
2.38.0.rc1.362.ged0d419d3c-goog


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 6/7] OvmfPkg: Implement AcceptAllUnacceptedMemory in CocoDxe
  2022-09-30 23:06 [PATCH v5 0/7] Add safe unaccepted memory behavior Dionna Glaze
                   ` (4 preceding siblings ...)
  2022-09-30 23:06 ` [PATCH v5 5/7] MdePkg: Introduce the AcceptAllUnacceptedMemory protocol Dionna Glaze
@ 2022-09-30 23:06 ` Dionna Glaze
  2022-09-30 23:06 ` [PATCH v5 7/7] OvmfPkg/PlatformPei: SEV-SNP make >=4GB unaccepted Dionna Glaze
  6 siblings, 0 replies; 16+ messages in thread
From: Dionna Glaze @ 2022-09-30 23:06 UTC (permalink / raw)
  To: devel
  Cc: Dionna Glaze, Gerd Hoffmann, James Bottomley, Jiewen Yao,
	Tom Lendacky, Ard Biesheuvel, Min M. Xu, Andrew Fish,
	Michael D. Kinney

This protocol implementation disables the accept-all-memory behavior
of the ExitBootServicesCallback instance thise driver adds.

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

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 OvmfPkg/CocoDxe/CocoDxe.c   | 25 ++++++++++++++++++++
 OvmfPkg/CocoDxe/CocoDxe.inf |  1 +
 2 files changed, 26 insertions(+)

diff --git a/OvmfPkg/CocoDxe/CocoDxe.c b/OvmfPkg/CocoDxe/CocoDxe.c
index dc37c292f4..d7478603f7 100644
--- a/OvmfPkg/CocoDxe/CocoDxe.c
+++ b/OvmfPkg/CocoDxe/CocoDxe.c
@@ -16,6 +16,7 @@
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/MemEncryptSevLib.h>
 #include <Library/MemEncryptTdxLib.h>
+#include <Protocol/AcceptAllUnacceptedMemory.h>
 #include <Protocol/ExitBootServicesCallback.h>
 #include <Protocol/MemoryAccept.h>
 
@@ -118,6 +119,21 @@ STATIC EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL mExitBootServicesCallbackProco
   FALSE,
 };
 
+STATIC
+EFI_STATUS
+EFIAPI
+DisableAcceptAllUnacceptedMemory (
+  IN  BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL  *This
+  )
+{
+  mExitBootServicesCallbackProcotol.Disabled = TRUE;
+  return EFI_SUCCESS;
+}
+
+STATIC
+BZ3987_ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL
+mAcceptAllUnacceptedMemoryProtocol = {DisableAcceptAllUnacceptedMemory};
+
 EFI_STATUS
 EFIAPI
 CocoDxeEntryPoint (
@@ -145,5 +161,14 @@ CocoDxeEntryPoint (
     DEBUG ((DEBUG_ERROR, "Install EdkiiExitBootServicesCallbackProtocol failed.\n"));
   }
 
+  Status = gBS->InstallProtocolInterface (&mCocoDxeHandle,
+                  &gBz3987AcceptAllUnacceptedMemoryProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mAcceptAllUnacceptedMemoryProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Install Bz3987AcceptAllUnacceptedMemoryProtocol failed.\n"));
+  }
+
   return EFI_SUCCESS;
 }
diff --git a/OvmfPkg/CocoDxe/CocoDxe.inf b/OvmfPkg/CocoDxe/CocoDxe.inf
index 3ff2a6fade..96ab3e1c68 100644
--- a/OvmfPkg/CocoDxe/CocoDxe.inf
+++ b/OvmfPkg/CocoDxe/CocoDxe.inf
@@ -39,5 +39,6 @@
   TRUE
 
 [Protocols]
+  gBz3987AcceptAllUnacceptedMemoryProtocolGuid
   gEdkiiExitBootServicesCallbackProtocolGuid
   gEfiMemoryAcceptProtocolGuid
-- 
2.38.0.rc1.362.ged0d419d3c-goog


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 7/7] OvmfPkg/PlatformPei: SEV-SNP make >=4GB unaccepted
  2022-09-30 23:06 [PATCH v5 0/7] Add safe unaccepted memory behavior Dionna Glaze
                   ` (5 preceding siblings ...)
  2022-09-30 23:06 ` [PATCH v5 6/7] OvmfPkg: Implement AcceptAllUnacceptedMemory in CocoDxe Dionna Glaze
@ 2022-09-30 23:06 ` Dionna Glaze
  6 siblings, 0 replies; 16+ messages in thread
From: Dionna Glaze @ 2022-09-30 23:06 UTC (permalink / raw)
  To: devel
  Cc: Dionna Glaze, Ard Biescheuvel, Min M. Xu, Gerd Hoffmann,
	James Bottomley, Tom Lendacky, Jiewen Yao, Erdem Aktas

Instead of eagerly accepting all memory in PEI, only accept memory under
the 4GB address. This allows a loaded image to use the
ACCEPT_ALL_UNACCEPTED_MEMORY_PROTOCOL to disable the accept behavior and
indicate that it can interpret the memory type accordingly.

This classification is safe since ExitBootServices will accept and
reclassify the memory as conventional if the disable protocol is not
used.

Cc: Ard Biescheuvel <ardb@kernel.org>
Cc: "Min M. Xu" <min.m.xu@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Tom Lendacky <Thomas.Lendacky@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Erdem Aktas <erdemaktas@google.com>

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 OvmfPkg/PlatformPei/AmdSev.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 385562b44c..2a52d6f491 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -16,6 +16,7 @@
 #include <Library/MemEncryptSevLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
+#include <Pi/PrePiHob.h>
 #include <PiPei.h>
 #include <Register/Amd/Msr.h>
 #include <Register/Intel/SmramSaveStateMap.h>
@@ -63,6 +64,10 @@ AmdSevSnpInitialize (
   for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
     if ((Hob.Raw != NULL) && (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR)) {
       ResourceHob = Hob.ResourceDescriptor;
+      if (ResourceHob->PhysicalStart >= SIZE_4GB) {
+        ResourceHob->ResourceType = EFI_RESOURCE_MEMORY_UNACCEPTED;
+        continue;
+      }
 
       if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
         MemEncryptSevSnpPreValidateSystemRam (
-- 
2.38.0.rc1.362.ged0d419d3c-goog


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol
  2022-09-30 23:06 ` [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol Dionna Glaze
@ 2022-10-01  0:15   ` Ni, Ray
  2022-10-03  1:16     ` Dionna Glaze
  0 siblings, 1 reply; 16+ messages in thread
From: Ni, Ray @ 2022-10-01  0:15 UTC (permalink / raw)
  To: devel@edk2.groups.io, dionnaglaze@google.com
  Cc: Gerd Hoffmann, Xu, Min M, James Bottomley, Yao, Jiewen,
	Tom Lendacky, Ard Biesheuvel, Andrew Fish, Kinney, Michael D

Is it defined by UEFI Spec?

________________________________________
From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Dionna Glaze via groups.io <dionnaglaze=google.com@groups.io>
Sent: Saturday, October 1, 2022 7:06
To: devel@edk2.groups.io
Cc: Dionna Glaze; Gerd Hoffmann; Xu, Min M; James Bottomley; Yao, Jiewen; Tom Lendacky; Ard Biesheuvel; Andrew Fish; Kinney, Michael D
Subject: [edk2-devel] [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol

This introduces a callback after the time that the timer is disabled and before
the MemoryMap is finalized.

This callback is useful to make final changes to the memory map due to protocols
initiated (or not initiated) by the OS loader.

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

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 MdePkg/Include/Protocol/ExitBootServicesCallback.h | 38 ++++++++++++++++++++
 MdePkg/MdePkg.dec                                  |  3 ++
 2 files changed, 41 insertions(+)

diff --git a/MdePkg/Include/Protocol/ExitBootServicesCallback.h b/MdePkg/Include/Protocol/ExitBootServicesCallback.h
new file mode 100644
index 0000000000..d21d7700f7
--- /dev/null
+++ b/MdePkg/Include/Protocol/ExitBootServicesCallback.h
@@ -0,0 +1,38 @@
+/** @file
+  The file provides the protocol that allows callbacks in ExitBootServices
+  immediately before TerminateMemoryMap.
+
+  Copyright (c) 2022, Google LLC. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef EXIT_BOOT_SERVICES_CALLBACK_H_
+#define EXIT_BOOT_SERVICES_CALLBACK_H_
+
+/* This protocol is internal to EDK2 only */
+
+#define EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL_GUID   {0xf5684799,                                             0x9a33,                                                 0x40f7,                                                 {0xa1, 0x5c, 0x10, 0x8e, 0x0e, 0x6b, 0x45, 0x25}}
+
+typedef struct _EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL
+    EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL;
+
+/**
+  @param This A pointer to a EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_TERMINATE_MEMORY_MAP_PREHOOK)(
+  IN  EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL  *This
+  );
+
+///
+/// The EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL allows callbacks in
+/// ExitBootServices immediately before TerminateMemoryMap.
+///
+struct _EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL {
+  EDKII_TERMINATE_MEMORY_MAP_PREHOOK  TerminateMemoryMapPrehook;
+  BOOLEAN                             Disabled;
+};
+
+extern EFI_GUID  gEdkiiExitBootServicesCallbackProtocolGuid;
+
+#endif
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index de3c56758b..43b099b396 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1019,6 +1019,9 @@
   gEfiPeiDelayedDispatchPpiGuid  = { 0x869c711d, 0x649c, 0x44fe, { 0x8b, 0x9e, 0x2c, 0xbb, 0x29, 0x11, 0xc3, 0xe6 }}

 [Protocols]
+  ## Include/Protocol/ExitBootServicesCallback.h
+  gEdkiiExitBootServicesCallbackProtocolGuid = { 0xf5684799, 0x9a33, 0x40f7, {0xa1, 0x5c, 0x10, 0x8e, 0x0e, 0x6b, 0x45, 0x25 }}
+
   ## Include/Protocol/MemoryAccept.h
   gEfiMemoryAcceptProtocolGuid   = { 0x38c74800, 0x5590, 0x4db4, { 0xa0, 0xf3, 0x67, 0x5d, 0x9b, 0x8e, 0x80, 0x26 }}

--
2.38.0.rc1.362.ged0d419d3c-goog







^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol
  2022-10-01  0:15   ` [edk2-devel] " Ni, Ray
@ 2022-10-03  1:16     ` Dionna Glaze
  2022-10-03 11:23       ` Ard Biesheuvel
  0 siblings, 1 reply; 16+ messages in thread
From: Dionna Glaze @ 2022-10-03  1:16 UTC (permalink / raw)
  To: Ni, Ray
  Cc: devel@edk2.groups.io, Gerd Hoffmann, Xu, Min M, James Bottomley,
	Yao, Jiewen, Tom Lendacky, Ard Biesheuvel, Andrew Fish,
	Kinney, Michael D

>
> Is it defined by UEFI Spec?
>

It is not. This is Ard's suggested solution
https://patchew.org/EDK2/20220928153323.2583389-1-dionnaglaze@google.com/20220928153323.2583389-5-dionnaglaze@google.com/#CAMj1kXFwbU9oiULUFXSrqhag1Pf+YU2dL4JbUZ2LO0k9uUEqRg@mail.gmail.com

-- 
-Dionna Glaze, PhD (she/her)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol
  2022-10-03  1:16     ` Dionna Glaze
@ 2022-10-03 11:23       ` Ard Biesheuvel
  2022-10-03 17:25         ` Dionna Glaze
  2022-10-05 16:20         ` Felix Polyudov
  0 siblings, 2 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2022-10-03 11:23 UTC (permalink / raw)
  To: Dionna Amalie Glaze
  Cc: Ni, Ray, devel@edk2.groups.io, Gerd Hoffmann, Xu, Min M,
	James Bottomley, Yao, Jiewen, Tom Lendacky, Andrew Fish,
	Kinney, Michael D

On Mon, 3 Oct 2022 at 03:16, Dionna Amalie Glaze <dionnaglaze@google.com> wrote:
>
> >
> > Is it defined by UEFI Spec?
> >
>
> It is not. This is Ard's suggested solution
> https://patchew.org/EDK2/20220928153323.2583389-1-dionnaglaze@google.com/20220928153323.2583389-5-dionnaglaze@google.com/#CAMj1kXFwbU9oiULUFXSrqhag1Pf+YU2dL4JbUZ2LO0k9uUEqRg@mail.gmail.com
>

It is not in the spec, which is why we called it
gEdkiiExitBootServicesCallbackProtocolGuid

What Ray is getting to (I think) is that that means that it should be
defined in MdeModulePkg not MdePkg.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 3/7] MdeModulePkg: Invoke all ExitBootServicesCallback instances at ExitBootServices
  2022-09-30 23:06 ` [PATCH v5 3/7] MdeModulePkg: Invoke all ExitBootServicesCallback instances at ExitBootServices Dionna Glaze
@ 2022-10-03 11:33   ` Ard Biesheuvel
  0 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2022-10-03 11:33 UTC (permalink / raw)
  To: Dionna Glaze, Ray Ni
  Cc: devel, Gerd Hoffmann, James Bottomley, Jiewen Yao, Tom Lendacky,
	Min M. Xu, Andrew Fish, Michael D. Kinney

(cc Ray)

On Sat, 1 Oct 2022 at 01:06, Dionna Glaze <dionnaglaze@google.com> wrote:
>
> The protocol's intent is to allow drivers to install callbacks that can
> modify the memory map at ExitBootServices time, so that any changes will
> lead to the EFI_INVALID_PARAMETER error. This error is specified to require
> the EBS caller to call GetMemoryMap again if it already had.
>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: "Min M. Xu" <min.m.xu@intel.com>
> Cc: Andrew Fish <afish@apple.com>
> Cc: "Michael D. Kinney" <michael.d.kinney@intel.com>
>
> Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
> ---
>  MdeModulePkg/Core/Dxe/DxeMain.inf       |  1 +
>  MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 62 ++++++++++++++++++++
>  2 files changed, 63 insertions(+)
>
> diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
> index e4bca89577..bdd9cf8222 100644
> --- a/MdeModulePkg/Core/Dxe/DxeMain.inf
> +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
> @@ -153,6 +153,7 @@
>    gEfiHiiPackageListProtocolGuid                ## SOMETIMES_PRODUCES
>    gEfiSmmBase2ProtocolGuid                      ## SOMETIMES_CONSUMES
>    gEdkiiPeCoffImageEmulatorProtocolGuid         ## SOMETIMES_CONSUMES
> +  gEdkiiExitBootServicesCallbackProtocolGuid    ## CONSUMES
>
>    # Arch Protocols
>    gEfiBdsArchProtocolGuid                       ## CONSUMES
> diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
> index 5733f0c8ec..8cf7d6bcbf 100644
> --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
> +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
> @@ -6,6 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>
>  **/
>
> +#include <Protocol/ExitBootServicesCallback.h>

This include belongs in DxeMain.h



>  #include "DxeMain.h"
>
>  //
> @@ -744,6 +745,54 @@ CalculateEfiHdrCrc (
>    Hdr->CRC32 = Crc;
>  }
>
> +/**
> +  Invokes TerminateMemoryMapPrehook from every instance of the
> +  EdkiiExitBootServicesProtocol.
> +**/
> +STATIC
> +EFI_STATUS
> +InvokeTerminateMemoryMapPrehooks (
> +  VOID
> +  )

We should decide whether or not we want to support a multitude of
these callback protocols. Some protocols in EFI are simply considered
singleton protocols, and I think we might want to stick with that
approach for the time being, as it makes the code much simpler,
especially because most users of this code are not confidential
compute.

> +{
> +  UINTN       NoHandles;
> +  UINTN       Index;
> +  EFI_HANDLE  *HandleBuffer;
> +  EFI_STATUS  Status;
> +  EDKII_EXIT_BOOT_SERVICES_CALLBACK_PROTOCOL *Callback;
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEdkiiExitBootServicesCallbackProtocolGuid,
> +                  NULL,
> +                  &NoHandles,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status) && NoHandles == 0) {
> +    return Status;
> +  }
> +
> +  for (Index = 0; Index < NoHandles; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gEdkiiExitBootServicesCallbackProtocolGuid,
> +                    (VOID **)&Callback
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      continue;
> +    }
> +
> +    Status = Callback->TerminateMemoryMapPrehook(Callback);
> +    if (EFI_ERROR (Status) || Status == EFI_WARN_STALE_DATA) {

EFI_WARN_STALE_DATA is not an error, so this routine might return a
non-error, which we fail to check for below.

Also, if multiple protocols exist, shouldn't we invoke all of them,
and collate the return codes in some way?

(Another reason to stick with a singleton protocol)

> +      goto done;
> +    }
> +  }
> +
> +done:
> +  FreePool(HandleBuffer);
> +  return Status;
> +}
> +
>  /**
>    Terminates all boot services.
>
> @@ -768,6 +817,19 @@ CoreExitBootServices (
>    //
>    gTimer->SetTimerPeriod (gTimer, 0);
>
> +  //
> +  // Invoke all protocols installed for ExitBootServices prior to
> +  // CoreTerminateMemoryMap.
> +  //
> +  Status = InvokeTerminateMemoryMapPrehooks();
> +  if (EFI_ERROR (Status)) {

This condition does not hold for EFI_WARN_STALE_DATA, nor is
EFI_WARN_STALE_DATA documented as a valid return value for
ExitBootServices().


> +    //
> +    // Notify other drivers that ExitBootServices failed
> +    //
> +    CoreNotifySignalList (&gEventExitBootServicesFailedGuid);
> +    return Status;
> +  }
> +
>    //
>    // Terminate memory services if the MapKey matches
>    //
> --
> 2.38.0.rc1.362.ged0d419d3c-goog
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 1/7] OvmfPkg: Realize EfiMemoryAcceptProtocol in AmdSevDxe
  2022-09-30 23:06 ` [PATCH v5 1/7] OvmfPkg: Realize EfiMemoryAcceptProtocol in AmdSevDxe Dionna Glaze
@ 2022-10-03 14:52   ` Lendacky, Thomas
  0 siblings, 0 replies; 16+ messages in thread
From: Lendacky, Thomas @ 2022-10-03 14:52 UTC (permalink / raw)
  To: Dionna Glaze, devel; +Cc: Gerd Hoffmann, James Bottomley, Jiewen Yao

On 9/30/22 18:06, Dionna Glaze wrote:
> From: Sophia Wolf <phiawolf@google.com>
> 
> When a guest OS does not support unaccepted memory, the unaccepted
> memory must be accepted before returning a memory map to the caller.
> 
> EfiMemoryAcceptProtocol is defined in MdePkg and is implemented /
> Installed in AmdSevDxe for AMD SEV-SNP memory acceptance.
> 
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Signed-off-by: Dionna Glaze <dionnaglaze@google.com>

Just some formatting suggestions and one area of cleanup from previous 
version of the patch below. Assuming you take care of those:

Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>

> ---
>   OvmfPkg/AmdSevDxe/AmdSevDxe.c                                      | 57 ++++++++++++++++++--
>   OvmfPkg/AmdSevDxe/AmdSevDxe.inf                                    |  3 ++
>   OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c | 24 +++++++--
>   3 files changed, 76 insertions(+), 8 deletions(-)
> 
> diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
> index 662d3c4ccb..77d3caa833 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 <Protocol/MemoryAccept.h>
>   
>   STATIC CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION  mSnpBootDxeTable = {
>     SIGNATURE_32 ('A',                                    'M', 'D', 'E'),
> @@ -31,6 +32,38 @@ STATIC CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION  mSnpBootDxeTable = {
>     FixedPcdGet32 (PcdOvmfCpuidSize),
>   };
>   
> +STATIC EFI_HANDLE mAmdSevDxeHandle = NULL;
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +AmdSevMemoryAccept (
> +  IN EFI_MEMORY_ACCEPT_PROTOCOL *This,
> +  IN EFI_PHYSICAL_ADDRESS StartAddress,
> +  IN UINTN Size
> +)
> +{
> +  //
> +  // The StartAddress must be page-aligned, and the Size must be a positive
> +  // multiple of SIZE_4KB. Use an assert instead of returning an erros since
> +  // this is an EDK2-internal protocol.
> +  //
> +  ASSERT (((StartAddress & ~(SIZE_4KB - 1)) == 0) &&
> +          ((Size & ~(SIZE_4KB - 1)) == 0) &&
> +          (Size != 0));

Create a generic alignment check macro?

#define IS_ALIGNED(x, y)  (((x) & ((y) - 1)) == 0)

Maybe keep the ASSERTs separate so they better identify which condition 
caused the assert, e.g.:

   ASSERT (IS_ALIGNED (StartAddress, SIZE_4KB));
   ASSERT (IS_ALIGNED (Size, SIZE_4KB));
   ASSERT (Size != 0);

?

Not sure if those are worth it or not, though.

> +
> +  MemEncryptSevSnpPreValidateSystemRam (
> +    StartAddress,
> +    EFI_SIZE_TO_PAGES (Size)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC EFI_MEMORY_ACCEPT_PROTOCOL mMemoryAcceptProtocol = {
> +  AmdSevMemoryAccept
> +};
> +
>   EFI_STATUS
>   EFIAPI
>   AmdSevDxeEntryPoint (
> @@ -147,11 +180,27 @@ AmdSevDxeEntryPoint (
>       }
>     }
>   
> -  //
> -  // 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.
> -  //
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Install EfiMemoryAcceptProtocol failed.\n"));
> +  }

Looks like this shouldn't be here.

> +
>     if (MemEncryptSevSnpIsEnabled ()) {
> +    //
> +    // Memory acceptance began being required in SEV-SNP, so install the
> +    // memory accept protocol implementation for a SEV-SNP active guest.
> +    //
> +    Status = gBS->InstallProtocolInterface (
> +                  &mAmdSevDxeHandle,
> +                  &gEfiMemoryAcceptProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mMemoryAcceptProtocol
> +                  );

Need to indent these two more spaces to align with the "s" in Install.

Thanks,
Tom

> +    ASSERT_EFI_ERROR (Status);
> +
> +    //
> +    // 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.
> +    //
>       return gBS->InstallConfigurationTable (
>                     &gConfidentialComputingSevSnpBlobGuid,
>                     &mSnpBootDxeTable
> diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
> index 9acf860cf2..5ddddabc32 100644
> --- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
> +++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
> @@ -47,6 +47,9 @@
>     gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
>     gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
>   
> +[Protocols]
> +  gEfiMemoryAcceptProtocolGuid
> +
>   [Guids]
>     gConfidentialComputingSevSnpBlobGuid
>   
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
> index d3a95e4913..ee3710f7b3 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
> @@ -14,6 +14,7 @@
>   #include <Library/MemEncryptSevLib.h>
>   
>   #include "SnpPageStateChange.h"
> +#include "VirtualMemory.h"
>   
>   /**
>     Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
> @@ -29,12 +30,27 @@ MemEncryptSevSnpPreValidateSystemRam (
>     IN UINTN             NumPages
>     )
>   {
> +  EFI_STATUS Status;
> +
>     if (!MemEncryptSevSnpIsEnabled ()) {
>       return;
>     }
>   
> -  //
> -  // All the pre-validation must be completed in the PEI phase.
> -  //
> -  ASSERT (FALSE);
> +  // DXE pre-validation may happen with the memory accept protocol.
> +  // The protocol should only be called outside the prevalidated ranges
> +  // that the PEI stage code explicitly skips. Specifically, only memory
> +  // ranges that are classified as unaccepted.
> +  if (BaseAddress >= SIZE_4GB) {
> +    Status = InternalMemEncryptSevCreateIdentityMap1G (
> +               0,
> +               BaseAddress,
> +               EFI_PAGES_TO_SIZE (NumPages)
> +               );
> +    if (EFI_ERROR (Status)) {
> +      ASSERT (FALSE);
> +      CpuDeadLoop ();
> +    }
> +  }
> +
> +  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
>   }

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol
  2022-10-03 11:23       ` Ard Biesheuvel
@ 2022-10-03 17:25         ` Dionna Glaze
  2022-10-05 16:20         ` Felix Polyudov
  1 sibling, 0 replies; 16+ messages in thread
From: Dionna Glaze @ 2022-10-03 17:25 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Ni, Ray, devel@edk2.groups.io, Gerd Hoffmann, Xu, Min M,
	James Bottomley, Yao, Jiewen, Tom Lendacky, Andrew Fish,
	Kinney, Michael D

>
> What Ray is getting to (I think) is that that means that it should be
> defined in MdeModulePkg not MdePkg.

Oh, MemoryAcceptProtocol is also not specified AFAICT, so I thought
this is where it would go. I can move it.

-- 
-Dionna Glaze, PhD (she/her)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol
  2022-10-03 11:23       ` Ard Biesheuvel
  2022-10-03 17:25         ` Dionna Glaze
@ 2022-10-05 16:20         ` Felix Polyudov
  2022-10-05 16:54           ` Dionna Glaze
  1 sibling, 1 reply; 16+ messages in thread
From: Felix Polyudov @ 2022-10-05 16:20 UTC (permalink / raw)
  To: devel@edk2.groups.io, ardb@kernel.org, Dionna Amalie Glaze
  Cc: Ni, Ray, Gerd Hoffmann, Xu, Min M, James Bottomley, Yao, Jiewen,
	Tom Lendacky, Andrew Fish, Kinney, Michael D

> On Mon, 3 Oct 2022 at 03:16, Dionna Amalie Glaze
> <dionnaglaze@google.com> wrote:
> >
> > >
> > > Is it defined by UEFI Spec?
> > >
> >
> > It is not. This is Ard's suggested solution

UEFI 2.9 defines new event EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES, which serves the same purpose
and has the timing you've described: "after the time that the timer is disabled and before the MemoryMap is finalized".

Here is event description from the spec (refer to EFI_BOOT_SERVICES.CreateEventEx() section of the UEFI 2.9):
"This event group is notified by the system when ExitBootServices() is invoked right before notifying EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group. The event presents the last opportunity to use firmware interfaces in the boot environment."
-The information contained in this message may be confidential and proprietary to American Megatrends (AMI). This communication is intended to be read only by the individual or entity to whom it is addressed or by their designee. If the reader of this message is not the intended recipient, you are on notice that any distribution of this message, in any form, is strictly prohibited. Please promptly notify the sender by reply e-mail or by telephone at 770-246-8600, and then delete or destroy all copies of the transmission.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol
  2022-10-05 16:20         ` Felix Polyudov
@ 2022-10-05 16:54           ` Dionna Glaze
  0 siblings, 0 replies; 16+ messages in thread
From: Dionna Glaze @ 2022-10-05 16:54 UTC (permalink / raw)
  To: Felix Polyudov
  Cc: devel@edk2.groups.io, ardb@kernel.org, Ni, Ray, Gerd Hoffmann,
	Xu, Min M, James Bottomley, Yao, Jiewen, Tom Lendacky,
	Andrew Fish, Kinney, Michael D

Thanks Felix, this is great! I'll change the implementation to just be
this specified thing.

On Wed, Oct 5, 2022 at 9:20 AM Felix Polyudov <Felixp@ami.com> wrote:
>
> > On Mon, 3 Oct 2022 at 03:16, Dionna Amalie Glaze
> > <dionnaglaze@google.com> wrote:
> > >
> > > >
> > > > Is it defined by UEFI Spec?
> > > >
> > >
> > > It is not. This is Ard's suggested solution
>
> UEFI 2.9 defines new event EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES, which serves the same purpose
> and has the timing you've described: "after the time that the timer is disabled and before the MemoryMap is finalized".
>
> Here is event description from the spec (refer to EFI_BOOT_SERVICES.CreateEventEx() section of the UEFI 2.9):
> "This event group is notified by the system when ExitBootServices() is invoked right before notifying EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group. The event presents the last opportunity to use firmware interfaces in the boot environment."
> -The information contained in this message may be confidential and proprietary to American Megatrends (AMI). This communication is intended to be read only by the individual or entity to whom it is addressed or by their designee. If the reader of this message is not the intended recipient, you are on notice that any distribution of this message, in any form, is strictly prohibited. Please promptly notify the sender by reply e-mail or by telephone at 770-246-8600, and then delete or destroy all copies of the transmission.



-- 
-Dionna Glaze, PhD (she/her)

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2022-10-05 16:54 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-30 23:06 [PATCH v5 0/7] Add safe unaccepted memory behavior Dionna Glaze
2022-09-30 23:06 ` [PATCH v5 1/7] OvmfPkg: Realize EfiMemoryAcceptProtocol in AmdSevDxe Dionna Glaze
2022-10-03 14:52   ` Lendacky, Thomas
2022-09-30 23:06 ` [PATCH v5 2/7] MdePkg: Introduce ExitBootServicesCallbackProtocol Dionna Glaze
2022-10-01  0:15   ` [edk2-devel] " Ni, Ray
2022-10-03  1:16     ` Dionna Glaze
2022-10-03 11:23       ` Ard Biesheuvel
2022-10-03 17:25         ` Dionna Glaze
2022-10-05 16:20         ` Felix Polyudov
2022-10-05 16:54           ` Dionna Glaze
2022-09-30 23:06 ` [PATCH v5 3/7] MdeModulePkg: Invoke all ExitBootServicesCallback instances at ExitBootServices Dionna Glaze
2022-10-03 11:33   ` Ard Biesheuvel
2022-09-30 23:06 ` [PATCH v5 4/7] OvmfPkg: Introduce CocoDxe driver Dionna Glaze
2022-09-30 23:06 ` [PATCH v5 5/7] MdePkg: Introduce the AcceptAllUnacceptedMemory protocol Dionna Glaze
2022-09-30 23:06 ` [PATCH v5 6/7] OvmfPkg: Implement AcceptAllUnacceptedMemory in CocoDxe Dionna Glaze
2022-09-30 23:06 ` [PATCH v5 7/7] OvmfPkg/PlatformPei: SEV-SNP make >=4GB unaccepted Dionna Glaze

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox