mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/PiSmmCore: MemoryAttributeTable need keep non-PE record.
Current memory attribute table implementation will only mark PE code to be EfiRuntimeServicesCode, and mark rest to be EfiRuntimeServicesData. However, there might be a case that a SMM code wants to allocate EfiRuntimeServicesCode explicitly to let page table protect this region to be read only. It is unsupported. This patch enhances the current solution so that MemoryAttributeTable does not touch non PE image record. Only the PE image region is forced to be EfiRuntimeServicesCode for code and EfiRuntimeServicesData for data. Cc: Jeff Fan <jeff.fan@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com> Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
parent
5f4d3e1794
commit
026e2ca2c3
|
@ -268,15 +268,19 @@ EnforceMemoryMapAttribute (
|
||||||
MemoryMapEntry = MemoryMap;
|
MemoryMapEntry = MemoryMap;
|
||||||
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);
|
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);
|
||||||
while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
|
while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
|
||||||
switch (MemoryMapEntry->Type) {
|
if (MemoryMapEntry->Attribute != 0) {
|
||||||
case EfiRuntimeServicesCode:
|
// It is PE image, the attribute is already set.
|
||||||
MemoryMapEntry->Attribute |= EFI_MEMORY_RO;
|
} else {
|
||||||
break;
|
switch (MemoryMapEntry->Type) {
|
||||||
case EfiRuntimeServicesData:
|
case EfiRuntimeServicesCode:
|
||||||
MemoryMapEntry->Attribute |= EFI_MEMORY_XP;
|
MemoryMapEntry->Attribute = EFI_MEMORY_RO;
|
||||||
break;
|
break;
|
||||||
|
case EfiRuntimeServicesData:
|
||||||
|
default:
|
||||||
|
MemoryMapEntry->Attribute |= EFI_MEMORY_XP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,6 +362,21 @@ SetNewRecord (
|
||||||
PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages);
|
PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages);
|
||||||
NewRecordCount = 0;
|
NewRecordCount = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Always create a new entry for non-PE image record
|
||||||
|
//
|
||||||
|
if (ImageRecord->ImageBase > TempRecord.PhysicalStart) {
|
||||||
|
NewRecord->Type = TempRecord.Type;
|
||||||
|
NewRecord->PhysicalStart = TempRecord.PhysicalStart;
|
||||||
|
NewRecord->VirtualStart = 0;
|
||||||
|
NewRecord->NumberOfPages = EfiSizeToPages(ImageRecord->ImageBase - TempRecord.PhysicalStart);
|
||||||
|
NewRecord->Attribute = TempRecord.Attribute;
|
||||||
|
NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
|
||||||
|
NewRecordCount ++;
|
||||||
|
TempRecord.PhysicalStart = ImageRecord->ImageBase;
|
||||||
|
TempRecord.NumberOfPages = EfiSizeToPages(PhysicalEnd - TempRecord.PhysicalStart);
|
||||||
|
}
|
||||||
|
|
||||||
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
|
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
|
||||||
|
|
||||||
ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
|
ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
|
||||||
|
@ -452,14 +471,10 @@ GetMaxSplitRecordCount (
|
||||||
if (ImageRecord == NULL) {
|
if (ImageRecord == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);
|
SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 2);
|
||||||
PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
|
PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
|
||||||
} while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
|
} while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
|
||||||
|
|
||||||
if (SplitRecordCount != 0) {
|
|
||||||
SplitRecordCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SplitRecordCount;
|
return SplitRecordCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,28 +531,16 @@ SplitRecord (
|
||||||
//
|
//
|
||||||
// No more image covered by this range, stop
|
// No more image covered by this range, stop
|
||||||
//
|
//
|
||||||
if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {
|
if (PhysicalEnd > PhysicalStart) {
|
||||||
//
|
//
|
||||||
// If this is still address in this record, need record.
|
// Always create a new entry for non-PE image record
|
||||||
//
|
//
|
||||||
NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
|
NewRecord->Type = TempRecord.Type;
|
||||||
if (NewRecord->Type == EfiRuntimeServicesData) {
|
NewRecord->PhysicalStart = TempRecord.PhysicalStart;
|
||||||
//
|
NewRecord->VirtualStart = 0;
|
||||||
// Last record is DATA, just merge it.
|
NewRecord->NumberOfPages = TempRecord.NumberOfPages;
|
||||||
//
|
NewRecord->Attribute = TempRecord.Attribute;
|
||||||
NewRecord->NumberOfPages = EfiSizeToPages(PhysicalEnd - NewRecord->PhysicalStart);
|
TotalNewRecordCount ++;
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Last record is CODE, create a new DATA entry.
|
|
||||||
//
|
|
||||||
NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
|
|
||||||
NewRecord->Type = EfiRuntimeServicesData;
|
|
||||||
NewRecord->PhysicalStart = TempRecord.PhysicalStart;
|
|
||||||
NewRecord->VirtualStart = 0;
|
|
||||||
NewRecord->NumberOfPages = TempRecord.NumberOfPages;
|
|
||||||
NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
|
|
||||||
TotalNewRecordCount ++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -580,6 +583,8 @@ SplitRecord (
|
||||||
==>
|
==>
|
||||||
+---------------+
|
+---------------+
|
||||||
| Record X |
|
| Record X |
|
||||||
|
+---------------+
|
||||||
|
| Record RtCode |
|
||||||
+---------------+ ----
|
+---------------+ ----
|
||||||
| Record RtData | |
|
| Record RtData | |
|
||||||
+---------------+ |
|
+---------------+ |
|
||||||
|
@ -587,12 +592,16 @@ SplitRecord (
|
||||||
+---------------+ |
|
+---------------+ |
|
||||||
| Record RtData | |
|
| Record RtData | |
|
||||||
+---------------+ ----
|
+---------------+ ----
|
||||||
|
| Record RtCode |
|
||||||
|
+---------------+ ----
|
||||||
| Record RtData | |
|
| Record RtData | |
|
||||||
+---------------+ |
|
+---------------+ |
|
||||||
| Record RtCode | |-> PE/COFF2
|
| Record RtCode | |-> PE/COFF2
|
||||||
+---------------+ |
|
+---------------+ |
|
||||||
| Record RtData | |
|
| Record RtData | |
|
||||||
+---------------+ ----
|
+---------------+ ----
|
||||||
|
| Record RtCode |
|
||||||
|
+---------------+
|
||||||
| Record Y |
|
| Record Y |
|
||||||
+---------------+
|
+---------------+
|
||||||
|
|
||||||
|
@ -622,7 +631,7 @@ SplitTable (
|
||||||
UINTN TotalSplitRecordCount;
|
UINTN TotalSplitRecordCount;
|
||||||
UINTN AdditionalRecordCount;
|
UINTN AdditionalRecordCount;
|
||||||
|
|
||||||
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
|
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;
|
||||||
|
|
||||||
TotalSplitRecordCount = 0;
|
TotalSplitRecordCount = 0;
|
||||||
//
|
//
|
||||||
|
@ -648,11 +657,13 @@ SplitTable (
|
||||||
//
|
//
|
||||||
// Adjust IndexNew according to real split.
|
// Adjust IndexNew according to real split.
|
||||||
//
|
//
|
||||||
CopyMem (
|
if (MaxSplitRecordCount != RealSplitRecordCount) {
|
||||||
((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
|
CopyMem (
|
||||||
((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
|
((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
|
||||||
RealSplitRecordCount * DescriptorSize
|
((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
|
||||||
);
|
(RealSplitRecordCount + 1) * DescriptorSize
|
||||||
|
);
|
||||||
|
}
|
||||||
IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
|
IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
|
||||||
TotalSplitRecordCount += RealSplitRecordCount;
|
TotalSplitRecordCount += RealSplitRecordCount;
|
||||||
IndexNew --;
|
IndexNew --;
|
||||||
|
@ -744,7 +755,7 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
|
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;
|
||||||
|
|
||||||
OldMemoryMapSize = *MemoryMapSize;
|
OldMemoryMapSize = *MemoryMapSize;
|
||||||
Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
|
Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
|
||||||
|
|
Loading…
Reference in New Issue