From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 6EDD381C8B for ; Thu, 1 Dec 2016 00:23:43 -0800 (PST) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP; 01 Dec 2016 00:23:43 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,723,1477983600"; d="scan'208";a="37560811" Received: from jyao1-mobl.ccr.corp.intel.com ([10.239.192.126]) by orsmga005.jf.intel.com with ESMTP; 01 Dec 2016 00:23:41 -0800 From: Jiewen Yao To: edk2-devel@lists.01.org Cc: Jeff Fan , Michael D Kinney , Laszlo Ersek Date: Thu, 1 Dec 2016 16:23:25 +0800 Message-Id: <1480580607-19928-2-git-send-email-jiewen.yao@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 In-Reply-To: <1480580607-19928-1-git-send-email-jiewen.yao@intel.com> References: <1480580607-19928-1-git-send-email-jiewen.yao@intel.com> Subject: [PATCH] MdeModulePkg/PiSmmCore: MemoryAttributeTable need keep non-PE record. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Dec 2016 08:23:43 -0000 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 Cc: Michael D Kinney Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c | 91 +++++++++++--------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c index 3a5a2c8..a6ab830 100644 --- a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c @@ -268,15 +268,19 @@ EnforceMemoryMapAttribute ( MemoryMapEntry = MemoryMap; MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - switch (MemoryMapEntry->Type) { - case EfiRuntimeServicesCode: - MemoryMapEntry->Attribute |= EFI_MEMORY_RO; - break; - case EfiRuntimeServicesData: - MemoryMapEntry->Attribute |= EFI_MEMORY_XP; - break; + if (MemoryMapEntry->Attribute != 0) { + // It is PE image, the attribute is already set. + } else { + switch (MemoryMapEntry->Type) { + case EfiRuntimeServicesCode: + MemoryMapEntry->Attribute = EFI_MEMORY_RO; + break; + case EfiRuntimeServicesData: + default: + MemoryMapEntry->Attribute |= EFI_MEMORY_XP; + break; + } } - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); } @@ -358,6 +362,21 @@ SetNewRecord ( PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages); 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; ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; @@ -452,14 +471,10 @@ GetMaxSplitRecordCount ( if (ImageRecord == NULL) { break; } - SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1); + SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 2); PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); - if (SplitRecordCount != 0) { - SplitRecordCount--; - } - return SplitRecordCount; } @@ -516,28 +531,16 @@ SplitRecord ( // // 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); - if (NewRecord->Type == EfiRuntimeServicesData) { - // - // Last record is DATA, just merge it. - // - NewRecord->NumberOfPages = EfiSizeToPages(PhysicalEnd - NewRecord->PhysicalStart); - } 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 ++; - } + NewRecord->Type = TempRecord.Type; + NewRecord->PhysicalStart = TempRecord.PhysicalStart; + NewRecord->VirtualStart = 0; + NewRecord->NumberOfPages = TempRecord.NumberOfPages; + NewRecord->Attribute = TempRecord.Attribute; + TotalNewRecordCount ++; } break; } @@ -580,6 +583,8 @@ SplitRecord ( ==> +---------------+ | Record X | + +---------------+ + | Record RtCode | +---------------+ ---- | Record RtData | | +---------------+ | @@ -587,12 +592,16 @@ SplitRecord ( +---------------+ | | Record RtData | | +---------------+ ---- + | Record RtCode | + +---------------+ ---- | Record RtData | | +---------------+ | | Record RtCode | |-> PE/COFF2 +---------------+ | | Record RtData | | +---------------+ ---- + | Record RtCode | + +---------------+ | Record Y | +---------------+ @@ -622,7 +631,7 @@ SplitTable ( UINTN TotalSplitRecordCount; UINTN AdditionalRecordCount; - AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount; + AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount; TotalSplitRecordCount = 0; // @@ -648,11 +657,13 @@ SplitTable ( // // Adjust IndexNew according to real split. // - CopyMem ( - ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize), - ((UINT8 *)MemoryMap + IndexNew * DescriptorSize), - RealSplitRecordCount * DescriptorSize - ); + if (MaxSplitRecordCount != RealSplitRecordCount) { + CopyMem ( + ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize), + ((UINT8 *)MemoryMap + IndexNew * DescriptorSize), + (RealSplitRecordCount + 1) * DescriptorSize + ); + } IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount; TotalSplitRecordCount += RealSplitRecordCount; IndexNew --; @@ -744,7 +755,7 @@ SmmCoreGetMemoryMapMemoryAttributesTable ( return EFI_INVALID_PARAMETER; } - AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount; + AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount; OldMemoryMapSize = *MemoryMapSize; Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); -- 2.7.4.windows.1