On 13 January 2015 at 16:15, Laszlo Ersek <[email protected]> wrote:
> 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.
>

Correct. I am looking into changing the allocation strategy for
runtime regions so they are aligned multiples of 64k (to accommodate
OSes running with 64k pages)

> 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.
>

OK, I am fine with that as well. In fact, I don't care deeply about
whether or not this check is performed at all, but the current
situation is a bit awkward.

-- 
Ard.

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