[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