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]]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to