Skip to content

Commit

Permalink
libfdt: Simplify adjustment of values for local fixups
Browse files Browse the repository at this point in the history
In a couple of places in fdt_overlay.c we need to adjust a phandle value
in a property (either a node's phandle itself or a reference) by some
delta.  Currently this is done if a fairly convoluted way, open-coding
loading the value and handling of a non-aligned reference, and then using
fdt_setprop_inplace_partial() to replace the value.  This becomes much
simpler if we use fdt_getprop_w() to get a writable pointer to the value
then we can just load/store it with fdt32_{ld,st}().

Signed-off-by: David Gibson <[email protected]>
  • Loading branch information
dgibson committed Feb 23, 2024
1 parent da39ee0 commit 24f6001
Showing 1 changed file with 15 additions and 37 deletions.
52 changes: 15 additions & 37 deletions libfdt/fdt_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,26 +101,22 @@ int fdt_overlay_target_offset(const void *fdt, const void *fdto,
static int overlay_phandle_add_offset(void *fdt, int node,
const char *name, uint32_t delta)
{
const fdt32_t *val;
uint32_t adj_val;
fdt32_t *valp, val;
int len;

val = fdt_getprop(fdt, node, name, &len);
if (!val)
valp = fdt_getprop_w(fdt, node, name, &len);
if (!valp)
return len;

if (len != sizeof(*val))
if (len != sizeof(val))
return -FDT_ERR_BADPHANDLE;

adj_val = fdt32_to_cpu(*val);
if ((adj_val + delta) < adj_val)
return -FDT_ERR_NOPHANDLES;

adj_val += delta;
if (adj_val == (uint32_t)-1)
val = fdt32_ld(valp);
if (val + delta < val || val + delta == (uint32_t)-1)

This comment has been minimized.

Copy link
@ukleinek

ukleinek Feb 23, 2024

Contributor

The commit log suggests no semantic change, but here is one. I'd split that out in a separate patch or at least mention it in the commit log.

This comment has been minimized.

Copy link
@dgibson

dgibson Feb 23, 2024

Author Owner

This shouldn't be a semantic change, it's just combining the conditions from the two adjacent ifs.

This comment has been minimized.

Copy link
@ukleinek

ukleinek Feb 23, 2024

Contributor

Oh indeed, I missed there being two ifs with the same return value. I didn't say anything!

return -FDT_ERR_NOPHANDLES;

return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
fdt32_st(valp, val + delta);
return 0;
}

/**
Expand Down Expand Up @@ -213,8 +209,8 @@ static int overlay_update_local_node_references(void *fdto,

fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
const fdt32_t *fixup_val;
const char *tree_val;
const char *name;
char *tree_val;
int fixup_len;
int tree_len;
int i;
Expand All @@ -228,7 +224,7 @@ static int overlay_update_local_node_references(void *fdto,
return -FDT_ERR_BADOVERLAY;
fixup_len /= sizeof(uint32_t);

tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
tree_val = fdt_getprop_w(fdto, tree_node, name, &tree_len);
if (!tree_val) {
if (tree_len == -FDT_ERR_NOTFOUND)
return -FDT_ERR_BADOVERLAY;
Expand All @@ -237,33 +233,15 @@ static int overlay_update_local_node_references(void *fdto,
}

for (i = 0; i < fixup_len; i++) {
fdt32_t adj_val;
uint32_t poffset;
fdt32_t *refp;

poffset = fdt32_to_cpu(fixup_val[i]);
refp = (fdt32_t *)(tree_val + fdt32_ld_(fixup_val + i));

/*
* phandles to fixup can be unaligned.
*
* Use a memcpy for the architectures that do
* not support unaligned accesses.
* phandles to fixup can be unaligned, so use
* fdt32_{ld,st}() to read/write them.
*/
memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));

adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);

ret = fdt_setprop_inplace_namelen_partial(fdto,
tree_node,
name,
strlen(name),
poffset,
&adj_val,
sizeof(adj_val));
if (ret == -FDT_ERR_NOSPACE)
return -FDT_ERR_BADOVERLAY;

if (ret)
return ret;
fdt32_st(refp, fdt32_ld(refp) + delta);
}
}

Expand Down

1 comment on commit 24f6001

@ukleinek
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise looks fine to me.
👍
Uwe

Please sign in to comment.