[PATCH 1/6 v14] ARM: Handle a device tree in lowmem

Ard Biesheuvel ardb at kernel.org
Mon Oct 5 10:22:47 EDT 2020


On Mon, 5 Oct 2020 at 15:36, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Mon, 5 Oct 2020 at 15:27, Linus Walleij <linus.walleij at linaro.org> wrote:
> >
> > On Mon, Oct 5, 2020 at 11:14 AM Ard Biesheuvel <ardb at kernel.org> wrote:
> > > On Mon, 5 Oct 2020 at 09:14, Ard Biesheuvel <ardb at kernel.org> wrote:
> >
> > > > Let me see if I can code up a PoC
> > >
> > > I pushed a branch to
> > >
> > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=arm-dt-mapping
> > >
> > > that moves the DT mapping to a read-only region at the top of the
> > > kernel VA space: there happened to be a 4 MB hole there (between
> > > VMALLOC_END and FIXADDR_START) that we can use, even if the purpose of
> > > that hole was as a guard region, as a read-only mapping still catches
> > > stray writes.
> >
> > I will test it when I'm back at the hardware.
> > I tried to do this thing as well but couldn't figure out a good
> > place to map it, putting it between VMALLOC_END
> > and FIXADDR_START seems like a good idea!
> >
> > But this is going to be a problem:
> >
> > + map.type = MT_ROM;
> >
> > Because the current code calls unflatten_device_tree() which
> > will unflatten the device tree right where it is.
> > So then the memory needs to be RW.
> >
>
> I don't think this is the case. Note that arm64 has been using r/o
> mappings for the device tree for a long time, and it calls
> unflatten_device_tree() without any problems.
>

I think the problem here may be that early_init_fdt_reserve_self()
uses the wrong translation for obtaining the PA of the device tree
blob. This is also the reason we no longer use it on arm64 IIRC.

When I add the following on top, everything works as expected with
MT_ROM, including the ability to dump the firmware provided DT from
/sys/firmware/fdt



diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 40fe688a7b76..1dbc8a46cf5f 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -18,6 +18,7 @@
 #include <linux/of_platform.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
+#include <linux/libfdt.h>
 #include <linux/of_fdt.h>
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
@@ -1082,8 +1083,11 @@ void __init setup_arch(char **cmdline_p)
                atags_vaddr = FDT_VIRT_ADDR(__atags_pointer);

        setup_processor();
-       if (atags_vaddr)
+       if (atags_vaddr) {
                mdesc = setup_machine_fdt(atags_vaddr);
+               if (mdesc)
+                       memblock_reserve(__atags_pointer,
fdt_totalsize(atags_vaddr));
+       }
        if (!mdesc)
                mdesc = setup_machine_tags(atags_vaddr, __machine_arch_type);
        if (!mdesc) {
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 000c1b48e973..652a87bd065c 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -223,7 +223,6 @@ void __init arm_memblock_init(const struct
machine_desc *mdesc)
        if (mdesc->reserve)
                mdesc->reserve();

-       early_init_fdt_reserve_self();
        early_init_fdt_scan_reserved_mem();

        /* reserve memory for DMA contiguous allocations */



More information about the linux-arm-kernel mailing list