Skip to content

Commit

Permalink
MdeModulePkg: Fix issues with AcceptMemoryResource()
Browse files Browse the repository at this point in the history
Support allocate type of AllocateMaxAddress and AllocateAddress in
AcceptMemoryResource().
Remove redundant memory map update of newly accepted memory region.
Delete some comments.
  • Loading branch information
gaojiaqi7 committed Aug 3, 2021
1 parent bc1c585 commit 13d5bc2
Showing 1 changed file with 80 additions and 28 deletions.
108 changes: 80 additions & 28 deletions MdeModulePkg/Core/Dxe/Mem/Page.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,27 +391,64 @@ CoreFreeMemoryMapStack (

EFI_STATUS
AcceptMemoryResource (
UINTN AcceptSize
IN UINTN 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;
MEMORY_ACCEPT_PROTOCOL *MemoryAcceptProtocol;
UINTN Start;
UINTN End;
EFI_STATUS Status;

Status = EFI_OUT_OF_RESOURCES;
UnacceptedEntryBase = 0;
UnacceptedEntryLength = 0;
AcceptSize = (AcceptSize + SIZE_32MB - 1) & ~(SIZE_32MB - 1);
Status = EFI_OUT_OF_RESOURCES;
UnacceptedEntryBase = 0;
UnacceptedEntryEnd = 0;
AcceptSize = (AcceptSize + SIZE_32MB - 1) & ~(SIZE_32MB - 1);

if (AcceptSize == 0) {
return EFI_INVALID_PARAMETER;
}

Status = gBS->LocateProtocol (&gMemoryAcceptProtocolGuid, NULL, (VOID **)&MemoryAcceptProtocol);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}

if (Type == AllocateAddress) {
Start = *Memory;
End = *Memory + AcceptSize;
}

if (Type == AllocateMaxAddress) {
if (*Memory < EFI_PAGE_MASK) {
return EFI_INVALID_PARAMETER;
}

if ((*Memory & EFI_PAGE_MASK) != EFI_PAGE_MASK) {
//
// Change MaxAddress to be 1 page lower
//
*Memory -= EFI_PAGE_SIZE;

//
// Set MaxAddress to a page boundary
//
*Memory &= ~(UINT64)EFI_PAGE_MASK;

//
// Set MaxAddress to end of the page
//
*Memory |= EFI_PAGE_MASK;
}
}

//
// Traverse the mGcdMemorySpaceMap to find out the unaccepted
// memory entry with enough size.
Expand All @@ -421,14 +458,30 @@ AcceptMemoryResource (
GcdEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

if (GcdEntry->GcdMemoryType == EfiGcdMemoryTypeUnaccepted) {
UnacceptedEntryBase = GcdEntry->BaseAddress;
if (Type == AllocateMaxAddress) {
if (GcdEntry->BaseAddress + AcceptSize - 1 > *Memory) {
continue;
}
} else if (Type == AllocateAddress) {
if (GcdEntry->BaseAddress > *Memory || GcdEntry->EndAddress < *Memory + AcceptSize - 1) {
continue;
}
}

UnacceptedEntryBase = GcdEntry->BaseAddress;
UnacceptedEntryEnd = GcdEntry->EndAddress;
UnacceptedEntryLength = GcdEntry->EndAddress - GcdEntry->BaseAddress + 1;
UnacceptedEntryCapability = GcdEntry->Capabilities;
//
// Remove the target memory space from GCD.
//
if (AcceptSize <= UnacceptedEntryLength) {
CoreRemoveMemorySpace (GcdEntry->BaseAddress, UnacceptedEntryLength);

if (Type != AllocateAddress) {
Start = GcdEntry->BaseAddress;
End = GcdEntry->BaseAddress + AcceptSize - 1;
}
break;
}
}
Expand All @@ -442,41 +495,44 @@ AcceptMemoryResource (
//
// Accept the memory using the interface provide by the protocol.
//
Status = MemoryAcceptProtocol->AcceptMemory (MemoryAcceptProtocol, UnacceptedEntryBase, AcceptSize);
Status = MemoryAcceptProtocol->AcceptMemory (MemoryAcceptProtocol, Start, AcceptSize);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}

//
// Add the remain lower part of unaccepted memory to the
// Gcd memory space and memory map.
//
if (Start > UnacceptedEntryBase) {
CoreAddMemorySpace (
EfiGcdMemoryTypeUnaccepted,
UnacceptedEntryBase,
Start - UnacceptedEntryBase,
UnacceptedEntryCapability
);
}

//
// Update accepted part of the memory entry to type of EfiGcdMemoryTypeSystemMemory
// and add the range to the memory map.
//
CoreAddMemorySpace (
EfiGcdMemoryTypeSystemMemory,
UnacceptedEntryBase,
Start,
AcceptSize,
EFI_MEMORY_RUNTIME | EFI_MEMORY_CPU_CRYPTO | EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP
);

CoreAcquireMemoryLock ();
CoreAddRange (
EfiConventionalMemory,
UnacceptedEntryBase,
UnacceptedEntryBase + AcceptSize - 1,
EFI_MEMORY_RUNTIME | EFI_MEMORY_CPU_CRYPTO | EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP
);
CoreReleaseMemoryLock ();

//
// Add the remain part of unaccepted memory to the
// Add the remain higher part of unaccepted memory to the
// Gcd memory space and memory map.
//
//
if (UnacceptedEntryLength - AcceptSize > 0) {
if (UnacceptedEntryEnd > End) {
CoreAddMemorySpace (
EfiGcdMemoryTypeUnaccepted,
UnacceptedEntryBase + AcceptSize,
UnacceptedEntryLength - AcceptSize,
End + 1,
UnacceptedEntryEnd - End,
UnacceptedEntryCapability
);
}
Expand Down Expand Up @@ -1451,17 +1507,14 @@ CoreInternalAllocatePages (
mMemoryTypeStatistics[CheckType].NumberOfPages > 0) {
if (Start >= mMemoryTypeStatistics[CheckType].BaseAddress &&
Start <= mMemoryTypeStatistics[CheckType].MaximumAddress) {
DEBUG ((DEBUG_INFO, "Memory region %x start address: 0x%lx, Max: 0x%lx\n", CheckType, mMemoryTypeStatistics[CheckType].BaseAddress, mMemoryTypeStatistics[CheckType].MaximumAddress));
return EFI_NOT_FOUND;
}
if (End >= mMemoryTypeStatistics[CheckType].BaseAddress &&
End <= mMemoryTypeStatistics[CheckType].MaximumAddress) {
DEBUG ((DEBUG_INFO, "Memory region %x start address: 0x%lx, Max: 0x%lx\n", CheckType, mMemoryTypeStatistics[CheckType].BaseAddress, mMemoryTypeStatistics[CheckType].MaximumAddress));
return EFI_NOT_FOUND;
}
if (Start < mMemoryTypeStatistics[CheckType].BaseAddress &&
End > mMemoryTypeStatistics[CheckType].MaximumAddress) {
DEBUG ((DEBUG_INFO, "Memory region %x start address: 0x%lx, Max: 0x%lx\n", CheckType, mMemoryTypeStatistics[CheckType].BaseAddress, mMemoryTypeStatistics[CheckType].MaximumAddress));
return EFI_NOT_FOUND;
}
}
Expand Down Expand Up @@ -1542,12 +1595,11 @@ CoreAllocatePages (
Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory,
NeedGuard);

if (Status == EFI_OUT_OF_RESOURCES && Type == AllocateAnyPages) {
Status = AcceptMemoryResource (NumberOfPages << EFI_PAGE_SHIFT);
if (Status == EFI_OUT_OF_RESOURCES) {
Status = AcceptMemoryResource (Type, NumberOfPages << EFI_PAGE_SHIFT, Memory);
if (!EFI_ERROR (Status)) {
Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory,
NeedGuard);
DEBUG ((DEBUG_INFO, "CoreInternalAllocatePages STATUS 0x%x\n", Status));
} else {
Status = EFI_OUT_OF_RESOURCES;
}
Expand Down

0 comments on commit 13d5bc2

Please sign in to comment.