Devicetree
 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>,
	Frank Li <Frank.Li@nxp.com>
Subject: Re: [PATCH v3 02/15] libfdt: Don't assume the root node is available at offset 0
Date: Tue, 1 Sep 2026 14:18:26 +0200	[thread overview]
Message-ID: <20260901141826.49b1a1b7@bootlin.com> (raw)
In-Reply-To: <apaBuQ8kn2bOzYcI@gractus.seuss>

Hi David,

On Tue, 1 Sep 2026 17:42:02 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Mon, Aug 31, 2026 at 02:01:19PM +0200, Herve Codina wrote:
> > Hi David,
> > 
> > On Sun, 30 Aug 2026 13:21:06 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > ...
> >   
> > > > -int fdt_next_node(const void *fdt, int offset, int *depth)
> > > > +int fdt_root_offset(const void *fdt)
> > > >  {
> > > >  	int nextoffset = 0;
> > > > +	int offset;
> > > > +	uint32_t tag;
> > > > +
> > > > +	do {
> > > > +		offset = nextoffset;
> > > > +		tag = fdt_next_tag(fdt, offset, &nextoffset);
> > > > +		switch (tag) {
> > > > +		case FDT_END_NODE:
> > > > +		case FDT_PROP:
> > > > +			return -FDT_ERR_BADSTRUCTURE;
> > > > +
> > > > +		case FDT_BEGIN_NODE:
> > > > +			return offset;
> > > > +
> > > > +		default:
> > > > +			break;
> > > > +		}
> > > > +	} while (tag != FDT_END);
> > > > +
> > > > +	return (nextoffset < 0) ? nextoffset : -FDT_ERR_NOTFOUND;    
> > > 
> > > This should be BADSTRUCTURE rather than NOTFOUND: a dtb without a root
> > > node is not validly constructed.  (This could matter quite a lot if
> > > this error gets propagated up a call chain - a NOTFOUND is usually
> > > non-fatal, but BADSTRUCTURE means there's basically nothing that can
> > > usefully be done with the dtb, which the caller needs to know as soon
> > > as possible).  
> > 
> > Now yes, a dtb without a root node is an invalid dtb but soon with addon this
> > will be allowed [1].  
> 
> Ah, ok.  I haven't looked at the addon stuff yet.  I do intend to, but
> it will certainly take a while (70+ patches!).
> 
> So, I'm guessing here, but it still seems odd to me that an addon with
> no BEGIN_NODE tags at all could be useful.

No BEGIN_NODE doesn't mean and empty addon.

Addons can have only orphan nodes without any root node. Those orphan nodes are
nodes existing in the base devicetree the addon is applied to. Addon needs to
refer those existing node and this reference is the orphan node.
--- 8< ---
/addon/

&node_from_base_dtb { /* <--- Orphan node. Node defined in the base DT */
   node_defined_in_addon { /* <--- Node added by the addon once applied */
      ...
   };
};
--- 8< ---

In the addon, those orphans are identified with BEGIN_NODE_REF [2] and cannot be
considered as root nodes.

[2] addon series, patch 51/74
    https://lore.kernel.org/all/20260826094950.1088288-52-herve.codina@bootlin.com/

> 
> > addon dtbs will be clearly identified (the dt_flags header field has
> > FDT_FLAG_ADDON set for addon dtbs) and so what do you think if the error code
> > returned depends on this flag.
> > 
> > NOTFOUND in case of addon and BADSTRUCTURE otherwise.  
> 
> I'd need to look at the details of addons to figure out if this makes
> sense but I'm not opposed to the approach in principle.
> 
> > If you are ok with that, I will update this current patch to return BADSTRUCTURE
> > in all case. Indeed, addon are not yet available.  
> 
> Right, regardless of where we go with addons eventually, I think it's
> preferable to return BADSTRUCTURE for now.  That can be changed once
> addons are actually implemented.

Exactly!

> 
> > 
> > [1] https://lore.kernel.org/all/20260826094950.1088288-54-herve.codina@bootlin.com/
> >   
...

> > > 
> > > Do you need this special casing? Won't the fact you've update
> > > fdt_next_node() to handle the offset 0 case be enough?  
> > 
> > The full loop is the following:
> > --- 8< ---
> > 	for (offset = root_offset, depth = 0;
> > 	     (offset >= 0) && (offset <= nodeoffset);
> > 	     offset = fdt_next_node(fdt, offset, &depth)) {
> > 		if (depth == supernodedepth)
> > 			supernodeoffset = offset;
> > 
> > 		if (offset == nodeoffset) {
> > 			if (nodedepth)
> > 				*nodedepth = depth;
> > 
> > 			if (supernodedepth > depth)
> > 				return -FDT_ERR_NOTFOUND;
> > 			else
> > 				return supernodeoffset;
> > 		}
> > 	}
> > --- 8< ---
> > 
> > The test 'offset == nodeoffset' is the problematic one. nodeoffset
> > is the parameter passed to the function.
> > 
> > I have chosen to avoid offset 0 for the root node and I have updated 'nodeoffset'
> > previously if it is 0.
> > 
> > Even if fdt_next_node() updates 'offset' if it is 0, 'nodeoffset' has also to be
> > update if it is 0. Indeed, 'offset' will be updated from 0 to the real root node
> > offset. In all case to have the test be correct, 'nodeoffset' should be updated
> > to the real root node offset if it is 0.  
> 
> > Having fdt_next_node() updating 'offset' if it is 0 will not handle all case.
> > When offsets comparison is done, both offsets should consider the real offset of
> > the root node instead of the 0 value.  
> 
> Ah, right.  I missed the fact it was updating the nodeoffset
> parameter, rather than the working/starting offset.
> 
> > Also the fdt_supernode_atdepth_offset() can be called with 'nodeoffset' set to the
> > real root node offset instead of 0. Indeed, fdt_root_offset() is available (and
> > needed).  
> 
> Theoretically we could avoid explicitly looking at the root offset for
> 'offset', by starting 'offset' negative and moving the fdt_next_node()
> to the start of the loop body instead of the end.  That would handle
> the nodeoffset == root_offset case, not not the nodeoffset == 0 case.
> Arguably we could disallow the later - finding the non-existent
> supernode of something we know at compile time to be the root node
> isn't very useful - if it only turned out to be the root node at
> runtime, I'd expect it to have come from another function, which
> should give us root_offset rather than 0.
> 
> But.. it's certainly safer to keep it working whether passed 0 or the
> real root offset.  There are other ways we could do it, but I think
> they'd turn out equally inelegant.
> 
> Ok, makes sense to me.
> 

Ok, I will update fdt_check_node_offset_() to have it updating its offset
parameter to the real offset of the root node when its value is 0.

Based on this update, will see where it goes. I mean, impacts on callers, if
it simplifies things or not, if the offset update needs also to be propagate
to caller's parameter or any other similar point that we can see during the
implementation.

Having something implemented and available in a patch will be the best to
compare changes and impacts related to fdt_check_node_offset_() update.

Here we have a version of handling offset 0 vs real root node without any
offset update done in fdt_check_node_offset_(). In the next iteration we will
have the version with update done in fdt_check_node_offset_().

I think the golden rules to follow on this point is "keep it as simple as
possible".

Best regards,
Hervé

  reply	other threads:[~2026-09-01 12:18 UTC|newest]

Thread overview: 26+ 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 [this message]
2026-09-02  7:06           ` 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-08-26  8:31 ` [PATCH v3 06/15] Introduce structured tag value definition Herve Codina
2026-08-26  8:31 ` [PATCH v3 07/15] fdtdump: Handle unknown tags Herve Codina
2026-08-26  8:31 ` [PATCH v3 08/15] flattree: " Herve Codina
2026-08-26  8:31 ` [PATCH v3 09/15] libfdt: Handle unknown tags in fdt_next_tag() 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-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-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=20260901141826.49b1a1b7@bootlin.com \
    --to=herve.codina@bootlin.com \
    --cc=Frank.Li@nxp.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