diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h index 090f3f089f4a9..32df829b00717 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Imem.h +++ b/MdeModulePkg/Core/Dxe/Mem/Imem.h @@ -69,6 +69,12 @@ CoreAllocatePoolPages ( ); +EFI_STATUS +AcceptMemoryResource ( + IN UINTN Type, + IN UINTN AcceptSize, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); /** Internal function. Frees pool pages allocated via AllocatePoolPages () diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index cefc0ad8d2bc3..de751666e88d9 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -391,26 +391,20 @@ CoreFreeMemoryMapStack ( EFI_STATUS AcceptMemoryResource ( - IN UINTN Type, + IN EFI_ALLOCATE_TYPE Type, IN UINTN AcceptSize, IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { LIST_ENTRY *Link; EFI_GCD_MAP_ENTRY *GcdEntry; - EFI_PHYSICAL_ADDRESS UnacceptedEntryBase; - UINTN UnacceptedEntryEnd; - UINTN UnacceptedEntryLength; - UINTN UnacceptedEntryCapability; + EFI_GCD_MAP_ENTRY UnacceptedEntry; MEMORY_ACCEPT_PROTOCOL *MemoryAcceptProtocol; UINTN Start; UINTN End; EFI_STATUS Status; - Status = EFI_OUT_OF_RESOURCES; - UnacceptedEntryBase = 0; - UnacceptedEntryEnd = 0; - AcceptSize = (AcceptSize + SIZE_32MB - 1) & ~(SIZE_32MB - 1); + AcceptSize = (AcceptSize + SIZE_32MB - 1) & ~(SIZE_32MB - 1); if (AcceptSize == 0) { return EFI_INVALID_PARAMETER; @@ -427,6 +421,7 @@ AcceptMemoryResource ( } if (Type == AllocateMaxAddress) { + if (*Memory < EFI_PAGE_MASK) { return EFI_INVALID_PARAMETER; } @@ -458,6 +453,7 @@ AcceptMemoryResource ( GcdEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); if (GcdEntry->GcdMemoryType == EfiGcdMemoryTypeUnaccepted) { + if (Type == AllocateMaxAddress) { if (GcdEntry->BaseAddress + AcceptSize - 1 > *Memory) { continue; @@ -468,15 +464,13 @@ AcceptMemoryResource ( } } - UnacceptedEntryBase = GcdEntry->BaseAddress; - UnacceptedEntryEnd = GcdEntry->EndAddress; - UnacceptedEntryLength = GcdEntry->EndAddress - GcdEntry->BaseAddress + 1; - UnacceptedEntryCapability = GcdEntry->Capabilities; + UnacceptedEntry = *GcdEntry; + // // Remove the target memory space from GCD. // - if (AcceptSize <= UnacceptedEntryLength) { - CoreRemoveMemorySpace (GcdEntry->BaseAddress, UnacceptedEntryLength); + if (AcceptSize <= UnacceptedEntry.EndAddress - UnacceptedEntry.BaseAddress + 1) { + CoreRemoveMemorySpace (GcdEntry->BaseAddress, UnacceptedEntry.EndAddress - UnacceptedEntry.BaseAddress + 1); if (Type != AllocateAddress) { Start = GcdEntry->BaseAddress; @@ -500,16 +494,21 @@ AcceptMemoryResource ( return EFI_OUT_OF_RESOURCES; } + // + // Fix me! CoreAddMemorySpace() should not be called in the allocation process + // because it will allocate memory for GCD map entry. + // + // // Add the remain lower part of unaccepted memory to the // Gcd memory space and memory map. // - if (Start > UnacceptedEntryBase) { + if (Start > UnacceptedEntry.BaseAddress) { CoreAddMemorySpace ( EfiGcdMemoryTypeUnaccepted, - UnacceptedEntryBase, - Start - UnacceptedEntryBase, - UnacceptedEntryCapability + UnacceptedEntry.BaseAddress, + Start - UnacceptedEntry.BaseAddress, + UnacceptedEntry.Capabilities ); } @@ -528,12 +527,12 @@ AcceptMemoryResource ( // Add the remain higher part of unaccepted memory to the // Gcd memory space and memory map. // - if (UnacceptedEntryEnd > End) { + if (UnacceptedEntry.EndAddress > End) { CoreAddMemorySpace ( EfiGcdMemoryTypeUnaccepted, End + 1, - UnacceptedEntryEnd - End, - UnacceptedEntryCapability + UnacceptedEntry.EndAddress - End, + UnacceptedEntry.Capabilities ); } @@ -2193,7 +2192,6 @@ CoreAllocatePoolPages ( ) { UINT64 Start; - // // Find the pages to convert // diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c index 734fc94bf6129..0881c0ab4acc3 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c +++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c @@ -276,6 +276,16 @@ CoreAllocatePool ( EFI_STATUS Status; Status = CoreInternalAllocatePool (PoolType, Size, Buffer); + + if (Status == EFI_OUT_OF_RESOURCES) { + Status = AcceptMemoryResource (AllocateAnyPages, Size, NULL); + if (!EFI_ERROR (Status)) { + Status = CoreInternalAllocatePool (PoolType, Size, Buffer); + } else { + Status = EFI_OUT_OF_RESOURCES; + } + } + if (!EFI_ERROR (Status)) { CoreUpdateProfile ( (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),