[PATCH v2 1/4] arm: mach-k3: Fix phandle corruption in fdt fixup
Andrew Davis
afd at ti.com
Thu Jul 2 17:13:18 CEST 2026
On 7/1/26 2:50 AM, Paresh Bhagat wrote:
> Fix phandle corruption in fdt_fixup_reserved_memory()
>
> The original implementation used a delete/recreate approach:
> - Find existing reserved memory node (e.g. tfa at 80000000)
> - Delete the entire node with fdt_del_node()
> - Create new node with fdtdec_add_reserved_memory()
>
> This worked fine for ATF and OPTEE nodes because no other device tree
> nodes reference them via phandles but other nodes example DM are
> referenced by R5 nodes.
>
> If these nodes are deleted and recreated, it will not have any phandle
> property but the nodes referencing it will still contain the old
> phandle, causing initialization to fail.
>
> Update nodes in-place instead of delete/recreate to update only the
> "reg" property using fdt_setprop().
>
> Fixes: 8b0fc29de0e3 ("arm: mach-k3: am62: Fixup TF-A/OP-TEE reserved-memory node in FDT")
>
> Signed-off-by: Paresh Bhagat <p-bhagat at ti.com>
> ---
> arch/arm/mach-k3/common_fdt.c | 31 +++++++------------------------
> 1 file changed, 7 insertions(+), 24 deletions(-)
>
> diff --git a/arch/arm/mach-k3/common_fdt.c b/arch/arm/mach-k3/common_fdt.c
> index 39cb00c3f43..4b833f5fabe 100644
> --- a/arch/arm/mach-k3/common_fdt.c
> +++ b/arch/arm/mach-k3/common_fdt.c
> @@ -119,7 +119,6 @@ static int fdt_fixup_reserved_memory(void *blob, const char *name,
> unsigned int new_size)
> {
> int nodeoffset, subnode;
> - int ret;
> struct fdt_memory carveout = {
> .start = new_address,
> };
> @@ -129,43 +128,27 @@ static int fdt_fixup_reserved_memory(void *blob, const char *name,
> if (nodeoffset < 0)
> goto add_carveout;
>
> - /* Find existing matching subnode and remove it */
> + /* Find existing matching subnode and update it in place */
> fdt_for_each_subnode(subnode, blob, nodeoffset) {
> const char *node_name;
> - fdt_addr_t addr;
> - fdt_size_t size;
> + u64 reg[2];
>
> /* Name matching */
> node_name = fdt_get_name(blob, subnode, NULL);
> if (!name)
> return -EINVAL;
> if (!strncmp(node_name, name, strlen(name))) {
> - /* Read out old size first */
> - addr = fdtdec_get_addr_size_auto_parent(
> - blob, nodeoffset, subnode, "reg", 0, &size,
> - false);
> - if (addr == FDT_ADDR_T_NONE)
> - return -EINVAL;
> - new_size = size;
> -
> - /* Delete node */
> - ret = fdt_del_node(blob, subnode);
> - if (ret < 0)
> - return ret;
> -
> - /* Only one matching node */
> - break;
> + /* Update the reg property in place */
> + reg[0] = cpu_to_fdt64(new_address);
> + reg[1] = cpu_to_fdt64(new_size);
> + return fdt_setprop(blob, subnode, "reg", reg, sizeof(reg));
Note that this only updates the `reg` property, not the node name itself
which will still include the old @address. Not that it really matters though,
I'm just trying to remember why I used a delete/recreate approach here in
the first place.
This also assumes address and size cells are always 64bit (which should
always be the case, but might be good to check).
Acked-by: Andrew Davis <afd at ti.com>
> }
> }
>
> add_carveout:
> carveout.end = new_address + new_size - 1;
> - ret = fdtdec_add_reserved_memory(blob, name, &carveout, NULL, 0, NULL,
> + return fdtdec_add_reserved_memory(blob, name, &carveout, NULL, 0, NULL,
> FDTDEC_RESERVED_MEMORY_NO_MAP);
> - if (ret < 0)
> - return ret;
> -
> - return 0;
> }
>
> int fdt_fixup_reserved(void *blob)
More information about the U-Boot
mailing list