From 42488064e10383247d0c321fe1e7fc13eec0752c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 21 Mar 2024 13:27:56 +0000 Subject: [PATCH] fix(fdt): reserved memory: detect existing region When fdt_add_reserved_memory() is called to add a memory region, we unconditionally add a node for that region. However there might be an existing region node in the DT already, or there might be an overlapping region. The Linux kernel will complain in those cases. Cover the simple case of the region already existing in the DT, as this is what we actually see on the Allwinner H616: The mainline DT contains a node reserving the memory for TF-A, in case the DT changed by TF-A itself is not given to the kernel. Our code always adds a region, making the kernel complain - albeit without further consequences. Covering all cases of overlapping regions would blow up the generic DT code too much, so just add a simple check for an existing region completely containing the to-be-added region, simply bailing out in this case. This prevents the kernel warning for the Allwinner H616. This code requires a function from fdt_wrappers.c, so we have to include that file for platforms that use the fdt_add_reserved_memory() function (rpi4 and versal2). Change-Id: I98404889163316addbb42130d7177f1a21c8be06 Signed-off-by: Andre Przywara --- common/fdt_fixup.c | 19 +++++++++++++++++++ plat/amd/versal2/platform.mk | 1 + plat/rpi/rpi4/platform.mk | 1 + 3 files changed, 21 insertions(+) diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c index 1bad74fe6..59b754359 100644 --- a/common/fdt_fixup.c +++ b/common/fdt_fixup.c @@ -197,6 +197,7 @@ int fdt_add_reserved_memory(void *dtb, const char *node_name, uintptr_t base, size_t size) { int offs = fdt_path_offset(dtb, "/reserved-memory"); + int node; uint32_t addresses[4]; int ac, sc; unsigned int idx = 0; @@ -213,6 +214,24 @@ int fdt_add_reserved_memory(void *dtb, const char *node_name, fdt_setprop(dtb, offs, "ranges", NULL, 0); } + /* Check for existing regions */ + fdt_for_each_subnode(node, dtb, offs) { + uintptr_t c_base; + size_t c_size; + int ret; + + ret = fdt_get_reg_props_by_index(dtb, node, 0, &c_base, &c_size); + /* Ignore illegal subnodes */ + if (ret != 0) { + continue; + } + + /* existing region entirely contains the new region */ + if (base >= c_base && (base + size) <= (c_base + c_size)) { + return 0; + } + } + if (ac > 1) { addresses[idx] = cpu_to_fdt32(HIGH_BITS(base)); idx++; diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk index c07fc36a8..1c977a309 100644 --- a/plat/amd/versal2/platform.mk +++ b/plat/amd/versal2/platform.mk @@ -116,6 +116,7 @@ BL31_SOURCES += plat/xilinx/common/plat_fdt.c \ plat/xilinx/common/versal.c \ ${PLAT_PATH}/bl31_setup.c \ common/fdt_fixup.c \ + common/fdt_wrappers.c \ ${LIBFDT_SRCS} \ ${PLAT_PATH}/sip_svc_setup.c \ ${PLAT_PATH}/gicv3.c diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk index cbfa6f2fd..c39a58776 100644 --- a/plat/rpi/rpi4/platform.mk +++ b/plat/rpi/rpi4/platform.mk @@ -31,6 +31,7 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ plat/common/plat_psci_common.c \ plat/rpi/common/rpi3_topology.c \ common/fdt_fixup.c \ + common/fdt_wrappers.c \ ${LIBFDT_SRCS} \ ${GICV2_SOURCES}