
From: Heinrich Schuchardt xypron.glpk@gmx.de Date: Thu, 13 May 2021 21:41:40 +0200
Hi Heinrich & Atish,
On 5/11/21 1:47 AM, Atish Patra wrote:
On Wed, Sep 2, 2020 at 12:10 AM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 31.08.20 20:08, Atish Patra wrote:
On Thu, Aug 27, 2020 at 9:16 AM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
If a reserved memory node in the device tree has the property no-map, remove it from the UEFI memory map provided by GetMemoryMap().
Signed-off-by: Heinrich Schuchardt xypron.glpk@gmx.de
In the mail-thread starting a
[PATCH 1/1] EBBR: GetMemoryMap(), handling of no-map DT property https://lists.linaro.org/pipermail/boot-architecture/2020-September/001389.h...
the issue has been discussed. The conclusion was that we should not change the current behavior.
Digging some old threads :)
The merged version of the patch marks any reserved memory as EFI_BOOT_SERVICES_DATA. AFAIK, these memory regions will be available after ExitBootservice. If the operating system chooses to map these region and access them, it violates the purpose of the reserved memory region specified by the firmware.
Did I miss something ?
The no-map property is neither described in the EBBR nor in the Devicetree specification v0.3 but only in Linux' reserved-memory.txt.
It is described (quite explicitly) in the current devicetree specification draft.
In https://lists.linaro.org/pipermail/boot-architecture/2020-September/001418.h... Ard requested that no-map memory shall be marked EfiReservedMemory because Linux will not map EfiReservedMemory, see Linux function is_usable_memory().
All reserved memory that is not marked as no-map shall be mapped by Linux. It may for instance serve as DMA pool or as video memory. Or it may even be reusable. See reserved-memory.txt.
Only drivers will access their own reserved memory if the region is not marked as reusable.
I suspect Atish is asking because of the issue I opened for opensbi:
https://github.com/riscv/opensbi/issues/210
On many RISC-V platforms, opensbi runs in "machine mode" (somewhat equivalent to EL3 on ARMv8) and allocates some memory for itself. It sets up protections for this memory such that "supervisor mode" (somewhat equivalent to EL1 on ARMv8) can't access this memory.
Older versions of opensbi marked this memory area as "no-map", resulting in that memory area being marked as EfiReservedMemoryType, and evrything is fine.
However, according to reserved-memory.txt, "no-map" means the the area isn't supposed to be mapped by the OS at all. That is deemed undesirable since it prevents the OS from using a large 2MB or 1G page table entry to map the memory range that happens to include the memory reserved for opensbi. That is sub-optimal as it means the OS has to allocated more levels of page tables for this memory block and has to use 4K pages which will increase TLB pressure. So newer versions of opensbi dropped the "no-map" property resulting in the area being marked as EfiBootServicesData. But that is obviously wrong since the OS can't actually access that memory range.
Now somewhat by accident the Linux kernel didn't actually attempt to use this memory area so the issue wasn't noticed. But we're working on OpenBSD/riscv64 and when I added code to use the EFI memory map the OpenBSD kernel tried to use that inaccessable memory, which obviously didn't end well.
I suspect differences between the ARMv8 and RISC-V architecture are at play here. On ARMv8 "secure" memory areas like this are not supposed to be mapped as speculative access might trigger a fault. But on RISC-V mapping a "protected" memory area is fine as long as you don't try to actually access it.
So the question really is how opensbi can express that a certain memory area is reserved (and should end up as EfiReservedMemoryType in the EFI memory map) but that it is ok to map it. Possible solution include:
* Change the interpretation of the "no-map" property for RISC-V such that it is clear that the region in question can be mapped but can not be accessed. This only makes sense if the RISC-V architecture guarantees that creating a mapping for physical memory will never cause problems even if those areas can't be accessed.
* Invent a new property that conveys the desired semantics.
* Always flag memory ranges under /reserved-memory as EfiReserbedMemoryType unless that memory range is marked as "reusable".
Cheers,
Mark