[edk2-devel] [PATCH V3 08/12] OvmfPkg: Introduce lazy accept in PlatformInitLib and PlatformPei
Min Xu
min.m.xu at intel.com
Mon Sep 5 08:35:02 UTC 2022
From: Min M Xu <min.m.xu at 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 it is under 4G address.If an
EFI_RESOURCE_MEMORY_UNACCEPTED memory region is cross the 4G address,
it will be split into 2 parts and only the left one (<4G) 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.
We will re-visit here in the future when on-demand accept memory is
required.
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.
Cc: Erdem Aktas <erdemaktas at google.com>
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>
Signed-off-by: Min Xu <min.m.xu at intel.com>
---
OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 129 ++++++++++++++++++--
OvmfPkg/Library/PlatformInitLib/MemDetect.c | 2 +
2 files changed, 121 insertions(+), 10 deletions(-)
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
index 396b14d919d2..333c69d1a854 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,11 +377,18 @@ ProcessHobList (
EFI_STATUS Status;
EFI_PEI_HOB_POINTERS Hob;
EFI_PHYSICAL_ADDRESS PhysicalEnd;
+ TDX_WORK_AREA *WorkArea;
+ UINT64 ResourceLength;
+ UINT64 AccumulateAcceptedMemory;
+ UINT64 MaxAcceptedMemoryAddress;
Status = EFI_SUCCESS;
ASSERT (VmmHobList != NULL);
Hob.Raw = (UINT8 *)VmmHobList;
+ AccumulateAcceptedMemory = 0;
+ MaxAcceptedMemoryAddress = 0;
+
//
// Parse the HOB list until end of list or matching type is found.
//
@@ -393,7 +402,16 @@ 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 (PhysicalEnd > SIZE_4GB) {
+ //
+ // In current stage, we only accept the memory under 4G
+ //
+ ResourceLength -= (PhysicalEnd - SIZE_4GB);
+ PhysicalEnd = SIZE_4GB;
+ }
Status = BspAcceptMemoryResourceRange (
Hob.ResourceDescriptor->PhysicalStart,
@@ -402,12 +420,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 +491,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 +576,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 +598,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..62132f9cacfa 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 (
--
2.29.2.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#93133): https://edk2.groups.io/g/devel/message/93133
Mute This Topic: https://groups.io/mt/93474519/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