On 01/13/15 16:13, Ard Biesheuvel wrote:
> The function CoreTerminateMemoryMap() performs some final sanity checks
> on the runtime regions in the memory map before allowing ExitBootServices()
> to complete. Unfortunately, it does so by testing the EFI_MEMORY_RUNTIME bit
> in the Attribute field, which is never set anywhere in the code.
> 
> Fix it by setting the bit where appropriate in CoreAddRange().
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <[email protected]>
> ---
>  MdeModulePkg/Core/Dxe/Mem/Page.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c 
> b/MdeModulePkg/Core/Dxe/Mem/Page.c
> index fa84e2612526..3abf934933d8 100644
> --- a/MdeModulePkg/Core/Dxe/Mem/Page.c
> +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
> @@ -240,6 +240,10 @@ CoreAddRange (
>      }
>    }
>  
> +  if (mMemoryTypeStatistics[Type].Runtime) {
> +    Attribute |= EFI_MEMORY_RUNTIME;
> +  }
> +
>    //
>    // Add descriptor
>    //
> 

I think the check that you imply in CoreTerminateMemoryMap() is indeed dead 
code. But, I don't see how your patch would make it less dead. :)

mMemoryTypeStatistics is a static array. Elements in that array never change 
their Runtime fields.

The CoreGetMemoryMap() function uses the Runtime field to set the 
EFI_MEMORY_RUNTIME bit for various types of memory (EfiRuntimeServicesCode, 
EfiRuntimeServicesData, EfiPalCode), but that bit is set only in the map built 
for the caller, never in the internal map.

When CoreTerminateMemoryMap() looks at the internal attribute bits, I agree 
that EFI_MEMORY_RUNTIME is never set, so that check is dead. However, the first 
check within that condition looks for at the type directly, 
EfiACPIReclaimMemory and EfiACPIMemoryNVS. Even if the EFI_MEMORY_RUNTIME bit 
had fired, this check would remain dead, because for these two memory types the 
Runtime bit is never set in the mMemoryTypeStatistics.

... Aha! You're not aiming at the first check here. You are looking at the 
start & end alignments.

In that case though, I don't think we should change the invariant

  the internal attributes never set EFI_MEMORY_RUNTIME

Instead, I think CoreTerminateMemoryMap() should replicate the check in seen 
CoreGetMemoryMap(). Something like:

> diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c 
> b/MdeModulePkg/Core/Dxe/Mem/Page.c
> index fa84e26..d9e2075 100644
> --- a/MdeModulePkg/Core/Dxe/Mem/Page.c
> +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
> @@ -1790,12 +1790,9 @@ CoreTerminateMemoryMap (
>  
>      for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = 
> Link->ForwardLink) {
>        Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
> -      if ((Entry->Attribute & EFI_MEMORY_RUNTIME) != 0) {
> -        if (Entry->Type == EfiACPIReclaimMemory || Entry->Type == 
> EfiACPIMemoryNVS) {
> -          DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: ACPI memory 
> entry has RUNTIME attribute set.\n"));
> -          Status =  EFI_INVALID_PARAMETER;
> -          goto Done;
> -        }
> +      if (mMemoryTypeStatistics[Entry->Type].Runtime) {
> +        ASSERT (Entry->Type != EfiACPIReclaimMemory);
> +        ASSERT (Entry->Type != EfiACPIMemoryNVS);
>          if ((Entry->Start & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 
> 1)) != 0) {
>            DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: A RUNTIME 
> memory entry is not on a proper alignment.\n"));
>            Status =  EFI_INVALID_PARAMETER;

Of course I have no jurisdiction in MdeModulePkg/Core/, so I'm just theorizing 
:) Still,

  the internal attributes never set EFI_MEMORY_RUNTIME

looks more like a deliberate invariant than an oversight.

Thanks
Laszlo

------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to