Skip to content

Commit

Permalink
OvmfPkg/Library/TdxStartupLib: Add lazy memory accept to the TDVF.
Browse files Browse the repository at this point in the history
Add unaccepted memory type to several structures and macro definitions to
indicate the unaccepted memory.

SEC Phase: Modify the Hob process function to partially accept memory.
Modify the Hob transfer function to build different types of system memory
Hobs for DXE phase, system memory is split to type of system memory and
unaccepted memory.

DXE Phase: Add case of unaccepted memory in the GCD memory service process
and memory map.
  • Loading branch information
gaojiaqi7 committed Apr 26, 2021
1 parent ba06323 commit e4da6c9
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 43 deletions.
4 changes: 4 additions & 0 deletions MdeModulePkg/Core/Dxe/Gcd/Gcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdMemoryTypeNames[] = {
"MMIO ", // EfiGcdMemoryTypeMemoryMappedIo
"PersisMem", // EfiGcdMemoryTypePersistent
"MoreRelia", // EfiGcdMemoryTypeMoreReliable
"Unaccepte", // EfiGcdMemoryTypeUnaccepted
"Unknown " // EfiGcdMemoryTypeMaximum
};

Expand Down Expand Up @@ -2563,6 +2564,9 @@ CoreInitializeGcdServices (
case EFI_RESOURCE_MEMORY_RESERVED:
GcdMemoryType = EfiGcdMemoryTypeReserved;
break;
case EFI_RESOURCE_MEMORY_UNACCEPTED:
GcdMemoryType = EfiGcdMemoryTypeUnaccepted;
break;
case EFI_RESOURCE_IO:
GcdIoType = EfiGcdIoTypeIo;
break;
Expand Down
28 changes: 28 additions & 0 deletions MdeModulePkg/Core/Dxe/Mem/Page.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ EFI_MEMORY_TYPE_STATISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {
{ 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIOPortSpace
{ 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiPalCode
{ 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiPersistentMemory
{ 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiUnacceptedMemory
{ 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE } // EfiMaxMemoryType
};

Expand All @@ -83,6 +84,7 @@ EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = {
{ EfiMemoryMappedIOPortSpace, 0 },
{ EfiPalCode, 0 },
{ EfiPersistentMemory, 0 },
{ EfiGcdMemoryTypeUnaccepted, 0 },
{ EfiMaxMemoryType, 0 }
};
//
Expand Down Expand Up @@ -1912,6 +1914,32 @@ CoreGetMemoryMap (
//
MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);
}

if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeUnaccepted) {
//
// Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR,
// it will be recorded as page PhysicalStart and NumberOfPages.
//
ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);
ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);

//
// Create EFI_MEMORY_DESCRIPTOR for every Unaccepted GCD entries
//
MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;
MemoryMap->VirtualStart = 0;
MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);
MemoryMap->Attribute = MergeGcdMapEntry.Attributes |
(MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |
EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));
MemoryMap->Type = EfiUnacceptedMemory;

//
// Check to see if the new Memory Map Descriptor can be merged with an
// existing descriptor if they are adjacent and have the same attributes
//
MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);
}
if (Link == &mGcdMemorySpaceMap) {
//
// break loop when arrive at head.
Expand Down
1 change: 1 addition & 0 deletions MdePkg/Include/Pi/PiDxeCis.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ typedef enum {
/// system. If all memory has the same reliability, then this bit is not used.
///
EfiGcdMemoryTypeMoreReliable,
EfiGcdMemoryTypeUnaccepted,
EfiGcdMemoryTypeMaximum
} EFI_GCD_MEMORY_TYPE;

Expand Down
3 changes: 2 additions & 1 deletion MdePkg/Include/Pi/PiHob.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ typedef UINT32 EFI_RESOURCE_TYPE;
#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004
#define EFI_RESOURCE_MEMORY_RESERVED 0x00000005
#define EFI_RESOURCE_IO_RESERVED 0x00000006
#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000007
#define EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008

///
/// A type of recount attribute type.
Expand Down
5 changes: 5 additions & 0 deletions MdePkg/Include/Uefi/UefiMultiPhase.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ typedef enum {
/// however it happens to also support byte-addressable non-volatility.
///
EfiPersistentMemory,
///
/// A memory region that describes system memory that has not been accepted
/// by a corresponding call to the underlying isolation architecture.
///
EfiUnacceptedMemory,
EfiMaxMemoryType
} EFI_MEMORY_TYPE;

Expand Down
138 changes: 103 additions & 35 deletions OvmfPkg/Library/TdxStartupLib/Hob.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include <IndustryStandard/UefiTcgPlatform.h>
#include "TdxStartupInternal.h"

UINT64 mTdxAcceptMemSize = 0;

VOID
EFIAPI
DEBUG_HOBLIST (
Expand Down Expand Up @@ -280,17 +282,27 @@ ProcessHobList (
{
EFI_PEI_HOB_POINTERS Hob;
EFI_PHYSICAL_ADDRESS PhysicalEnd;
EFI_PHYSICAL_ADDRESS PhysicalStart;
UINT64 Length;
EFI_HOB_RESOURCE_DESCRIPTOR *LowMemoryResource = NULL;
UINT64 ResourceLength;
UINT64 AccumulateAccepted;
EFI_PHYSICAL_ADDRESS LowMemoryStart;
UINT64 LowMemoryLength;

ASSERT (VmmHobList != NULL);

AccumulateAccepted = 0;
Hob.Raw = (UINT8 *) VmmHobList;
LowMemoryLength = 0;

mTdxAcceptMemSize = FixedPcdGet64(PcdTdxAcceptPartialMemorySize);
if (mTdxAcceptMemSize <= 0) {
mTdxAcceptMemSize = ~(UINT64) 0;;
}
DEBUG ((DEBUG_INFO, "mTdxAcceptMemSize: 0x%llx\n", mTdxAcceptMemSize));

//
// 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) && AccumulateAccepted < mTdxAcceptMemSize) {

if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
Expand All @@ -311,43 +323,49 @@ ProcessHobList (
DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));

PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;

ResourceLength = Hob.ResourceDescriptor->ResourceLength;

if (AccumulateAccepted + ResourceLength > mTdxAcceptMemSize) {
//
// If the memory can't be accepted completely, accept the part of it to meet the
// TDX_PARTIAL_ACCEPTED_MEM_SIZE.
//
ResourceLength = mTdxAcceptMemSize - AccumulateAccepted;
PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + ResourceLength;
}
if (PhysicalEnd <= BASE_4GB) {
if ((LowMemoryResource == NULL) || (Hob.ResourceDescriptor->ResourceLength > LowMemoryResource->ResourceLength)) {
LowMemoryResource = Hob.ResourceDescriptor;
if (ResourceLength > LowMemoryLength) {
LowMemoryStart = Hob.ResourceDescriptor->PhysicalStart;
LowMemoryLength = ResourceLength;
}
}

DEBUG ((DEBUG_INFO, "Accept Start and End: %x, %x\n", Hob.ResourceDescriptor->PhysicalStart, PhysicalEnd));
MpAcceptMemoryResourceRange (
Hob.ResourceDescriptor->PhysicalStart,
PhysicalEnd);

AccumulateAccepted += PhysicalEnd - Hob.ResourceDescriptor->PhysicalStart;
}
}
Hob.Raw = GET_NEXT_HOB (Hob);
}

ASSERT (LowMemoryResource != NULL);

PhysicalStart = LowMemoryResource->PhysicalStart;
Length = LowMemoryResource->ResourceLength;

//
// HobLib doesn't like HobStart at address 0 so adjust is needed
//
if (PhysicalStart == 0) {
PhysicalStart += EFI_PAGE_SIZE;
Length -= EFI_PAGE_SIZE;
if (LowMemoryStart == 0) {
LowMemoryStart += EFI_PAGE_SIZE;
LowMemoryLength -= EFI_PAGE_SIZE;
}


HobConstructor (
(VOID *) PhysicalStart,
Length,
(VOID *) PhysicalStart,
(VOID *) (PhysicalStart + Length)
(VOID *) LowMemoryStart,
LowMemoryLength,
(VOID *) LowMemoryStart,
(VOID *) (LowMemoryStart + LowMemoryLength)
);

PrePeiSetHobList ((VOID *)(UINT64)PhysicalStart);
PrePeiSetHobList ((VOID *)(UINT64)LowMemoryStart);
}

/**
Expand All @@ -363,28 +381,78 @@ TransferHobList (
)
{
EFI_PEI_HOB_POINTERS Hob;
EFI_RESOURCE_TYPE ResourceType;
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
EFI_PHYSICAL_ADDRESS PhysicalEnd;
EFI_PHYSICAL_ADDRESS PhysicalStart;
UINT64 ResourceLength;
UINT64 AccumulateAccepted;

Hob.Raw = (UINT8 *) VmmHobList;
AccumulateAccepted = 0;

Hob.Raw = (UINT8 *) VmmHobList;
while (!END_OF_HOB_LIST (Hob)) {
switch (Hob.Header->HobType) {
case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
ResourceAttribute = Hob.ResourceDescriptor->ResourceAttribute;
PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;

//
// We mark each resource that we issue AcceptPage to with EFI_RESOURCE_SYSTEM_MEMORY
//
if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
(PhysicalEnd <= BASE_4GB)) {
ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_ENCRYPTED;
ResourceLength = Hob.ResourceDescriptor->ResourceLength;
ResourceType = Hob.ResourceDescriptor->ResourceType;
PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;

if (ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED;

//
// Set type of systme memory less than TDX_PARTIAL_ACCEPTED_MEM_SIZE to
// EFI_RESOURCE_SYSTEM_MEMORY and set other to EFI_RESOURCE_MEMORY_UNACCEPTED.
//
if (AccumulateAccepted >= mTdxAcceptMemSize) {
ResourceType = EFI_RESOURCE_MEMORY_UNACCEPTED;
ResourceAttribute &= ~(EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_ENCRYPTED);
} else {
//
// Judge if the whole memory is accepted.
//
if (AccumulateAccepted + ResourceLength <= mTdxAcceptMemSize) {
AccumulateAccepted += ResourceLength;
ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_TESTED;
if (PhysicalStart + ResourceLength <= BASE_4GB) {
ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_ENCRYPTED;
}
} else {
//
// Set the resouce type, attribute and memory range of the the accepted part
// of the memory.
//
ResourceType = EFI_RESOURCE_SYSTEM_MEMORY;
ResourceLength = mTdxAcceptMemSize - AccumulateAccepted;

ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_TESTED;
if (PhysicalStart + ResourceLength <= BASE_4GB) {
ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_ENCRYPTED;
}
BuildResourceDescriptorHob (
ResourceType,
ResourceAttribute,
PhysicalStart,
ResourceLength);
AccumulateAccepted += ResourceLength;

//
// Transfer the other part to the unaccepted memory.
//
PhysicalStart = PhysicalStart + ResourceLength;
ResourceLength = Hob.ResourceDescriptor->ResourceLength - ResourceLength;
ResourceType = EFI_RESOURCE_MEMORY_UNACCEPTED;
ResourceAttribute &= ~(EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_ENCRYPTED);
}
}
}

BuildResourceDescriptorHob (
Hob.ResourceDescriptor->ResourceType,
ResourceType,
ResourceAttribute,
Hob.ResourceDescriptor->PhysicalStart,
Hob.ResourceDescriptor->ResourceLength);
PhysicalStart,
ResourceLength);
break;
case EFI_HOB_TYPE_MEMORY_ALLOCATION:
BuildMemoryAllocationHob (
Expand Down
13 changes: 7 additions & 6 deletions OvmfPkg/Library/TdxStartupLib/TdxStartupLib.inf
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,14 @@
gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize
gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation
gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageChunkSize
gUefiOvmfPkgTokenSpaceGuid.PcdTdxSetNxForStack
gUefiOvmfPkgTokenSpaceGuid.PcdTdxPteMemoryEncryptionAddressOrMask
gUefiOvmfPkgTokenSpaceGuid.PcdTdxSetNxForStack
gUefiOvmfPkgTokenSpaceGuid.PcdTdxPteMemoryEncryptionAddressOrMask
gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPartialMemorySize

//
// TODO check these PCDs' impact on Ovmf
//
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## CONSUMES
//
// TODO check these PCDs' impact on Ovmf
//
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
Expand Down
1 change: 1 addition & 0 deletions OvmfPkg/OvmfPkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@
gUefiOvmfPkgTokenSpaceGuid.PcdTdxSetNxForStack|FALSE|BOOLEAN|0x5b
gUefiOvmfPkgTokenSpaceGuid.PcdTdxPteMemoryEncryptionAddressOrMask|0|UINT64|0x5c

gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPartialMemorySize|0|UINT64|0x5d

[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
Expand Down
5 changes: 4 additions & 1 deletion OvmfPkg/OvmfPkgX64.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
DEFINE TDX_IGNORE_VE_HLT = FALSE
DEFINE TDX_EMULATION_ENABLE = FALSE
DEFINE TDX_SUPPORT = TRUE
DEFINE TDX_MEM_PARTIAL_ACCEPT = 0

# Network definition
#
DEFINE NETWORK_TLS_ENABLE = FALSE
Expand Down Expand Up @@ -606,7 +608,8 @@
!endif
# 32M
gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageChunkSize|0x2000000

# Accept memory size.
gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPartialMemorySize|$(TDX_MEM_PARTIAL_ACCEPT)
# Noexec settings for DXE.
# TDX doesn't allow us to change EFER so make sure these are disabled
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000
Expand Down
6 changes: 6 additions & 0 deletions ShellPkg/Library/UefiShellDebug1CommandsLib/MemMap.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ STATIC CONST CHAR16 NameEfiACPIMemoryNVS[] = L"ACPIMemoryNVS";
STATIC CONST CHAR16 NameEfiMemoryMappedIO[] = L"MemoryMappedIO";
STATIC CONST CHAR16 NameEfiMemoryMappedIOPortSpace[] = L"MemoryMappedIOPortSpace";
STATIC CONST CHAR16 NameEfiPalCode[] = L"PalCode";
STATIC CONST CHAR16 NameEfiUnacceptedMemory[] = L"Unaccepted";

//
// Need short names for some memory types
Expand Down Expand Up @@ -300,6 +301,11 @@ ShellCommandRunMemMap (
TotalPages += Walker->NumberOfPages;
PalCodePages += Walker->NumberOfPages;
break;
case EfiUnacceptedMemory:
ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiUnacceptedMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute);
TotalPages += Walker->NumberOfPages;
PalCodePages += Walker->NumberOfPages;
break;
default:
//
// Shell Spec defines the SFO format.
Expand Down

0 comments on commit e4da6c9

Please sign in to comment.