public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Min Xu" <min.m.xu@intel.com>
To: devel@edk2.groups.io
Cc: Min M Xu <min.m.xu@intel.com>,
	Erdem Aktas <erdemaktas@google.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	James Bottomley <jejb@linux.ibm.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Tom Lendacky <thomas.lendacky@amd.com>
Subject: [PATCH V2 09/14] OvmfPkg: Introduce lazy accept in PlatformInitLib and PlatformPei
Date: Sat, 27 Aug 2022 14:21:16 +0800	[thread overview]
Message-ID: <24efa78fa0cac5bf3c8293734215f61a4ba1f405.1661579220.git.min.m.xu@intel.com> (raw)
In-Reply-To: <cover.1661579220.git.min.m.xu@intel.com>

From: Min M Xu <min.m.xu@intel.com>

RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937

There are below major changes in PlatformInitLib/PlatformPei
1. ProcessHobList
  The unaccepted memory is accepted if the accumulated accepted memory is
  smaller than the LazyAcceptMemSize. If a EFI_RESOURCE_MEMORY_UNACCEPTED
  hob is cross the LazyAcceptMemSize, it will be split into 2 parts and
  only the left one is accepted. The max accepted memory address is
  stored in Tdx workarea which will be used in TransferTdxHobList.

  Please be noted: in current stage, we only accept the memory under 4G.

2. TransferTdxHobList
  Transfer the unaccepted memory hob to EFI_RESOURCE_SYSTEM_MEMORY hob
  if it is accepted. As it is mentioned in 1), there may be a
  EFI_RESOURCE_MEMORY_UNACCEPTED hob which only part of the memory
  describes in the hob is accepted. We also handles this situation
  in TransferTdxHobList.

3. PlatformAdjustSystemMemorySizeBelow4gbForLazyAccep
  The system memory size below 4GB may be larger than the accepted
  memory. This function is used to handle this situation.

Cc: Erdem Aktas <erdemaktas@google.com>
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: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/Library/PlatformInitLib.h     |   6 +
 OvmfPkg/Library/PlatformInitLib/IntelTdx.c    | 152 ++++++++++++++++--
 OvmfPkg/Library/PlatformInitLib/MemDetect.c   |  27 ++++
 .../PlatformInitLib/PlatformInitLib.inf       |   1 +
 OvmfPkg/PlatformPei/MemDetect.c               |   5 +
 5 files changed, 180 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
index 2987a367cc9c..187efcf34e14 100644
--- a/OvmfPkg/Include/Library/PlatformInitLib.h
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -144,6 +144,12 @@ PlatformGetSystemMemorySizeBelow4gb (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
+UINT32
+EFIAPI
+PlatformAdjustSystemMemorySizeBelow4gbForLazyAccept (
+  IN UINT32  LowerMemorySize
+  );
+
 /**
   Initialize the PhysMemAddressWidth field in PlatformInfoHob based on guest RAM size.
 **/
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
index 396b14d919d2..5c408758756e 100644
--- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
@@ -7,6 +7,7 @@
 
 **/
 
+#include <Base.h>
 #include <PiPei.h>
 #include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
@@ -24,7 +25,8 @@
 #include <WorkArea.h>
 #include <ConfidentialComputingGuestAttr.h>
 
-#define ALIGNED_2MB_MASK                0x1fffff
+#define ALIGNED_2MB_MASK  0x1fffff
+#define MEGABYTE_SHIFT    20
 
 /**
   This function will be called to accept pages. Only BSP accepts pages.
@@ -375,15 +377,33 @@ ProcessHobList (
   EFI_STATUS            Status;
   EFI_PEI_HOB_POINTERS  Hob;
   EFI_PHYSICAL_ADDRESS  PhysicalEnd;
+  TDX_WORK_AREA         *WorkArea;
+  UINT64                ResourceLength;
+  UINT64                AccumulateAcceptedMemory;
+  UINT64                LazyAcceptMemSize;
+  UINT64                MaxAcceptedMemoryAddress;
 
   Status = EFI_SUCCESS;
   ASSERT (VmmHobList != NULL);
   Hob.Raw = (UINT8 *)VmmHobList;
 
+  AccumulateAcceptedMemory = 0;
+  MaxAcceptedMemoryAddress = 0;
+  LazyAcceptMemSize        = FixedPcdGet64 (PcdLazyAcceptPartialMemorySize);
+  //
+  // If specified accept size is zero, accept all of the memory.
+  // Else transfer the size in megabyte to the number in byte.
+  //
+  if (LazyAcceptMemSize == 0) {
+    LazyAcceptMemSize = MAX_UINT64;
+  } else {
+    LazyAcceptMemSize <<= MEGABYTE_SHIFT;
+  }
+
   //
   // Parse the HOB list until end of list or matching type is found.
   //
-  while (!END_OF_HOB_LIST (Hob)) {
+  while (!END_OF_HOB_LIST (Hob) && AccumulateAcceptedMemory < LazyAcceptMemSize) {
     if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
       DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
 
@@ -393,7 +413,26 @@ ProcessHobList (
         DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));
         DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
 
-        PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
+        PhysicalEnd    = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
+        ResourceLength = Hob.ResourceDescriptor->ResourceLength;
+
+        if (AccumulateAcceptedMemory + ResourceLength > LazyAcceptMemSize) {
+          //
+          // If the memory can't be accepted completely, accept the part of it to meet the
+          // PcdLazyAcceptPartialMemorySize.
+          //
+          ResourceLength = LazyAcceptMemSize - AccumulateAcceptedMemory;
+          PhysicalEnd    = Hob.ResourceDescriptor->PhysicalStart + ResourceLength;
+        }
+
+        if (PhysicalEnd > SIZE_4GB) {
+          //
+          // In current stage, we only accept the memory under 4G
+          //
+          ResourceLength    -= (PhysicalEnd - SIZE_4GB);
+          LazyAcceptMemSize -= (PhysicalEnd - SIZE_4GB);
+          PhysicalEnd        = SIZE_4GB;
+        }
 
         Status = BspAcceptMemoryResourceRange (
                    Hob.ResourceDescriptor->PhysicalStart,
@@ -402,12 +441,25 @@ ProcessHobList (
         if (EFI_ERROR (Status)) {
           break;
         }
+
+        AccumulateAcceptedMemory += ResourceLength;
+        MaxAcceptedMemoryAddress  = PhysicalEnd;
       }
     }
 
     Hob.Raw = GET_NEXT_HOB (Hob);
   }
 
+  //
+  // Record MaxAcceptedMemoryAddress in OvmfWorkArea.
+  // This information is useful later but in SEC phase we cannot use a global
+  // variable to pass this value. So it is stored in OvmfWorkarea.
+  //
+  WorkArea = (TDX_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
+  ASSERT (WorkArea != NULL);
+  ASSERT (WorkArea->Header.GuestType == CcGuestTypeIntelTdx);
+  WorkArea->SecTdxWorkArea.MaxAcceptedMemoryAddress = MaxAcceptedMemoryAddress;
+
   return Status;
 }
 
@@ -460,6 +512,74 @@ ProcessTdxHobList (
   return Status;
 }
 
+/**
+ * Build ResourceDescriptorHob for the unaccepted memory region.
+ * This memory region may be splitted into 2 parts because of lazy accept.
+ *
+ * @param Hob     Point to the EFI_HOB_RESOURCE_DESCRIPTOR
+ * @param MaxAcceptedMemoryAddress The max accepted memory address
+ * @return VOID
+ */
+VOID
+BuildResourceDescriptorHobForUnacceptedMemory (
+  IN EFI_HOB_RESOURCE_DESCRIPTOR  *Hob,
+  IN UINT64                       MaxAcceptedMemoryAddress
+  )
+{
+  EFI_PHYSICAL_ADDRESS         PhysicalStart;
+  EFI_PHYSICAL_ADDRESS         PhysicalEnd;
+  UINT64                       ResourceLength;
+  EFI_RESOURCE_TYPE            ResourceType;
+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute;
+  UINT64                       AcceptedResourceLength;
+
+  ASSERT (Hob->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED);
+
+  ResourceType      = EFI_RESOURCE_MEMORY_UNACCEPTED;
+  ResourceAttribute = Hob->ResourceAttribute;
+  PhysicalStart     = Hob->PhysicalStart;
+  ResourceLength    = Hob->ResourceLength;
+  PhysicalEnd       = PhysicalStart + ResourceLength;
+
+  if (PhysicalEnd <= MaxAcceptedMemoryAddress) {
+    //
+    // This memory region has been accepted.
+    //
+    ResourceType       = EFI_RESOURCE_SYSTEM_MEMORY;
+    ResourceAttribute |= (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED);
+  } else if (PhysicalStart >= MaxAcceptedMemoryAddress) {
+    //
+    // This memory region hasn't been accepted.
+    // So keep the ResourceType and ResourceAttribute unchange.
+    //
+  } else {
+    //
+    // This memory region is splitted into 2 parts:
+    // the accepted and unaccepted.
+    //
+    AcceptedResourceLength = MaxAcceptedMemoryAddress - Hob->PhysicalStart;
+
+    // We build the ResourceDescriptorHob for the accepted part.
+    // The unaccepted part will be build out side the if-else block.
+    BuildResourceDescriptorHob (
+      EFI_RESOURCE_SYSTEM_MEMORY,
+      ResourceAttribute | (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED),
+      Hob->PhysicalStart,
+      AcceptedResourceLength
+      );
+
+    PhysicalStart   = Hob->PhysicalStart + AcceptedResourceLength;
+    ResourceLength -= AcceptedResourceLength;
+  }
+
+  BuildResourceDescriptorHob (
+    ResourceType,
+    ResourceAttribute,
+    PhysicalStart,
+    ResourceLength
+    );
+}
+
 /**
   Transfer the incoming HobList for the TD to the final HobList for Dxe.
   The Hobs transferred in this function are ResourceDescriptor hob and
@@ -477,6 +597,16 @@ TransferTdxHobList (
   EFI_PEI_HOB_POINTERS         Hob;
   EFI_RESOURCE_TYPE            ResourceType;
   EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute;
+  UINT64                       MaxAcceptedMemoryAddress;
+  TDX_WORK_AREA                *WorkArea;
+
+  WorkArea = (TDX_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
+  ASSERT (WorkArea != NULL);
+  ASSERT (WorkArea->Header.GuestType == CcGuestTypeIntelTdx);
+  MaxAcceptedMemoryAddress = WorkArea->SecTdxWorkArea.MaxAcceptedMemoryAddress;
+  if (MaxAcceptedMemoryAddress == 0) {
+    MaxAcceptedMemoryAddress = MAX_UINT64;
+  }
 
   //
   // PcdOvmfSecGhcbBase is used as the TD_HOB in Tdx guest.
@@ -489,16 +619,16 @@ TransferTdxHobList (
         ResourceAttribute = Hob.ResourceDescriptor->ResourceAttribute;
 
         if (ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) {
-          ResourceType       = EFI_RESOURCE_SYSTEM_MEMORY;
-          ResourceAttribute |= (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED);
+          BuildResourceDescriptorHobForUnacceptedMemory (Hob.ResourceDescriptor, MaxAcceptedMemoryAddress);
+        } else {
+          BuildResourceDescriptorHob (
+            ResourceType,
+            ResourceAttribute,
+            Hob.ResourceDescriptor->PhysicalStart,
+            Hob.ResourceDescriptor->ResourceLength
+            );
         }
 
-        BuildResourceDescriptorHob (
-          ResourceType,
-          ResourceAttribute,
-          Hob.ResourceDescriptor->PhysicalStart,
-          Hob.ResourceDescriptor->ResourceLength
-          );
         break;
       case EFI_HOB_TYPE_MEMORY_ALLOCATION:
         BuildMemoryAllocationHob (
diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
index 942eaf89cfcf..d7c8b938f263 100644
--- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c
+++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
@@ -42,6 +42,8 @@ Module Name:
 
 #include <Library/PlatformInitLib.h>
 
+#define MEGABYTE_SHIFT  20
+
 VOID
 EFIAPI
 PlatformQemuUc32BaseInitialization (
@@ -289,6 +291,31 @@ GetHighestSystemMemoryAddressFromPvhMemmap (
   return HighestAddress;
 }
 
+UINT32
+EFIAPI
+PlatformAdjustSystemMemorySizeBelow4gbForLazyAccept (
+  IN UINT32  LowerMemorySize
+  )
+{
+ #ifdef MDE_CPU_X64
+  UINT64  LazyAcceptMemSize;
+
+  LazyAcceptMemSize = FixedPcdGet64 (PcdLazyAcceptPartialMemorySize);
+  //
+  // If specified accept size is not zero,
+  // transfer the size in megabyte to the number in byte.
+  //
+  if (LazyAcceptMemSize != 0) {
+    LazyAcceptMemSize <<= MEGABYTE_SHIFT;
+    if (LazyAcceptMemSize < LowerMemorySize) {
+      LowerMemorySize = (UINT32)(UINTN)LazyAcceptMemSize;
+    }
+  }
+
+ #endif
+  return LowerMemorySize;
+}
+
 UINT32
 EFIAPI
 PlatformGetSystemMemorySizeBelow4gb (
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
index d2fa2d998df8..1c5ed1067ad4 100644
--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -96,6 +96,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
 
   gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdLazyAcceptPartialMemorySize
 
 [FeaturePcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 2e47b1322990..acc1d7f63ee8 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -279,6 +279,11 @@ PublishPeiMemory (
     LowerMemorySize -= mPlatformInfoHob.Q35TsegMbytes * SIZE_1MB;
   }
 
+  //
+  // Adjustment for Lazy accept because it may accept part of the memory.
+  //
+  LowerMemorySize = PlatformAdjustSystemMemorySizeBelow4gbForLazyAccept (LowerMemorySize);
+
   S3AcpiReservedMemoryBase = 0;
   S3AcpiReservedMemorySize = 0;
 
-- 
2.29.2.windows.2


  parent reply	other threads:[~2022-08-27  6:22 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-27  6:21 [PATCH V2 00/14] Introduce Lazy-accept for Tdx guest Min Xu
2022-08-27  6:21 ` [PATCH V2 01/14] MdeModulePkg: Add PrePiHob.h Min Xu
2022-09-01 15:47   ` Gerd Hoffmann
2022-09-01 23:34     ` Min Xu
2022-09-04 11:34     ` Min Xu
2022-09-07  5:30       ` Gerd Hoffmann
2022-09-07 23:56         ` [edk2-devel] " Min Xu
2022-08-27  6:21 ` [PATCH V2 02/14] MdePkg: Increase EFI_RESOURCE_MAX_MEMORY_TYPE Min Xu
2022-08-27  6:21 ` [PATCH V2 03/14] OvmfPkg: Use EFI_RESOURCE_MEMORY_UNACCEPTED which defined in MdeModulePkg Min Xu
2022-08-27  6:21 ` [PATCH V2 04/14] MdePkg: Add UEFI Unaccepted memory definition Min Xu
2022-08-27  6:21 ` [PATCH V2 05/14] MdeModulePkg: Update Dxe to handle unaccepted memory type Min Xu
2022-08-27  6:21 ` [PATCH V2 06/14] ShellPkg: Update shell command memmap to show unaccepted memory Min Xu
2022-09-01 15:50   ` Gerd Hoffmann
2022-08-27  6:21 ` [PATCH V2 07/14] OvmfPkg: Add PCD and DEFINEs for Lazy Accept page Min Xu
2022-09-01 15:56   ` Gerd Hoffmann
2022-09-01 23:33     ` [edk2-devel] " Min Xu
2022-09-02  5:30       ` Gerd Hoffmann
2022-08-27  6:21 ` [PATCH V2 08/14] OvmfPkg: Add MaxAcceptedMemoryAddress in TDX work area Min Xu
2022-08-27  6:21 ` Min Xu [this message]
2022-08-27  6:21 ` [PATCH V2 10/14] OvmfPkg: Update ConstructFwHobList for lazy accept Min Xu
2022-08-27  6:21 ` [PATCH V2 11/14] MdePkg: The prototype definition of EdkiiMemoryAcceptProtocol Min Xu
2022-09-01 15:57   ` Gerd Hoffmann
2022-08-27  6:21 ` [PATCH V2 12/14] OvmfPkg: Realize EdkiiMemoryAcceptProtocol in TdxDxe Min Xu
2022-09-01 15:58   ` Gerd Hoffmann
2022-08-27  6:21 ` [PATCH V2 13/14] OvmfPkg: Call gEdkiiMemoryAcceptProtocolGuid to accept pages Min Xu
2022-09-01 15:59   ` Gerd Hoffmann
2022-08-27  6:21 ` [PATCH V2 14/14] MdeModulePkg: Pool and page functions accept memory when OOM occurs Min Xu
2022-08-29 20:47   ` Lendacky, Thomas
2022-08-30  0:29     ` [edk2-devel] " Ni, Ray
2022-08-30  6:00       ` Min Xu
2022-08-30  6:14         ` Ni, Ray
2022-08-30  6:35           ` Min Xu
2022-08-30  7:12             ` Ni, Ray
2022-08-30  7:30               ` Min Xu
2022-08-30  7:43                 ` Ni, Ray
2022-08-30  8:08                   ` Min Xu
2022-08-30  9:28                     ` Ni, Ray
     [not found]                 ` <17100F9FBCB0C570.28430@groups.io>
2022-08-30  7:47                   ` Ni, Ray
2022-08-30  3:20     ` Min Xu
2022-08-30 14:24       ` Lendacky, Thomas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=24efa78fa0cac5bf3c8293734215f61a4ba1f405.1661579220.git.min.m.xu@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox