MdeModulePkg: Fix Memory Attributes table type issue

According to the spec, each entry in the Memory
Attributes table shall have the same type as
the region it was carved out of in the UEFI memory map.
The current attribute uses RTData for PE Data, but
it should be RTCode.

This patch fixed the issue. It is validated with or
without PropertiesTable.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <jiewen.yao@intel.com>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Jiewen Yao 2016-02-23 12:43:57 +08:00 committed by Hao Wu
parent 97033ebfa3
commit 82f0f411c7
2 changed files with 37 additions and 83 deletions

View File

@ -72,8 +72,6 @@ CoreGetMemoryMapPropertiesTable (
extern EFI_PROPERTIES_TABLE mPropertiesTable; extern EFI_PROPERTIES_TABLE mPropertiesTable;
BOOLEAN mIsConstructingMemoryAttributesTable = FALSE;
/** /**
Install MemoryAttributesTable. Install MemoryAttributesTable.
@ -105,8 +103,6 @@ InstallMemoryAttributesTable (
return ; return ;
} }
mIsConstructingMemoryAttributesTable = TRUE;
MemoryMapSize = 0; MemoryMapSize = 0;
MemoryMap = NULL; MemoryMap = NULL;
Status = CoreGetMemoryMapPropertiesTable ( Status = CoreGetMemoryMapPropertiesTable (
@ -181,8 +177,6 @@ InstallMemoryAttributesTable (
Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, MemoryAttributesTable); Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, MemoryAttributesTable);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
mIsConstructingMemoryAttributesTable = FALSE;
} }
/** /**

View File

@ -1,7 +1,7 @@
/** @file /** @file
UEFI PropertiesTable support UEFI PropertiesTable support
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -80,14 +80,7 @@ EFI_PROPERTIES_TABLE mPropertiesTable = {
EFI_LOCK mPropertiesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); EFI_LOCK mPropertiesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
// BOOLEAN mPropertiesTableEnable;
// Temporary save for original memory map.
// This is for MemoryAttributesTable only.
//
extern BOOLEAN mIsConstructingMemoryAttributesTable;
EFI_MEMORY_DESCRIPTOR *mMemoryMapOrg;
UINTN mMemoryMapOrgSize;
UINTN mDescriptorSize;
// //
// Below functions are for MemoryMap // Below functions are for MemoryMap
@ -198,42 +191,6 @@ SortMemoryMap (
return ; return ;
} }
/**
Check if this memory entry spans across original memory map boundary.
@param PhysicalStart The PhysicalStart of memory
@param NumberOfPages The NumberOfPages of memory
@retval TRUE This memory entry spans across original memory map boundary.
@retval FALSE This memory entry does not span cross original memory map boundary.
**/
STATIC
BOOLEAN
DoesEntrySpanAcrossBoundary (
IN UINT64 PhysicalStart,
IN UINT64 NumberOfPages
)
{
EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
UINT64 MemoryBlockLength;
MemoryMapEntry = mMemoryMapOrg;
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) mMemoryMapOrg + mMemoryMapOrgSize);
while (MemoryMapEntry < MemoryMapEnd) {
MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages));
if ((MemoryMapEntry->PhysicalStart <= PhysicalStart) &&
(MemoryMapEntry->PhysicalStart + MemoryBlockLength > PhysicalStart) &&
(MemoryMapEntry->PhysicalStart + MemoryBlockLength < PhysicalStart + EfiPagesToSize (NumberOfPages))) {
return TRUE;
}
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, mDescriptorSize);
}
return FALSE;
}
/** /**
Merge continous memory map entries whose have same attributes. Merge continous memory map entries whose have same attributes.
@ -271,8 +228,7 @@ MergeMemoryMap (
if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
(MemoryMapEntry->Type == NextMemoryMapEntry->Type) && (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&
(MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) && (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&
((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart) && ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) {
(!DoesEntrySpanAcrossBoundary (MemoryMapEntry->PhysicalStart, MemoryMapEntry->NumberOfPages + NextMemoryMapEntry->NumberOfPages))) {
MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
if (NewMemoryMapEntry != MemoryMapEntry) { if (NewMemoryMapEntry != MemoryMapEntry) {
NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
@ -430,7 +386,11 @@ SetNewRecord (
// //
// DATA // DATA
// //
if (!mPropertiesTableEnable) {
NewRecord->Type = TempRecord.Type;
} else {
NewRecord->Type = EfiRuntimeServicesData; NewRecord->Type = EfiRuntimeServicesData;
}
NewRecord->PhysicalStart = TempRecord.PhysicalStart; NewRecord->PhysicalStart = TempRecord.PhysicalStart;
NewRecord->VirtualStart = 0; NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart); NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);
@ -443,7 +403,11 @@ SetNewRecord (
// //
// CODE // CODE
// //
if (!mPropertiesTableEnable) {
NewRecord->Type = TempRecord.Type;
} else {
NewRecord->Type = EfiRuntimeServicesCode; NewRecord->Type = EfiRuntimeServicesCode;
}
NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase; NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;
NewRecord->VirtualStart = 0; NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize); NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize);
@ -467,7 +431,11 @@ SetNewRecord (
// Final DATA // Final DATA
// //
if (TempRecord.PhysicalStart < ImageEnd) { if (TempRecord.PhysicalStart < ImageEnd) {
if (!mPropertiesTableEnable) {
NewRecord->Type = TempRecord.Type;
} else {
NewRecord->Type = EfiRuntimeServicesData; NewRecord->Type = EfiRuntimeServicesData;
}
NewRecord->PhysicalStart = TempRecord.PhysicalStart; NewRecord->PhysicalStart = TempRecord.PhysicalStart;
NewRecord->VirtualStart = 0; NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart); NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);
@ -549,6 +517,7 @@ SplitRecord (
UINT64 PhysicalEnd; UINT64 PhysicalEnd;
UINTN NewRecordCount; UINTN NewRecordCount;
UINTN TotalNewRecordCount; UINTN TotalNewRecordCount;
BOOLEAN IsLastRecordData;
if (MaxSplitRecordCount == 0) { if (MaxSplitRecordCount == 0) {
CopyMem (NewRecord, OldRecord, DescriptorSize); CopyMem (NewRecord, OldRecord, DescriptorSize);
@ -576,7 +545,17 @@ SplitRecord (
// If this is still address in this record, need record. // If this is still address in this record, need record.
// //
NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
IsLastRecordData = FALSE;
if (!mPropertiesTableEnable) {
if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {
IsLastRecordData = TRUE;
}
} else {
if (NewRecord->Type == EfiRuntimeServicesData) { if (NewRecord->Type == EfiRuntimeServicesData) {
IsLastRecordData = TRUE;
}
}
if (IsLastRecordData) {
// //
// Last record is DATA, just merge it. // Last record is DATA, just merge it.
// //
@ -586,7 +565,11 @@ SplitRecord (
// Last record is CODE, create a new DATA entry. // Last record is CODE, create a new DATA entry.
// //
NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
if (!mPropertiesTableEnable) {
NewRecord->Type = TempRecord.Type;
} else {
NewRecord->Type = EfiRuntimeServicesData; NewRecord->Type = EfiRuntimeServicesData;
}
NewRecord->PhysicalStart = TempRecord.PhysicalStart; NewRecord->PhysicalStart = TempRecord.PhysicalStart;
NewRecord->VirtualStart = 0; NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = TempRecord.NumberOfPages; NewRecord->NumberOfPages = TempRecord.NumberOfPages;
@ -814,38 +797,13 @@ CoreGetMemoryMapPropertiesTable (
// //
Status = EFI_BUFFER_TOO_SMALL; Status = EFI_BUFFER_TOO_SMALL;
} else { } else {
if (mIsConstructingMemoryAttributesTable) {
//
// If the memory map is constructed for memory attributes table,
// save original memory map, because they will be checked later
// to make sure the memory attributes table entry does not cross
// the original memory map entry boundary.
// This work must NOT be done in normal GetMemoryMap() because
// allocating memory is not allowed due to MapKey update.
//
mDescriptorSize = *DescriptorSize;
mMemoryMapOrgSize = *MemoryMapSize;
mMemoryMapOrg = AllocateCopyPool (*MemoryMapSize, MemoryMap);
if (mMemoryMapOrg == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Exit;
}
}
// //
// Split PE code/data // Split PE code/data
// //
SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize); SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);
if (mIsConstructingMemoryAttributesTable) {
FreePool (mMemoryMapOrg);
mMemoryMapOrg = NULL;
mMemoryMapOrgSize = 0;
}
} }
} }
Exit:
CoreReleasePropertiesTableLock (); CoreReleasePropertiesTableLock ();
return Status; return Status;
} }
@ -1412,6 +1370,8 @@ InstallPropertiesTable (
DEBUG ((EFI_D_VERBOSE, "Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); DEBUG ((EFI_D_VERBOSE, "Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
DEBUG ((EFI_D_VERBOSE, "Dump ImageRecord:\n")); DEBUG ((EFI_D_VERBOSE, "Dump ImageRecord:\n"));
DumpImageRecord (); DumpImageRecord ();
mPropertiesTableEnable = TRUE;
} }
} }