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@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 <[email protected]> --- 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 <[email protected]>
} }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)

