From c4c085a2a680afc712b40e37f5aeb69ce25478ce Mon Sep 17 00:00:00 2001 From: rsun3 Date: Wed, 13 Jul 2011 08:40:55 +0000 Subject: [PATCH] Fix an issue that there may be an infinite loop in the CoreInitializeMemoryServices() in Gcd.c of the DXE Core. Also update logic to use continue statements to reduce the level of nesting in the two loops that search the HOB lists. More comment are added. Signed-off-by: rsun3 Reviewed-by: mdkinney Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12015 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 179 +++++++++++++++++++------------- 1 file changed, 109 insertions(+), 70 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c index 0ec75ca502..ab8677a972 100644 --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c +++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c @@ -1930,9 +1930,9 @@ CoreInitializeMemoryServices ( EFI_PHYSICAL_ADDRESS MaxMemoryBaseAddress; UINT64 MaxMemoryLength; UINT64 MaxMemoryAttributes; - EFI_PHYSICAL_ADDRESS MaxAddress; + EFI_PHYSICAL_ADDRESS TestedMemoryBaseAddress; + UINT64 TestedMemoryLength; EFI_PHYSICAL_ADDRESS HighAddress; - EFI_HOB_RESOURCE_DESCRIPTOR *MaxResourceHob; EFI_HOB_GUID_TYPE *GuidHob; UINT32 ReservedCodePageNumber; @@ -1952,7 +1952,6 @@ CoreInitializeMemoryServices ( // Initialize Local Variables // PhitResourceHob = NULL; - MaxResourceHob = NULL; ResourceHob = NULL; BaseAddress = 0; Length = 0; @@ -1989,43 +1988,68 @@ CoreInitializeMemoryServices ( } // - // Find the Resource Descriptor HOB that contains range FreeMemoryBaseAddress..FreeMemoryLength + // Find the Resource Descriptor HOB that contains PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop // Length = 0; Found = FALSE; for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { + // + // Skip all HOBs except Resource Descriptor HOBs + // + if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + continue; + } - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + // + // Skip Resource Descriptor HOBs that do not describe tested system memory + // + ResourceHob = Hob.ResourceDescriptor; + if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { + continue; + } + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) { + continue; + } - ResourceHob = Hob.ResourceDescriptor; + // + // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop + // + if (PhitHob->EfiFreeMemoryBottom < ResourceHob->PhysicalStart) { + continue; + } + if (PhitHob->EfiFreeMemoryTop > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) { + continue; + } - if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && - (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES ) { - - if (PhitHob->EfiFreeMemoryBottom >= ResourceHob->PhysicalStart && - PhitHob->EfiFreeMemoryTop <= (ResourceHob->PhysicalStart + ResourceHob->ResourceLength) ) { - - // - // Cache the resource descriptor HOB for the memory region described by the PHIT HOB - // - PhitResourceHob = ResourceHob; - Found = TRUE; - - Attributes = PhitResourceHob->ResourceAttribute; - BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop); - Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress); - if (Length < MINIMUM_INITIAL_MEMORY_SIZE) { - BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom); - Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress); - if (Length < MINIMUM_INITIAL_MEMORY_SIZE) { - BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart); - Length = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress)); - } - } - break; - } + // + // Cache the resource descriptor HOB for the memory region described by the PHIT HOB + // + PhitResourceHob = ResourceHob; + Found = TRUE; + + // + // Compute range between PHIT EfiFreeMemoryTop and the end of the Resource Descriptor HOB + // + Attributes = PhitResourceHob->ResourceAttribute; + BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop); + Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress); + if (Length < MINIMUM_INITIAL_MEMORY_SIZE) { + // + // If that range is not large enough to intialize the DXE Core, then + // Compute range between PHIT EfiFreeMemoryBottom and PHIT EfiFreeMemoryTop + // + BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom); + Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress); + if (Length < MINIMUM_INITIAL_MEMORY_SIZE) { + // + // If that range is not large enough to intialize the DXE Core, then + // Compute range between the start of the Resource Descriptor HOB and the start of the HOB List + // + BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart); + Length = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress)); } } + break; } // @@ -2038,51 +2062,66 @@ CoreInitializeMemoryServices ( // region that is big enough to initialize the DXE core. Always skip the PHIT Resource HOB. // The max address must be within the physically addressible range for the processor. // - MaxMemoryLength = 0; - MaxAddress = MAX_ADDRESS; - do { - HighAddress = 0; - Found = FALSE; + HighAddress = MAX_ADDRESS; + for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { // - // Search for a tested memory region that is below MaxAddress + // Skip the Resource Descriptor HOB that contains the PHIT // - for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - - // - // See if this is a resource descriptor HOB that does not contain the PHIT. - // - if (Hob.ResourceDescriptor != PhitResourceHob && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if (Hob.ResourceDescriptor == PhitResourceHob) { + continue; + } + // + // Skip all HOBs except Resource Descriptor HOBs + // + if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + continue; + } - ResourceHob = Hob.ResourceDescriptor; - // - // See if this resource descrior HOB describes tested system memory below MaxAddress - // - if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && - (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES && - ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MaxAddress) { - // - // See if this is the highest tested system memory region below MaxAddress - // - if (ResourceHob->PhysicalStart > HighAddress) { - - MaxResourceHob = ResourceHob; - HighAddress = MaxResourceHob->PhysicalStart; - Found = TRUE; - } - } - } + // + // Skip Resource Descriptor HOBs that do not describe tested system memory below MAX_ADDRESS + // + ResourceHob = Hob.ResourceDescriptor; + if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { + continue; } - if (Found) { - // - // Compute the size of the tested memory region below MaxAddrees - // - MaxMemoryBaseAddress = PageAlignAddress (MaxResourceHob->PhysicalStart); - MaxMemoryLength = PageAlignLength (MaxResourceHob->PhysicalStart + MaxResourceHob->ResourceLength - MaxMemoryBaseAddress); - MaxMemoryAttributes = MaxResourceHob->ResourceAttribute; + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) { + continue; + } + if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS) { + continue; } - MaxAddress = ResourceHob->PhysicalStart; - } while (Found && MaxMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE); + + // + // Skip Resource Descriptor HOBs that are below a previously found Resource Descriptor HOB + // + if (HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS && ResourceHob->PhysicalStart <= HighAddress) { + continue; + } + + // + // Skip Resource Descriptor HOBs that are not large enough to initilize the DXE Core + // + TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart); + TestedMemoryLength = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - TestedMemoryBaseAddress); + if (TestedMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE) { + continue; + } + + // + // Save the Resource Descriptor HOB context that is large enough to initilize the DXE Core + // + MaxMemoryBaseAddress = TestedMemoryBaseAddress; + MaxMemoryLength = TestedMemoryLength; + MaxMemoryAttributes = ResourceHob->ResourceAttribute; + HighAddress = ResourceHob->PhysicalStart; + } + // + // If Length is not large enough to initialize the DXE Core or a Resource + // Descriptor HOB was found above the PHIT HOB that is large enough to initialize + // the DXE Core, then use the range described by the Resource Descriptor + // HOB that was found above the PHIT HOB. + // if ((Length < MINIMUM_INITIAL_MEMORY_SIZE) || (MaxMemoryBaseAddress > BaseAddress && MaxMemoryLength >= MINIMUM_INITIAL_MEMORY_SIZE)) { BaseAddress = MaxMemoryBaseAddress; -- 2.39.2