On 27 August 2014 13:53, Laszlo Ersek <ler...@redhat.com> wrote:
> On 08/27/14 13:12, Ard Biesheuvel wrote:
>> On 27 August 2014 12:36, Laszlo Ersek <ler...@redhat.com> wrote:
>>> On 08/27/14 11:35, Ard Biesheuvel wrote:
>>>> On 27 August 2014 11:07, Laszlo Ersek <ler...@redhat.com> wrote:
>>>>> On 08/27/14 09:10, Ard Biesheuvel wrote:
>>>>>> On 27 August 2014 00:24, Laszlo Ersek <ler...@redhat.com> wrote:
>>>
>>>>>>> (b) Predictably, my second question is about the second world. The
>>>>>>> permanent PEI memory must be distinct from the DTB.
>>>>>>>
>>>>>>> InitializeMemory() calculates where to place the permanent PEI memory.
>>>>>>> The permanent PEI memory does not cover the entire system RAM. It's
>>>>>>> (calculated) base address is UefiMemoryBase, and it's size comes from
>>>>>>> PcdSystemMemoryUefiRegionSize (64MB, see the next patch).
>>>>>>>
>>>>>>
>>>>>> Yes, so running with 64 MB will result in this region colliding with the 
>>>>>> DTB.
>>>>>
>>>>> Right.
>>>>>
>>>>> Note that this question can be short-circuited by a list of guarantees,
>>>>> for example:
>>>>> - the firmware volume will always (or never) be shadowed from flash to
>>>>>   system RAM (--> because this helps us see which outer branch in
>>>>>   InitializeMemory() will be taken),
>>>>> - and we'll never boot a guest with less than 128 MB RAM (--> this
>>>>>   determines the inner branch, and given the size of the firmware
>>>>>   volume, allows deducing the exact location of the permanent PEI RAM)
>>>>>
>>>>> If we can guarantee such things, I'm completely fine with that as an 
>>>>> answer.
>>>>>
>>>>
>>>> OK, so by shadowing in this context, you mean invoking QEMU in such a
>>>> way that the UEFI image is preloaded into DRAM?
>>>
>>> No. What I mean is the following. In edk2 you can build flash images (FD
>>> files) that contain various firmware volumes. A firmware volume's FFS
>>> (firmware volume file system) may contain an LZMA compressed file that
>>> is itself a firmware volume, after decompression.
>>>
>>> When your platform starts up, the reset vector and SEC run from flash.
>>> On some platforms, SEC locates these compressed FFS files in the initial
>>> boot firmware volume (mapped into flash), and decompresses them to
>>> system RAM. Thereby creating "shadowed" firmware volumes.
>>>
>>> I have no clue how this looks on the ARM platforms, but it's not
>>> something that changes from run to run. It's a design choice that is
>>> reflected in the FDF file, and the SEC code. If you just instrument
>>> these branches in question with a few DEBUG() calls, you'll see what the
>>> case is for this new platform.
>>>
>>> We "agreed" that PcdSystemMemoryInitializeInSec would be FALSE in our
>>> case. Given that SEC doesn't initialize the system memory, it's hard to
>>> imagine it would decompress firmware volumes to it. Hence I expect your
>>> debug messages should prove that there's no shadowing here. (Actually
>>> you might be able to deduce that statically, by tracking down
>>> PcdFdBaseAddress.)
>>>
>>
>> Looking the the logs, the first module that executed from DRAM is
>> Build/AArch64Virtualization-KVM/DEBUG_ARMLINUXGCC/AARCH64/MdeModulePkg/Core/Pei/PeiMain/DEBUG/PeiCore.dll,
>> everything before that is executed in place from NOR.
>>
>> So something like this should do the trick then?
>>
>> in ArmPlatformInitialize():
>>   ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));
>
> I can't immediately see where ArmPlatformInitialize() is called. If this
> ASSERT() runs before we enter InitializeMemory(), then it's fine.
>

It is called from CEntryPoint () in
ArmPlatformPkg/PrePeiCore/PrePeiCore.c, so that should be ok.

>>
>> and in ArmPlatformInitializeSystemMemory():
>>   ASSERT (NewSize >= SIZE_128MB);
>
> Seems OK.
>
>>   ASSERT (PcdGet32 (PcdFdBaseAddress) + PcdGet32 (PcdFdSize) < NewBase ||
>>           PcdGet32 (PcdFdBaseAddress) > NewBase + NewSize);
>>
>> (with comments describing the rationale, of course)
>
> Ah okay, these would assert that the FV and the system DRAM do not overlap.
>
> Seems good, but equality should be allowed in both expressions. You
> compare exclusive high limits against inclusive low limits, *plus*
> PcdFdSize is nonzero.
>
> If the first expression holds (with the proposed <=):
>
>   PcdGet32 (PcdFdBaseAddress) + PcdGet32 (PcdFdSize) <= NewBase
>
> Then that implies
>
>   PcdGet32 (PcdFdBaseAddress)                        <  NewBase
>
> which is exactly the negative of InitializeMemory()'s
>
>   FdBase                                             >= SystemMemoryBase
>
>
> Similarly, if the second one holds (with the proposed >=):
>
>   PcdGet32 (PcdFdBaseAddress) >= NewBase + NewSize
>
> then that implies
>
>      PcdGet32 (PcdFdBaseAddress) + PcdGet32 (PcdFdSize)
>   >  PcdGet32 (PcdFdBaseAddress)
>   >= NewBase + NewSize
>
> ie.
>
>   PcdGet32 (PcdFdBaseAddress) + PcdGet32 (PcdFdSize) > NewBase + NewSize
>
> which is exactly the negative of InitializeMemory()'s
>
>   FdTop                                              <= SystemMemoryTop
>
>
> So, yes these are good, but you should also allow equality.
>

ok

> The comments would be appreciated.
>

ok

>> The only thing that still needs some consideration is whether to allow
>> NewBase to be different from 0x4000_0000. It kind of complicates the
>> logic, and for no obvious gain, so I should probably add an assert for
>> that as well.
>
> Probably a good idea, yes.
>
>> Well, the arm64 kernel does not deal very well with DRAM below the
>> kernel Image. It would be much preferable to put the Image at base of
>> DRAM if the only thing occupying that area is the initial DTB (as the
>> EFI stub will relocate it anyway)
>
> Okay. In this case:
>
>>> Well, relocation *is* possible, if you want to do it.
>>>
>>> Namely, rather than calling BuildMemoryAllocationHob(), in order to
>>> cover the DTB *in place*, you can simply call AllocatePages() or
>>> AllocatePool() and copy the DTB there, from its original place. Importantly,
>>>
>>> - this allocation and copying needs to be done in the exact same place
>>>   as you'd call BuildMemoryAllocationHob() -- namely, still in PEI, and
>>>   after the permanent PEI RAM has been installed;
>>>
>>> - the AllocatePages() / AllocatePool() call itself would be internally
>>>   served *from* the permanent PEI RAM,
>>>
>>> - and, internally again, a very similar memory allocation HOB would be
>>>   created.
>>>
>>> Again: you can implement the protection from DXE with a relocation that
>>> is done in PEI (after permanent PEI RAM has been installed), instead of
>>> with an in-place BuildMemoryAllocationHob(). The only difference would
>>> be that ultimately the DTB would go on to live in the permanent PEI RAM
>>> range, not at it's original address, where QEMU has placed it.
>>>
>>> The problem in this case, however, is that in DXE you'd have a hard time
>>> finding the relocated DTB (for parsing it). As you said, you'd need yet
>>> another dynamic PCD, to store the address.
>>>
>>
>> So would a dynamic PCD be the only feasible way to do this?
>
> Yes, that's required. We use this pattern in OVMF as well (allocate some
> RAM in PEI, in the permanent PEI RAM, then point a dynamic PCD at it,
> then access the area in DXE).
>
> This is most certainly doable. I frowned at the introduction of another
> dynamic PCD only for a moment, and only because of extra "mental load".
> It's a clean technical approach though.
>

OK, good to know.

>>> ... Okay, summary time.
>>> - Temporary SEC/PEI RAM seems to be safely distinct.
>>> - permanent PEI RAM can be made distinct, by controlling a handful of
>>>   PCDs, and by asserting 128 MB minimum required memory size in
>>>   ArmPlatformInitializeSystemMemory(), when you parse the DTB.
>>> - We discussed four options for DXE protection:
>>>   - in-place DTB coverage at 0x4000_0000, with a memalloc HOB. Pro:
>>>     simple to do; con: might surprise the kernel and some tools.
>>>   - in-place DTB coverage at 0x4100_0000, with a memalloc HOB. Pro:
>>>     simple to do and likely no surprises for the kernel; con: QEMU
>>>     needs to be adapted.
>>>   - relocation from 0x4000_0000 to a dynamically allocated chunk of the
>>>     permanent PEI RAM. Pro: no surprises for the kernel; con: needs at
>>>     least one further dynamic PCD.
>>>   - (more than just DXE protection, actually): present the DTB over an
>>>     MMIO "channel". Whoever cares can fetch it into a temporary array,
>>>     parse it, then throw it away. Pro: DTB is unable to overlap with
>>>     system DRAM, and this discussion goes away. Con: needs new hardware
>>>     in machtype virt.
>>>
>>
>> OK, got my work cut out for me then
>
> Looks like we agreed on the asserts for Q2 then.
>
> For Q3, apparently you'll go with the relocation (option 3), because we
> don't really mind the new dynamic PCD, and other than that, option 3 is
> pure win.
>

OK, glad we cleared that up.

-- 
Ard.

------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to