UefiCpuPkg/PiSmmCpuDxeSmm: Centralize Non-Mmram Mem Management Code
Centralize the SMM Non-Mmram Memory Management related code into the NonMmramMapDxeSmm.c. The file SmmCpuMemoryManagement.c will be target to use for both SMM and MM in subsequent patches. No function impact. Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Dun Tan <dun.tan@intel.com> Cc: Hongbin1 Zhang <hongbin1.zhang@intel.com> Cc: Wei6 Xu <wei6.xu@intel.com> Cc: Yuanhao Xie <yuanhao.xie@intel.com>
This commit is contained in:
parent
cc5df45eb6
commit
8ccf7f65e5
|
@ -0,0 +1,488 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "PiSmmCpuCommon.h"
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
|
||||
//
|
||||
// attributes for reserved memory before it is promoted to system memory
|
||||
//
|
||||
#define EFI_MEMORY_PRESENT 0x0100000000000000ULL
|
||||
#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL
|
||||
#define EFI_MEMORY_TESTED 0x0400000000000000ULL
|
||||
|
||||
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
|
||||
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
|
||||
|
||||
EFI_MEMORY_DESCRIPTOR *mUefiMemoryMap;
|
||||
UINTN mUefiMemoryMapSize;
|
||||
UINTN mUefiDescriptorSize;
|
||||
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL;
|
||||
UINTN mGcdMemNumberOfDesc = 0;
|
||||
|
||||
EFI_MEMORY_ATTRIBUTES_TABLE *mUefiMemoryAttributesTable = NULL;
|
||||
|
||||
/**
|
||||
Sort memory map entries based upon PhysicalStart, from low to high.
|
||||
|
||||
@param MemoryMap A pointer to the buffer in which firmware places
|
||||
the current memory map.
|
||||
@param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
|
||||
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
SortMemoryMap (
|
||||
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
||||
IN UINTN MemoryMapSize,
|
||||
IN UINTN DescriptorSize
|
||||
)
|
||||
{
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
|
||||
EFI_MEMORY_DESCRIPTOR TempMemoryMap;
|
||||
|
||||
MemoryMapEntry = MemoryMap;
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
|
||||
while (MemoryMapEntry < MemoryMapEnd) {
|
||||
while (NextMemoryMapEntry < MemoryMapEnd) {
|
||||
if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
|
||||
CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
}
|
||||
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
|
||||
}
|
||||
|
||||
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Return if a UEFI memory page should be marked as not present in SMM page table.
|
||||
If the memory map entries type is
|
||||
EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
|
||||
EfiUnusableMemory, EfiACPIReclaimMemory, return TRUE.
|
||||
Or return FALSE.
|
||||
|
||||
@param[in] MemoryMap A pointer to the memory descriptor.
|
||||
|
||||
@return TRUE The memory described will be marked as not present in SMM page table.
|
||||
@return FALSE The memory described will not be marked as not present in SMM page table.
|
||||
**/
|
||||
BOOLEAN
|
||||
IsUefiPageNotPresent (
|
||||
IN EFI_MEMORY_DESCRIPTOR *MemoryMap
|
||||
)
|
||||
{
|
||||
switch (MemoryMap->Type) {
|
||||
case EfiLoaderCode:
|
||||
case EfiLoaderData:
|
||||
case EfiBootServicesCode:
|
||||
case EfiBootServicesData:
|
||||
case EfiConventionalMemory:
|
||||
case EfiUnusableMemory:
|
||||
case EfiACPIReclaimMemory:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Merge continuous memory map entries whose type is
|
||||
EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
|
||||
EfiUnusableMemory, EfiACPIReclaimMemory, because the memory described by
|
||||
these entries will be set as NOT present in SMM page table.
|
||||
|
||||
@param[in, out] MemoryMap A pointer to the buffer in which firmware places
|
||||
the current memory map.
|
||||
@param[in, out] MemoryMapSize A pointer to the size, in bytes, of the
|
||||
MemoryMap buffer. On input, this is the size of
|
||||
the current memory map. On output,
|
||||
it is the size of new memory map after merge.
|
||||
@param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
MergeMemoryMapForNotPresentEntry (
|
||||
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
||||
IN OUT UINTN *MemoryMapSize,
|
||||
IN UINTN DescriptorSize
|
||||
)
|
||||
{
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
|
||||
UINT64 MemoryBlockLength;
|
||||
EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
|
||||
|
||||
MemoryMapEntry = MemoryMap;
|
||||
NewMemoryMapEntry = MemoryMap;
|
||||
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize);
|
||||
while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
|
||||
CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
|
||||
do {
|
||||
MemoryBlockLength = (UINT64)(EFI_PAGES_TO_SIZE ((UINTN)MemoryMapEntry->NumberOfPages));
|
||||
if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
|
||||
IsUefiPageNotPresent (MemoryMapEntry) && IsUefiPageNotPresent (NextMemoryMapEntry) &&
|
||||
((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart))
|
||||
{
|
||||
MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
|
||||
if (NewMemoryMapEntry != MemoryMapEntry) {
|
||||
NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
|
||||
}
|
||||
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
|
||||
continue;
|
||||
} else {
|
||||
MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
|
||||
break;
|
||||
}
|
||||
} while (TRUE);
|
||||
|
||||
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);
|
||||
}
|
||||
|
||||
*MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
This function caches the GCD memory map information.
|
||||
**/
|
||||
VOID
|
||||
GetGcdMemoryMap (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN NumberOfDescriptors;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mGcdMemNumberOfDesc = 0;
|
||||
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
||||
if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&
|
||||
((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
|
||||
(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
|
||||
)
|
||||
{
|
||||
mGcdMemNumberOfDesc++;
|
||||
}
|
||||
}
|
||||
|
||||
mGcdMemSpace = AllocateZeroPool (mGcdMemNumberOfDesc * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));
|
||||
ASSERT (mGcdMemSpace != NULL);
|
||||
if (mGcdMemSpace == NULL) {
|
||||
mGcdMemNumberOfDesc = 0;
|
||||
gBS->FreePool (MemSpaceMap);
|
||||
return;
|
||||
}
|
||||
|
||||
mGcdMemNumberOfDesc = 0;
|
||||
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
||||
if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&
|
||||
((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
|
||||
(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
|
||||
)
|
||||
{
|
||||
CopyMem (
|
||||
&mGcdMemSpace[mGcdMemNumberOfDesc],
|
||||
&MemSpaceMap[Index],
|
||||
sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)
|
||||
);
|
||||
mGcdMemNumberOfDesc++;
|
||||
}
|
||||
}
|
||||
|
||||
gBS->FreePool (MemSpaceMap);
|
||||
}
|
||||
|
||||
/**
|
||||
Get UEFI MemoryAttributesTable.
|
||||
**/
|
||||
VOID
|
||||
GetUefiMemoryAttributesTable (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
|
||||
UINTN MemoryAttributesTableSize;
|
||||
|
||||
Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
|
||||
if (!EFI_ERROR (Status) && (MemoryAttributesTable != NULL)) {
|
||||
MemoryAttributesTableSize = sizeof (EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;
|
||||
mUefiMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);
|
||||
ASSERT (mUefiMemoryAttributesTable != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This function caches the UEFI memory map information.
|
||||
**/
|
||||
VOID
|
||||
GetUefiMemoryMap (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN MapKey;
|
||||
UINT32 DescriptorVersion;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
||||
UINTN UefiMemoryMapSize;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "GetUefiMemoryMap\n"));
|
||||
|
||||
UefiMemoryMapSize = 0;
|
||||
MemoryMap = NULL;
|
||||
Status = gBS->GetMemoryMap (
|
||||
&UefiMemoryMapSize,
|
||||
MemoryMap,
|
||||
&MapKey,
|
||||
&mUefiDescriptorSize,
|
||||
&DescriptorVersion
|
||||
);
|
||||
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
|
||||
|
||||
do {
|
||||
Status = gBS->AllocatePool (EfiBootServicesData, UefiMemoryMapSize, (VOID **)&MemoryMap);
|
||||
ASSERT (MemoryMap != NULL);
|
||||
if (MemoryMap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Status = gBS->GetMemoryMap (
|
||||
&UefiMemoryMapSize,
|
||||
MemoryMap,
|
||||
&MapKey,
|
||||
&mUefiDescriptorSize,
|
||||
&DescriptorVersion
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (MemoryMap);
|
||||
MemoryMap = NULL;
|
||||
}
|
||||
} while (Status == EFI_BUFFER_TOO_SMALL);
|
||||
|
||||
if (MemoryMap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SortMemoryMap (MemoryMap, UefiMemoryMapSize, mUefiDescriptorSize);
|
||||
MergeMemoryMapForNotPresentEntry (MemoryMap, &UefiMemoryMapSize, mUefiDescriptorSize);
|
||||
|
||||
mUefiMemoryMapSize = UefiMemoryMapSize;
|
||||
mUefiMemoryMap = AllocateCopyPool (UefiMemoryMapSize, MemoryMap);
|
||||
ASSERT (mUefiMemoryMap != NULL);
|
||||
|
||||
gBS->FreePool (MemoryMap);
|
||||
|
||||
//
|
||||
// Get additional information from GCD memory map.
|
||||
//
|
||||
GetGcdMemoryMap ();
|
||||
|
||||
//
|
||||
// Get UEFI memory attributes table.
|
||||
//
|
||||
GetUefiMemoryAttributesTable ();
|
||||
}
|
||||
|
||||
/**
|
||||
This function sets UEFI memory attribute according to UEFI memory map.
|
||||
|
||||
The normal memory region is marked as not present, such as
|
||||
EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
|
||||
EfiUnusableMemory, EfiACPIReclaimMemory.
|
||||
**/
|
||||
VOID
|
||||
SetUefiMemMapAttributes (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
||||
UINTN MemoryMapEntryCount;
|
||||
UINTN Index;
|
||||
EFI_MEMORY_DESCRIPTOR *Entry;
|
||||
BOOLEAN WriteProtect;
|
||||
BOOLEAN CetEnabled;
|
||||
|
||||
PERF_FUNCTION_BEGIN ();
|
||||
|
||||
DEBUG ((DEBUG_INFO, "SetUefiMemMapAttributes\n"));
|
||||
|
||||
WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled);
|
||||
|
||||
if (mUefiMemoryMap != NULL) {
|
||||
MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
|
||||
MemoryMap = mUefiMemoryMap;
|
||||
for (Index = 0; Index < MemoryMapEntryCount; Index++) {
|
||||
if (IsUefiPageNotPresent (MemoryMap)) {
|
||||
Status = SmmSetMemoryAttributes (
|
||||
MemoryMap->PhysicalStart,
|
||||
EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
|
||||
EFI_MEMORY_RP
|
||||
);
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"UefiMemory protection: 0x%lx - 0x%lx %r\n",
|
||||
MemoryMap->PhysicalStart,
|
||||
MemoryMap->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
|
||||
Status
|
||||
));
|
||||
}
|
||||
|
||||
MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do not free mUefiMemoryMap, it will be checked in IsSmmCommBufferForbiddenAddress().
|
||||
//
|
||||
|
||||
//
|
||||
// Set untested memory as not present.
|
||||
//
|
||||
if (mGcdMemSpace != NULL) {
|
||||
for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
|
||||
Status = SmmSetMemoryAttributes (
|
||||
mGcdMemSpace[Index].BaseAddress,
|
||||
mGcdMemSpace[Index].Length,
|
||||
EFI_MEMORY_RP
|
||||
);
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"GcdMemory protection: 0x%lx - 0x%lx %r\n",
|
||||
mGcdMemSpace[Index].BaseAddress,
|
||||
mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length,
|
||||
Status
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress().
|
||||
//
|
||||
|
||||
//
|
||||
// Set UEFI runtime memory with EFI_MEMORY_RO as not present.
|
||||
//
|
||||
if (mUefiMemoryAttributesTable != NULL) {
|
||||
Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);
|
||||
for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
|
||||
if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) {
|
||||
if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
|
||||
Status = SmmSetMemoryAttributes (
|
||||
Entry->PhysicalStart,
|
||||
EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages),
|
||||
EFI_MEMORY_RP
|
||||
);
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n",
|
||||
Entry->PhysicalStart,
|
||||
Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages),
|
||||
Status
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
|
||||
|
||||
//
|
||||
// Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress().
|
||||
//
|
||||
|
||||
PERF_FUNCTION_END ();
|
||||
}
|
||||
|
||||
/**
|
||||
Return if the Address is forbidden as SMM communication buffer.
|
||||
|
||||
@param[in] Address the address to be checked
|
||||
|
||||
@return TRUE The address is forbidden as SMM communication buffer.
|
||||
@return FALSE The address is allowed as SMM communication buffer.
|
||||
**/
|
||||
BOOLEAN
|
||||
IsSmmCommBufferForbiddenAddress (
|
||||
IN UINT64 Address
|
||||
)
|
||||
{
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
||||
UINTN MemoryMapEntryCount;
|
||||
UINTN Index;
|
||||
EFI_MEMORY_DESCRIPTOR *Entry;
|
||||
|
||||
if (mUefiMemoryMap != NULL) {
|
||||
MemoryMap = mUefiMemoryMap;
|
||||
MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
|
||||
for (Index = 0; Index < MemoryMapEntryCount; Index++) {
|
||||
if (IsUefiPageNotPresent (MemoryMap)) {
|
||||
if ((Address >= MemoryMap->PhysicalStart) &&
|
||||
(Address < MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (mGcdMemSpace != NULL) {
|
||||
for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
|
||||
if ((Address >= mGcdMemSpace[Index].BaseAddress) &&
|
||||
(Address < mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mUefiMemoryAttributesTable != NULL) {
|
||||
Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);
|
||||
for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
|
||||
if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) {
|
||||
if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
|
||||
if ((Address >= Entry->PhysicalStart) &&
|
||||
(Address < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -46,6 +46,7 @@
|
|||
SmmMp.c
|
||||
SmmMpPerf.h
|
||||
SmmMpPerf.c
|
||||
NonMmramMapDxeSmm.c
|
||||
|
||||
[Sources.Ia32]
|
||||
Ia32/PageTbl.c
|
||||
|
|
|
@ -7,25 +7,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
|
||||
#include "PiSmmCpuCommon.h"
|
||||
|
||||
//
|
||||
// attributes for reserved memory before it is promoted to system memory
|
||||
//
|
||||
#define EFI_MEMORY_PRESENT 0x0100000000000000ULL
|
||||
#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL
|
||||
#define EFI_MEMORY_TESTED 0x0400000000000000ULL
|
||||
|
||||
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
|
||||
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
|
||||
|
||||
EFI_MEMORY_DESCRIPTOR *mUefiMemoryMap;
|
||||
UINTN mUefiMemoryMapSize;
|
||||
UINTN mUefiDescriptorSize;
|
||||
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL;
|
||||
UINTN mGcdMemNumberOfDesc = 0;
|
||||
|
||||
EFI_MEMORY_ATTRIBUTES_TABLE *mUefiMemoryAttributesTable = NULL;
|
||||
|
||||
BOOLEAN mIsShadowStack = FALSE;
|
||||
BOOLEAN m5LevelPagingNeeded = FALSE;
|
||||
PAGING_MODE mPagingMode = PagingModeMax;
|
||||
|
@ -1118,464 +1099,6 @@ SetMemMapAttributes (
|
|||
PERF_FUNCTION_END ();
|
||||
}
|
||||
|
||||
/**
|
||||
Sort memory map entries based upon PhysicalStart, from low to high.
|
||||
|
||||
@param MemoryMap A pointer to the buffer in which firmware places
|
||||
the current memory map.
|
||||
@param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
|
||||
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
SortMemoryMap (
|
||||
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
||||
IN UINTN MemoryMapSize,
|
||||
IN UINTN DescriptorSize
|
||||
)
|
||||
{
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
|
||||
EFI_MEMORY_DESCRIPTOR TempMemoryMap;
|
||||
|
||||
MemoryMapEntry = MemoryMap;
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
|
||||
while (MemoryMapEntry < MemoryMapEnd) {
|
||||
while (NextMemoryMapEntry < MemoryMapEnd) {
|
||||
if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
|
||||
CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
}
|
||||
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
|
||||
}
|
||||
|
||||
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Return if a UEFI memory page should be marked as not present in SMM page table.
|
||||
If the memory map entries type is
|
||||
EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
|
||||
EfiUnusableMemory, EfiACPIReclaimMemory, return TRUE.
|
||||
Or return FALSE.
|
||||
|
||||
@param[in] MemoryMap A pointer to the memory descriptor.
|
||||
|
||||
@return TRUE The memory described will be marked as not present in SMM page table.
|
||||
@return FALSE The memory described will not be marked as not present in SMM page table.
|
||||
**/
|
||||
BOOLEAN
|
||||
IsUefiPageNotPresent (
|
||||
IN EFI_MEMORY_DESCRIPTOR *MemoryMap
|
||||
)
|
||||
{
|
||||
switch (MemoryMap->Type) {
|
||||
case EfiLoaderCode:
|
||||
case EfiLoaderData:
|
||||
case EfiBootServicesCode:
|
||||
case EfiBootServicesData:
|
||||
case EfiConventionalMemory:
|
||||
case EfiUnusableMemory:
|
||||
case EfiACPIReclaimMemory:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Merge continuous memory map entries whose type is
|
||||
EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
|
||||
EfiUnusableMemory, EfiACPIReclaimMemory, because the memory described by
|
||||
these entries will be set as NOT present in SMM page table.
|
||||
|
||||
@param[in, out] MemoryMap A pointer to the buffer in which firmware places
|
||||
the current memory map.
|
||||
@param[in, out] MemoryMapSize A pointer to the size, in bytes, of the
|
||||
MemoryMap buffer. On input, this is the size of
|
||||
the current memory map. On output,
|
||||
it is the size of new memory map after merge.
|
||||
@param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
MergeMemoryMapForNotPresentEntry (
|
||||
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
||||
IN OUT UINTN *MemoryMapSize,
|
||||
IN UINTN DescriptorSize
|
||||
)
|
||||
{
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
|
||||
UINT64 MemoryBlockLength;
|
||||
EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
|
||||
|
||||
MemoryMapEntry = MemoryMap;
|
||||
NewMemoryMapEntry = MemoryMap;
|
||||
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize);
|
||||
while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
|
||||
CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
|
||||
do {
|
||||
MemoryBlockLength = (UINT64)(EFI_PAGES_TO_SIZE ((UINTN)MemoryMapEntry->NumberOfPages));
|
||||
if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
|
||||
IsUefiPageNotPresent (MemoryMapEntry) && IsUefiPageNotPresent (NextMemoryMapEntry) &&
|
||||
((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart))
|
||||
{
|
||||
MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
|
||||
if (NewMemoryMapEntry != MemoryMapEntry) {
|
||||
NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
|
||||
}
|
||||
|
||||
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
|
||||
continue;
|
||||
} else {
|
||||
MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
|
||||
break;
|
||||
}
|
||||
} while (TRUE);
|
||||
|
||||
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||
NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);
|
||||
}
|
||||
|
||||
*MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
This function caches the GCD memory map information.
|
||||
**/
|
||||
VOID
|
||||
GetGcdMemoryMap (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN NumberOfDescriptors;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mGcdMemNumberOfDesc = 0;
|
||||
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
||||
if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&
|
||||
((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
|
||||
(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
|
||||
)
|
||||
{
|
||||
mGcdMemNumberOfDesc++;
|
||||
}
|
||||
}
|
||||
|
||||
mGcdMemSpace = AllocateZeroPool (mGcdMemNumberOfDesc * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));
|
||||
ASSERT (mGcdMemSpace != NULL);
|
||||
if (mGcdMemSpace == NULL) {
|
||||
mGcdMemNumberOfDesc = 0;
|
||||
gBS->FreePool (MemSpaceMap);
|
||||
return;
|
||||
}
|
||||
|
||||
mGcdMemNumberOfDesc = 0;
|
||||
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
||||
if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&
|
||||
((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
|
||||
(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
|
||||
)
|
||||
{
|
||||
CopyMem (
|
||||
&mGcdMemSpace[mGcdMemNumberOfDesc],
|
||||
&MemSpaceMap[Index],
|
||||
sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)
|
||||
);
|
||||
mGcdMemNumberOfDesc++;
|
||||
}
|
||||
}
|
||||
|
||||
gBS->FreePool (MemSpaceMap);
|
||||
}
|
||||
|
||||
/**
|
||||
Get UEFI MemoryAttributesTable.
|
||||
**/
|
||||
VOID
|
||||
GetUefiMemoryAttributesTable (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
|
||||
UINTN MemoryAttributesTableSize;
|
||||
|
||||
Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
|
||||
if (!EFI_ERROR (Status) && (MemoryAttributesTable != NULL)) {
|
||||
MemoryAttributesTableSize = sizeof (EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;
|
||||
mUefiMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);
|
||||
ASSERT (mUefiMemoryAttributesTable != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This function caches the UEFI memory map information.
|
||||
**/
|
||||
VOID
|
||||
GetUefiMemoryMap (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN MapKey;
|
||||
UINT32 DescriptorVersion;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
||||
UINTN UefiMemoryMapSize;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "GetUefiMemoryMap\n"));
|
||||
|
||||
UefiMemoryMapSize = 0;
|
||||
MemoryMap = NULL;
|
||||
Status = gBS->GetMemoryMap (
|
||||
&UefiMemoryMapSize,
|
||||
MemoryMap,
|
||||
&MapKey,
|
||||
&mUefiDescriptorSize,
|
||||
&DescriptorVersion
|
||||
);
|
||||
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
|
||||
|
||||
do {
|
||||
Status = gBS->AllocatePool (EfiBootServicesData, UefiMemoryMapSize, (VOID **)&MemoryMap);
|
||||
ASSERT (MemoryMap != NULL);
|
||||
if (MemoryMap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Status = gBS->GetMemoryMap (
|
||||
&UefiMemoryMapSize,
|
||||
MemoryMap,
|
||||
&MapKey,
|
||||
&mUefiDescriptorSize,
|
||||
&DescriptorVersion
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (MemoryMap);
|
||||
MemoryMap = NULL;
|
||||
}
|
||||
} while (Status == EFI_BUFFER_TOO_SMALL);
|
||||
|
||||
if (MemoryMap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SortMemoryMap (MemoryMap, UefiMemoryMapSize, mUefiDescriptorSize);
|
||||
MergeMemoryMapForNotPresentEntry (MemoryMap, &UefiMemoryMapSize, mUefiDescriptorSize);
|
||||
|
||||
mUefiMemoryMapSize = UefiMemoryMapSize;
|
||||
mUefiMemoryMap = AllocateCopyPool (UefiMemoryMapSize, MemoryMap);
|
||||
ASSERT (mUefiMemoryMap != NULL);
|
||||
|
||||
gBS->FreePool (MemoryMap);
|
||||
|
||||
//
|
||||
// Get additional information from GCD memory map.
|
||||
//
|
||||
GetGcdMemoryMap ();
|
||||
|
||||
//
|
||||
// Get UEFI memory attributes table.
|
||||
//
|
||||
GetUefiMemoryAttributesTable ();
|
||||
}
|
||||
|
||||
/**
|
||||
This function sets UEFI memory attribute according to UEFI memory map.
|
||||
|
||||
The normal memory region is marked as not present, such as
|
||||
EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
|
||||
EfiUnusableMemory, EfiACPIReclaimMemory.
|
||||
**/
|
||||
VOID
|
||||
SetUefiMemMapAttributes (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
||||
UINTN MemoryMapEntryCount;
|
||||
UINTN Index;
|
||||
EFI_MEMORY_DESCRIPTOR *Entry;
|
||||
BOOLEAN WriteProtect;
|
||||
BOOLEAN CetEnabled;
|
||||
|
||||
PERF_FUNCTION_BEGIN ();
|
||||
|
||||
DEBUG ((DEBUG_INFO, "SetUefiMemMapAttributes\n"));
|
||||
|
||||
WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled);
|
||||
|
||||
if (mUefiMemoryMap != NULL) {
|
||||
MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
|
||||
MemoryMap = mUefiMemoryMap;
|
||||
for (Index = 0; Index < MemoryMapEntryCount; Index++) {
|
||||
if (IsUefiPageNotPresent (MemoryMap)) {
|
||||
Status = SmmSetMemoryAttributes (
|
||||
MemoryMap->PhysicalStart,
|
||||
EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
|
||||
EFI_MEMORY_RP
|
||||
);
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"UefiMemory protection: 0x%lx - 0x%lx %r\n",
|
||||
MemoryMap->PhysicalStart,
|
||||
MemoryMap->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
|
||||
Status
|
||||
));
|
||||
}
|
||||
|
||||
MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do not free mUefiMemoryMap, it will be checked in IsSmmCommBufferForbiddenAddress().
|
||||
//
|
||||
|
||||
//
|
||||
// Set untested memory as not present.
|
||||
//
|
||||
if (mGcdMemSpace != NULL) {
|
||||
for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
|
||||
Status = SmmSetMemoryAttributes (
|
||||
mGcdMemSpace[Index].BaseAddress,
|
||||
mGcdMemSpace[Index].Length,
|
||||
EFI_MEMORY_RP
|
||||
);
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"GcdMemory protection: 0x%lx - 0x%lx %r\n",
|
||||
mGcdMemSpace[Index].BaseAddress,
|
||||
mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length,
|
||||
Status
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress().
|
||||
//
|
||||
|
||||
//
|
||||
// Set UEFI runtime memory with EFI_MEMORY_RO as not present.
|
||||
//
|
||||
if (mUefiMemoryAttributesTable != NULL) {
|
||||
Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);
|
||||
for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
|
||||
if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) {
|
||||
if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
|
||||
Status = SmmSetMemoryAttributes (
|
||||
Entry->PhysicalStart,
|
||||
EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages),
|
||||
EFI_MEMORY_RP
|
||||
);
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n",
|
||||
Entry->PhysicalStart,
|
||||
Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages),
|
||||
Status
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
|
||||
|
||||
//
|
||||
// Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress().
|
||||
//
|
||||
|
||||
PERF_FUNCTION_END ();
|
||||
}
|
||||
|
||||
/**
|
||||
Return if the Address is forbidden as SMM communication buffer.
|
||||
|
||||
@param[in] Address the address to be checked
|
||||
|
||||
@return TRUE The address is forbidden as SMM communication buffer.
|
||||
@return FALSE The address is allowed as SMM communication buffer.
|
||||
**/
|
||||
BOOLEAN
|
||||
IsSmmCommBufferForbiddenAddress (
|
||||
IN UINT64 Address
|
||||
)
|
||||
{
|
||||
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
||||
UINTN MemoryMapEntryCount;
|
||||
UINTN Index;
|
||||
EFI_MEMORY_DESCRIPTOR *Entry;
|
||||
|
||||
if (mUefiMemoryMap != NULL) {
|
||||
MemoryMap = mUefiMemoryMap;
|
||||
MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
|
||||
for (Index = 0; Index < MemoryMapEntryCount; Index++) {
|
||||
if (IsUefiPageNotPresent (MemoryMap)) {
|
||||
if ((Address >= MemoryMap->PhysicalStart) &&
|
||||
(Address < MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (mGcdMemSpace != NULL) {
|
||||
for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
|
||||
if ((Address >= mGcdMemSpace[Index].BaseAddress) &&
|
||||
(Address < mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mUefiMemoryAttributesTable != NULL) {
|
||||
Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);
|
||||
for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
|
||||
if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) {
|
||||
if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
|
||||
if ((Address >= Entry->PhysicalStart) &&
|
||||
(Address < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
This function set given attributes of the memory region specified by
|
||||
BaseAddress and Length.
|
||||
|
|
Loading…
Reference in New Issue