Thread (29 messages) flat view 29 messages, 5 authors, 2021-06-16

Re: [PATCH v19 05/13] of: Add a common kexec FDT setup function

From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: 2021-06-15 12:18:15
Also in: linux-devicetree, linux-integrity, linuxppc-dev, lkml

Hi Lakshmi and Rob,

On Sun, Feb 21, 2021 at 6:52 PM Lakshmi Ramasubramanian
[off-list ref] wrote:
From: Rob Herring <robh@kernel.org>

Both arm64 and powerpc do essentially the same FDT /chosen setup for
kexec.  The differences are either omissions that arm64 should have
or additional properties that will be ignored.  The setup code can be
combined and shared by both powerpc and arm64.

The differences relative to the arm64 version:
 - If /chosen doesn't exist, it will be created (should never happen).
 - Any old dtb and initrd reserved memory will be released.
 - The new initrd and elfcorehdr are marked reserved.
 - "linux,booted-from-kexec" is set.

The differences relative to the powerpc version:
 - "kaslr-seed" and "rng-seed" may be set.
 - "linux,elfcorehdr" is set.
 - Any existing "linux,usable-memory-range" is removed.

Combine the code for setting up the /chosen node in the FDT and updating
the memory reservation for kexec, for powerpc and arm64, in
of_kexec_alloc_and_setup_fdt() and move it to "drivers/of/kexec.c".

Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Lakshmi Ramasubramanian <redacted>
quoted hunk ↗ jump to hunk
--- /dev/null
+++ b/drivers/of/kexec.c
+/*
+ * of_kexec_alloc_and_setup_fdt - Alloc and setup a new Flattened Device Tree
+ *
+ * @image:             kexec image being loaded.
+ * @initrd_load_addr:  Address where the next initrd will be loaded.
+ * @initrd_len:                Size of the next initrd, or 0 if there will be none.
+ * @cmdline:           Command line for the next kernel, or NULL if there will
+ *                     be none.
+ * @extra_fdt_size:    Additional size for the new FDT buffer.
+ *
+ * Return: fdt on success, or NULL errno on error.
+ */
+void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
+                                  unsigned long initrd_load_addr,
+                                  unsigned long initrd_len,
+                                  const char *cmdline, size_t extra_fdt_size)
+{
+       /* Did we boot using an initrd? */
+       prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL);
+       if (prop) {
+               u64 tmp_start, tmp_end, tmp_size;
+
+               tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
+
+               prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", NULL);
+               if (!prop) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
Some kernel code assumes "linux,initrd-{start,end}" are 64-bit,
other code assumes 32-bit.
linux/Documentation/arm/uefi.rst says 64-bit,
dt-schema/schemas/chosen.yaml says 32-bit.
+
+               /*
+                * kexec reserves exact initrd size, while firmware may
+                * reserve a multiple of PAGE_SIZE, so check for both.
+                */
+               tmp_size = tmp_end - tmp_start;
+               ret = fdt_find_and_del_mem_rsv(fdt, tmp_start, tmp_size);
+               if (ret == -ENOENT)
+                       ret = fdt_find_and_del_mem_rsv(fdt, tmp_start,
+                                                      round_up(tmp_size, PAGE_SIZE));
+               if (ret == -EINVAL)
+                       goto out;
+       }
+
+       /* add initrd-* */
+       if (initrd_load_addr) {
+               ret = fdt_setprop_u64(fdt, chosen_node, FDT_PROP_INITRD_START,
+                                     initrd_load_addr);
+               if (ret)
+                       goto out;
+
+               ret = fdt_setprop_u64(fdt, chosen_node, FDT_PROP_INITRD_END,
+                                     initrd_load_addr + initrd_len);
+               if (ret)
+                       goto out;
+
+               ret = fdt_add_mem_rsv(fdt, initrd_load_addr, initrd_len);
+               if (ret)
+                       goto out;
+
+       } else {
+               ret = fdt_delprop(fdt, chosen_node, FDT_PROP_INITRD_START);
+               if (ret && (ret != -FDT_ERR_NOTFOUND))
+                       goto out;
+
+               ret = fdt_delprop(fdt, chosen_node, FDT_PROP_INITRD_END);
+               if (ret && (ret != -FDT_ERR_NOTFOUND))
+                       goto out;
+       }
Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help