From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 041A73128A3; Tue, 10 Feb 2026 17:34:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744865; cv=none; b=vB7/JjinO80g2+67dpHHPlAeEciNsSwoWnbBf5Sjyw7FvskMkjYVxXcobDfzl+DHAQyLEhDE+bDRVFs0b3uoZVbFyYWXzJjDsdcgrt2UcVQ4hwRD1bd3X2OeHTyDBdk2hpoOtljgeXe4mWt5F8tZiqwwgqVcTpvV7RttxgjZAIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744865; c=relaxed/simple; bh=/CPOb5wezrA1J+WyG49Si3hqreflaqzMwMHgrNQDD/E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EicdJL4Arl+DoJ9z/2in0REXLc8R8pufPuGdlTu3wJQbQIm5w3iyAAjRfIHYYTiZ9pLK/wAtqqGLGAjydzPt8zV6Ha6bJg2Y/LcOwMoM7NPoWTnVQpJGKjR5gl24fKFgGPY4ad3oRE58bIEdgkUm+pQyERqbzA5zzfHRMVLEeuk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Ym8NiQ3P; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Ym8NiQ3P" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 7E3A51A0D81; Tue, 10 Feb 2026 17:34:22 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 54222606BD; Tue, 10 Feb 2026 17:34:22 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5819B10B91B35; Tue, 10 Feb 2026 18:34:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744861; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=7+ALKX18P777BGJJpM5hpvhIjeNnWAA1h7zd2J24J8c=; b=Ym8NiQ3PxoXUjn2OhBvPJba/5od0kUFXl69/owDv0oszIHwF25NaodfWU8QYfHGwaGW5C1 DZLj4F+FhAm10SHVNh7snvkD9dSsOC8AzIPmY81oMoYVt42dKkoKG2YAZAoJsqNCL2Wm7F Ta1libKI15YFqdHIdMTIPmyJT1+P7Mrv0mNrMMVCWuM9X91PlDTCj0/qY1tz2gcEIujM0R kMgYc+vGA7RbtHlX0Q/lROqc0gTAM99HQV1CzWLnbH+RQ54gcmyOMEyI0GJ9+Ce9Iukb3u Kp7pfcD0OHCjcqdtJO1XJMMq3S2z9g/KDsw540cgqJT0mVoqQs3kgJYCQiR7zg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 01/15] dtc: Use a consistent type for basenamelen Date: Tue, 10 Feb 2026 18:33:29 +0100 Message-ID: <20260210173349.636766-2-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The basenamelen member in the node structure is set in all cases to a positive value, the length of the basename string. Also it is used as parameters on function expecting a size_t type. Further more an implicit cast of strspn() returned value from size_t to int is needed in checks.c to avoid a signed/unsigned compilation warning when this value is checked. This member has no reason to be a signed integer and its obvious type is size_t. Be consistent and fix its type. Signed-off-by: Herve Codina --- checks.c | 2 +- dtc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checks.c b/checks.c index 45d0213..946c142 100644 --- a/checks.c +++ b/checks.c @@ -324,7 +324,7 @@ ERROR(node_name_chars, check_node_name_chars, NODECHARS= ); static void check_node_name_chars_strict(struct check *c, struct dt_info *= dti, struct node *node) { - int n =3D strspn(node->name, c->data); + size_t n =3D strspn(node->name, c->data); =20 if (n < node->basenamelen) FAIL(c, dti, node, "Character '%c' not recommended in node name", diff --git a/dtc.h b/dtc.h index 7231200..473552e 100644 --- a/dtc.h +++ b/dtc.h @@ -227,7 +227,7 @@ struct node { struct node *next_sibling; =20 char *fullpath; - int basenamelen; + size_t basenamelen; =20 cell_t phandle; int addr_cells, size_cells; --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46AA138A709; Tue, 10 Feb 2026 17:34:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744866; cv=none; b=PK/WK3MJ3FqJvY3vXsYb3sUmVGBfqb1wtyONFABL3Ti/gwZTlSVWE7wLHg46iYS0UxKGS9wArRpbxIOPcxyuIbtBy7PJdaXGxwWLmeXVdXVPn8lWDA08VHBFYdqNqpMB2EtCpwkj3dI/bCAPKQRUVmI+V89yGpR4Nuh20ETA0kI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744866; c=relaxed/simple; bh=WtKphMCsjPcCVX5VwtmFrAns3o9ylLtWGgEPh01Qm1s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MWN842WEJ+mVHvr4VZxxo+GZ4+ek4LG93mBFdgqT5ASrYVHY9iEkUIghaLUJuEc2iGwF8uc4Icy5QmuzF+41fgFFzF66jEVgwEsY+G/1fWD5l/2oMhCosPtsY3azWrIDtJ3fmHmTnXtujrnZ90Zrhlb+YlNGleSFf6ouFRKBqzQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=ta2DXNjz; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="ta2DXNjz" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id EC5D51A0D83; Tue, 10 Feb 2026 17:34:23 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id C0A8B606BD; Tue, 10 Feb 2026 17:34:23 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B445710B9221F; Tue, 10 Feb 2026 18:34:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744862; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Vj+nbmbL/ubeh6lBT2UK7368Bw4bAaxwTg/HQfQrIks=; b=ta2DXNjztKdSya0GuB61Wd5PsVWIW7Dhi3eUXS0hnngmoC5WKlB2kxmF4aP8oHX+kZ/E95 vsP9ZpW8Dxhg5hmaDLFoF9QUO5ZmwqwLnF8V7L/o6IXrTmR54YspwK1UyXaFTscMf2Epbs qvi/1Z6MnP+YXqFD106AwshVSfpkwQ0bBCncjB2KeWUMAYDhXthhMGkoydwuwj2yyNHERO RhnCQ6xus8GfsBUQV8yqL35wNTt7D7IPfq2VcmfHRZbp+RJyB8CKHColii108SJrIZeqTF D1WUH9F4E91a8oSfZMKbUPjeEjnVBJN2kt0S85apVPNFbFF8BO0WPNxAWV8Gfw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 02/15] fdtdump: Remove dtb version check Date: Tue, 10 Feb 2026 18:33:30 +0100 Message-ID: <20260210173349.636766-3-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" fdtdump checks the dtb version and simply failed if the dtb version is newer than the last version supported by fdtdump. This check is not needed and too restrictive. Indeed, fdtdump does read-only operations on the dtb provided and should rely only the last_comp_version header field to know whether or not it can read the dtb. The current check also avoid the use of fdtdump in tests checking for the libfdt behavior when an new (future) dtb version is used. Relax fdtdump checks removing the check of the dtb version header field. Signed-off-by: Herve Codina --- fdtdump.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fdtdump.c b/fdtdump.c index 0260609..6c9ad90 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -169,7 +169,6 @@ static bool valid_header(char *p, size_t len) { if (len < sizeof(struct fdt_header) || fdt_magic(p) !=3D FDT_MAGIC || - fdt_version(p) > MAX_VERSION || fdt_last_comp_version(p) > MAX_VERSION || fdt_totalsize(p) >=3D len || fdt_off_dt_struct(p) >=3D len || --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 696E738A9BB; Tue, 10 Feb 2026 17:34:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744867; cv=none; b=UkP6jpYB/3Ab0jC2HnjYS+XTC7EZdQN52jp5nyEGu2SO+VdBbax4N6/CDYROZX6GkrWxabcNcO0060AYmj9rBN8G5AXLj+HOO2aaYw9cKsTtkf4qcqc8kyhlNBxAottKQnvv46deEcQR4teGfyHtpx3eE6XFY26AxXeLLB1UUDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744867; c=relaxed/simple; bh=1GYTl899loeKuDybjdYgszBFDSlbIF8YB849krPxnc0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=babV4831rNzu/dmcIjPLyzDAw/zLOn/qn/R67Yrb88PJhzMAElaKfpq/BB0AubceEZRd10PS1pD3E+/5eN976ebKo+9QRtQprGlUozbEC3cnVbKRr/XHxLoAGHcWQoNxMwZMagVMhyDq+2Iphw1+GKnyvLeLkz77tT6aT4XTWU0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=hp9f3GGH; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="hp9f3GGH" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 36A4A1A0D9C; Tue, 10 Feb 2026 17:34:25 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0226A606BD; Tue, 10 Feb 2026 17:34:25 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3534B10B91FBE; Tue, 10 Feb 2026 18:34:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744864; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=0s0U5LlMK8JRmYuXCMEm1DGi0KEOLQu1ipU4LX8zcW4=; b=hp9f3GGHrJEauLs7fC+MSDCAEKP0qOlI1lLkhle9YArbhXYMQ6WP2ZA+rHT2fPTaVrdo2l 0ekNpVnF/CdoZZkpCJmZdaaXO6JSOgxib5sVZ21pKqt8Vmaw/Mhdj6bObolLNrgsSpqBUD UpIxyZ9LX6vtFRBLsomPyWOSVfMOuim1mcDkneo4is7UHAiYMQcTtHhyfDPUmNvSKHxOhK +7+LOeuv7Ik0/uQ5TikzmDNxNd3F5ujYGTzPu4VA4UsJbMirThPN1qfRktBwwrpqsjhAOK vbUfoiTIedvuuYy7RdAwDt1rgDjjqNLYbBRWjYhjAnPQ/ruA8UUsQti21/Enng== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 03/15] fdtdump: Return an error code on wrong tag value Date: Tue, 10 Feb 2026 18:33:31 +0100 Message-ID: <20260210173349.636766-4-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" fdtdump prints a message on stderr when it encounters a wrong tag and stop its processing without returning an error code. Having a wrong tag is really a failure. Indeed, the processing cannot continue. Be more strict. Stop the processing, print a message and return an error code. In other words, call die(). Signed-off-by: Herve Codina --- fdtdump.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fdtdump.c b/fdtdump.c index 6c9ad90..0e7a265 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -146,8 +146,7 @@ static void dump_blob(void *blob, bool debug) continue; } =20 - fprintf(stderr, "%*s ** Unknown tag 0x%08"PRIx32"\n", depth * shift, "",= tag); - break; + die("** Unknown tag 0x%08"PRIx32"\n", tag); } } =20 --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA42E3128A3; Tue, 10 Feb 2026 17:34:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744869; cv=none; b=kkPqwY+2q3j+gJ/7gR1kfWGk4Auoq4z8GFrtp5OHqH20Rxl6PcpiqH00o0E6nJJTcxB8C5FXbZUkZ6DGUSm2lW2ltffI3ARjS/CY6uc/NyBmE/1PDQx+TgEb7yrnelOQ3CyNyjcfHtkvJ8y7zY0UB/bsjJsZKSxwXIYJAGUqoxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744869; c=relaxed/simple; bh=zYENmNeoK50FAEN/MLEGVot7VFgpGQ/IT83bdETLvKc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eYEFuneXczWZgTNNMNOZ3R/pVBF6n75f+P/YLxsCDMdb+IfbR1HixycTqb+KbEdtswhUrJa5pzj1KYtEt/WSDzLpcDTsW9fAQ7DEO+IxpyLKITgxh56eyT3pfG9gE5zljz7UKmsECOwd8GCryF637wIj7K0/kdgmEhEpCGkrDh8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=ArA5Y/d5; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="ArA5Y/d5" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id D0C22C8F456; Tue, 10 Feb 2026 17:34:34 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 71698606BD; Tue, 10 Feb 2026 17:34:26 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 898F010B92227; Tue, 10 Feb 2026 18:34:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744865; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=wExgBnhPT8Yp1uOS4Aujf9960S3oyDSX7kIazJEW+VM=; b=ArA5Y/d5CuD9se5qO4fTdM0mGZhUxHPaWjS2z3ptBTIm7T9lqQY179GQqXAmF0YBZuUgfM U0UC/NQlheM8rDEIYSg810KALGVUXOc2RvVSKoL0X42fxSQd5SLMm5drdcLXjCVJb1orVL XfxMwb9rh+XvO1P0cnK7GKr3JpK9Ot3TVlY+G3vQUkx5LUN1yvLKbUyMK7SsG7Vi5haFfm vbY3kXbwU2JxEdGfcvRMQLhPyNNVWhuqGZXERSLJ9ouuIpLjjRPbMaH6h7CFBPY3zc3xdH ckksJxhzf4oYK7pVkRp/nfguPAjh2ihPYXAJwTwc7sDxl9hbaSsPRzvjKHDk4w== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 04/15] libfdt: fdt_rw: Introduce fdt_downgrade_version() Date: Tue, 10 Feb 2026 18:33:32 +0100 Message-ID: <20260210173349.636766-5-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Current code perform a version downgrade at one place only, the end of fdt_rw_probe_(). In order to offer a finer grain and choose to downgrade or not depending on the exact writes done, introduce fdt_downgrade_version() to perform the downgrade operation. The modification doesn't introduce any functional changes. Signed-off-by: Herve Codina --- libfdt/fdt_rw.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 7475caf..90ea14e 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -22,6 +22,12 @@ static int fdt_blocks_misordered_(const void *fdt, (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); } =20 +static void fdt_downgrade_version(void *fdt) +{ + if (!can_assume(LATEST) && fdt_version(fdt) > FDT_LAST_SUPPORTED_VERSION) + fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); +} + static int fdt_rw_probe_(void *fdt) { if (can_assume(VALID_DTB)) @@ -33,9 +39,8 @@ static int fdt_rw_probe_(void *fdt) if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), fdt_size_dt_struct(fdt))) return -FDT_ERR_BADLAYOUT; - if (!can_assume(LATEST) && fdt_version(fdt) > 17) - fdt_set_version(fdt, 17); =20 + fdt_downgrade_version(fdt); return 0; } =20 --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B23338B7CD; Tue, 10 Feb 2026 17:34:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744870; cv=none; b=DLDm/cm8WDNcu+enuuIsbYcAzfX993rg8S8+T8GuI51O3za5tUyNiyub9AvU56ORj79TpQAooTcG5jqA52Bohg+g2oUhqcFnTC29bYePlFQs22upGKYDQ63DmZaMvui3eiCDdifRoJF2HUjqQBRnV/eJX8VJL8TVvX37lYqS/2U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744870; c=relaxed/simple; bh=mZqSgwnKCpa15sF6HzNPxNtM7iJNXr4LfjyUvoCEc90=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZQr9TlOGpk6EV81U2/2eCrJjIrKCJl9oxjlZLagiXjlRo6pdQV37ttjTLPYE5BxjHsOTWDVM58aLs73tCAEvsO+ZoowyRzluxI5jpL0WBpSr6J4M4TN434Sgbp+f5rdysBDKHV+qQH6PYh87Cswu/S30OpSQnX3xp/1Zqv1K/dE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=2Ree5f83; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="2Ree5f83" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 16CD91A0D81; Tue, 10 Feb 2026 17:34:28 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E1CAA606BD; Tue, 10 Feb 2026 17:34:27 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 09ECB10B921D3; Tue, 10 Feb 2026 18:34:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744867; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=DRWBCWSnytZ6SddzKx+UOrvKKZEvOAMIVqPtoAKNUGY=; b=2Ree5f83VtXu87+5FDgLsYutSejxdFo5CeY313rgMsKtXo4/fKhgoF9pXjo7FYuSZnhTtb YGw8dW4e5RolRh1m6qnni/CPzh5GhDK0a2KkLsN169Gg5JnIygYq6+O36U0qBQoP9mfMn4 8f5OlZ5Pz98Jt9WHAGIGIWB2yU4Wsim4hH9YuhkGV0FElvneWzcxJqeXDuKWcUFSUPDAl6 6rEwwRqflDuxmmfQLMjqKntRD2u8k2dtyGTnMnsGPU5dlZrPZsMxHlpMwyeDd0SQxQSPDs a/j0Z/O3CcYeZAr0c9tEBaVuS9FH/RvgPK7pK9oRXrRade7SLusRBkDk9SDVqg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 05/15] libfdt: Introduce fdt_first_node() Date: Tue, 10 Feb 2026 18:33:33 +0100 Message-ID: <20260210173349.636766-6-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" In several places, libfdt assumes that a FDT_BEGIN_NODE tag is present at the offset 0 of the structure block. This assumption is not correct. Indeed, a FDT_NOP can be present at the offset 0 and this is a legit case. Introduce fdt_first_node() in order to get the offset of the first node (first FDT_BEGIN_NODE tag) available in a fdt blob. Signed-off-by: Herve Codina --- libfdt/fdt.c | 25 +++++++++++++++++++++++++ libfdt/libfdt_internal.h | 1 + 2 files changed, 26 insertions(+) diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 56d4dcb..676c7d7 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -252,6 +252,31 @@ int fdt_check_prop_offset_(const void *fdt, int offset) return offset; } =20 +int fdt_first_node(const void *fdt) +{ + int nextoffset =3D 0; + int offset; + uint32_t tag; + + do { + offset =3D nextoffset; + tag =3D 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 !=3D FDT_END); + + return (nextoffset < 0) ? nextoffset : -FDT_ERR_NOTFOUND; +} + int fdt_next_node(const void *fdt, int offset, int *depth) { int nextoffset =3D 0; diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index 0e103ca..4c15264 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -32,6 +32,7 @@ static inline const char *fdt_find_string_(const char *st= rtab, int tabsize, } =20 int fdt_node_end_offset_(void *fdt, int nodeoffset); +int fdt_first_node(const void *fdt); =20 static inline const void *fdt_offset_ptr_(const void *fdt, int offset) { --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE07438B7CA; Tue, 10 Feb 2026 17:34:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744871; cv=none; b=al7B1AhoW8pUGCgaW4EIQV5yhwKNl1FbolKBFaUS9Qoll/s1hVOvela6KAUKvUQSSsZm3BetASEQBN2INCM86srTlJvy25CrQRCtO6KyGUdn4sD7/IKIltiD/JkRCPdj2SdUbgh7yAfpQev463qaGwtWqdpSfQZnAGDiqWVoOHQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744871; c=relaxed/simple; bh=Z/oydfpGOCxdFGc372aiXq83qdbcRaqJqG51xjNfBrI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pifzUA15m7FQaoOqGzoOAqG4H14ILzjZFQooXw9YFtd/HXO5rSP52spn9LDn0XHv3Xc59QZ9DJA2gsFrpBEuupabDdxXkIyz/SLbETExaE3ziA8SkPrwRZgOZgYADlRy3ZrAP1VyrqsiSQSKl/OO/gJ7MBXVQLk+vUVMBQWFb3g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=N5sRmW2h; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="N5sRmW2h" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 65BF54E40C0D; Tue, 10 Feb 2026 17:34:29 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 3BE8B606BD; Tue, 10 Feb 2026 17:34:29 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5FF9110B92228; Tue, 10 Feb 2026 18:34:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744868; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=lfBZyaOnQKahul2oKqZRv4nz6l5s4zrM0dhVGQ0T4Ak=; b=N5sRmW2hTPH7fhqm581SWeOx+3u7OTlL6VWaYvZ3Fvb2WCDzZAhpnr+9d58vItsBnolJAd r267RfSI27SHVweFqiiofw2+c9Taer9MQ4Zmaomj9CVSL5K2iLkkpAn3G1rULTexeO6+fK xD0PO/jUdP3HswSJaaNgcHfIgvPn6p1BkIIh6ePALVL5OqhxwRDszrB8iIb/LJmGgx3OYX xMPEnnWQtCIWxhmDV5br8wq7q6Kd+tAetPpx0RvdYgsW/SVq6nGPWqDPWCsvWRoNzJZSbY ctvmcfIUPDQlcv3CMqGFStmC2LnIQB6yxtF4mV5/RhMv3al2/LH/XX+7bxG3MA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 06/15] libfdt: Don't assume that a FDT_BEGIN_NODE tag is available at offset 0 Date: Tue, 10 Feb 2026 18:33:34 +0100 Message-ID: <20260210173349.636766-7-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" In several places, libfdt assumes that a FDT_BEGIN_NODE tag is present at the offset 0 of the structure block. This assumption is not correct. Indeed, a FDT_NOP can be present at the offset 0 and this is a legit case. fdt_first_node() has been introduce recently to get the offset of the first node (first FDT_BEGIN_NODE) in a fdt blob. Use this function to get the first node offset instead of looking for this node at offset 0. Signed-off-by: Herve Codina --- libfdt/fdt.c | 10 ++++++++-- libfdt/fdt_ro.c | 16 +++++++++++++--- libfdt/fdt_rw.c | 6 ++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 676c7d7..ff2fa6c 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -279,11 +279,17 @@ int fdt_first_node(const void *fdt) =20 int fdt_next_node(const void *fdt, int offset, int *depth) { - int nextoffset =3D 0; + int nextoffset =3D offset; uint32_t tag; =20 + if (offset <=3D 0) { + nextoffset =3D fdt_first_node(fdt); + if (nextoffset < 0) + return nextoffset; + } + if (offset >=3D 0) - if ((nextoffset =3D fdt_check_node_offset_(fdt, offset)) < 0) + if ((nextoffset =3D fdt_check_node_offset_(fdt, nextoffset)) < 0) return nextoffset; =20 do { diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 63494fb..8e1db7d 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -229,6 +229,12 @@ int fdt_subnode_offset_namelen(const void *fdt, int of= fset, =20 FDT_RO_PROBE(fdt); =20 + if (!offset) { + offset =3D fdt_first_node(fdt); + if (offset < 0) + return offset; + } + for (depth =3D 0; (offset >=3D 0) && (depth >=3D 0); offset =3D fdt_next_node(fdt, offset, &depth)) @@ -251,13 +257,17 @@ int fdt_path_offset_namelen(const void *fdt, const ch= ar *path, int namelen) { const char *end =3D path + namelen; const char *p =3D path; - int offset =3D 0; + int offset; =20 FDT_RO_PROBE(fdt); =20 if (!can_assume(VALID_INPUT) && namelen <=3D 0) return -FDT_ERR_BADPATH; =20 + offset =3D fdt_first_node(fdt); + if (offset < 0) + return offset; + /* see if we have an alias */ if (*path !=3D '/') { const char *q =3D memchr(path, '/', end - p); @@ -579,7 +589,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char = *buf, int buflen) if (buflen < 2) return -FDT_ERR_NOSPACE; =20 - for (offset =3D 0, depth =3D 0; + for (offset =3D fdt_first_node(fdt), depth =3D 0; (offset >=3D 0) && (offset <=3D nodeoffset); offset =3D fdt_next_node(fdt, offset, &depth)) { while (pdepth > depth) { @@ -617,7 +627,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char = *buf, int buflen) else if (offset =3D=3D -FDT_ERR_BADOFFSET) return -FDT_ERR_BADSTRUCTURE; =20 - return offset; /* error from fdt_next_node() */ + return offset; /* error from fdt_next_node() or fdt_first_node() */ } =20 int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 90ea14e..f5c28fc 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -354,6 +354,12 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffse= t, =20 FDT_RW_PROBE(fdt); =20 + if (!parentoffset) { + parentoffset =3D fdt_first_node(fdt); + if (parentoffset < 0) + return parentoffset; + } + offset =3D fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); if (offset >=3D 0) return -FDT_ERR_EXISTS; --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1DF1B38F220; Tue, 10 Feb 2026 17:34:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744873; cv=none; b=ngykumc5YXFzkjE4gBRTz/b2EkuC0eKfETZprkXhAtgK/j2cevX/eLWEvkB/w3vfrr9KRVwow+q+uoxRjlpdSDA8xTwkQM1XQ0IpTI+lpvKdBmLmvtluYm55eyw0iKLO0RXtt9t6cbQC8g2MW9flonnK2wrN3DYd3lGDHmyfh2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744873; c=relaxed/simple; bh=EM6J0dEcKfIdr7d2XOOqiXEzf+XkS7OHUWgKVYm9Hd4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FEjat7c8SGij8l/7GpyWBk9SeD31vRgjDUlZngON+YOHlm1Moi5qFSKSUweVgX9Gazu6itfVS1opape9F6ncgEScUtj1Jx0/I3crTWGpzcuRQyIwdOxOuV0ldf02SAiAqTyr47ytSz8U8OR2/GL1TC1HlabjnT0Wmqumtj6ouRE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=cXMnk9f9; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="cXMnk9f9" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id E26454E40BFD; Tue, 10 Feb 2026 17:34:30 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B9C90606BD; Tue, 10 Feb 2026 17:34:30 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B7A9C10B9222C; Tue, 10 Feb 2026 18:34:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744869; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Kw02+4pfGTQRfMaOOh1LaHp+lrmAxxrpyVPxs0syLUY=; b=cXMnk9f9r+S/DTfTi3XxF/JBrdsGbUnrBIqKUKs+cAu94zkbAr8bEmeaoFPm0VwL8MOcNk u9dZ0hn/2cciQp/eJu8+DOtWfa3B857Pf2XABoruPS3Mi7tTlNTY8ZIuGDjzLfQBRCDGC4 lSiOZqpFZdIExDcToiwYt01BDhdHX1FS5boqyjwEAF4lc9mxisNf0+U7ZPU8OVRGzok1w6 J/Q7UeVH413p9j9qK9ICMlLKUb5UcbGGCIOAvblajI6TiNcNIgwPr1P7JunPw9B2I1MjDH zbIlMiQ4iSSagCHDc/CkDO05yupnftWkaVu77v3nHy4mhE5/Xb0J/ANfjCo1BQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 07/15] libfdt: fdt_check_full: Handle FDT_NOP when FDT_END is expected Date: Tue, 10 Feb 2026 18:33:35 +0100 Message-ID: <20260210173349.636766-8-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" fdt_check_full() makes the assumption that a FDT_END tag is present immediately after the FDT_END_NODE tag related to the root node. This assumption is not correct. Indeed, FDT_NOP tags can be present between this FDT_END_NODE tag and the FDT_END tag. Handle those possible FDT_NOP tags. Signed-off-by: Herve Codina --- libfdt/fdt_check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfdt/fdt_check.c b/libfdt/fdt_check.c index a21ebbc..cca0523 100644 --- a/libfdt/fdt_check.c +++ b/libfdt/fdt_check.c @@ -43,7 +43,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) return nextoffset; =20 /* If we see two root nodes, something is wrong */ - if (expect_end && tag !=3D FDT_END) + if (expect_end && tag !=3D FDT_END && tag !=3D FDT_NOP) return -FDT_ERR_BADSTRUCTURE; =20 switch (tag) { --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A166393DE7 for ; Tue, 10 Feb 2026 17:34:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744875; cv=none; b=Tzjdc8WXpHMZNN5yLBo27ODWkn0dVhkX4tOoTkg7JUA+Uxexsejiw9c1Ss/r7ItBqJXOW/8Q0yl4izannM9zlqfbQD7J4ahDtJCmkfN1z0ZudoHWo//dzauxi/9CN4aeU0wp0DQ0IC4fuX9A5gIhEGxT0nfFgv5xygWi3gXQM40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744875; c=relaxed/simple; bh=kHRGihOy6m8oDXS/75QNz1877zsdyY+cQ4ynaVyUZ1w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ghSsqFjbJ7+ZqCxNrzFFdmWRq2VmrFAnjXgxrqDm+cSE9HDWnYeA57c6txyEX73LpgutD3f0tpvn9aTds4fiwXDcbSAO/jy+SbpkXGtLbVBA6xG5qeNeBljZEiP1SNFs/EA3srWMftAPETDGb072quz+5vQaBIIJJC88QgLOzgA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=NRpjwJLd; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="NRpjwJLd" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id E40131A0D9C; Tue, 10 Feb 2026 17:34:32 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B9BC5606BD; Tue, 10 Feb 2026 17:34:32 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 53F5510B91B35; Tue, 10 Feb 2026 18:34:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744871; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=MRm5gadAPy/JOC6qJTX8byNIg7bTWl9sy1ThiPgeJwc=; b=NRpjwJLdl7n5/iRzAaTOePiu747xDJS8lfvya++1MvahYhtegZb1iCrlb7u2V4NbOtEnG2 XnO5EBJo+Mw9y36Xjz+Y/s67wtPJQmMVeqRGrXqcgeBfOmX9ASyKwGz/daEaqDn3ohcrql Z76VFzEvOELfwygEh//P9rkrkxtkdI/49ehltE4emHS5kWGrJjr5XBQ0yMi8aIY45ZiNyO UzbkVc5a15X1nOC/hHmRh052HGDTx8khwn6tYU8e8onjgzvQFVPqzb8uSq0JsqrHIZENeW gNXvf1Tts/KtpkCT/SmwItDlo8dwOonGa67pmF6mB+cq3kbybzizr1nTW8MHDA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 08/15] tests: asm: Introduce treehdr_vers macro Date: Tue, 10 Feb 2026 18:33:36 +0100 Message-ID: <20260210173349.636766-9-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" tree.S is used to generate custom dtbs. It uses the treehdr macro to build the header part. The current definition of this macro doesn't allow to set custom settings related to version fields. In order to easily generate some dtb with custom version values without duplicating the full header computation, introduce the treehdr_vers macro. The modification doesn't introduce any functional changes. Signed-off-by: Herve Codina --- tests/trees.S | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/trees.S b/tests/trees.S index d69f7f1..4db2b9b 100644 --- a/tests/trees.S +++ b/tests/trees.S @@ -8,7 +8,7 @@ .byte (\val) & 0xff .endm =20 - .macro treehdr tree + .macro treehdr_vers tree vers last_comp_vers .balign 8 .globl \tree \tree : @@ -17,13 +17,17 @@ fdtlong (\tree\()_struct - \tree) fdtlong (\tree\()_strings - \tree) fdtlong (\tree\()_rsvmap - \tree) - fdtlong 0x11 - fdtlong 0x10 + fdtlong \vers + fdtlong \last_comp_vers fdtlong 0 fdtlong (\tree\()_strings_end - \tree\()_strings) fdtlong (\tree\()_struct_end - \tree\()_struct) .endm =20 + .macro treehdr tree + treehdr_vers \tree 0x11 0x10 + .endm + .macro rsvmape addrh, addrl, lenh, lenl fdtlong \addrh fdtlong \addrl --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ACC56395D88; Tue, 10 Feb 2026 17:34:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744877; cv=none; b=V7I1kYffR3eXwiDRYfj8H5l2w9s0A1QQY5UikkTZUv/bDtEktHU8w3YmefXg5UgeIrrJ9i/yp/5HkqvJk9FprcKUKidVyDbFup3BdOnyNuuMlwUm56arDKVxv4GubzowU43WcPTZWoLcnDHeHuha/4ZPmDc7Py109cXRxytx/kk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744877; c=relaxed/simple; bh=39K4m3cDwzIk0lw+fWTf25HhLhw7zbT6CjlxHX8Oc8Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nKD0n0RAi5z21t99ebMzGVgzFkhq0fOW3uK/jnkOWcdbTXspKVlYo2CExoHw2Xsk86WBg+cL2+hPILg3pG5pJnc79JJ1CpHYCJwoPHTXKsMf4w3JL4WIeLBqJsPnne8UWDpnKpAixrZqRHLShDmYN77BVPq+JL7YLh1AUzo56mg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=phsanotU; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="phsanotU" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 7043E1A0DB1; Tue, 10 Feb 2026 17:34:34 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 47D68606BD; Tue, 10 Feb 2026 17:34:34 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1165810B91FBE; Tue, 10 Feb 2026 18:34:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744873; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=5ibmTCsT8ORXKdaMNLgIZH3vWyXFUJS/N9D+sJGZPHo=; b=phsanotUjbErY3UW6KKNe8xnMrtoRFQQoRqXQ9K4PaDZqVjJZ+GDWrkwIqHRgjWD8b8+jw U4TplRwZjEaqFlwC2W2eiyXK4RRU1gePqYXqBQpySUMRy2hn0Gln4KcGZw+Dos1n6MbkyC ERECTsuCLXouf220RILbCu2e5OT7nS4J7RuVBpsrIftgENkrGsdCni+/E5avJss43YPKig HQUm9tQ/F8TymoR83i+/4SyBw/aqSVPKAkgOsXw6yvopTFIsC88uHTuHHFs+Xtlf2ABf16 zfI0HTWd2VSqOE+cPuz3ek2+FqFV2ryCz507lz1qFz3BsNP/V0UrDm8q5+Kteg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 09/15] Introduce structured tag value definition Date: Tue, 10 Feb 2026 18:33:37 +0100 Message-ID: <20260210173349.636766-10-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The goal of structured tag values is to ease the introduction of new tags in future releases with the capability for an already existing release to ignore those structured tags. In order to do that data length related to the unknown tag needs to be identify. Also a flag is present to tell an old release if this tag can be simply skipped or must lead to an error. Structured tag value is defined on 32bit and is defined as follow: Bits | 31 | 30 | 29 28 | 27 0| ------+----+----------+-------------------+--------+ Fields| 1 | CAN_SKIP | DATA_LNG_ENCODING | TAG_ID | ------+----+----------+-------------------+--------+ Bit 31 is always set to 1 to identified a structured tag value. Bit 30 (CAN_SKIP) is set to 1 if the tag can be safely ignore when its TAG_ID value is not a known value (unknown tag). If the CAN_SKIP bit is set to 0 this tag must not be ignored and an error should be reported when its TAG_ID value is not a known value (unknown tag). Bits 29..28 (DATA_LNG_ENCODING) indicates the length of the data related to the tag. Following values are possible: - 0b00: No data. The tag is followed by the next tag value. - 0b01: 1 cell data The tag is followed by a 1 cell (u32) data. The next tag is available after this cell. - 0b10: 2 cells data The tag is followed by a 2 cells (2 * u32) data. The next tag is available after those two cells. - 0b11: Data length encoding The tag is followed by a cell (u32) indicating the size of the data. This size is given in bytes. Data are available right after this cell. The next tag is available after the data. Padding is present after the data in order to have the next tag aligned on 32bits. This padding is not included in the size of the data. Bits 27..0 (TAG_ID) is the tag identifier defining a specific tag. Introduce the structured tag values definition and some specific tags reserved for tests based on this structure definition. Signed-off-by: Herve Codina --- libfdt/fdt.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/libfdt/fdt.h b/libfdt/fdt.h index a07abfc..2e07599 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -49,6 +49,7 @@ struct fdt_property { =20 #define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ #define FDT_TAGSIZE sizeof(fdt32_t) +#define FDT_CELLSIZE sizeof(fdt32_t) =20 #define FDT_BEGIN_NODE 0x1 /* Start node: full name */ #define FDT_END_NODE 0x2 /* End node */ @@ -57,6 +58,28 @@ struct fdt_property { #define FDT_NOP 0x4 /* nop */ #define FDT_END 0x9 =20 +/* Tag values flags */ +#define FDT_TAG_STRUCTURED (1<<31) +#define FDT_TAG_SKIP_SAFE (1<<30) +#define FDT_TAG_DATA_MASK (3<<28) +#define FDT_TAG_DATA_NONE (0<<28) +#define FDT_TAG_DATA_1CELL (1<<28) +#define FDT_TAG_DATA_2CELLS (2<<28) +#define FDT_TAG_DATA_LNG (3<<28) + +#define FDT_TAG_NO_SKIP(tag_data, tag_id) \ + (FDT_TAG_STRUCTURED | tag_data | tag_id) + +#define FDT_TAG_CAN_SKIP(tag_data, tag_id) \ + (FDT_TAG_STRUCTURED | FDT_TAG_SKIP_SAFE | tag_data | tag_id) + +/* Tests reserved tags */ +#define FDT_TEST_NONE_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_NONE, 0) +#define FDT_TEST_1CELL_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_1CELL, 0) +#define FDT_TEST_2CELLS_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_2CELLS, 0) +#define FDT_TEST_LNG_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_LNG, 0) +#define FDT_TEST_NONE_NO_SKIP FDT_TAG_NO_SKIP(FDT_TAG_DATA_NONE, 0) + #define FDT_V1_SIZE (7*sizeof(fdt32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DED8F399010; Tue, 10 Feb 2026 17:34:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744879; cv=none; b=SimRFWnFVWrcHR5hn3ibrhb44wU4qx78cD0gPuA3mGsZdrIsrd2MgMunNnrLaAqtkKOi0aG8UDozVfgy4wB/VYLiPi56RQdq49yhgdoKbJ8UbZoXOV7aMllcsGbv/fc323xh+dBn0TNDdazbE5Jn5ogM1Mt6C2MhtjvASmaFDH8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744879; c=relaxed/simple; bh=6oSS3Gjaq5pHhOjJKcEyJyHC93xQI35PkBt/9oTWx8o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=upZeK+lIBvJ+Jks/BZkly6wrstRaolHQ9c5gAAH6vBy0zzp1IBwRlHnU1pJ+XHDAjy0RlP/99dKNqKpxMt6c1ApJapGjQqirkPTope+IN2vyFPbZitmK7XMzhrAAt1JGf1g8cC8FYl0BkEmJBvpuUZI8/atvuC9A+DZoou96seY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=BFc8JhG3; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="BFc8JhG3" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id AF4311A0D81; Tue, 10 Feb 2026 17:34:35 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 860C9606BD; Tue, 10 Feb 2026 17:34:35 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9C8B810B921D3; Tue, 10 Feb 2026 18:34:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744874; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=cRSd/rE0sOqm3dI53YYlvF6U6UePz1Pna27Ugbu+jEQ=; b=BFc8JhG3YWPJfIopswd+qeoY5P3GKsvGF8+jGdCHiYS+JVZHWviNik/zCTNIurXkJMRXz+ utMSxpi3x/UK/ojievODKwcXAjkW0IPUUhmVDXEPfwp0++QV8ufwHycgLLL/UwmhDoVbxT uyMqbgxwpAFt2SY0ejPnFYAmG90ptNRHPh6LhqOrOOy/Ls597q6NWQ1+eOQIlPIWlvJS2v QUiU/JL0aq+CuvrQMk157LDKNzdt9HSvyGLM8ARTZmLROoqa/9sycAL1PiEiuJWvvuhFKa lNPl7TF7LFm5ix/9vMJ+jOGp3on54Ws73OG9A7mzkYHPMev+Y1Ao368PPJqpoA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 10/15] fdtdump: Handle unknown tags Date: Tue, 10 Feb 2026 18:33:38 +0100 Message-ID: <20260210173349.636766-11-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The structured tag value definition introduced recently gives the ability to ignore unknown tags without any error when they are read. Handle those structured tag. Signed-off-by: Herve Codina --- fdtdump.c | 45 +++++++++- tests/dumptrees.c | 4 +- tests/run_tests.sh | 41 +++++++++ tests/testdata.h | 2 + tests/trees.S | 110 +++++++++++++++++++++++++ tests/unknown_tags_can_skip.dtb.expect | 26 ++++++ 6 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 tests/unknown_tags_can_skip.dtb.expect diff --git a/fdtdump.c b/fdtdump.c index 0e7a265..eb8cda9 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -44,7 +44,7 @@ static const char *tagname(uint32_t tag) #define dumpf(fmt, args...) \ do { if (debug) printf("// " fmt, ## args); } while (0) =20 -static void dump_blob(void *blob, bool debug) +static void dump_blob(void *blob, bool debug, int dump_unknown) { uintptr_t blob_off =3D (uintptr_t)blob; struct fdt_header *bph =3D blob; @@ -146,20 +146,55 @@ static void dump_blob(void *blob, bool debug) continue; } =20 + if ((tag & FDT_TAG_STRUCTURED) && (tag & FDT_TAG_SKIP_SAFE)) { + sz =3D 0; + switch (tag & FDT_TAG_DATA_MASK) { + case FDT_TAG_DATA_NONE: + break; + case FDT_TAG_DATA_1CELL: + sz =3D FDT_CELLSIZE; + break; + case FDT_TAG_DATA_2CELLS: + sz =3D 2 * FDT_CELLSIZE; + break; + case FDT_TAG_DATA_LNG: + /* Get the length */ + sz =3D fdt32_to_cpu(GET_CELL(p)); + break; + } + + if (dump_unknown) { + printf("%*s// Unknown tag ignored: 0x%08"PRIx32", data lng %d", + depth * shift, "", tag, sz); + if (dump_unknown > 1 && sz !=3D 0) { + printf(" "); + for (i =3D 0; i < sz; i++) + printf("%02hhx", *(p + i)); + } + printf("\n"); + } + + /* Skip the data bytes */ + p =3D PALIGN(p + sz, 4); + continue; + } + die("** Unknown tag 0x%08"PRIx32"\n", tag); } } =20 /* Usage related data. */ static const char usage_synopsis[] =3D "fdtdump [options] "; -static const char usage_short_opts[] =3D "ds" USAGE_COMMON_SHORT_OPTS; +static const char usage_short_opts[] =3D "dus" USAGE_COMMON_SHORT_OPTS; static struct option const usage_long_opts[] =3D { {"debug", no_argument, NULL, 'd'}, + {"unknown", no_argument, NULL, 'u'}, {"scan", no_argument, NULL, 's'}, USAGE_COMMON_LONG_OPTS }; static const char * const usage_opts_help[] =3D { "Dump debug information while decoding the file", + "Dump unknown tags information while decoding the file (-uu to have data)= ", "Scan for an embedded fdt in file", USAGE_COMMON_OPTS_HELP }; @@ -183,6 +218,7 @@ int main(int argc, char *argv[]) const char *file; char *buf; bool debug =3D false; + int dump_unknown =3D 0; bool scan =3D false; size_t len; =20 @@ -198,6 +234,9 @@ int main(int argc, char *argv[]) case 'd': debug =3D true; break; + case 'u': + dump_unknown++; + break; case 's': scan =3D true; break; @@ -242,7 +281,7 @@ int main(int argc, char *argv[]) } else if (!valid_header(buf, len)) die("%s: header is not valid\n", file); =20 - dump_blob(buf, debug); + dump_blob(buf, debug, dump_unknown); =20 return 0; } diff --git a/tests/dumptrees.c b/tests/dumptrees.c index 08967b3..4732fff 100644 --- a/tests/dumptrees.c +++ b/tests/dumptrees.c @@ -25,7 +25,9 @@ static struct { TREE(truncated_property), TREE(truncated_string), TREE(truncated_memrsv), TREE(two_roots), - TREE(named_root) + TREE(named_root), + TREE(unknown_tags_can_skip), + TREE(unknown_tags_no_skip) }; =20 #define NUM_TREES (sizeof(trees) / sizeof(trees[0])) diff --git a/tests/run_tests.sh b/tests/run_tests.sh index f07092b..b69b61b 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -196,6 +196,40 @@ check_align () { ) } =20 +# $1: f1 file +# $2: f2 file +check_diff () { + printf "diff $1 $2: " + local f1=3D"$1" + local f2=3D"$2" + ( + if diff $f1 $f2 >/dev/null; then + PASS + else + if [ -z "$QUIET_TEST" ]; then + echo "DIFF :-:" + diff -u $f1 $f2 + fi + FAIL "Results differ from expected" + fi + ) +} + +# $1: dtb file +# $2: out file +wrap_fdtdump () { + printf "wrap_fdtdump -uu $1: " + local dtb=3D"$1" + local out=3D"$2" + ( + if $FDTDUMP -uu ${dtb} 2>/dev/null >${out}; then + PASS + else + FAIL + fi + ) +} + run_dtc_test () { printf "dtc $*: " base_run_test wrap_test $VALGRIND $DTC "$@" @@ -1007,6 +1041,13 @@ utilfdt_tests () { =20 fdtdump_tests () { run_fdtdump_test "$SRCDIR/fdtdump.dts" + + base_run_test wrap_fdtdump unknown_tags_can_skip.dtb unknown_tags_can_= skip.dtb.out + # Remove unneeded comments + sed -i '/^\/\/ /d' unknown_tags_can_skip.dtb.out + base_run_test check_diff unknown_tags_can_skip.dtb.out "$SRCDIR/unknow= n_tags_can_skip.dtb.expect" + + run_wrap_error_test $FDTDUMP unknown_tags_no_skip.dtb } =20 fdtoverlay_tests() { diff --git a/tests/testdata.h b/tests/testdata.h index fcebc2c..aef04ab 100644 --- a/tests/testdata.h +++ b/tests/testdata.h @@ -57,4 +57,6 @@ extern struct fdt_header truncated_string; extern struct fdt_header truncated_memrsv; extern struct fdt_header two_roots; extern struct fdt_header named_root; +extern struct fdt_header unknown_tags_can_skip; +extern struct fdt_header unknown_tags_no_skip; #endif /* ! __ASSEMBLER__ */ diff --git a/tests/trees.S b/tests/trees.S index 4db2b9b..221c9fd 100644 --- a/tests/trees.S +++ b/tests/trees.S @@ -328,3 +328,113 @@ named_root_strings: named_root_strings_end: =20 named_root_end: + + + /* Tree with "unknown" tags that can be skipped + * Use a really future dtb version to check version downgrade on + * modification. + */ + treehdr_vers unknown_tags_can_skip 0xffffffff 0x10 + empty_rsvmap unknown_tags_can_skip + +unknown_tags_can_skip_struct: + fdtlong FDT_TEST_1CELL_CAN_SKIP + fdtlong 0x1 + + beginn "" + fdtlong FDT_TEST_NONE_CAN_SKIP + + propu32 unknown_tags_can_skip, prop_int, 1 + + fdtlong FDT_TEST_1CELL_CAN_SKIP + fdtlong 0x11 + + propstr unknown_tags_can_skip, prop_str, "abcd" + + fdtlong FDT_TEST_2CELLS_CAN_SKIP + fdtlong 0x12 + fdtlong 0x12 + + fdtlong FDT_TEST_LNG_CAN_SKIP + fdtlong 3 + .byte 0x13 + .byte 0x13 + .byte 0x13 + .byte 0 /* padding */ + + beginn "subnode1" + propu64 unknown_tags_can_skip, prop_int, 1, 2 + fdtlong FDT_TEST_NONE_CAN_SKIP + endn + + beginn "subnode2" + fdtlong FDT_TEST_1CELL_CAN_SKIP + fdtlong 0x121 + propu64 unknown_tags_can_skip, prop_int1, 1, 2 + fdtlong FDT_TEST_1CELL_CAN_SKIP + fdtlong 0x122 + propu64 unknown_tags_can_skip, prop_int2, 1, 2 + beginn "subsubnode" + fdtlong FDT_TEST_1CELL_CAN_SKIP + fdtlong 0x123 + propu64 unknown_tags_can_skip, prop_int, 1, 2 + endn + fdtlong FDT_TEST_1CELL_CAN_SKIP + fdtlong 0x124 + endn + + fdtlong FDT_TEST_LNG_CAN_SKIP + fdtlong 5 + .byte 0x14 + .byte 0x14 + .byte 0x14 + .byte 0x14 + .byte 0x14 + .byte 0 /* padding */ + .byte 0 /* padding */ + .byte 0 /* padding */ + endn + + fdtlong FDT_TEST_1CELL_CAN_SKIP + fdtlong 0x2 + + fdtlong FDT_TEST_LNG_CAN_SKIP + fdtlong 2 + .byte 0x3 + .byte 0x3 + .byte 0 /* padding */ + .byte 0 /* padding */ + + fdtlong FDT_END + +unknown_tags_can_skip_struct_end: + +unknown_tags_can_skip_strings: + string unknown_tags_can_skip, prop_int, "prop-int" + string unknown_tags_can_skip, prop_int1, "prop-int1" + string unknown_tags_can_skip, prop_int2, "prop-int2" + string unknown_tags_can_skip, prop_str, "prop-str" +unknown_tags_can_skip_strings_end: + +unknown_tags_can_skip_end: + + + /* Tree with "unknown" tags that cannot be skipped */ + treehdr unknown_tags_no_skip + empty_rsvmap unknown_tags_no_skip + +unknown_tags_no_skip_struct: + beginn "" + fdtlong FDT_TEST_NONE_NO_SKIP + beginn "subnode1" + propu64 unknown_tags_no_skip, prop_int, 1, 2 + endn + endn + fdtlong FDT_END +unknown_tags_no_skip_struct_end: + +unknown_tags_no_skip_strings: + string unknown_tags_no_skip, prop_int, "prop-int" +unknown_tags_no_skip_strings_end: + +unknown_tags_no_skip_end: diff --git a/tests/unknown_tags_can_skip.dtb.expect b/tests/unknown_tags_ca= n_skip.dtb.expect new file mode 100644 index 0000000..32e3f46 --- /dev/null +++ b/tests/unknown_tags_can_skip.dtb.expect @@ -0,0 +1,26 @@ +/dts-v1/; + +/ { + // Unknown tag ignored: 0xc0000000, data lng 0 + prop-int =3D <0x00000001>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000011 + prop-str =3D "abcd"; + // Unknown tag ignored: 0xe0000000, data lng 8 0000001200000012 + // Unknown tag ignored: 0xf0000000, data lng 3 131313 + subnode1 { + prop-int =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xc0000000, data lng 0 + }; + subnode2 { + // Unknown tag ignored: 0xd0000000, data lng 4 00000121 + prop-int1 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000122 + prop-int2 =3D <0x00000001 0x00000002>; + subsubnode { + // Unknown tag ignored: 0xd0000000, data lng 4 00000123 + prop-int =3D <0x00000001 0x00000002>; + }; + // Unknown tag ignored: 0xd0000000, data lng 4 00000124 + }; + // Unknown tag ignored: 0xf0000000, data lng 5 1414141414 +}; --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F073396B71; Tue, 10 Feb 2026 17:34:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744879; cv=none; b=rxgmASp0iswBohtt1uNwiuaVGQOyjoI5dg7B2GbyoVVVkK7SYi2aNwGa4sLz7hB7Cgg5wwTpKk374PQuvE1N7bkPmm4+inVj9BaUmSuIMXBsVuEarOCkHXc3dJgT13tkZmeiFPrXVZo+L3+7DeBUr2mZebxj7hbCqsbP9Gvufeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744879; c=relaxed/simple; bh=mChCLV73SfDyjkx1FnS/Bp4AcikarcmzTUZ+U8IvJ0w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HTtyNiAgMmv/vDONJdDXReLcYPu+ihdchPhM/F1CQaNM+sGM5TicXysf1ZbxCvyS+KMxKZVSoyPr3/+JtrjHq09kKY6gxLpkzhKRTcXTajYHry1Nlqf5oUsdlgColtnHrH7Dnn4UwzCxMb50BGM69QyPLtvAVgzH/Zot1wudDfY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=VJmFcoWV; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="VJmFcoWV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 6259DC8F455; Tue, 10 Feb 2026 17:34:45 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 03175606BD; Tue, 10 Feb 2026 17:34:37 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 0420B10B9213C; Tue, 10 Feb 2026 18:34:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744876; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=yTNPBv983V3G10hN3xMTv91meECHpLrvslxwBaJ5IF8=; b=VJmFcoWV9zBZznwDaBWZN7O5NnhudKSRVamYIcWSJKf1bbf5HtXBOT3/bU12BjgiHIMCcZ 8kPrplPs7H8OWRQMkEW125lomkbSwWBrsWbK6t5n2+CDDj1p7wJqS8Ak3nXBOxIzhSwHbK SA0cWBTZskWQkcYO4CHAZzu/rijVnXREaMoOrxrmb6/T7OUJHXsLoqVD4sI3jM2EBKnWK3 ejPWCD5u/mzxVgyBUZ55u6zc8LZAz0gKzF6elPH/36arr0wDEzIaCCVBamY2tng2Nf3H+f y5/6nFmIYoEtHFbZIhwK5buF4Ft732Db+z9mmBeSJCwWKrajig9S4WjyKpUmkg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 11/15] flattree: Handle unknown tags Date: Tue, 10 Feb 2026 18:33:39 +0100 Message-ID: <20260210173349.636766-12-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The structured tag value definition introduced recently gives the ability to ignore unknown tags without any error when they are read. Handle those structured tag. Signed-off-by: Herve Codina --- flattree.c | 65 ++++++++++++++++++++-- tests/run_tests.sh | 5 ++ tests/unknown_tags_can_skip.dtb.dts.expect | 19 +++++++ 3 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 tests/unknown_tags_can_skip.dtb.dts.expect diff --git a/flattree.c b/flattree.c index f3b698c..23813e2 100644 --- a/flattree.c +++ b/flattree.c @@ -579,7 +579,8 @@ static void flat_read_chunk(struct inbuf *inb, void *p,= int len) if ((inb->ptr + len) > inb->limit) die("Premature end of data parsing flat device tree\n"); =20 - memcpy(p, inb->ptr, len); + if (p) + memcpy(p, inb->ptr, len); =20 inb->ptr +=3D len; } @@ -604,6 +605,61 @@ static void flat_realign(struct inbuf *inb, int align) die("Premature end of data parsing flat device tree\n"); } =20 +static bool flat_skip_unknown_tag(struct inbuf *inb, uint32_t tag) +{ + uint32_t lng; + + if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE)) + return false; + + switch (tag & FDT_TAG_DATA_MASK) { + case FDT_TAG_DATA_NONE: + break; + + case FDT_TAG_DATA_1CELL: + flat_read_word(inb); + break; + + case FDT_TAG_DATA_2CELLS: + flat_read_word(inb); + flat_read_word(inb); + break; + + case FDT_TAG_DATA_LNG: + /* Get the length */ + lng =3D flat_read_word(inb); + + /* Skip the following length bytes */ + flat_read_chunk(inb, NULL, lng); + + flat_realign(inb, sizeof(uint32_t)); + break; + } + + return true; +} + +static uint32_t flat_read_tag(struct inbuf *inb) +{ + uint32_t tag; + + do { + tag =3D flat_read_word(inb); + switch (tag) { + case FDT_BEGIN_NODE: + case FDT_END_NODE: + case FDT_PROP: + case FDT_NOP: + case FDT_END: + return tag; + default: + break; + } + } while (flat_skip_unknown_tag(inb, tag)); + + die("Cannot skip unknown tag 0x%08x\n", tag); +} + static const char *flat_read_string(struct inbuf *inb) { int len =3D 0; @@ -750,7 +806,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, struct property *prop; struct node *child; =20 - val =3D flat_read_word(dtbuf); + val =3D flat_read_tag(dtbuf); switch (val) { case FDT_PROP: if (node->children) @@ -905,14 +961,13 @@ struct dt_info *dt_from_blob(const char *fname) =20 reservelist =3D flat_read_mem_reserve(&memresvbuf); =20 - val =3D flat_read_word(&dtbuf); - + val =3D flat_read_tag(&dtbuf); if (val !=3D FDT_BEGIN_NODE) die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%= 08x)\n", val); =20 tree =3D unflatten_tree(&dtbuf, &strbuf, "", flags); =20 - val =3D flat_read_word(&dtbuf); + val =3D flat_read_tag(&dtbuf); if (val !=3D FDT_END) die("Device tree blob doesn't end with FDT_END\n"); =20 diff --git a/tests/run_tests.sh b/tests/run_tests.sh index b69b61b..98fa4f4 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -881,6 +881,11 @@ dtc_tests () { =20 # Tests for overlay/plugin generation dtc_overlay_tests + + # Tests with "unknown tags" + run_dtc_test -I dtb -O dts -o unknown_tags_can_skip.dtb.dts unknown_ta= gs_can_skip.dtb + base_run_test check_diff unknown_tags_can_skip.dtb.dts "$SRCDIR/unknow= n_tags_can_skip.dtb.dts.expect" + run_wrap_error_test $DTC -I dtb -O dts -o unknown_tags_no_skip.dtb.dts= unknown_tags_no_skip.dtb } =20 cmp_tests () { diff --git a/tests/unknown_tags_can_skip.dtb.dts.expect b/tests/unknown_tag= s_can_skip.dtb.dts.expect new file mode 100644 index 0000000..94fa6d6 --- /dev/null +++ b/tests/unknown_tags_can_skip.dtb.dts.expect @@ -0,0 +1,19 @@ +/dts-v1/; + +/ { + prop-int =3D <0x01>; + prop-str =3D "abcd"; + + subnode1 { + prop-int =3D <0x01 0x02>; + }; + + subnode2 { + prop-int1 =3D <0x01 0x02>; + prop-int2 =3D <0x01 0x02>; + + subsubnode { + prop-int =3D <0x01 0x02>; + }; + }; +}; --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 212113A1E63; Tue, 10 Feb 2026 17:34:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744882; cv=none; b=tvNbG8awisOrQGqulVRKiFhTlejf07UNeDVFrZqSEye8mhN5zZaZChCttMo4RnzOoF3h0Q1O80tP5dchrrws6vzOuYiNic+xjw8uJHJEzOC815UorXlLpFeBfNAv5Vy4uPxzUF+2GyKMAYCwaKhVPUBZ2UxJ8nQ+vNjSmIz57ko= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744882; c=relaxed/simple; bh=BUK2NieV3t+PRz1JGkcE3kPYIyTQYMide+st0mYdSB4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g06bzeIKQ8u7bgNbQhMLiuvUUuCedT2Si+fP/G/4DzFhIdxtcQ85FwWrDO6FoZIlG2gmjrvzeWrLTfE7kvMSuIk7ncYXsmSujdQ0rgsEEQ0Qnwhtye/spCk+DEoWz0Ewgv2cXe5/5jXEhf0uCRSaMy2RVlPxq+Iylk5PTqQJKEc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=24vaG7TL; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="24vaG7TL" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 38298C8F450; Tue, 10 Feb 2026 17:34:47 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id CC622606BD; Tue, 10 Feb 2026 17:34:38 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id C56A710B92227; Tue, 10 Feb 2026 18:34:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744877; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=ykwVwiDzTEMjCwJf+cPIkHgzhvZz+yEanxd5gh8w6+w=; b=24vaG7TLLfBFX9aGf389bG13gCJoebnmvbTPEbpRZyJQ3fZ08WlEThd/0EQGPk9BhCSUfh mc0+tlxbPhxUlovC59O6RPbtn8Nb+UqFazqsjR71cRJ+XnovrJ6xuM1UhBGVW2afTjGvMa Fn7ov9scfVYrUTBsi+2jl9EWrBuen9Y193YXVPLMSAuWo/gz9WeQ/yQ61Zt5AyxlXRCXJk +wEvi0iQ755fCHu563QXBb4QMpSZfqChF6tQ8cDmvP0zW4iJiLR7bzVujnz2GHfncdhI74 dqxzbv94/UTncOfVATrf2ZIo7ngy5Mq1hKtOIkoPyDAjO8nbr2zEbmFmCNn0Wg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 12/15] libfdt: Handle unknown tags in fdt_get_next() Date: Tue, 10 Feb 2026 18:33:40 +0100 Message-ID: <20260210173349.636766-13-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The structured tag value definition introduced recently gives the ability to ignore unknown tags without any error when they are read. libfdt uses fdt_get_next() to get a tag. Filtering out tags that should be ignored in fdt_get_next() allows to have the filtering done globally and allows, in future release, to have a central place to add new known tags that should not be filtered out. An already known tag exists with the meaning of "just ignore". This tag is FDT_NOP. fdt_get_next() callers already handle the FDT_NOP tag. Avoid unneeded modification at callers side and use a fake FDT_NOP tag when an unknown tag that should be ignored is encountered. Add also fdt_get_next_() internal function for callers who need to know if the FDT_NOP tag returned is a real FDT_NOP or a fake FDT_NOP due to an unknown tag. Signed-off-by: Herve Codina --- libfdt/fdt.c | 75 ++++++++++++++++++++++++++++++++++++++-- libfdt/libfdt_internal.h | 3 ++ tests/run_tests.sh | 9 +++-- 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/libfdt/fdt.c b/libfdt/fdt.c index ff2fa6c..790cbbd 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -167,7 +167,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset,= unsigned int len) return fdt_offset_ptr_(fdt, offset); } =20 -uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) +static uint32_t fdt_next_tag_all(const void *fdt, int startoffset, int *ne= xtoffset) { const fdt32_t *tagp, *lenp; uint32_t tag, len, sum; @@ -218,7 +218,37 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset= , int *nextoffset) break; =20 default: - return FDT_END; + if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE)) + return FDT_END; + + switch (tag & FDT_TAG_DATA_MASK) { + case FDT_TAG_DATA_NONE: + break; + case FDT_TAG_DATA_1CELL: + offset +=3D FDT_CELLSIZE; + break; + case FDT_TAG_DATA_2CELLS: + offset +=3D 2 * FDT_CELLSIZE; + break; + case FDT_TAG_DATA_LNG: + /* Get the length */ + lenp =3D fdt_offset_ptr(fdt, offset, sizeof(*lenp)); + if (!can_assume(VALID_DTB) && !lenp) + return FDT_END; /* premature end */ + len =3D fdt32_to_cpu(*lenp); + /* + * Skip the cell encoding the length and the + * following length bytes + */ + len +=3D sizeof(*lenp); + sum =3D len + offset; + if (!can_assume(VALID_DTB) && + (sum >=3D INT_MAX || sum < (uint32_t) offset)) + return FDT_END; /* premature end */ + + offset +=3D len; + break; + } } =20 if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) @@ -228,6 +258,47 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset= , int *nextoffset) return tag; } =20 +static bool fdt_is_unknown_tag(uint32_t tag) +{ + switch (tag) { + case FDT_BEGIN_NODE: + case FDT_END_NODE: + case FDT_PROP: + case FDT_NOP: + case FDT_END: + return false; + default: + break; + } + return true; +} + +uint32_t fdt_next_tag_(const void *fdt, int startoffset, int *nextoffset, = bool *is_unknown) +{ + uint32_t tag; + bool unknown =3D false; + + /* Retrieve next tag */ + tag =3D fdt_next_tag_all(fdt, startoffset, nextoffset); + if (tag =3D=3D FDT_END) + goto end; + + if (fdt_is_unknown_tag(tag)) { + unknown =3D true; + /* Use a known tag that should be skipped by the caller */ + tag =3D FDT_NOP; + } +end: + if (is_unknown) + *is_unknown =3D unknown; + return tag; +} + +uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) +{ + return fdt_next_tag_(fdt, startoffset, nextoffset, NULL); +} + int fdt_check_node_offset_(const void *fdt, int offset) { if (!can_assume(VALID_INPUT) diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index 4c15264..c1ae306 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -20,6 +20,9 @@ int32_t fdt_ro_probe_(const void *fdt); } \ } =20 +uint32_t fdt_next_tag_(const void *fdt, int startoffset, int *nextoffset, + bool *is_unknown); + int fdt_check_node_offset_(const void *fdt, int offset); int fdt_check_prop_offset_(const void *fdt, int offset); =20 diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 98fa4f4..690a141 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -576,11 +576,12 @@ libfdt_tests () { run_test dtbs_equal_ordered cell-overflow.test.dtb cell-overflow-resul= ts.test.dtb =20 # check full tests - for good in test_tree1.dtb; do + for good in test_tree1.dtb unknown_tags_can_skip.dtb; do run_test check_full $good done for bad in truncated_property.dtb truncated_string.dtb \ - truncated_memrsv.dtb two_roots.dtb named_root.dtb; do + truncated_memrsv.dtb two_roots.dtb named_root.dtb \ + unknown_tags_no_skip.dtb; do run_test check_full -n $bad done } @@ -961,6 +962,10 @@ fdtget_tests () { run_fdtget_test "" -tx \ -d "" $dtb /randomnode doctor-who run_fdtget_test "" -tx -d "" $dtb /memory doctor-who + + # test with unknown tags involved + run_fdtget_test "1 2" unknown_tags_can_skip.dtb /subnode1 prop-int + run_wrap_error_test $DTGET unknown_tags_no_skip.dtb /subnode1 prop-int } =20 fdtput_tests () { --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CEF6038B7B5 for ; Tue, 10 Feb 2026 17:34:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744883; cv=none; b=gombE7PihGcez9Bar7SY5s2iBcJ4x8J3EO1EJ/ax2tqz229fgeHf2UuVhXR0Gs31JryK1WSS2/XcKGyt/IToWG4L0IYl65S34mSzPN9yBJXCI2OeF9OPkVzGdMyRdNSUBu/ALO0ExdcY34NGhrcSJcQNWzg4EeQkRTSyY8R6tFs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744883; c=relaxed/simple; bh=HQ4pWzYerX30F4hSO8byThnhG2+VNt8BytSWSpIE4eQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VzJuzr1vP2FKCeZbXJBBvh2N/Bw53zXmFTTVpyyxl8gm8TEdXZ/1W8WsmDhjeeG+ToOjNMy3SZ7822CgdunN6rXsQfqHzHBXuL+bgE1KyB3Y2LjopV35sSB6wslm0+N/VNCobtQhIJOYNTD5Gdn1mxOBMo5k7CgRsEaCegMgizA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=sNCt7FYF; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="sNCt7FYF" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 887934E40C03; Tue, 10 Feb 2026 17:34:40 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 5FE4C606BD; Tue, 10 Feb 2026 17:34:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3620410B9221F; Tue, 10 Feb 2026 18:34:38 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744879; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=DSVj63KfoDkgV6+eP5+RXnlkCT5AQSLoR9qU3u9WU6U=; b=sNCt7FYFHAWlf40+DTFC2iwkyQlwkKO2wxHX3hNsYhc1Gtmokza/UWXLftKjlcfxi2QB0c Zt7rGKrlzDEhYq8Kk4Dm4Xy+X/XvN1xNSXiBhEo6LaJyiDr9Tb594B3ASRaMi+5V5QTZ9r X6qW4YvE5nvOI6YKkJK/U0RA1xWgUrgrhmPAkOcF3iqh2m6ZGPwBdHuOZdbEGVp+YQk/XO CY0rGlDPyXN0tZgYCIhJ23iBAQvZNMd71wfr5Iwsrvnr6N67ygk1dVH9WZ+jXC2GTWs9Ze zb5UCv43mGK4OYKJnY6oR09L0Uwpbr36ppk8wF/k+R+ysqLcwuo3/Nqg+M1EIw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 13/15] libfdt: Introduce fdt_ptr_offset_ Date: Tue, 10 Feb 2026 18:33:41 +0100 Message-ID: <20260210173349.636766-14-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" libfdt provides internal used helpers to convert an offset to a pointer but nothing to do the reverse operation. Fill this lack and introduce the fdt_ptr_offset_() internal helper to convert a pointer to an offset. Signed-off-by: Herve Codina --- libfdt/libfdt_internal.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index c1ae306..9fd0012 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -47,6 +47,11 @@ static inline void *fdt_offset_ptr_w_(void *fdt, int off= set) return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset); } =20 +static inline int fdt_ptr_offset_(const void *fdt, const void *ptr) +{ + return (const char *)ptr - (const char *)fdt_offset_ptr_(fdt, 0); +} + static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt= , int n) { const struct fdt_reserve_entry *rsv_table =3D --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 820D63ACA51 for ; Tue, 10 Feb 2026 17:34:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744885; cv=none; b=vEOB8gSzqSeCC4C0mVaNEhDl/c+PP1AgBxFrKgiqLWSJzTbglSJwSFg9MRGSXSHrWiqVA0p8uXuiO6ruQnpZAc8JbXyrlRqLikJGdQ06X+HvfVtaEz2LmzjrgqBwFdz0ugdcW+7brRTO6KnuRieUHYL4gGf9PZnlETOyYQPKH5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744885; c=relaxed/simple; bh=jCd7W0+SwrS40OVE3WgQZooVnxYlDbJH/cd1M/t/csw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JwNSF9ud6jQYQVwDV8swb3AHOI52lhnpUpa0qMWAzT8PMv+GEmBDjZT61fAD6fYp5LaSZHDxYOG/SUXoyzxChpIg2BP7pbmY2Ggo0q1OcLPPXEo5f4Dnb9CvTAOwgCWcOO4Solh/V6BlV/kDcvri9rnMRHKe4I4pbxQR2bMJdBA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=wUv+52Es; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="wUv+52Es" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 21C114E40C06; Tue, 10 Feb 2026 17:34:42 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EB975606BD; Tue, 10 Feb 2026 17:34:41 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E400110B92226; Tue, 10 Feb 2026 18:34:39 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744881; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Cey6txh3ecv9PyGNUxnI7vsqR6x5ql89oT71DjSD+2g=; b=wUv+52EsUgZECDSWlHL2N5xB7ObjTaOzA1gzVCDCTXPDnlS/9oeB0ZYgbdPxc3NMJDk9xp LLMbu7q9c/5mcWpFkAV2yDVvUycmf3ePwpagRvvNFDIjGjVUvHuoIenrjS7nCcCvhzDp9K FB+KLSr263NRxiPsSqU5N+0IdJXI5mNNKqaj0awAxTlxkhPNa9eVOtodmrJIvydixHSEFn nzJ8EAPQdQf3M3GGXV1YkU+D1xQkHF34s2sXp4b39iXRMqgxuvWsKANk0AB3+sffH/LD4Y HBEOpJIqfDuND2TzTnjGot/wzFu5P15chn63hxRb54V6Wz50UF2BeZYnJx6gKw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 14/15] libfdt: Handle unknown tags on dtb modifications Date: Tue, 10 Feb 2026 18:33:42 +0100 Message-ID: <20260210173349.636766-15-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The structured tag value definition introduced recently gives the ability to ignore unknown tags without any error. When the dtb is modified those unknown tags have to be taken into account. First, depending on the unknown tag location, the item associated with the tag is identified: - An unknown tag located just after a FDT_BEGIN_NODE is related to the node. - An unknown tag located just after a FDT_PROP is related to the property. - An unknown tag out of any node (i.e located before the first FDT_BEGIN_NODE or after the last FDT_END_NODE is a global tag related to the dtb itself. Then, if we are allowed to write a dtb containing unknown tags, the following rules are used: - When a property is modified, tags related to this property are removed and the dtb version is downgraded. - When a property is removed, tags related to this property are obviously removed. The dtb version is kept unchanged. - When a property or a node is added, obviously no unknown tags are added and the dtb version is kept unchanged. - When a node is removed, tags related to this node are obviously removed. The dtb version is kept unchanged. - Adding, removing or modifying a property is not considered as a node modification and so, those operations have no impacts on unknown tags related to the node. Those node related tags are kept unchanged. - The only modification considered as a node modification is setting its name. We consider that this operation has no impact on tags related to the node. Here also, those node related tags and the dtb version are kept unchanged. - Global (dtb related) unknown tags are kept unchanged regardless the modification done. Implement those rules when a dtb is modified. Signed-off-by: Herve Codina --- libfdt/fdt_rw.c | 118 +++++++++++++++++- tests/run_tests.sh | 50 ++++++++ ...own_tags_can_skip.fdtput.test.dtb.0.expect | 31 +++++ ...own_tags_can_skip.fdtput.test.dtb.1.expect | 35 ++++++ ...own_tags_can_skip.fdtput.test.dtb.2.expect | 33 +++++ ...own_tags_can_skip.fdtput.test.dtb.3.expect | 35 ++++++ ...own_tags_can_skip.fdtput.test.dtb.4.expect | 34 +++++ ...own_tags_can_skip.fdtput.test.dtb.5.expect | 32 +++++ ...own_tags_can_skip.fdtput.test.dtb.6.expect | 27 ++++ 9 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index f5c28fc..a8f53b4 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -188,6 +188,60 @@ int fdt_del_mem_rsv(void *fdt, int n) return fdt_splice_mem_rsv_(fdt, re, 1, 0); } =20 +static void fdt_nopify_area(void *fdt, int start_offset, int next_offset) +{ + int count =3D (next_offset - start_offset) / sizeof(fdt32_t); + fdt32_t fdt32_nop =3D cpu_to_fdt32(FDT_NOP); + fdt32_t *ptr; + + ptr =3D fdt_offset_ptr_w_(fdt, start_offset); + while (count--) + *(ptr++) =3D fdt32_nop; +}; + +static int fdt_property_remove_unknown_tags(void *fdt, + const struct fdt_property *prop, + bool downgrade_version) +{ + int nextoffset, offset; + bool is_unknown; + uint32_t tag; + + tag =3D fdt_next_tag(fdt, fdt_ptr_offset_(fdt, prop), &nextoffset); + if (tag =3D=3D FDT_END) + return nextoffset; + + /* + * Look at all tags related to the current property. I.e. tags after the + * current property and before either the next property, a sub-node or + * the end of current node + */ + do { + offset =3D nextoffset; + tag =3D fdt_next_tag_(fdt, offset, &nextoffset, &is_unknown); + if (tag =3D=3D FDT_END) + return nextoffset; + + /* + * Unknown tags are returned as NOP. Force FDT_NOP to be really + * present in the area to remove the unknown tag and its related + * data. Also, as a tag is removed, downgrade the dtb version + * if asked for. + */ + if (tag =3D=3D FDT_NOP) { + if (is_unknown) { + if (downgrade_version) + fdt_downgrade_version(fdt); + fdt_nopify_area(fdt, offset, nextoffset); + } + } + + } while ((tag !=3D FDT_PROP) && (tag !=3D FDT_BEGIN_NODE) && + (tag !=3D FDT_END_NODE)); + + return 0; +} + static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name, int namelen, int len, struct fdt_property **prop) @@ -200,6 +254,14 @@ static int fdt_resize_property_(void *fdt, int nodeoff= set, if (!*prop) return oldlen; =20 + /* + * The property is resized. Remove possible unknown tags related to the + * property downgrading the dtb version. + */ + err =3D fdt_property_remove_unknown_tags(fdt, *prop, true); + if (err) + return err; + if ((err =3D fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), FDT_TAGALIGN(len)))) return err; @@ -208,6 +270,29 @@ static int fdt_resize_property_(void *fdt, int nodeoff= set, return 0; } =20 +static int fdt_node_skip_unknown_tags(void *fdt, int next) +{ + int nextoffset =3D next; + int offset; + uint32_t tag; + + /* + * Skip all tags related to the current node. I.e. tags after the + * current node and before either the next property, a sub-node or the + * end of current node. + */ + do { + offset =3D nextoffset; + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + if (tag =3D=3D FDT_END) + return nextoffset; + + } while ((tag !=3D FDT_PROP) && (tag !=3D FDT_BEGIN_NODE) && + (tag !=3D FDT_END_NODE)); + + return offset; +} + static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, int namelen, int len, struct fdt_property **prop) { @@ -220,6 +305,15 @@ static int fdt_add_property_(void *fdt, int nodeoffset= , const char *name, if ((nextoffset =3D fdt_check_node_offset_(fdt, nodeoffset)) < 0) return nextoffset; =20 + /* + * nextoffset it at the first tag after the node. + * Skip possible unknown tags related to the node in order to add the + * property after those tags. + */ + nextoffset =3D fdt_node_skip_unknown_tags(fdt, nextoffset); + if (nextoffset < 0) + return nextoffset; + namestroff =3D fdt_find_add_string_(fdt, name, namelen, &allocated); if (namestroff < 0) return namestroff; @@ -309,6 +403,14 @@ int fdt_appendprop(void *fdt, int nodeoffset, const ch= ar *name, =20 prop =3D fdt_get_property_w(fdt, nodeoffset, name, &oldlen); if (prop) { + /* + * The property is going to be modified. Remove possible unknown + * tags related to this property downgrading the dtb version. + */ + err =3D fdt_property_remove_unknown_tags(fdt, prop, true); + if (err) + return err; + newlen =3D len + oldlen; err =3D fdt_splice_struct_(fdt, prop->data, FDT_TAGALIGN(oldlen), @@ -331,6 +433,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *= name) { struct fdt_property *prop; int len, proplen; + int err; =20 FDT_RW_PROBE(fdt); =20 @@ -338,6 +441,14 @@ int fdt_delprop(void *fdt, int nodeoffset, const char = *name) if (!prop) return len; =20 + /* + * The property is going to be removed. Remove also possible unknown + * tags related to this property. Keep the dtb version unchanged. + */ + err =3D fdt_property_remove_unknown_tags(fdt, prop, false); + if (err) + return err; + proplen =3D sizeof(*prop) + FDT_TAGALIGN(len); return fdt_splice_struct_(fdt, prop, proplen, 0); } @@ -366,7 +477,12 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffse= t, else if (offset !=3D -FDT_ERR_NOTFOUND) return offset; =20 - /* Try to place the new node after the parent's properties */ + /* + * Try to place the new node after the parent's properties and unknown + * tags related to those properties. + * Unknown tags are reported as FDT_NOP tags by fdt_next_tag. + * Skipping FDT_NOP tags will correctly skip unknown tags. + */ tag =3D fdt_next_tag(fdt, parentoffset, &nextoffset); /* the fdt_subnode_offset_namelen() should ensure this never hits */ if (!can_assume(LIBFDT_FLAWLESS) && (tag !=3D FDT_BEGIN_NODE)) diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 690a141..e88f641 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1043,6 +1043,56 @@ fdtput_tests () { run_wrap_error_test $DTPUT $dtb -d /chosen non-existent-prop =20 # TODO: Add tests for verbose mode? + + # Modify a dtb containing some "unknown" tags that can be skipped + dtb=3Dunknown_tags_can_skip.fdtput.test.dtb + cp unknown_tags_can_skip.dtb $dtb + base_run_test wrap_fdtdump $dtb $dtb.0.out + # Remove unneeded header fields (keep those related to versions) + sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.0.out + base_run_test check_diff $dtb.0.out "$SRCDIR/$dtb.0.expect" + + run_fdtput_test "vwxyz" $dtb / prop-str -ts "vwxyz" + base_run_test wrap_fdtdump $dtb $dtb.1.out + # Remove unneeded header fields (keep those related to versions) + sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.1.out + base_run_test check_diff $dtb.1.out "$SRCDIR/$dtb.1.expect" + + cp unknown_tags_can_skip.dtb $dtb + run_wrap_test $DTPUT $dtb -c /tst-fdtput + base_run_test wrap_fdtdump $dtb $dtb.2.out + # Remove unneeded header fields (keep those related to versions) + sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.2.out + base_run_test check_diff $dtb.2.out "$SRCDIR/$dtb.2.expect" + run_wrap_test $DTPUT $dtb -c /tst-fdtput/n1 /tst-fdtput/n2 /tst-fdtput= /n3 + run_wrap_test $DTPUT $dtb -r /tst-fdtput/n1 /tst-fdtput/n3 + run_fdtget_test "n2" $dtb -l /tst-fdtput + base_run_test wrap_fdtdump $dtb $dtb.3.out + # Remove unneeded header fields (keep those related to versions) + sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.3.out + base_run_test check_diff $dtb.3.out "$SRCDIR/$dtb.3.expect" + + cp unknown_tags_can_skip.dtb $dtb + run_wrap_test $DTPUT $dtb -d / prop-str + run_fdtget_test "prop-int" $dtb -p / + base_run_test wrap_fdtdump $dtb $dtb.4.out + # Remove unneeded header fields (keep those related to versions) + sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.4.out + base_run_test check_diff $dtb.4.out "$SRCDIR/$dtb.4.expect" + + cp unknown_tags_can_skip.dtb $dtb + run_wrap_test $DTPUT $dtb /subnode2 prop-tst-fdtput -ts "Test fdtput" + base_run_test wrap_fdtdump $dtb $dtb.5.out + # Remove unneeded header fields (keep those related to versions) + sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.5.out + base_run_test check_diff $dtb.5.out "$SRCDIR/$dtb.5.expect" + + cp unknown_tags_can_skip.dtb $dtb + run_wrap_test $DTPUT $dtb -r /subnode2/subsubnode + base_run_test wrap_fdtdump $dtb $dtb.6.out + # Remove unneeded header fields (keep those related to versions) + sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.6.out + base_run_test check_diff $dtb.6.out "$SRCDIR/$dtb.6.expect" } =20 utilfdt_tests () { diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.0.expect new file mode 100644 index 0000000..b611a87 --- /dev/null +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect @@ -0,0 +1,31 @@ +/dts-v1/; +// version: 4294967295 +// last_comp_version: 16 + +// Unknown tag ignored: 0xd0000000, data lng 4 00000001 +/ { + // Unknown tag ignored: 0xc0000000, data lng 0 + prop-int =3D <0x00000001>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000011 + prop-str =3D "abcd"; + // Unknown tag ignored: 0xe0000000, data lng 8 0000001200000012 + // Unknown tag ignored: 0xf0000000, data lng 3 131313 + subnode1 { + prop-int =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xc0000000, data lng 0 + }; + subnode2 { + // Unknown tag ignored: 0xd0000000, data lng 4 00000121 + prop-int1 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000122 + prop-int2 =3D <0x00000001 0x00000002>; + subsubnode { + // Unknown tag ignored: 0xd0000000, data lng 4 00000123 + prop-int =3D <0x00000001 0x00000002>; + }; + // Unknown tag ignored: 0xd0000000, data lng 4 00000124 + }; + // Unknown tag ignored: 0xf0000000, data lng 5 1414141414 +}; +// Unknown tag ignored: 0xd0000000, data lng 4 00000002 +// Unknown tag ignored: 0xf0000000, data lng 2 0303 diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.1.expect new file mode 100644 index 0000000..8b331f3 --- /dev/null +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect @@ -0,0 +1,35 @@ +/dts-v1/; +// version: 17 +// last_comp_version: 16 + +// Unknown tag ignored: 0xd0000000, data lng 4 00000001 +/ { + // Unknown tag ignored: 0xc0000000, data lng 0 + prop-int =3D <0x00000001>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000011 + prop-str =3D "vwxyz"; + // [NOP] + // [NOP] + // [NOP] + // [NOP] + // [NOP] + // [NOP] + subnode1 { + prop-int =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xc0000000, data lng 0 + }; + subnode2 { + // Unknown tag ignored: 0xd0000000, data lng 4 00000121 + prop-int1 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000122 + prop-int2 =3D <0x00000001 0x00000002>; + subsubnode { + // Unknown tag ignored: 0xd0000000, data lng 4 00000123 + prop-int =3D <0x00000001 0x00000002>; + }; + // Unknown tag ignored: 0xd0000000, data lng 4 00000124 + }; + // Unknown tag ignored: 0xf0000000, data lng 5 1414141414 +}; +// Unknown tag ignored: 0xd0000000, data lng 4 00000002 +// Unknown tag ignored: 0xf0000000, data lng 2 0303 diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.2.expect new file mode 100644 index 0000000..e2dfe91 --- /dev/null +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect @@ -0,0 +1,33 @@ +/dts-v1/; +// version: 17 +// last_comp_version: 16 + +// Unknown tag ignored: 0xd0000000, data lng 4 00000001 +/ { + // Unknown tag ignored: 0xc0000000, data lng 0 + prop-int =3D <0x00000001>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000011 + prop-str =3D "abcd"; + // Unknown tag ignored: 0xe0000000, data lng 8 0000001200000012 + // Unknown tag ignored: 0xf0000000, data lng 3 131313 + tst-fdtput { + }; + subnode1 { + prop-int =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xc0000000, data lng 0 + }; + subnode2 { + // Unknown tag ignored: 0xd0000000, data lng 4 00000121 + prop-int1 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000122 + prop-int2 =3D <0x00000001 0x00000002>; + subsubnode { + // Unknown tag ignored: 0xd0000000, data lng 4 00000123 + prop-int =3D <0x00000001 0x00000002>; + }; + // Unknown tag ignored: 0xd0000000, data lng 4 00000124 + }; + // Unknown tag ignored: 0xf0000000, data lng 5 1414141414 +}; +// Unknown tag ignored: 0xd0000000, data lng 4 00000002 +// Unknown tag ignored: 0xf0000000, data lng 2 0303 diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.3.expect new file mode 100644 index 0000000..d12ce6f --- /dev/null +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect @@ -0,0 +1,35 @@ +/dts-v1/; +// version: 17 +// last_comp_version: 16 + +// Unknown tag ignored: 0xd0000000, data lng 4 00000001 +/ { + // Unknown tag ignored: 0xc0000000, data lng 0 + prop-int =3D <0x00000001>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000011 + prop-str =3D "abcd"; + // Unknown tag ignored: 0xe0000000, data lng 8 0000001200000012 + // Unknown tag ignored: 0xf0000000, data lng 3 131313 + tst-fdtput { + n2 { + }; + }; + subnode1 { + prop-int =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xc0000000, data lng 0 + }; + subnode2 { + // Unknown tag ignored: 0xd0000000, data lng 4 00000121 + prop-int1 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000122 + prop-int2 =3D <0x00000001 0x00000002>; + subsubnode { + // Unknown tag ignored: 0xd0000000, data lng 4 00000123 + prop-int =3D <0x00000001 0x00000002>; + }; + // Unknown tag ignored: 0xd0000000, data lng 4 00000124 + }; + // Unknown tag ignored: 0xf0000000, data lng 5 1414141414 +}; +// Unknown tag ignored: 0xd0000000, data lng 4 00000002 +// Unknown tag ignored: 0xf0000000, data lng 2 0303 diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.4.expect new file mode 100644 index 0000000..bb40346 --- /dev/null +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect @@ -0,0 +1,34 @@ +/dts-v1/; +// version: 17 +// last_comp_version: 16 + +// Unknown tag ignored: 0xd0000000, data lng 4 00000001 +/ { + // Unknown tag ignored: 0xc0000000, data lng 0 + prop-int =3D <0x00000001>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000011 + // [NOP] + // [NOP] + // [NOP] + // [NOP] + // [NOP] + // [NOP] + subnode1 { + prop-int =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xc0000000, data lng 0 + }; + subnode2 { + // Unknown tag ignored: 0xd0000000, data lng 4 00000121 + prop-int1 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000122 + prop-int2 =3D <0x00000001 0x00000002>; + subsubnode { + // Unknown tag ignored: 0xd0000000, data lng 4 00000123 + prop-int =3D <0x00000001 0x00000002>; + }; + // Unknown tag ignored: 0xd0000000, data lng 4 00000124 + }; + // Unknown tag ignored: 0xf0000000, data lng 5 1414141414 +}; +// Unknown tag ignored: 0xd0000000, data lng 4 00000002 +// Unknown tag ignored: 0xf0000000, data lng 2 0303 diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.5.expect new file mode 100644 index 0000000..5a5e574 --- /dev/null +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect @@ -0,0 +1,32 @@ +/dts-v1/; +// version: 17 +// last_comp_version: 16 + +// Unknown tag ignored: 0xd0000000, data lng 4 00000001 +/ { + // Unknown tag ignored: 0xc0000000, data lng 0 + prop-int =3D <0x00000001>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000011 + prop-str =3D "abcd"; + // Unknown tag ignored: 0xe0000000, data lng 8 0000001200000012 + // Unknown tag ignored: 0xf0000000, data lng 3 131313 + subnode1 { + prop-int =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xc0000000, data lng 0 + }; + subnode2 { + // Unknown tag ignored: 0xd0000000, data lng 4 00000121 + prop-tst-fdtput =3D "Test fdtput"; + prop-int1 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000122 + prop-int2 =3D <0x00000001 0x00000002>; + subsubnode { + // Unknown tag ignored: 0xd0000000, data lng 4 00000123 + prop-int =3D <0x00000001 0x00000002>; + }; + // Unknown tag ignored: 0xd0000000, data lng 4 00000124 + }; + // Unknown tag ignored: 0xf0000000, data lng 5 1414141414 +}; +// Unknown tag ignored: 0xd0000000, data lng 4 00000002 +// Unknown tag ignored: 0xf0000000, data lng 2 0303 diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.6.expect new file mode 100644 index 0000000..f62c1e1 --- /dev/null +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect @@ -0,0 +1,27 @@ +/dts-v1/; +// version: 17 +// last_comp_version: 16 + +// Unknown tag ignored: 0xd0000000, data lng 4 00000001 +/ { + // Unknown tag ignored: 0xc0000000, data lng 0 + prop-int =3D <0x00000001>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000011 + prop-str =3D "abcd"; + // Unknown tag ignored: 0xe0000000, data lng 8 0000001200000012 + // Unknown tag ignored: 0xf0000000, data lng 3 131313 + subnode1 { + prop-int =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xc0000000, data lng 0 + }; + subnode2 { + // Unknown tag ignored: 0xd0000000, data lng 4 00000121 + prop-int1 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000122 + prop-int2 =3D <0x00000001 0x00000002>; + // Unknown tag ignored: 0xd0000000, data lng 4 00000124 + }; + // Unknown tag ignored: 0xf0000000, data lng 5 1414141414 +}; +// Unknown tag ignored: 0xd0000000, data lng 4 00000002 +// Unknown tag ignored: 0xf0000000, data lng 2 0303 --=20 2.52.0 From nobody Tue Feb 10 22:15:48 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B1CE3AEF36; Tue, 10 Feb 2026 17:34:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744887; cv=none; b=p57IP9ZAf93kNPpr7ZvSaiDmH4wXaJ1ANJFwdXtfg6f0PF0hi1amSqru1X6Zb4sQzdMuLhEwYgxWgg8GsQ56hBFPZ4jaZ2DN9YTiyp2QUajkPrK/HWvV3z3op2you9STKOrPhZIKmNtS7a7ipwsDpQwFqdTE2hGIgvxG9VoGd74= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744887; c=relaxed/simple; bh=SYKpQnuz+Y5v0rw8rQaSB4C2BbMeU2JFsVkisVva0+8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uqJnJa0YOfqXei7Ulkoy0E9UZuuFCoYHKluKXY4GLx0ucT+voWZEYR5Te5VH3xfYyrGddcngwRDPnsw0as0HZRdNX9KQDU8P668DpF0mAzIAIUZPqvQhYAUtH3xi2te7BCaXmPHwikSt2HBDpBKuiUlfjuwGoowTKNdGP5NqbTc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=k+c9BIJV; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="k+c9BIJV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 99E1CC8F452; Tue, 10 Feb 2026 17:34:52 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 320ED606C0; Tue, 10 Feb 2026 17:34:44 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D827810B91B35; Tue, 10 Feb 2026 18:34:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744883; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=iVTtB/uyZ3EoE86/WiaQu00UBhCqGXt3XbnwrkN05Go=; b=k+c9BIJVL37lclpgqPXKWbDwD0aoKcnnh9S9QOMiuVRGgbDMpuHC7EFTKQ6PuYELEpn3Ux vb+/Ys5r14GDuPSp5wOdgC/SdqV1yFKJT5AhFtYfrH3urMLzMTw3WfYBtu1pJZ4z13YnMQ oP2hZdOsg23OgRGXkyWf7XcEuPTMXJyFbKgRGtHKxdQgPNJ7A0C3QQunC+yClH0ehM90gu ddEPtVfd/+ZDxUF/oFtEM66vUId4r1tz5hO9UvwGqEfHqL8wc8L58hhhw+Jnos/KeiFcTG Iilf9Lb7Px3ks1064pxEQ7G7ORDE6jj6WY0B0zapDoJHfiY7swaj+2lyp+Ru0w== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 15/15] Introduce v18 dtb version Date: Tue, 10 Feb 2026 18:33:43 +0100 Message-ID: <20260210173349.636766-16-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" This v18 version will add support for - Structured tags. Those tags value definition will allow old libfdt, dtc and other tools to skip unknown tags if encountered in future dtb version. - dt_flags header field. For now this flag field is set to 0. It is a placeholder for future dtb version and could be used to store some dtb related information such as the kind of dtb. - last_comp_version_w header field. This field is similar to last_comp_version but for writing. It contains the lowest version of the devicetree data structure with which the version used can safely perform modifications (taking into account following rules related to unknown tags). If this lowest version is greater than the last known supported version, modification are simply forbidden and lead to a FDT_ERR_BADVERSION error. For modification, when an unknown tag that can be skipped is involved and last_comp_version_w allows modifications, the following rules applies: - When a property is modified, tags related to this property are removed and the dtb version is downgraded. - When a property is removed, tags related to this property are obviously removed. The dtb version is kept unchanged. - When a property or a node is added, obviously no unknown tags are added and the dtb version is kept unchanged. - When a node is removed, tags related to this node are obviously removed. The dtb version is kept unchanged. - Adding, removing or modifying a property is not considered as a node modification and so, those operations have no impacts on unknown tags related to the node. Those node related tags are kept unchanged. - The only modification considered as a node modification is setting its name. We consider that this operation has no impact on tags related to the node. Here also, those node related tags and the dtb version are kept unchanged. - Global (dtb related) unknown tags are kept unchanged regardless the modification done. In all cases, if unknown tags are not involved in a modification, the dtb version is not downgraded when the modification is node. Compared to previous version, it is worth noting that the dtb is not downgrade for all modification but only when unknown tags are removed due a property modification. Signed-off-by: Herve Codina --- dtc.h | 2 +- fdtdump.c | 8 +++- flattree.c | 37 +++++++++++++++---- libfdt/fdt.h | 5 +++ libfdt/fdt_rw.c | 20 +++++++--- libfdt/fdt_sw.c | 3 ++ libfdt/libfdt.h | 7 +++- pylibfdt/libfdt.i | 18 +++++++++ tests/dumptrees.c | 3 +- tests/pylibfdt_tests.py | 10 +++-- tests/run_tests.sh | 26 +++++++++---- tests/testdata.h | 1 + tests/testutils.c | 2 +- tests/trees.S | 29 +++++++++++++-- ...own_tags_can_skip.fdtput.test.dtb.0.expect | 1 + ...own_tags_can_skip.fdtput.test.dtb.1.expect | 3 +- ...own_tags_can_skip.fdtput.test.dtb.2.expect | 3 +- ...own_tags_can_skip.fdtput.test.dtb.3.expect | 3 +- ...own_tags_can_skip.fdtput.test.dtb.4.expect | 3 +- ...own_tags_can_skip.fdtput.test.dtb.5.expect | 3 +- ...own_tags_can_skip.fdtput.test.dtb.6.expect | 3 +- 21 files changed, 152 insertions(+), 38 deletions(-) diff --git a/dtc.h b/dtc.h index 473552e..f0c2cde 100644 --- a/dtc.h +++ b/dtc.h @@ -29,7 +29,7 @@ #define debug(...) #endif =20 -#define DEFAULT_FDT_VERSION 17 +#define DEFAULT_FDT_VERSION 18 =20 /* * Command line options diff --git a/fdtdump.c b/fdtdump.c index eb8cda9..22ae798 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -18,7 +18,7 @@ #include "util.h" =20 #define FDT_MAGIC_SIZE 4 -#define MAX_VERSION 17U +#define MAX_VERSION 18U =20 #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #define PALIGN(p, a) ((void *)(ALIGN((uintptr_t)(p), (a)))) @@ -86,6 +86,12 @@ static void dump_blob(void *blob, bool debug, int dump_u= nknown) if (version >=3D 17) printf("// size_dt_struct:\t0x%"PRIx32"\n", fdt32_to_cpu(bph->size_dt_struct)); + if (version >=3D 18) { + printf("// dt_flags:\t\t0x%"PRIx32"\n", + fdt32_to_cpu(bph->dt_flags)); + printf("// last_comp_version_w:\t%"PRIu32"\n", + fdt32_to_cpu(bph->last_comp_version_w)); + } printf("\n"); =20 for (i =3D 0; ; i++) { diff --git a/flattree.c b/flattree.c index 23813e2..ffd3cc5 100644 --- a/flattree.c +++ b/flattree.c @@ -13,23 +13,29 @@ #define FTF_STRTABSIZE 0x10 #define FTF_STRUCTSIZE 0x20 #define FTF_NOPS 0x40 +#define FTF_DTFLAGS 0x80 +#define FTF_LCVERSW 0x100 =20 static struct version_info { int version; int last_comp_version; + int last_comp_version_w; int hdr_size; int flags; } version_table[] =3D { - {1, 1, FDT_V1_SIZE, + {1, 1, 0, FDT_V1_SIZE, FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS}, - {2, 1, FDT_V2_SIZE, + {2, 1, 0, FDT_V2_SIZE, FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID}, - {3, 1, FDT_V3_SIZE, + {3, 1, 0, FDT_V3_SIZE, FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE}, - {16, 16, FDT_V3_SIZE, + {16, 16, 0, FDT_V3_SIZE, FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS}, - {17, 16, FDT_V17_SIZE, + {17, 16, 0, FDT_V17_SIZE, FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS}, + {18, 16, 17, FDT_V18_SIZE, + FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS|FTF_DTFLAGS| + FTF_LCVERSW}, }; =20 struct emitter { @@ -314,7 +320,7 @@ static struct data flatten_reserve_list(struct reserve_= info *reservelist, static void make_fdt_header(struct fdt_header *fdt, struct version_info *vi, int reservesize, int dtsize, int strsize, - int boot_cpuid_phys) + int boot_cpuid_phys, uint32_t dt_flags) { int reserve_off; =20 @@ -341,6 +347,10 @@ static void make_fdt_header(struct fdt_header *fdt, fdt->size_dt_strings =3D cpu_to_fdt32(strsize); if (vi->flags & FTF_STRUCTSIZE) fdt->size_dt_struct =3D cpu_to_fdt32(dtsize); + if (vi->flags & FTF_DTFLAGS) + fdt->dt_flags =3D cpu_to_fdt32(dt_flags); + if (vi->flags & FTF_LCVERSW) + fdt->last_comp_version_w =3D cpu_to_fdt32(vi->last_comp_version_w); } =20 void dt_to_blob(FILE *f, struct dt_info *dti, int version) @@ -368,7 +378,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int versi= on) =20 /* Make header */ make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, - dti->boot_cpuid_phys); + dti->boot_cpuid_phys, 0); =20 /* * If the user asked for more space than is used, adjust the totalsize. @@ -499,6 +509,16 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int versi= on) symprefix, symprefix); } =20 + if (vi->flags & FTF_DTFLAGS) { + fprintf(f, "\t/* dt_flags */\n"); + asm_emit_cell(f, 0); + } + + if (vi->flags & FTF_LCVERSW) { + fprintf(f, "\t/* last_comp_version_w */\n"); + asm_emit_cell(f, vi->last_comp_version_w); + } + /* * Reserve map entries. * Align the reserve map to a doubleword boundary. @@ -955,6 +975,9 @@ struct dt_info *dt_from_blob(const char *fname) flags |=3D FTF_NOPS; } =20 + if (version >=3D 18) + flags |=3D FTF_DTFLAGS | FTF_LCVERSW; + inbuf_init(&memresvbuf, blob + off_mem_rsvmap, blob + totalsize); inbuf_init(&dtbuf, blob + off_dt, blob + totalsize); diff --git a/libfdt/fdt.h b/libfdt/fdt.h index 2e07599..56aa75b 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -26,6 +26,10 @@ struct fdt_header { =20 /* version 17 fields below */ fdt32_t size_dt_struct; /* size of the structure block */ + + /* version 18 fields below */ + fdt32_t dt_flags; /* Ored value of FDT_FLAG_XXXX */ + fdt32_t last_comp_version_w; /* last compatible version for writing */ }; =20 struct fdt_reserve_entry { @@ -85,5 +89,6 @@ struct fdt_property { #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) #define FDT_V16_SIZE FDT_V3_SIZE #define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) +#define FDT_V18_SIZE (FDT_V17_SIZE + 2 * sizeof(fdt32_t)) =20 #endif /* FDT_H */ diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index a8f53b4..0a4a03f 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -34,13 +34,17 @@ static int fdt_rw_probe_(void *fdt) return 0; FDT_RO_PROBE(fdt); =20 - if (!can_assume(LATEST) && fdt_version(fdt) < 17) - return -FDT_ERR_BADVERSION; + if (!can_assume(LATEST)) { + if (fdt_version(fdt) < 17) + return -FDT_ERR_BADVERSION; + else if (fdt_version(fdt) >=3D 18 && + fdt_last_comp_version_w(fdt) > FDT_LAST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + } if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), fdt_size_dt_struct(fdt))) return -FDT_ERR_BADLAYOUT; =20 - fdt_downgrade_version(fdt); return 0; } =20 @@ -582,7 +586,11 @@ int fdt_open_into(const void *fdt, void *buf, int bufs= ize) err =3D fdt_move(fdt, buf, bufsize); if (err) return err; - fdt_set_version(buf, 17); + if (can_assume(LATEST) || fdt_version(fdt) < 18) { + fdt_set_version(buf, 18); + fdt_set_dt_flags(buf, 0); + fdt_set_last_comp_version_w(buf, 17); + } fdt_set_size_dt_struct(buf, struct_size); fdt_set_totalsize(buf, bufsize); return 0; @@ -611,8 +619,10 @@ int fdt_open_into(const void *fdt, void *buf, int bufs= ize) =20 fdt_set_magic(buf, FDT_MAGIC); fdt_set_totalsize(buf, bufsize); - fdt_set_version(buf, 17); + fdt_set_version(buf, 18); fdt_set_last_comp_version(buf, 16); + fdt_set_dt_flags(buf, 0); + fdt_set_last_comp_version_w(buf, 17); fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt)); =20 return 0; diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c index 4c569ee..10da0d6 100644 --- a/libfdt/fdt_sw.c +++ b/libfdt/fdt_sw.c @@ -137,6 +137,9 @@ int fdt_create_with_flags(void *buf, int bufsize, uint3= 2_t flags) fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); fdt_set_off_dt_strings(fdt, 0); =20 + fdt_set_dt_flags(fdt, 0); + fdt_set_last_comp_version_w(fdt, FDT_LAST_COMPATIBLE_VERSION_W); + return 0; } =20 diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index 7a10f66..71c7de5 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -15,7 +15,8 @@ extern "C" { =20 #define FDT_FIRST_SUPPORTED_VERSION 0x02 #define FDT_LAST_COMPATIBLE_VERSION 0x10 -#define FDT_LAST_SUPPORTED_VERSION 0x11 +#define FDT_LAST_COMPATIBLE_VERSION_W 0x11 +#define FDT_LAST_SUPPORTED_VERSION 0x12 =20 /* Error codes: informative error codes */ #define FDT_ERR_NOTFOUND 1 @@ -284,6 +285,8 @@ int fdt_next_subnode(const void *fdt, int offset); #define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) #define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) +#define fdt_dt_flags(fdt) (fdt_get_header(fdt, dt_flags)) +#define fdt_last_comp_version_w(fdt) (fdt_get_header(fdt, last_comp_versio= n_w)) =20 #define fdt_set_hdr_(name) \ static inline void fdt_set_##name(void *fdt, uint32_t val) \ @@ -301,6 +304,8 @@ fdt_set_hdr_(last_comp_version) fdt_set_hdr_(boot_cpuid_phys) fdt_set_hdr_(size_dt_strings) fdt_set_hdr_(size_dt_struct) +fdt_set_hdr_(dt_flags) +fdt_set_hdr_(last_comp_version_w) #undef fdt_set_hdr_ =20 /** diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i index 1f9c047..90966bd 100644 --- a/pylibfdt/libfdt.i +++ b/pylibfdt/libfdt.i @@ -281,6 +281,22 @@ class FdtRo(object): """ return fdt_size_dt_struct(self._fdt) =20 + def dt_flags(self): + """Return flags from the header + + Returns: + flags value from the header + """ + return fdt_dt_flags(self._fdt) + + def last_comp_version_w(self): + """Return the last compatible version for writing of the device tr= ee + + Returns: + Last compatible version number for writing of the device tree + """ + return fdt_last_comp_version_w(self._fdt) + def num_mem_rsv(self, quiet=3D()): """Return the number of memory reserve-map records =20 @@ -1215,6 +1231,8 @@ uint32_t fdt_last_comp_version(const void *fdt); uint32_t fdt_boot_cpuid_phys(const void *fdt); uint32_t fdt_size_dt_strings(const void *fdt); uint32_t fdt_size_dt_struct(const void *fdt); +uint32_t fdt_dt_flags(const void *fdt); +uint32_t fdt_last_comp_version_w(const void *fdt); =20 int fdt_property_string(void *fdt, const char *name, const char *val); int fdt_property_cell(void *fdt, const char *name, uint32_t val); diff --git a/tests/dumptrees.c b/tests/dumptrees.c index 4732fff..c05d216 100644 --- a/tests/dumptrees.c +++ b/tests/dumptrees.c @@ -27,7 +27,8 @@ static struct { TREE(two_roots), TREE(named_root), TREE(unknown_tags_can_skip), - TREE(unknown_tags_no_skip) + TREE(unknown_tags_no_skip), + TREE(last_comp_version_w_future) }; =20 #define NUM_TREES (sizeof(trees) / sizeof(trees[0])) diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py index a4f73ed..72c98c5 100644 --- a/tests/pylibfdt_tests.py +++ b/tests/pylibfdt_tests.py @@ -285,14 +285,16 @@ class PyLibfdtBasicTests(unittest.TestCase): """Test that we can access the header values""" self.assertEqual(self.fdt.magic(), 0xd00dfeed) self.assertEqual(self.fdt.totalsize(), len(self.fdt._fdt)) - self.assertEqual(self.fdt.off_dt_struct(), 88) - self.assertEqual(self.fdt.off_dt_strings(), 652) - self.assertEqual(self.fdt.off_mem_rsvmap(), 40) - self.assertEqual(self.fdt.version(), 17) + self.assertEqual(self.fdt.off_dt_struct(), 96) + self.assertEqual(self.fdt.off_dt_strings(), 660) + self.assertEqual(self.fdt.off_mem_rsvmap(), 48) + self.assertEqual(self.fdt.version(), 18) self.assertEqual(self.fdt.last_comp_version(), 16) self.assertEqual(self.fdt.boot_cpuid_phys(), 0) self.assertEqual(self.fdt.size_dt_strings(), 105) self.assertEqual(self.fdt.size_dt_struct(), 564) + self.assertEqual(self.fdt.dt_flags(), 0) + self.assertEqual(self.fdt.last_comp_version_w(), 17) =20 def testPack(self): """Test that we can pack the tree after deleting something""" diff --git a/tests/run_tests.sh b/tests/run_tests.sh index e88f641..1253b88 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -576,7 +576,8 @@ libfdt_tests () { run_test dtbs_equal_ordered cell-overflow.test.dtb cell-overflow-resul= ts.test.dtb =20 # check full tests - for good in test_tree1.dtb unknown_tags_can_skip.dtb; do + for good in test_tree1.dtb unknown_tags_can_skip.dtb \ + last_comp_version_w_future.dtb; do run_test check_full $good done for bad in truncated_property.dtb truncated_string.dtb \ @@ -1044,32 +1045,41 @@ fdtput_tests () { =20 # TODO: Add tests for verbose mode? =20 + # Not allowed to modify a dtb due to last_comp_version_w + # FDT_ERR_BADVERSION error code is returned + dtb=3Dlast_comp_version_w_future.fdtput.test.dtb + cp last_comp_version_w_future.dtb $dtb + run_wrap_error_test $DTPUT $dtb /subnode prop-int -tu 123 + run_wrap_error_test $DTPUT $dtb -d /subnode prop-int + run_wrap_error_test $DTPUT $dtb -c /new-node + run_wrap_error_test $DTPUT $dtb -r /subnode + # Modify a dtb containing some "unknown" tags that can be skipped dtb=3Dunknown_tags_can_skip.fdtput.test.dtb cp unknown_tags_can_skip.dtb $dtb base_run_test wrap_fdtdump $dtb $dtb.0.out # Remove unneeded header fields (keep those related to versions) - sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.0.out + sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.0.out base_run_test check_diff $dtb.0.out "$SRCDIR/$dtb.0.expect" =20 run_fdtput_test "vwxyz" $dtb / prop-str -ts "vwxyz" base_run_test wrap_fdtdump $dtb $dtb.1.out # Remove unneeded header fields (keep those related to versions) - sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.1.out + sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.1.out base_run_test check_diff $dtb.1.out "$SRCDIR/$dtb.1.expect" =20 cp unknown_tags_can_skip.dtb $dtb run_wrap_test $DTPUT $dtb -c /tst-fdtput base_run_test wrap_fdtdump $dtb $dtb.2.out # Remove unneeded header fields (keep those related to versions) - sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.2.out + sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.2.out base_run_test check_diff $dtb.2.out "$SRCDIR/$dtb.2.expect" run_wrap_test $DTPUT $dtb -c /tst-fdtput/n1 /tst-fdtput/n2 /tst-fdtput= /n3 run_wrap_test $DTPUT $dtb -r /tst-fdtput/n1 /tst-fdtput/n3 run_fdtget_test "n2" $dtb -l /tst-fdtput base_run_test wrap_fdtdump $dtb $dtb.3.out # Remove unneeded header fields (keep those related to versions) - sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.3.out + sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.3.out base_run_test check_diff $dtb.3.out "$SRCDIR/$dtb.3.expect" =20 cp unknown_tags_can_skip.dtb $dtb @@ -1077,21 +1087,21 @@ fdtput_tests () { run_fdtget_test "prop-int" $dtb -p / base_run_test wrap_fdtdump $dtb $dtb.4.out # Remove unneeded header fields (keep those related to versions) - sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.4.out + sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.4.out base_run_test check_diff $dtb.4.out "$SRCDIR/$dtb.4.expect" =20 cp unknown_tags_can_skip.dtb $dtb run_wrap_test $DTPUT $dtb /subnode2 prop-tst-fdtput -ts "Test fdtput" base_run_test wrap_fdtdump $dtb $dtb.5.out # Remove unneeded header fields (keep those related to versions) - sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.5.out + sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.5.out base_run_test check_diff $dtb.5.out "$SRCDIR/$dtb.5.expect" =20 cp unknown_tags_can_skip.dtb $dtb run_wrap_test $DTPUT $dtb -r /subnode2/subsubnode base_run_test wrap_fdtdump $dtb $dtb.6.out # Remove unneeded header fields (keep those related to versions) - sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.6.out + sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.6.out base_run_test check_diff $dtb.6.out "$SRCDIR/$dtb.6.expect" } =20 diff --git a/tests/testdata.h b/tests/testdata.h index aef04ab..26c7c18 100644 --- a/tests/testdata.h +++ b/tests/testdata.h @@ -59,4 +59,5 @@ extern struct fdt_header two_roots; extern struct fdt_header named_root; extern struct fdt_header unknown_tags_can_skip; extern struct fdt_header unknown_tags_no_skip; +extern struct fdt_header last_comp_version_w_future; #endif /* ! __ASSEMBLER__ */ diff --git a/tests/testutils.c b/tests/testutils.c index 54da2e4..728d89c 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -344,7 +344,7 @@ void *open_blob_rw(const void *blob) { int err; void *buf; - int newsize =3D fdt_totalsize(blob) + 8; + int newsize =3D fdt_totalsize(blob) + 8 + 2 * 4; =20 buf =3D xmalloc(newsize); err =3D fdt_open_into(blob, buf, newsize); diff --git a/tests/trees.S b/tests/trees.S index 221c9fd..73b2d0b 100644 --- a/tests/trees.S +++ b/tests/trees.S @@ -8,7 +8,7 @@ .byte (\val) & 0xff .endm =20 - .macro treehdr_vers tree vers last_comp_vers + .macro treehdr_vers tree vers last_comp_vers last_comp_vers_w .balign 8 .globl \tree \tree : @@ -22,10 +22,12 @@ fdtlong 0 fdtlong (\tree\()_strings_end - \tree\()_strings) fdtlong (\tree\()_struct_end - \tree\()_struct) + fdtlong 0 + fdtlong \last_comp_vers_w .endm =20 .macro treehdr tree - treehdr_vers \tree 0x11 0x10 + treehdr_vers \tree 0x12 0x10 0x11 .endm =20 .macro rsvmape addrh, addrl, lenh, lenl @@ -334,7 +336,7 @@ named_root_end: * Use a really future dtb version to check version downgrade on * modification. */ - treehdr_vers unknown_tags_can_skip 0xffffffff 0x10 + treehdr_vers unknown_tags_can_skip 0xffffffff 0x10 0x11 empty_rsvmap unknown_tags_can_skip =20 unknown_tags_can_skip_struct: @@ -438,3 +440,24 @@ unknown_tags_no_skip_strings: unknown_tags_no_skip_strings_end: =20 unknown_tags_no_skip_end: + + + /* Tree with last_comp_version_w set to avoid any modifications */ + treehdr_vers last_comp_version_w_future 0xffffffff 0x10 0xffffffff + empty_rsvmap last_comp_version_w_future + +last_comp_version_w_future_struct: + beginn "" + propu64 last_comp_version_w_future, prop_int, 1, 2 + beginn "subnode" + propu64 last_comp_version_w_future, prop_int, 1, 2 + endn + endn + fdtlong FDT_END +last_comp_version_w_future_struct_end: + +last_comp_version_w_future_strings: + string last_comp_version_w_future, prop_int, "prop-int" +last_comp_version_w_future_strings_end: + +last_comp_version_w_future_end: diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.0.expect index b611a87..2de0fe4 100644 --- a/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect @@ -1,6 +1,7 @@ /dts-v1/; // version: 4294967295 // last_comp_version: 16 +// last_comp_version_w: 17 =20 // Unknown tag ignored: 0xd0000000, data lng 4 00000001 / { diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.1.expect index 8b331f3..aac87c7 100644 --- a/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect @@ -1,6 +1,7 @@ /dts-v1/; -// version: 17 +// version: 18 // last_comp_version: 16 +// last_comp_version_w: 17 =20 // Unknown tag ignored: 0xd0000000, data lng 4 00000001 / { diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.2.expect index e2dfe91..ef42222 100644 --- a/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect @@ -1,6 +1,7 @@ /dts-v1/; -// version: 17 +// version: 4294967295 // last_comp_version: 16 +// last_comp_version_w: 17 =20 // Unknown tag ignored: 0xd0000000, data lng 4 00000001 / { diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.3.expect index d12ce6f..1c902dc 100644 --- a/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect @@ -1,6 +1,7 @@ /dts-v1/; -// version: 17 +// version: 4294967295 // last_comp_version: 16 +// last_comp_version_w: 17 =20 // Unknown tag ignored: 0xd0000000, data lng 4 00000001 / { diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.4.expect index bb40346..b0630e6 100644 --- a/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect @@ -1,6 +1,7 @@ /dts-v1/; -// version: 17 +// version: 4294967295 // last_comp_version: 16 +// last_comp_version_w: 17 =20 // Unknown tag ignored: 0xd0000000, data lng 4 00000001 / { diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.5.expect index 5a5e574..2475cd3 100644 --- a/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect @@ -1,6 +1,7 @@ /dts-v1/; -// version: 17 +// version: 4294967295 // last_comp_version: 16 +// last_comp_version_w: 17 =20 // Unknown tag ignored: 0xd0000000, data lng 4 00000001 / { diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.6.expect index f62c1e1..7485b9f 100644 --- a/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect @@ -1,6 +1,7 @@ /dts-v1/; -// version: 17 +// version: 4294967295 // last_comp_version: 16 +// last_comp_version_w: 17 =20 // Unknown tag ignored: 0xd0000000, data lng 4 00000001 / { --=20 2.52.0