From 5f4d3e179435f539395748bcd5187e3c395b0bf9 Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Wed, 30 Nov 2016 23:08:51 +0800 Subject: [PATCH] MdeModulePkg/PiSmmCore: AllocatePool should use MemoryType. PiSmmCore supports page level protection based upon the Memory Type (EfiRuntimeServicesCode/EfiRuntimeServicesData) and PE image. However, the Memory Type information is ignored in AllocatePool(). If a caller calls AllocatePool with EfiRuntimeServicesCode, the final memory is still allocated as EfiRuntimeServicesData. This patch supports AllocatePool with EfiRuntimeServicesCode. Cc: Jeff Fan Cc: Michael D Kinney Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao Reviewed-by: Jeff Fan Regression-tested-by: Laszlo Ersek --- MdeModulePkg/Core/PiSmmCore/PiSmmCore.h | 13 +- MdeModulePkg/Core/PiSmmCore/Pool.c | 66 +++++++--- .../Core/PiSmmCore/SmramProfileRecord.c | 114 ++++++++++-------- 3 files changed, 124 insertions(+), 69 deletions(-) diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h index e2fee549f8..8df1e500f0 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h @@ -1109,8 +1109,9 @@ extern LIST_ENTRY mSmmMemoryMap; #define MAX_POOL_INDEX (MAX_POOL_SHIFT - MIN_POOL_SHIFT + 1) typedef struct { - UINTN Size; - BOOLEAN Available; + UINTN Size; + BOOLEAN Available; + EFI_MEMORY_TYPE Type; } POOL_HEADER; typedef struct { @@ -1118,6 +1119,12 @@ typedef struct { LIST_ENTRY Link; } FREE_POOL_HEADER; -extern LIST_ENTRY mSmmPoolLists[MAX_POOL_INDEX]; +typedef enum { + SmmPoolTypeCode, + SmmPoolTypeData, + SmmPoolTypeMax, +} SMM_POOL_TYPE; + +extern LIST_ENTRY mSmmPoolLists[SmmPoolTypeMax][MAX_POOL_INDEX]; #endif diff --git a/MdeModulePkg/Core/PiSmmCore/Pool.c b/MdeModulePkg/Core/PiSmmCore/Pool.c index aae6a6e217..173650ae1d 100644 --- a/MdeModulePkg/Core/PiSmmCore/Pool.c +++ b/MdeModulePkg/Core/PiSmmCore/Pool.c @@ -14,13 +14,37 @@ #include "PiSmmCore.h" -LIST_ENTRY mSmmPoolLists[MAX_POOL_INDEX]; +LIST_ENTRY mSmmPoolLists[SmmPoolTypeMax][MAX_POOL_INDEX]; // // To cache the SMRAM base since when Loading modules At fixed address feature is enabled, // all module is assigned an offset relative the SMRAM base in build time. // GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS gLoadModuleAtFixAddressSmramBase = 0; +/** + Convert a UEFI memory type to SMM pool type. + + @param[in] MemoryType Type of pool to allocate. + + @return SMM pool type +**/ +SMM_POOL_TYPE +UefiMemoryTypeToSmmPoolType ( + IN EFI_MEMORY_TYPE MemoryType + ) +{ + ASSERT ((MemoryType == EfiRuntimeServicesCode) || (MemoryType == EfiRuntimeServicesData)); + switch (MemoryType) { + case EfiRuntimeServicesCode: + return SmmPoolTypeCode; + case EfiRuntimeServicesData: + return SmmPoolTypeData; + default: + return SmmPoolTypeMax; + } +} + + /** Called to initialize the memory service. @@ -35,15 +59,18 @@ SmmInitializeMemoryServices ( ) { UINTN Index; - UINT64 SmmCodeSize; - UINTN CurrentSmramRangesIndex; - UINT64 MaxSize; + UINT64 SmmCodeSize; + UINTN CurrentSmramRangesIndex; + UINT64 MaxSize; + UINTN SmmPoolTypeIndex; // // Initialize Pool list // - for (Index = ARRAY_SIZE (mSmmPoolLists); Index > 0;) { - InitializeListHead (&mSmmPoolLists[--Index]); + for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { + for (Index = 0; Index < ARRAY_SIZE (mSmmPoolLists[SmmPoolTypeIndex]); Index++) { + InitializeListHead (&mSmmPoolLists[SmmPoolTypeIndex][Index]); + } } CurrentSmramRangesIndex = 0; // @@ -120,6 +147,7 @@ SmmInitializeMemoryServices ( /** Internal Function. Allocate a pool by specified PoolIndex. + @param PoolType Type of pool to allocate. @param PoolIndex Index which indicate the Pool size. @param FreePoolHdr The returned Free pool. @@ -129,6 +157,7 @@ SmmInitializeMemoryServices ( **/ EFI_STATUS InternalAllocPoolByIndex ( + IN EFI_MEMORY_TYPE PoolType, IN UINTN PoolIndex, OUT FREE_POOL_HEADER **FreePoolHdr ) @@ -136,25 +165,29 @@ InternalAllocPoolByIndex ( EFI_STATUS Status; FREE_POOL_HEADER *Hdr; EFI_PHYSICAL_ADDRESS Address; + SMM_POOL_TYPE SmmPoolType; + + SmmPoolType = UefiMemoryTypeToSmmPoolType(PoolType); ASSERT (PoolIndex <= MAX_POOL_INDEX); Status = EFI_SUCCESS; Hdr = NULL; if (PoolIndex == MAX_POOL_INDEX) { - Status = SmmInternalAllocatePages (AllocateAnyPages, EfiRuntimeServicesData, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address); + Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } Hdr = (FREE_POOL_HEADER *) (UINTN) Address; - } else if (!IsListEmpty (&mSmmPoolLists[PoolIndex])) { - Hdr = BASE_CR (GetFirstNode (&mSmmPoolLists[PoolIndex]), FREE_POOL_HEADER, Link); + } else if (!IsListEmpty (&mSmmPoolLists[SmmPoolType][PoolIndex])) { + Hdr = BASE_CR (GetFirstNode (&mSmmPoolLists[SmmPoolType][PoolIndex]), FREE_POOL_HEADER, Link); RemoveEntryList (&Hdr->Link); } else { - Status = InternalAllocPoolByIndex (PoolIndex + 1, &Hdr); + Status = InternalAllocPoolByIndex (PoolType, PoolIndex + 1, &Hdr); if (!EFI_ERROR (Status)) { Hdr->Header.Size >>= 1; Hdr->Header.Available = TRUE; - InsertHeadList (&mSmmPoolLists[PoolIndex], &Hdr->Link); + Hdr->Header.Type = PoolType; + InsertHeadList (&mSmmPoolLists[SmmPoolType][PoolIndex], &Hdr->Link); Hdr = (FREE_POOL_HEADER*)((UINT8*)Hdr + Hdr->Header.Size); } } @@ -162,6 +195,7 @@ InternalAllocPoolByIndex ( if (!EFI_ERROR (Status)) { Hdr->Header.Size = MIN_POOL_SIZE << PoolIndex; Hdr->Header.Available = FALSE; + Hdr->Header.Type = PoolType; } *FreePoolHdr = Hdr; @@ -181,16 +215,19 @@ InternalFreePoolByIndex ( IN FREE_POOL_HEADER *FreePoolHdr ) { - UINTN PoolIndex; + UINTN PoolIndex; + SMM_POOL_TYPE SmmPoolType; ASSERT ((FreePoolHdr->Header.Size & (FreePoolHdr->Header.Size - 1)) == 0); ASSERT (((UINTN)FreePoolHdr & (FreePoolHdr->Header.Size - 1)) == 0); ASSERT (FreePoolHdr->Header.Size >= MIN_POOL_SIZE); + SmmPoolType = UefiMemoryTypeToSmmPoolType(FreePoolHdr->Header.Type); + PoolIndex = (UINTN) (HighBitSet32 ((UINT32)FreePoolHdr->Header.Size) - MIN_POOL_SHIFT); FreePoolHdr->Header.Available = TRUE; ASSERT (PoolIndex < MAX_POOL_INDEX); - InsertHeadList (&mSmmPoolLists[PoolIndex], &FreePoolHdr->Link); + InsertHeadList (&mSmmPoolLists[SmmPoolType][PoolIndex], &FreePoolHdr->Link); return EFI_SUCCESS; } @@ -237,6 +274,7 @@ SmmInternalAllocatePool ( PoolHdr = (POOL_HEADER*)(UINTN)Address; PoolHdr->Size = EFI_PAGES_TO_SIZE (Size); PoolHdr->Available = FALSE; + PoolHdr->Type = PoolType; *Buffer = PoolHdr + 1; return Status; } @@ -247,7 +285,7 @@ SmmInternalAllocatePool ( PoolIndex++; } - Status = InternalAllocPoolByIndex (PoolIndex, &FreePoolHdr); + Status = InternalAllocPoolByIndex (PoolType, PoolIndex, &FreePoolHdr); if (!EFI_ERROR(Status)) { *Buffer = &FreePoolHdr->Header + 1; } diff --git a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c index d983cefbb3..dda9f12a7d 100644 --- a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c +++ b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c @@ -1596,6 +1596,7 @@ SmramProfileGetDataSize ( FREE_POOL_HEADER *Pool; UINTN PoolListIndex; UINTN Index; + UINTN SmmPoolTypeIndex; ContextData = GetSmramProfileContext (); if (ContextData == NULL) { @@ -1638,19 +1639,20 @@ SmramProfileGetDataSize ( Node = Node->BackLink) { Index++; } - for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { - FreePoolList = &mSmmPoolLists[PoolListIndex]; - for (Node = FreePoolList->BackLink; - Node != FreePoolList; - Node = Node->BackLink) { - Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); - if (Pool->Header.Available) { - Index++; + for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { + for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { + FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][PoolListIndex]; + for (Node = FreePoolList->BackLink; + Node != FreePoolList; + Node = Node->BackLink) { + Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); + if (Pool->Header.Available) { + Index++; + } } } } - TotalSize += (sizeof (MEMORY_PROFILE_FREE_MEMORY) + Index * sizeof (MEMORY_PROFILE_DESCRIPTOR)); TotalSize += (sizeof (MEMORY_PROFILE_MEMORY_RANGE) + mFullSmramRangeCount * sizeof (MEMORY_PROFILE_DESCRIPTOR)); @@ -1698,6 +1700,7 @@ SmramProfileCopyData ( UINT64 RemainingSize; UINTN PdbSize; UINTN ActionStringSize; + UINTN SmmPoolTypeIndex; ContextData = GetSmramProfileContext (); if (ContextData == NULL) { @@ -1785,14 +1788,16 @@ SmramProfileCopyData ( Node = Node->BackLink) { Index++; } - for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { - FreePoolList = &mSmmPoolLists[MAX_POOL_INDEX - PoolListIndex - 1]; - for (Node = FreePoolList->BackLink; - Node != FreePoolList; - Node = Node->BackLink) { - Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); - if (Pool->Header.Available) { - Index++; + for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { + for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { + FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][MAX_POOL_INDEX - PoolListIndex - 1]; + for (Node = FreePoolList->BackLink; + Node != FreePoolList; + Node = Node->BackLink) { + Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); + if (Pool->Header.Available) { + Index++; + } } } } @@ -1827,29 +1832,31 @@ SmramProfileCopyData ( } Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR); } - for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { - FreePoolList = &mSmmPoolLists[MAX_POOL_INDEX - PoolListIndex - 1]; - for (Node = FreePoolList->BackLink; - Node != FreePoolList; - Node = Node->BackLink) { - Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); - if (Pool->Header.Available) { - if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) { - if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) { - MemoryProfileDescriptor = ProfileBuffer; - MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE; - MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR); - MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION; - MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pool; - MemoryProfileDescriptor->Size = Pool->Header.Size; - - RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR); - ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR); - } else { - goto Done; + for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { + for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { + FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][MAX_POOL_INDEX - PoolListIndex - 1]; + for (Node = FreePoolList->BackLink; + Node != FreePoolList; + Node = Node->BackLink) { + Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); + if (Pool->Header.Available) { + if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) { + if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) { + MemoryProfileDescriptor = ProfileBuffer; + MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE; + MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR); + MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION; + MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pool; + MemoryProfileDescriptor->Size = Pool->Header.Size; + + RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR); + ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR); + } else { + goto Done; + } } + Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR); } - Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR); } } } @@ -2577,6 +2584,7 @@ DumpFreePoolList ( UINTN PoolListIndex; MEMORY_PROFILE_CONTEXT_DATA *ContextData; BOOLEAN SmramProfileGettingStatus; + UINTN SmmPoolTypeIndex; ContextData = GetSmramProfileContext (); if (ContextData == NULL) { @@ -2586,23 +2594,25 @@ DumpFreePoolList ( SmramProfileGettingStatus = mSmramProfileGettingStatus; mSmramProfileGettingStatus = TRUE; - DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n")); - - for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { - DEBUG ((EFI_D_INFO, "FreePoolList (%d):\n", PoolListIndex)); - FreePoolList = &mSmmPoolLists[PoolListIndex]; - for (Node = FreePoolList->BackLink, Index = 0; - Node != FreePoolList; - Node = Node->BackLink, Index++) { - Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); - DEBUG ((EFI_D_INFO, " Index - 0x%x\n", Index)); - DEBUG ((EFI_D_INFO, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS) (UINTN) Pool)); - DEBUG ((EFI_D_INFO, " Size - 0x%08x\n", Pool->Header.Size)); - DEBUG ((EFI_D_INFO, " Available - 0x%02x\n", Pool->Header.Available)); + DEBUG ((DEBUG_INFO, "======= SmramProfile begin =======\n")); + + for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { + for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { + DEBUG ((DEBUG_INFO, "FreePoolList(%d)(%d):\n", SmmPoolTypeIndex, PoolListIndex)); + FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][PoolListIndex]; + for (Node = FreePoolList->BackLink, Index = 0; + Node != FreePoolList; + Node = Node->BackLink, Index++) { + Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); + DEBUG ((DEBUG_INFO, " Index - 0x%x\n", Index)); + DEBUG ((DEBUG_INFO, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS) (UINTN) Pool)); + DEBUG ((DEBUG_INFO, " Size - 0x%08x\n", Pool->Header.Size)); + DEBUG ((DEBUG_INFO, " Available - 0x%02x\n", Pool->Header.Available)); + } } } - DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n")); + DEBUG ((DEBUG_INFO, "======= SmramProfile end =======\n")); mSmramProfileGettingStatus = SmramProfileGettingStatus; } -- 2.39.2