[PATCH] efi_loader: consider no-map property of reserved memory

Mark Kettenis mark.kettenis at xs4all.nl
Thu May 13 23:53:41 CEST 2021


> From: Heinrich Schuchardt <xypron.glpk at 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 at 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 at 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 at 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.html
> >>
> >> 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.html
> 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


More information about the U-Boot mailing list