efi_loader: consider no-map property of reserved memory
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Thu, 27 Aug 2020 10:52:20 +0000 (12:52 +0200)
committerHeinrich Schuchardt <xypron.glpk@gmx.de>
Tue, 6 Oct 2020 05:43:56 +0000 (07:43 +0200)
The device tree may contain a /reserved-memory node. The no-map property
of the sub-nodes signals if the memory may be accessed by the UEFI payload
or not.

In the EBBR specification (https://github.com/arm-software/ebbr) the
modeling of the reserved memory has been clarified.

If a reserved memory node in the device tree has the no-map property map,
create a EfiReservedMemoryType memory map entry else use
EfiBootServicesData.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
cmd/bootefi.c

index 40d5ef2..fdf909f 100644 (file)
@@ -135,12 +135,29 @@ done:
        return ret;
 }
 
-static void efi_reserve_memory(u64 addr, u64 size)
+/**
+ * efi_reserve_memory() - add reserved memory to memory map
+ *
+ * @addr:      start address of the reserved memory range
+ * @size:      size of the reserved memory range
+ * @nomap:     indicates that the memory range shall not be accessed by the
+ *             UEFI payload
+ */
+static void efi_reserve_memory(u64 addr, u64 size, bool nomap)
 {
+       int type;
+       efi_uintn_t ret;
+
        /* Convert from sandbox address space. */
        addr = (uintptr_t)map_sysmem(addr, 0);
-       if (efi_add_memory_map(addr, size,
-                              EFI_RESERVED_MEMORY_TYPE) != EFI_SUCCESS)
+
+       if (nomap)
+               type = EFI_RESERVED_MEMORY_TYPE;
+       else
+               type = EFI_BOOT_SERVICES_DATA;
+
+       ret = efi_add_memory_map(addr, size, type);
+       if (ret != EFI_SUCCESS)
                log_err("Reserved memory mapping failed addr %llx size %llx\n",
                        addr, size);
 }
@@ -166,7 +183,7 @@ static void efi_carve_out_dt_rsv(void *fdt)
        for (i = 0; i < nr_rsv; i++) {
                if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0)
                        continue;
-               efi_reserve_memory(addr, size);
+               efi_reserve_memory(addr, size, false);
        }
 
        /* process reserved-memory */
@@ -186,8 +203,13 @@ static void efi_carve_out_dt_rsv(void *fdt)
                         * a size instead of a reg property.
                         */
                        if (fdt_addr != FDT_ADDR_T_NONE &&
-                           fdtdec_get_is_enabled(fdt, subnode))
-                               efi_reserve_memory(fdt_addr, fdt_size);
+                           fdtdec_get_is_enabled(fdt, subnode)) {
+                               bool nomap;
+
+                               nomap = !!fdt_getprop(fdt, subnode, "no-map",
+                                                     NULL);
+                               efi_reserve_memory(fdt_addr, fdt_size, nomap);
+                       }
                        subnode = fdt_next_subnode(fdt, subnode);
                }
        }