mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Herve Codina <herve.codina@bootlin.com>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	David Lechner <dlechner@baylibre.com>,
	Ayush Singh <ayush@beagleboard.org>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org,
	Hui Pu <hui.pu@gehealthcare.com>,
	Ian Ray <ian.ray@gehealthcare.com>,
	Luca Ceresoli <luca.ceresoli@bootlin.com>,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Subject: Re: [PATCH v3 11/15] libfdt: Introduce fdt_getprop_by_offset_w()
Date: Wed, 16 Sep 2026 12:42:05 +0200	[thread overview]
Message-ID: <20260916124205.28a71859@bootlin.com> (raw)
In-Reply-To: <aqpnzXyR_k4fs7Jk@gractus.seuss>

Hi David,

On Wed, 16 Sep 2026 19:56:46 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Wed, Aug 26, 2026 at 10:31:42AM +0200, Herve Codina wrote:
> > Future operations, such as handling unknown tags on dtb modifications,
> > need to modify properties retrieved by their offset.
> > 
> > fdt_getprop_by_offset() already exists to get a preperty by its offset
> > but the property returned is read-only. A writable returned property is
> > needed.  
> 
> Since we already have fdt_get_property_by_offset_w() this is an
> obvious gap and I'd be happy in principle to apply this independent of
> the rest of the series.

Nice :)

> 
> > Fill the lack and introduce fdt_getprop_by_offset_w(), the write enabled
> > variant of fdt_getprop_by_offset().
> > 
> > Add also its related test.
> > 
> > Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> > ---
> >  libfdt/libfdt.h           |  6 +++
> >  tests/.gitignore          |  1 +
> >  tests/Makefile.tests      |  2 +-
> >  tests/get_prop_offset_w.c | 84 +++++++++++++++++++++++++++++++++++++++
> >  tests/meson.build         |  1 +
> >  tests/run_tests.sh        |  1 +
> >  tests/tests.h             |  1 +
> >  tests/testutils.c         | 18 +++++++++
> >  8 files changed, 113 insertions(+), 1 deletion(-)
> >  create mode 100644 tests/get_prop_offset_w.c
> > 
> > diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
> > index 7a1915a5..82965e32 100644
> > --- a/libfdt/libfdt.h
> > +++ b/libfdt/libfdt.h
> > @@ -856,6 +856,12 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
> >  #ifndef SWIG /* This function is not useful in Python */
> >  const void *fdt_getprop_by_offset(const void *fdt, int offset,
> >  				  const char **namep, int *lenp);
> > +static inline void *fdt_getprop_by_offset_w(const void *fdt, int offset,
> > +					    const char **namep, int *lenp)
> > +{
> > +	return (void *)(uintptr_t)fdt_getprop_by_offset(fdt, offset, namep,
> > +							lenp);
> > +}
> >  #endif
> >  
> >  /**
> > diff --git a/tests/.gitignore b/tests/.gitignore
> > index 69693129..1091174a 100644
> > --- a/tests/.gitignore
> > +++ b/tests/.gitignore
> > @@ -30,6 +30,7 @@ tmp.*
> >  /get_phandle
> >  /getprop
> >  /get_prop_offset
> > +/get_prop_offset_w
> >  /incbin
> >  /integer-expressions
> >  /fs_tree1
> > diff --git a/tests/Makefile.tests b/tests/Makefile.tests
> > index 63e201ae..0d4d399f 100644
> > --- a/tests/Makefile.tests
> > +++ b/tests/Makefile.tests
> > @@ -16,7 +16,7 @@ LIB_TESTS_L = get_mem_rsv \
> >  	sw_tree1 sw_states \
> >  	move_and_save mangle-layout nopulate \
> >  	open_pack rw_tree1 rw_oom set_name setprop del_property del_node \
> > -	appendprop1 appendprop2 propname_escapes \
> > +	appendprop1 appendprop2 propname_escapes get_prop_offset_w \
> >  	string_escapes references path-references phandle_format \
> >  	boot-cpuid incbin relref_merge \
> >  	extra-terminating-null \
> > diff --git a/tests/get_prop_offset_w.c b/tests/get_prop_offset_w.c
> > new file mode 100644
> > index 00000000..dbfa5dd7
> > --- /dev/null
> > +++ b/tests/get_prop_offset_w.c
> > @@ -0,0 +1,84 @@
> > +// SPDX-License-Identifier: LGPL-2.1-or-later
> > +/*
> > + * libfdt - Flat Device Tree manipulation
> > + *	Testcase for fdt_getprop_by_offset_w()
> > + * Copyright (C) 2026 Bootlin.
> > + */
> > +
> > +#include <stdlib.h>
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <stdint.h>
> > +
> > +#include <libfdt.h>
> > +
> > +#include "tests.h"
> > +#include "testdata.h"
> > +
> > +#define SPACE		65536
> > +
> > +int main(int argc, char *argv[])
> > +{
> > +	const void *exp_val;
> > +	const char *name;
> > +	char *modif_val;
> > +	void *propval;
> > +	int proplen;
> > +	int exp_len;
> > +	int poffset;
> > +	void *fdt;
> > +	void *buf;
> > +	int err;
> > +
> > +	test_init(argc, argv);
> > +	fdt = load_blob_arg(argc, argv);
> > +
> > +	buf = xmalloc(SPACE);
> > +
> > +	err = fdt_open_into(fdt, buf, SPACE);  
> 
> You shouldn't need an fdt_open_into().  You're modifying the contents
> of a single property, but not moving tags about or (specifically)
> expanding the tree as a whole.  This is a "write in place" operation
> rather than a "read/write" operation in libfdt terms.

Ok, I will update in the next iteration.

> 
> > +	if (err)
> > +		FAIL("fdt_open_into(): %s", fdt_strerror(err));
> > +
> > +	free(fdt);
> > +	fdt = buf;
> > +
> > +	/* Retrieve the offset of the 'prop-str' property */
> > +	poffset = get_poffset(fdt, 0, "prop-str");
> > +	if (poffset < 0)
> > +		FAIL("Property 'prop-str' not found")  
> 
> Introducing get_poffset() seems a bit awkward compared to using an
> fdt_for_each_property_offset() like get_prop_offset.c does.

Ok, will use fdt_for_each_property_offset() directly here and remove
get_poffset() in the next iteration.

> 
> > +
> > +	/* Get the property value for modification */
> > +	propval = fdt_getprop_by_offset_w(fdt, poffset, &name, &proplen);
> > +	if (!propval)
> > +		FAIL("fdt_getprop_by_offset_w(%d): %s", poffset,
> > +		     fdt_strerror(proplen));
> > +
> > +	/* Check original values */
> > +	if (strcmp(name, "prop-str"))
> > +		FAIL("Name mismatch : %s instead of prop-str", name);
> > +
> > +	exp_len = strlen(TEST_STRING_1) + 1;
> > +	if (proplen != exp_len)
> > +		FAIL("Original size mismatch on property \"%s\": %d instead of %d",
> > +		     name, proplen, exp_len);
> > +
> > +	exp_val = TEST_STRING_1;
> > +	if (memcmp(exp_val, propval, exp_len))
> > +		FAIL("Original data mismatch on property \"%s\"", name);
> > +  
> 
> You could re-use check_get_prop_offset() from testutils.c to perform
> these tests before invoking fdt_getprop_by_offset_w().

I wanted to test that the value returned by fdt_getprop_by_offset_w() is the
correct one. check_get_prop_offset() calls fdt_getprop_by_offset() and not
fdt_getprop_by_offset_w(). I know it doesn't matter with current implementation
of fdt_getprop_by_offset_w() but I am not supposed to know about this
implementation here in the test. Also, this implementation could change in the
future (not planned on my side).

> 
> > +	if (exp_len < 4)
> > +		CONFIG("Property \"%s\" should be at least 4 bytes", name);
> > +
> > +	/* Modify the property value */
> > +	modif_val = xmalloc(proplen);
> > +	memcpy(modif_val, propval, proplen);  
> 
> Why malloc() and memcpy()?  The whole point of
> fdt_getprop_by_offset_w() is that you get a writable pointer into the
> fdt which you can modify in place.

I want to keep the modified value for later comparison.

- modif_val : Current property val + modification.
- Update propval: Current property val.
- Check reading the property with check_get_prop_offset() that the
  property has been really updated.

If instead I use only propval, I use only one buffer and so
- propval = modified value
- check that get check_get_prop_offset() which will also return the 
  propval buffer matches the propval buffer.

In check_get_prop_offset();
--- 8< ---
const void *check_get_prop_offset(void *fdt, int poffset, const char *exp_name,
                                  int exp_len, const void *exp_val)
{
	const void *propval;
	...
	propval = fdt_getprop_by_offset(fdt, poffset, &name, &proplen);
	...
 	if (exp_len && memcmp(exp_val, propval, exp_len))
             FAIL("Data mismatch on property \"%s\"", name);
        ...
}

Using a pointer returned by fdt_getprop_by_offset_w() as exp_val parameter
leads to something like:
	memcmp(propval, propval, exp_len)

This is always successful even if the propval buffer doesn't contain the
data expected by the test. If for whatever reason the propval buffer is
wrongly modified by some internal libfdt function called by
check_get_prop_offset(), we cannot see it.

With the additional buffer (modif_val) which is never passed to libfdt,
and contains expected data, we can see any wrong proval modification.

> 
> > +	modif_val[1] = (modif_val[1] != 'A') ? 'A' : 'a';
> > +	modif_val[3] = (modif_val[3] != 'B') ? 'B' : 'b';
> > +	memcpy(propval, modif_val, exp_len);
> > +
> > +	/* Check that the modified value is taken into account */
> > +	if (!check_get_prop_offset(fdt, poffset, "prop-str", exp_len, modif_val))
> > +		FAIL("Modified property 'prop-str' not found");
> > +
> > +	PASS();
> > +}
> > diff --git a/tests/meson.build b/tests/meson.build
> > index 779e6bc7..dae6a941 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -50,6 +50,7 @@ tests = [
> >    'get_path',
> >    'get_phandle',
> >    'get_prop_offset',
> > +  'get_prop_offset_w',
> >    'get_next_tag_invalid_prop_len',
> >    'getprop',
> >    'incbin',
> > diff --git a/tests/run_tests.sh b/tests/run_tests.sh
> > index 225c22f8..419a24d8 100755
> > --- a/tests/run_tests.sh
> > +++ b/tests/run_tests.sh
> > @@ -419,6 +419,7 @@ tree1_tests_rw () {
> >      run_test setprop $TREE
> >      run_test del_property $TREE
> >      run_test del_node $TREE
> > +    run_test get_prop_offset_w $TREE  
> 
> This belongs with the other write-in-place tests in tree1_tests(), not
> as an rw test.

Ok, I will move it.

Best regards,
Hervé

  reply	other threads:[~2026-09-16 10:42 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26  8:31 [PATCH v3 00/15] Add support for structured tags and v18 dtb version Herve Codina
2026-08-26  8:31 ` [PATCH v3 01/15] fdtget: Use libfdt iterators instead of open coded loops Herve Codina
2026-08-27  3:55   ` David Gibson
2026-08-26  8:31 ` [PATCH v3 02/15] libfdt: Don't assume the root node is available at offset 0 Herve Codina
2026-08-30  3:21   ` David Gibson
2026-08-31 12:01     ` Herve Codina
2026-09-01  7:42       ` David Gibson
2026-09-01 12:18         ` Herve Codina
2026-09-02  7:06           ` David Gibson
2026-09-07 16:46             ` Herve Codina
2026-09-08  6:41               ` David Gibson
2026-09-08  8:08                 ` Herve Codina
2026-09-09  6:18                   ` David Gibson
2026-09-09  6:58                     ` Herve Codina
2026-09-09  7:02                       ` David Gibson
2026-08-26  8:31 ` [PATCH v3 03/15] tests: " Herve Codina
2026-09-01  8:03   ` David Gibson
2026-09-01 13:36     ` Herve Codina
2026-09-02  8:56       ` David Gibson
2026-08-26  8:31 ` [PATCH v3 04/15] tests/nopulate: Add a FDT_NOP before the root node Herve Codina
2026-09-01  8:05   ` David Gibson
2026-08-26  8:31 ` [PATCH v3 05/15] tests: treegen: Introduce emit_fdt_header_vers() Herve Codina
2026-09-09  6:38   ` David Gibson
2026-08-26  8:31 ` [PATCH v3 06/15] Introduce structured tag value definition Herve Codina
2026-09-10  4:51   ` David Gibson
2026-09-10  7:41     ` Herve Codina
2026-09-10  9:32       ` David Gibson
2026-09-11  7:16         ` Herve Codina
2026-09-12  2:34           ` David Gibson
2026-09-14 10:19             ` Herve Codina
2026-09-16  5:21               ` David Gibson
2026-09-17  7:04                 ` Herve Codina
2026-09-10  5:33   ` David Gibson
2026-09-10  7:58     ` Herve Codina
2026-09-10  9:41       ` David Gibson
2026-09-11  7:53         ` Herve Codina
2026-09-12  2:35           ` David Gibson
2026-09-17  8:56             ` Herve Codina
2026-08-26  8:31 ` [PATCH v3 07/15] fdtdump: Handle unknown tags Herve Codina
2026-09-10  5:25   ` David Gibson
2026-08-26  8:31 ` [PATCH v3 08/15] flattree: " Herve Codina
2026-09-14  8:23   ` David Gibson
2026-09-15 10:16     ` Herve Codina
2026-09-15 11:52       ` David Gibson
2026-09-16  6:31         ` Herve Codina
2026-09-16  8:27           ` David Gibson
2026-09-17  7:11             ` Herve Codina
2026-08-26  8:31 ` [PATCH v3 09/15] libfdt: Handle unknown tags in fdt_next_tag() Herve Codina
2026-09-16  9:10   ` David Gibson
2026-09-17  8:34     ` Herve Codina
2026-09-17  9:36       ` David Gibson
2026-09-17 17:28         ` Herve Codina
2026-08-26  8:31 ` [PATCH v3 10/15] libfdt: Introduce fdt_ptr_offset_() Herve Codina
2026-08-26  8:31 ` [PATCH v3 11/15] libfdt: Introduce fdt_getprop_by_offset_w() Herve Codina
2026-09-16  9:56   ` David Gibson
2026-09-16 10:42     ` Herve Codina [this message]
2026-09-17  4:52       ` David Gibson
2026-09-17  8:43         ` Herve Codina
2026-08-26  8:31 ` [PATCH v3 12/15] libfdt: Introduce fdt_getprop_offset_namelen() Herve Codina
2026-08-26  8:31 ` [PATCH v3 13/15] tests: Add wip_func utility Herve Codina
2026-09-16 10:00   ` David Gibson
2026-09-16 17:27     ` Herve Codina
2026-08-26  8:31 ` [PATCH v3 14/15] libfdt: Handle unknown tags on dtb modifications Herve Codina
2026-08-26  8:31 ` [PATCH v3 15/15] Introduce v18 dtb version Herve Codina

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260916124205.28a71859@bootlin.com \
    --to=herve.codina@bootlin.com \
    --cc=ayush@beagleboard.org \
    --cc=conor+dt@kernel.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=devicetree-compiler@vger.kernel.org \
    --cc=devicetree-spec@vger.kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=geert@linux-m68k.org \
    --cc=hui.pu@gehealthcare.com \
    --cc=ian.ray@gehealthcare.com \
    --cc=krzk@kernel.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luca.ceresoli@bootlin.com \
    --cc=robh@kernel.org \
    --cc=thomas.petazzoni@bootlin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®