]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
arm: mach-k3: Fix phandle corruption in fdt fixup
authorParesh Bhagat <p-bhagat@ti.com>
Wed, 1 Jul 2026 07:50:18 +0000 (13:20 +0530)
committerTom Rini <trini@konsulko.com>
Thu, 16 Jul 2026 18:04:48 +0000 (12:04 -0600)
Fix phandle corruption in fdt_fixup_reserved_memory()

The original implementation used a delete/recreate approach:
- Find existing reserved memory node (e.g. tfa@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@ti.com>
Reviewed-by: Neha Malcom Francis <n-francis@ti.com>
Acked-by: Andrew Davis <afd@ti.com>
arch/arm/mach-k3/common_fdt.c

index 39cb00c3f4394a13ad78466c327e0c7627489e1e..4b833f5fabedf33912429b7fb465c652efe419e1 100644 (file)
@@ -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));
                }
        }
 
 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)