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 <[email protected]> Cc: Gua Guo <[email protected]> Cc: Guo Dong <[email protected]> Cc: James Lu <[email protected]> Cc: Sean Rhodes <[email protected]> Cc: Shuo Liu <[email protected]> Assisted-by: claude-opus-5 Signed-off-by: Alexander Graf <[email protected]> --- .../UefiPayloadEntry/UefiPayloadEntry.c | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c index 8a730cce65..7233ed24db 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c @@ -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; } -- 2.47.3 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#122088): https://edk2.groups.io/g/devel/message/122088 Mute This Topic: https://groups.io/mt/120797202/21656 Group Owner: [email protected] Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
