[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