mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
UefiPayloadPkg/UefiPayloadEntry: Don't mutate the bootloader memory map
FindFreeMemForHobCallback() aligns the base of a candidate RAM region up to 1 MiB and, on 32-bit builds, clips its size at 4 GiB. It makes both adjustments through the incoming MemoryMapEntry pointer, and for Slim Bootloader that pointer refers directly into the gLoaderMemoryMapInfoGuid HOB the bootloader handed over, so we rewrite the bootloader's map in place. MemInfoCallback() walks the same array afterwards to publish the system memory resource HOBs. On any platform whose RAM base is not already 1 MiB aligned we therefore drop the leading fragment silently: it is published neither as system memory nor as anything else, and ends up NonExistent in the GCD map with no way for the OS to reclaim it. On 32-bit builds we lose RAM above 4 GiB the same way. Copy the entry to a local before adjusting it, mirroring the MemoryMapEntrySplit idiom the function already uses when it recurses around the payload FV. The selected HobMemBase is unchanged; only the caller's array stops being corrupted. CbParseLib is unaffected: its ParseMemoryInfo() already passes a stack-local MEMORY_MAP_ENTRY to the callback and refills it on every iteration. Cc: Benjamin Doron <benjamin.doron@9elements.com> Cc: Gua Guo <gua.guo@intel.com> Cc: Guo Dong <guo.dong@intel.com> Cc: James Lu <james.lu@intel.com> Cc: Sean Rhodes <sean@starlabs.systems> Cc: Shuo Liu <shuo.liu@intel.com> Assisted-by: claude-opus-5 Signed-off-by: Alexander Graf <graf@amazon.com>
This commit is contained in:
parent
339e8221af
commit
ed3e2c6143
1 changed files with 22 additions and 14 deletions
|
|
@ -190,6 +190,7 @@ FindFreeMemForHobCallback (
|
|||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MEMORY_MAP_ENTRY Entry;
|
||||
MEMORY_MAP_ENTRY MemoryMapEntrySplit;
|
||||
UINTN *HobMemBase = (UINTN *)Params;
|
||||
|
||||
|
|
@ -207,56 +208,63 @@ FindFreeMemForHobCallback (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Operate on a copy so the caller's memory map is not modified.
|
||||
// SblParseLib passes pointers into the bootloader's HOB and the same
|
||||
// array is walked again later to publish system memory resource HOBs.
|
||||
//
|
||||
Entry = *MemoryMapEntry;
|
||||
|
||||
//
|
||||
// Align on 1 MiB
|
||||
//
|
||||
if (ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) > MemoryMapEntry->Base) {
|
||||
if (ALIGN_VALUE (Entry.Base, SIZE_1MB) > Entry.Base) {
|
||||
//
|
||||
// Skip too small
|
||||
//
|
||||
if (ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) >= (MemoryMapEntry->Base + MemoryMapEntry->Size)) {
|
||||
if (ALIGN_VALUE (Entry.Base, SIZE_1MB) >= (Entry.Base + Entry.Size)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
MemoryMapEntry->Size -= ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB) - MemoryMapEntry->Base;
|
||||
MemoryMapEntry->Base = ALIGN_VALUE (MemoryMapEntry->Base, SIZE_1MB);
|
||||
Entry.Size -= ALIGN_VALUE (Entry.Base, SIZE_1MB) - Entry.Base;
|
||||
Entry.Base = ALIGN_VALUE (Entry.Base, SIZE_1MB);
|
||||
}
|
||||
|
||||
//
|
||||
// Skip resources above 4GiB on x86_32
|
||||
//
|
||||
if ((sizeof (UINTN) == 4) && (MemoryMapEntry->Base >= 0x100000000ULL)) {
|
||||
if ((sizeof (UINTN) == 4) && (Entry.Base >= 0x100000000ULL)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if ((sizeof (UINTN) == 4) && ((MemoryMapEntry->Base + MemoryMapEntry->Size) > 0x100000000ULL)) {
|
||||
MemoryMapEntry->Size = 0x100000000ULL - MemoryMapEntry->Base;
|
||||
if ((sizeof (UINTN) == 4) && ((Entry.Base + Entry.Size) > 0x100000000ULL)) {
|
||||
Entry.Size = 0x100000000ULL - Entry.Base;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip too small
|
||||
//
|
||||
if (MemoryMapEntry->Size < FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
|
||||
if (Entry.Size < FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Overlaps UefiPayload, split into smaller chunks
|
||||
//
|
||||
if ((MemoryMapEntry->Base <= PcdGet32 (PcdPayloadFdMemBase)) &&
|
||||
((MemoryMapEntry->Base + MemoryMapEntry->Size) >= PcdGet32 (PcdPayloadFdMemBase)))
|
||||
if ((Entry.Base <= PcdGet32 (PcdPayloadFdMemBase)) &&
|
||||
((Entry.Base + Entry.Size) >= PcdGet32 (PcdPayloadFdMemBase)))
|
||||
{
|
||||
MemoryMapEntrySplit.Type = E820_RAM;
|
||||
MemoryMapEntrySplit.Base = MemoryMapEntry->Base;
|
||||
MemoryMapEntrySplit.Base = Entry.Base;
|
||||
MemoryMapEntrySplit.Size = PcdGet32 (PcdPayloadFdMemBase) - MemoryMapEntrySplit.Base;
|
||||
Status = FindFreeMemForHobCallback (&MemoryMapEntrySplit, Params);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((MemoryMapEntry->Base + MemoryMapEntry->Size) > (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize))) {
|
||||
if ((Entry.Base + Entry.Size) > (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize))) {
|
||||
MemoryMapEntrySplit.Base = PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize);
|
||||
MemoryMapEntrySplit.Size = (MemoryMapEntry->Base + MemoryMapEntry->Size) - MemoryMapEntrySplit.Base;
|
||||
MemoryMapEntrySplit.Size = (Entry.Base + Entry.Size) - MemoryMapEntrySplit.Base;
|
||||
Status = FindFreeMemForHobCallback (&MemoryMapEntrySplit, Params);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
|
|
@ -266,7 +274,7 @@ FindFreeMemForHobCallback (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
*HobMemBase = MemoryMapEntry->Base;
|
||||
*HobMemBase = Entry.Base;
|
||||
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue