mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v4 00/11] Add FIT image overlay support
@ 2025-07-29 15:34 Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 01/11] FIT: fix missing free in fit_open error path Marco Felsch
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch, Ahmad Fatoum

Hi,

this series add the support to load FIT image supplied devicetree overlays.

The overlay loading wasn't coupled to bootm due to the following
reasons:
 - Users can add their own overlay filter
 - By making use of the common overlay handling we can specifiy a
   different/separate FIT image which provides only overlays.
 - It should be possible to apply FIT image overlay to the barebox
   live-tree (not implemented yet).

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
Changes in v4:
- Link to v3: https://lore.barebox.org/20240703-v2024-05-0-topic-fit-overlay-v3-0-c1fd766fd31d@pengutronix.de
- resolve possible filename links to make caching more robust

Changes in v3:
- Link to v2: https://lore.barebox.org/barebox/20240613125818.30499-1-m.felsch@pengutronix.de/
- drop of.overlay.fitconfigpattern usage and make use of an match-fn
  instead
- fit_get_handle(): make use of strcmp
- open_fits: make it static
- fit_close(): use free unconditional

Changes in v2:
- Link to v1: https://lore.pengutronix.de/barebox/20240322164953.1772129-1-m.felsch@pengutronix.de/
- add caching to improve the overlay load time if the same FIT, which
  provides the overlays, provides the kernel, of, initrd.

---
Marco Felsch (11):
      FIT: fix missing free in fit_open error path
      FIT: fit_open_configuration: add match function support
      of: overlay: make the pattern match function more generic
      of: overlay: make search dir more generic
      of: overlay: refactor of_overlay_global_fixup
      FIT: make fit_config_verify_signature public
      of: overlay: add FIT image overlay support
      of: overlay: replace filename with an more unique name
      FIT: fit_open: make filename handling more robust
      FIT: fit_open: save the filename
      FIT: add support to cache opened fit images

 Documentation/user/devicetree.rst |  27 ++---
 common/bootm.c                    |  13 ++-
 common/image-fit.c                |  76 +++++++++++--
 drivers/of/overlay.c              | 217 ++++++++++++++++++++++++++++++--------
 include/image-fit.h               |  10 +-
 include/of.h                      |   3 +-
 6 files changed, 281 insertions(+), 65 deletions(-)
---
base-commit: 89bf1fcc998fc5fea0ce613d9930dd9ee39c0fb2
change-id: 20240703-v2024-05-0-topic-fit-overlay-76d5176c1d4e

Best regards,
-- 
Marco Felsch <m.felsch@pengutronix.de>




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 01/11] FIT: fix missing free in fit_open error path
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 02/11] FIT: fit_open_configuration: add match function support Marco Felsch
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch, Ahmad Fatoum

Free the handle if read_file_2() fails.

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 common/image-fit.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/common/image-fit.c b/common/image-fit.c
index 5006394eb7bbd0873a37a0102d5a0d89ea7c6b9f..4d5c5bfe12472af85b26cd1ee93e7c99316b283c 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -977,6 +977,7 @@ struct fit_handle *fit_open(const char *filename, bool verbose,
 			  max_size);
 	if (ret && ret != -EFBIG) {
 		pr_err("unable to read %s: %pe\n", filename, ERR_PTR(ret));
+		free(handle);
 		return ERR_PTR(ret);
 	}
 

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 02/11] FIT: fit_open_configuration: add match function support
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 01/11] FIT: fix missing free in fit_open error path Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 03/11] of: overlay: make the pattern match function more generic Marco Felsch
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

The FIT spec is not very specific and was growing over the past years,
e.g. according U-Boot (doc/usage/fit/source_file_format.rst) either a
"kernel" or "firmware" property is mandatory whereas the fit-overlay
example (doc/usage/fit/overlay-fdt-boot.rst) doesn't fulfil this
requirement. Instead it allows nodes which contain only a "fdt"
property.

This inconsistency makes it hard to detect the purpose of a
configuration node. So far we have three different configuration nodes

- bootable nodes (the usual use-case):

|	config-0 {
|		compatible = "machine-compatible";
|		kernel = "kernel-img-name";
|		fdt = "fdt-img-name";
|	}

- firmware only nodes like (doc/usage/fit/sec_firmware_ppa.rst):

|	config-1 {
|		description = "PPA Secure firmware";
|		firmware = "firmware@1";
|		loadables = "trustedOS@1", "fuse_scr";
|	};

- overlay only nodes:

|	config-2 {
|		fdt = "fdt-overlay-img-name";
|	}

This commit adds an optional match function which can be passed to the
fit_open_configuration() to sort out config nodes which are not
interessting, e.g. the bootm code is only interested in config nodes
which do provide a "kernel" image.

This new match function gets called if no explicit configuration node
name was specified.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 common/bootm.c      | 13 ++++++++++++-
 common/image-fit.c  | 22 ++++++++++++++++------
 include/image-fit.h |  4 +++-
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/common/bootm.c b/common/bootm.c
index 95211011fe8bf5f52ce3155de419bc9b09ff2228..7f37c74eb41e5c7a89aa4038bae46cee5f056f5f 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -609,6 +609,16 @@ static int bootm_open_os_uimage(struct image_data *data)
 	return 0;
 }
 
+static bool bootm_fit_config_valid(struct fit_handle *fit,
+				   struct device_node *config)
+{
+	/*
+	 * Consider only FIT configurations which do provide a loadable kernel
+	 * image.
+	 */
+	return !!fit_has_image(fit, config, "kernel");
+}
+
 static int bootm_open_fit(struct image_data *data)
 {
 	struct fit_handle *fit;
@@ -634,7 +644,8 @@ static int bootm_open_fit(struct image_data *data)
 	data->os_fit = fit;
 
 	data->fit_config = fit_open_configuration(data->os_fit,
-						  data->os_part);
+						  data->os_part,
+						  bootm_fit_config_valid);
 	if (IS_ERR(data->fit_config)) {
 		pr_err("Cannot open FIT image configuration '%s'\n",
 		       data->os_part ? data->os_part : "default");
diff --git a/common/image-fit.c b/common/image-fit.c
index 4d5c5bfe12472af85b26cd1ee93e7c99316b283c..0fc3b2e4aa7217a47710ef613426456420e81324 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -782,7 +782,9 @@ static int fit_fdt_is_compatible(struct fit_handle *handle,
 
 static int fit_find_compatible_unit(struct fit_handle *handle,
 				    struct device_node *conf_node,
-				    const char **unit)
+				    const char **unit,
+				    bool (*config_node_valid)(struct fit_handle *handle,
+							      struct device_node *config))
 {
 	struct device_node *child = NULL;
 	struct device_node *barebox_root;
@@ -799,7 +801,12 @@ static int fit_find_compatible_unit(struct fit_handle *handle,
 		return -ENOENT;
 
 	for_each_child_of_node(conf_node, child) {
-		int score = of_device_is_compatible(child, machine);
+		int score;
+
+		if (config_node_valid && !config_node_valid(handle, child))
+			continue;
+
+		score = of_device_is_compatible(child, machine);
 
 		if (!score)
 			score = fit_fdt_is_compatible(handle, child, machine);
@@ -857,7 +864,9 @@ static int fit_find_last_unit(struct fit_handle *handle,
  * Return: If successful a pointer to a valid configuration node,
  *         otherwise a ERR_PTR()
  */
-void *fit_open_configuration(struct fit_handle *handle, const char *name)
+void *fit_open_configuration(struct fit_handle *handle, const char *name,
+			     bool (*match_valid)(struct fit_handle *handle,
+						 struct device_node *config))
 {
 	struct device_node *conf_node = handle->configurations;
 	const char *unit, *desc = "(no description)";
@@ -869,7 +878,8 @@ void *fit_open_configuration(struct fit_handle *handle, const char *name)
 	if (name) {
 		unit = name;
 	} else {
-		ret = fit_find_compatible_unit(handle, conf_node, &unit);
+		ret = fit_find_compatible_unit(handle, conf_node, &unit,
+					       match_valid);
 		if (ret) {
 			pr_info("Couldn't get a valid configuration. Aborting.\n");
 			return ERR_PTR(ret);
@@ -1044,12 +1054,12 @@ static int fuzz_fit(const u8 *data, size_t size)
 	if (ret)
 		goto out;
 
-	config = fit_open_configuration(&handle, NULL);
+	config = fit_open_configuration(&handle, NULL, NULL);
 	if (IS_ERR(config)) {
 		ret = fit_find_last_unit(&handle, &unit);
 		if (ret)
 			goto out;
-		config = fit_open_configuration(&handle, unit);
+		config = fit_open_configuration(&handle, unit, NULL);
 	}
 	if (IS_ERR(config)) {
 		ret = PTR_ERR(config);
diff --git a/include/image-fit.h b/include/image-fit.h
index 0b8e94bf46357a1fe01ef90cd8b0fca0c41641c3..416f1f2c1896949d2bcb7ab1a31f1aa6b5682edf 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -26,7 +26,9 @@ struct fit_handle *fit_open(const char *filename, bool verbose,
 			    enum bootm_verify verify, loff_t max_size);
 struct fit_handle *fit_open_buf(const void *buf, size_t len, bool verbose,
 				enum bootm_verify verify);
-void *fit_open_configuration(struct fit_handle *handle, const char *name);
+void *fit_open_configuration(struct fit_handle *handle, const char *name,
+			     bool (*match_valid)(struct fit_handle *handle,
+						 struct device_node *config));
 int fit_has_image(struct fit_handle *handle, void *configuration,
 		  const char *name);
 int fit_open_image(struct fit_handle *handle, void *configuration,

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 03/11] of: overlay: make the pattern match function more generic
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 01/11] FIT: fix missing free in fit_open error path Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 02/11] FIT: fit_open_configuration: add match function support Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 04/11] of: overlay: make search dir " Marco Felsch
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

The current overlay mechanism can handle files only, so filepattern was
an obvious name.

Drop the "file" prefix to prepare the codebase to handle overlays
supplied via a FIT images as well.

Keep the backward compatibility by still providing the filepattern
filter and the global of.overlay.filepattern variable, but mark them as
deprecated.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 Documentation/user/devicetree.rst |  6 +++---
 drivers/of/overlay.c              | 37 ++++++++++++++++++++++++++-----------
 2 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/Documentation/user/devicetree.rst b/Documentation/user/devicetree.rst
index ea2945ab2b564a10a780ba0055daa37ed0c85581..ef04e14f7c0dde579493425073f1ee01395f0d8c 100644
--- a/Documentation/user/devicetree.rst
+++ b/Documentation/user/devicetree.rst
@@ -118,15 +118,15 @@ the kernel. The behaviour is controlled by different variables:
   these compatibles will be applied. When this list is empty then all overlays
   will be applied. Overlays that don't have a compatible are considered being
   always compatible.
-``global.of.overlay.filepattern``
+``global.of.overlay.pattern``
   This is a space separated list of file patterns. An overlay is only applied
   when its filename matches one of the patterns. The patterns can contain
   ``*`` and ``?`` as wildcards. The default is ``*`` which means all files are
   applied.
 ``global.of.overlay.filter``
   This is a space separated list of filters to apply. There are two generic filters:
-  ``filepattern`` matches ``global.of.overlay.filepattern`` above, ``compatible`` matches
-  ``global.of.overlay.compatible`` above. The default is ``filepattern compatible``
+  ``pattern`` matches ``global.of.overlay.pattern`` above, ``compatible`` matches
+  ``global.of.overlay.compatible`` above. The default is ``pattern compatible``
   which means the two generic filters are active. This list may be replaced or
   supplemented by board specific filters.
 
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 6944dd4a744de909c89622322c99b81fc046e43b..a63cca1b47e74615d4453a27a55fb15d1f706fae 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -407,7 +407,7 @@ int of_register_overlay(struct device_node *overlay)
 	return of_register_fixup(of_overlay_fixup, overlay);
 }
 
-static char *of_overlay_filepattern;
+static char *of_overlay_pattern;
 static char *of_overlay_dir;
 static char *of_overlay_basedir;
 
@@ -504,10 +504,10 @@ int of_overlay_register_filter(struct of_overlay_filter *filter)
 }
 
 /**
- * of_overlay_filter_filename - A filter that matches on the filename of
+ * of_overlay_filter_pattern - A filter that matches on the filename or
  *                                an overlay
  * @f: The filter
- * @filename: The filename of the overlay
+ * @pattern: The filename of the overlay
  *
  * This filter matches when the filename matches one of the patterns given
  * in global.of.overlay.filepattern. global.of.overlay.filepattern shall
@@ -515,20 +515,20 @@ int of_overlay_register_filter(struct of_overlay_filter *filter)
  *
  * @return: True when the overlay shall be applied, false otherwise.
  */
-static bool of_overlay_filter_filename(struct of_overlay_filter *f,
-				       const char *filename)
+static bool of_overlay_filter_pattern(struct of_overlay_filter *f,
+				      const char *pattern)
 {
 	char *p, *path, *n;
 	int ret;
 	bool apply;
 
-	p = path = strdup(of_overlay_filepattern);
+	p = path = strdup(of_overlay_pattern);
 
 	while ((n = strsep_unescaped(&p, " ", NULL))) {
 		if (!*n)
 			continue;
 
-		ret = fnmatch(n, filename, 0);
+		ret = fnmatch(n, pattern, 0);
 
 		if (!ret) {
 			apply = true;
@@ -543,6 +543,18 @@ static bool of_overlay_filter_filename(struct of_overlay_filter *f,
 	return apply;
 }
 
+static struct of_overlay_filter of_overlay_pattern_filter = {
+	.name = "pattern",
+	.filter_filename = of_overlay_filter_pattern,
+};
+
+static bool of_overlay_filter_filename(struct of_overlay_filter *f,
+				       const char *filename)
+{
+	pr_warn("'filepattern' filter is marked as deprecated, convert to 'pattern' filter\n");
+	return of_overlay_filter_pattern(f, filename);
+}
+
 static struct of_overlay_filter of_overlay_filepattern_filter = {
 	.name = "filepattern",
 	.filter_filename = of_overlay_filter_filename,
@@ -597,15 +609,18 @@ static struct of_overlay_filter of_overlay_compatible_filter = {
 
 static int of_overlay_init(void)
 {
-	of_overlay_filepattern = strdup("*");
-	of_overlay_filter = strdup("filepattern compatible");
+	of_overlay_pattern = strdup("*");
+	of_overlay_filter = strdup("pattern compatible");
 	of_overlay_set_basedir("/");
 
 	globalvar_add_simple_string("of.overlay.compatible", &of_overlay_compatible);
-	globalvar_add_simple_string("of.overlay.filepattern", &of_overlay_filepattern);
+	globalvar_add_simple_string("of.overlay.pattern", &of_overlay_pattern);
 	globalvar_add_simple_string("of.overlay.filter", &of_overlay_filter);
 	globalvar_add_simple_string("of.overlay.dir", &of_overlay_dir);
 
+	globalvar_alias_deprecated("of.overlay.filepattern", "of.overlay.pattern");
+
+	of_overlay_register_filter(&of_overlay_pattern_filter);
 	of_overlay_register_filter(&of_overlay_filepattern_filter);
 	of_overlay_register_filter(&of_overlay_compatible_filter);
 
@@ -616,6 +631,6 @@ static int of_overlay_init(void)
 device_initcall(of_overlay_init);
 
 BAREBOX_MAGICVAR(global.of.overlay.compatible, "space separated list of compatibles an overlay must match");
-BAREBOX_MAGICVAR(global.of.overlay.filepattern, "space separated list of filepatterns an overlay must match");
+BAREBOX_MAGICVAR(global.of.overlay.pattern, "space separated list of filepatterns an overlay must match");
 BAREBOX_MAGICVAR(global.of.overlay.dir, "Directory to look for dt overlays");
 BAREBOX_MAGICVAR(global.of.overlay.filter, "space separated list of filters");

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 04/11] of: overlay: make search dir more generic
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
                   ` (2 preceding siblings ...)
  2025-07-29 15:34 ` [PATCH v4 03/11] of: overlay: make the pattern match function more generic Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 05/11] of: overlay: refactor of_overlay_global_fixup Marco Felsch
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

Rename global.of.overlay.dir to global.of.overlay.path to prepare the
codebase to handle FIT image overlays as well because *.path doesn't
imply that it have to be a directory.

Keep the backward compatibility by providing the of.overlay.dir variable
but mark it as deprecated.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 Documentation/user/devicetree.rst |  2 +-
 drivers/of/overlay.c              | 15 ++++++++-------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/Documentation/user/devicetree.rst b/Documentation/user/devicetree.rst
index ef04e14f7c0dde579493425073f1ee01395f0d8c..30a15a8865c154f8afe23d641da10d0afa84423b 100644
--- a/Documentation/user/devicetree.rst
+++ b/Documentation/user/devicetree.rst
@@ -108,7 +108,7 @@ Device tree overlays on the kernel device tree
 Overlays can be applied to the kernel device tree before it is handed over to
 the kernel. The behaviour is controlled by different variables:
 
-``global.of.overlay.dir``
+``global.of.overlay.path``
   Overlays are read from this directory. barebox will try to apply all overlays
   found here if not limited by one of the other variables below. When the path
   given here is an absolute path it is used as is. A relative path is relative
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index a63cca1b47e74615d4453a27a55fb15d1f706fae..bc3fdff0cd277b3460981769c2b220adfced6e80 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -408,7 +408,7 @@ int of_register_overlay(struct device_node *overlay)
 }
 
 static char *of_overlay_pattern;
-static char *of_overlay_dir;
+static char *of_overlay_path;
 static char *of_overlay_basedir;
 
 /**
@@ -468,13 +468,13 @@ static int of_overlay_global_fixup(struct device_node *root, void *data)
 	char *dir;
 	int ret;
 
-	if (*of_overlay_dir == '/')
-		return of_overlay_apply_dir(root, of_overlay_dir, true);
+	if (*of_overlay_path == '/')
+		return of_overlay_apply_dir(root, of_overlay_path, true);
 
-	if (*of_overlay_dir == '\0')
+	if (*of_overlay_path == '\0')
 		return 0;
 
-	dir = concat_path_file(of_overlay_basedir, of_overlay_dir);
+	dir = concat_path_file(of_overlay_basedir, of_overlay_path);
 
 	ret = of_overlay_apply_dir(root, dir, true);
 
@@ -616,9 +616,10 @@ static int of_overlay_init(void)
 	globalvar_add_simple_string("of.overlay.compatible", &of_overlay_compatible);
 	globalvar_add_simple_string("of.overlay.pattern", &of_overlay_pattern);
 	globalvar_add_simple_string("of.overlay.filter", &of_overlay_filter);
-	globalvar_add_simple_string("of.overlay.dir", &of_overlay_dir);
+	globalvar_add_simple_string("of.overlay.path", &of_overlay_path);
 
 	globalvar_alias_deprecated("of.overlay.filepattern", "of.overlay.pattern");
+	globalvar_alias_deprecated("of.overlay.dir", "of.overlay.path");
 
 	of_overlay_register_filter(&of_overlay_pattern_filter);
 	of_overlay_register_filter(&of_overlay_filepattern_filter);
@@ -632,5 +633,5 @@ device_initcall(of_overlay_init);
 
 BAREBOX_MAGICVAR(global.of.overlay.compatible, "space separated list of compatibles an overlay must match");
 BAREBOX_MAGICVAR(global.of.overlay.pattern, "space separated list of filepatterns an overlay must match");
-BAREBOX_MAGICVAR(global.of.overlay.dir, "Directory to look for dt overlays");
+BAREBOX_MAGICVAR(global.of.overlay.path, "Path to look for dt overlays");
 BAREBOX_MAGICVAR(global.of.overlay.filter, "space separated list of filters");

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 05/11] of: overlay: refactor of_overlay_global_fixup
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
                   ` (3 preceding siblings ...)
  2025-07-29 15:34 ` [PATCH v4 04/11] of: overlay: make search dir " Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 06/11] FIT: make fit_config_verify_signature public Marco Felsch
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

Prepare of_overlay_global_fixup() for upcoming FIT image based overlays
support.

Check if the of_overlay_path is empty and return early. Make use of
isempty() helper while on it.

Simplify the code flow by setting up the dir variable accordingly before
calling of_overlay_apply_dir() to drop special '/' path
of_overlay_apply_dir() call.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/of/overlay.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index bc3fdff0cd277b3460981769c2b220adfced6e80..f02a12d44f0d53db3fb7bb065461c0ef193d0ab3 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -468,13 +468,13 @@ static int of_overlay_global_fixup(struct device_node *root, void *data)
 	char *dir;
 	int ret;
 
-	if (*of_overlay_path == '/')
-		return of_overlay_apply_dir(root, of_overlay_path, true);
-
-	if (*of_overlay_path == '\0')
+	if (isempty(of_overlay_path))
 		return 0;
 
-	dir = concat_path_file(of_overlay_basedir, of_overlay_path);
+	if (*of_overlay_path == '/')
+		dir = xstrdup(of_overlay_path);
+	else
+		dir = concat_path_file(of_overlay_basedir, of_overlay_path);
 
 	ret = of_overlay_apply_dir(root, dir, true);
 

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 06/11] FIT: make fit_config_verify_signature public
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
                   ` (4 preceding siblings ...)
  2025-07-29 15:34 ` [PATCH v4 05/11] of: overlay: refactor of_overlay_global_fixup Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 07/11] of: overlay: add FIT image overlay support Marco Felsch
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

The upcoming FIT overlay support requires this helper, so make it public
available.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 common/image-fit.c  | 2 +-
 include/image-fit.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 0fc3b2e4aa7217a47710ef613426456420e81324..0067f46e60bc954b418aef3398e2c10856b41c02 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -694,7 +694,7 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
 	return 0;
 }
 
-static int fit_config_verify_signature(struct fit_handle *handle, struct device_node *conf_node)
+int fit_config_verify_signature(struct fit_handle *handle, struct device_node *conf_node)
 {
 	struct device_node *sig_node;
 	int ret = -EINVAL;
diff --git a/include/image-fit.h b/include/image-fit.h
index 416f1f2c1896949d2bcb7ab1a31f1aa6b5682edf..f8321aa87e11fcea642593e790a37df72a2e93b1 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -37,6 +37,7 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
 int fit_get_image_address(struct fit_handle *handle, void *configuration,
 			  const char *name, const char *property,
 			  unsigned long *address);
+int fit_config_verify_signature(struct fit_handle *handle, struct device_node *conf_node);
 
 void fit_close(struct fit_handle *handle);
 

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 07/11] of: overlay: add FIT image overlay support
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
                   ` (5 preceding siblings ...)
  2025-07-29 15:34 ` [PATCH v4 06/11] FIT: make fit_config_verify_signature public Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-08-05 10:57   ` Sascha Hauer
  2025-07-29 15:34 ` [PATCH v4 08/11] of: overlay: replace filename with an more unique name Marco Felsch
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

This adds the support to load devicetree overlays from a FIT image.
There are a few options to handle FIT overlays since the FIT overlay
spec is not very strict.

This implements the most configurable case where each overlay does have
its own config node (including the optional signature).

- The "pattern" filter matches the config-node names (the node names
  below the configurations node), not the overlay image names (the node
  names below the images node).

- The "compatible" filter check doesn't differ from the file based overlay
  handling.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 Documentation/user/devicetree.rst |  19 +++---
 drivers/of/overlay.c              | 132 +++++++++++++++++++++++++++++++++++---
 2 files changed, 134 insertions(+), 17 deletions(-)

diff --git a/Documentation/user/devicetree.rst b/Documentation/user/devicetree.rst
index 30a15a8865c154f8afe23d641da10d0afa84423b..4431ae26bd0f13f3b703881ccb1ed134c844cbf6 100644
--- a/Documentation/user/devicetree.rst
+++ b/Documentation/user/devicetree.rst
@@ -109,20 +109,23 @@ Overlays can be applied to the kernel device tree before it is handed over to
 the kernel. The behaviour is controlled by different variables:
 
 ``global.of.overlay.path``
-  Overlays are read from this directory. barebox will try to apply all overlays
-  found here if not limited by one of the other variables below. When the path
-  given here is an absolute path it is used as is. A relative path is relative
-  to ``/`` or relative to the rootfs when using bootloader spec.
+  Overlays are read from this path. The path can either be a directory which
+  contains the overlays or an absolute path to a FIT-image. barebox will try to
+  apply all found overlays found if not limited by one of the other variables
+  below. When the path given here is an absolute path it is used as is. A
+  relative path is relative to ``/`` or relative to the rootfs when using
+  bootloader spec.
 ``global.of.overlay.compatible``
   This is a space separated list of compatibles. Only overlays matching one of
   these compatibles will be applied. When this list is empty then all overlays
   will be applied. Overlays that don't have a compatible are considered being
   always compatible.
 ``global.of.overlay.pattern``
-  This is a space separated list of file patterns. An overlay is only applied
-  when its filename matches one of the patterns. The patterns can contain
-  ``*`` and ``?`` as wildcards. The default is ``*`` which means all files are
-  applied.
+  This is a space separated list of file patterns or FIT-image config-node name
+  patterns. An overlay is only applied when its filename or FIT-image
+  config-node name matches one of the patterns. The patterns can contain ``*``
+  and ``?`` as wildcards. The default is ``*`` which means all files or FIT-Image
+  config-nodes are applied.
 ``global.of.overlay.filter``
   This is a space separated list of filters to apply. There are two generic filters:
   ``pattern`` matches ``global.of.overlay.pattern`` above, ``compatible`` matches
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index f02a12d44f0d53db3fb7bb065461c0ef193d0ab3..604ce0998cd8044cca59c40e65f4e9b95bec6112 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -8,10 +8,13 @@
  */
 #define pr_fmt(fmt) "of_overlay: " fmt
 
+#include <bootm.h>
 #include <common.h>
 #include <of.h>
 #include <errno.h>
+#include <filetype.h>
 #include <globalvar.h>
+#include <image-fit.h>
 #include <magicvar.h>
 #include <string.h>
 #include <libfile.h>
@@ -463,8 +466,99 @@ static int of_overlay_apply_dir(struct device_node *root, const char *dirname,
 	return ret;
 }
 
+static int of_overlay_apply_fit(struct device_node *root, struct fit_handle *fit,
+				struct device_node *config)
+{
+	const char *name = config->name;
+	struct device_node *overlay;
+	unsigned long ovl_sz;
+	const void *ovl;
+	int ret;
+
+	if (!of_overlay_matches_filter(name, NULL))
+		return 0;
+
+	ret = fit_open_image(fit, config, "fdt", &ovl, &ovl_sz);
+	if (ret)
+		return ret;
+
+	overlay = of_unflatten_dtb(ovl, ovl_sz);
+
+	if (!of_overlay_matches_filter(NULL, overlay)) {
+		ret = 0;
+		goto out;
+	}
+
+	ret = of_overlay_apply_tree(root, overlay);
+	if (ret == -ENODEV)
+		pr_debug("Not applied %s (not compatible)\n", name);
+	else if (ret)
+		pr_err("Cannot apply %s: %s\n", name, strerror(-ret));
+	else
+		pr_info("Applied %s\n", name);
+
+out:
+	of_delete_node(overlay);
+
+	return ret;
+}
+
+static bool of_overlay_valid_config(struct fit_handle *fit,
+				    struct device_node *config)
+{
+	/*
+	 * Either kernel or firmware is marked as mandatory by U-Boot
+	 * (doc/usage/fit/source_file_format.rst) except for overlays
+	 * (doc/usage/fit/overlay-fdt-boot.rst). Therefore we need to ensure
+	 * that only "fdt" config nodes are recognized as overlay config node.
+	 */
+	if (!fit_has_image(fit, config, "fdt") ||
+	    fit_has_image(fit, config, "kernel") ||
+	    fit_has_image(fit, config, "firmware"))
+		return false;
+
+	return true;
+}
+
+static int of_overlay_global_fixup_fit(struct device_node *root,
+				       const char *fit_path, loff_t fit_size)
+{
+	enum bootm_verify verify = bootm_get_verify_mode();
+	struct device_node *conf_node;
+	struct fit_handle *fit;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_FITIMAGE))
+		return 0;
+
+	fit = fit_open(fit_path, 0, verify, fit_size);
+	if (IS_ERR(fit)) {
+		pr_err("Loading FIT image %s failed with: %pe\n", fit_path, fit);
+		return PTR_ERR(fit);
+	}
+
+	for_each_child_of_node(fit->configurations, conf_node) {
+		if (!of_overlay_valid_config(fit, conf_node))
+			continue;
+
+		ret = fit_config_verify_signature(fit, conf_node);
+		if (ret)
+			goto out;
+
+		ret = of_overlay_apply_fit(root, fit, conf_node);
+		if (ret)
+			goto out;
+	}
+
+out:
+	fit_close(fit);
+	return ret;
+}
+
 static int of_overlay_global_fixup(struct device_node *root, void *data)
 {
+	enum filetype type;
+	struct stat s;
 	char *dir;
 	int ret;
 
@@ -476,10 +570,30 @@ static int of_overlay_global_fixup(struct device_node *root, void *data)
 	else
 		dir = concat_path_file(of_overlay_basedir, of_overlay_path);
 
-	ret = of_overlay_apply_dir(root, dir, true);
+	if (stat(dir, &s)) {
+		pr_err("Failed to detect file status\n");
+		ret = -errno;
+		goto out;
+	}
 
-	free(dir);
+	if (S_ISDIR(s.st_mode)) {
+		ret = of_overlay_apply_dir(root, dir, true);
+		goto out;
+	}
 
+	ret = file_name_detect_type(dir, &type);
+	if (ret)
+		goto out;
+
+	if (type == filetype_oftree) {
+		ret = of_overlay_global_fixup_fit(root, dir, s.st_size);
+		goto out;
+	}
+
+	pr_err("No suitable overlay provider found!\n");
+	ret = -EINVAL;
+out:
+	free(dir);
 	return ret;
 }
 
@@ -505,13 +619,13 @@ int of_overlay_register_filter(struct of_overlay_filter *filter)
 
 /**
  * of_overlay_filter_pattern - A filter that matches on the filename or
- *                                an overlay
+ *			       FIT config-node name of an overlay
  * @f: The filter
- * @pattern: The filename of the overlay
+ * @pattern: The filename or FIT config-node name of the overlay
  *
- * This filter matches when the filename matches one of the patterns given
- * in global.of.overlay.filepattern. global.of.overlay.filepattern shall
- * contain a space separated list of wildcard patterns.
+ * This filter matches when the filename or FIT config-node name matches one of
+ * the patterns given in global.of.overlay.pattern. global.of.overlay.pattern
+ * shall contain a space separated list of wildcard patterns.
  *
  * @return: True when the overlay shall be applied, false otherwise.
  */
@@ -632,6 +746,6 @@ static int of_overlay_init(void)
 device_initcall(of_overlay_init);
 
 BAREBOX_MAGICVAR(global.of.overlay.compatible, "space separated list of compatibles an overlay must match");
-BAREBOX_MAGICVAR(global.of.overlay.pattern, "space separated list of filepatterns an overlay must match");
-BAREBOX_MAGICVAR(global.of.overlay.path, "Path to look for dt overlays");
+BAREBOX_MAGICVAR(global.of.overlay.pattern, "space separated list of filename or fit config-node name patterns an overlay must match");
+BAREBOX_MAGICVAR(global.of.overlay.path, "Path to look for dt overlays or a path to a FIT image");
 BAREBOX_MAGICVAR(global.of.overlay.filter, "space separated list of filters");

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 08/11] of: overlay: replace filename with an more unique name
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
                   ` (6 preceding siblings ...)
  2025-07-29 15:34 ` [PATCH v4 07/11] of: overlay: add FIT image overlay support Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 09/11] FIT: fit_open: make filename handling more robust Marco Felsch
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

Since FIT image overlays and file/dir based overlays are supported,
'filename' based variables or function hooks are no longer sufficient.

Rename them to 'pattern' based variables or function hooks. The
filter_filename function hook is still supported, to keep the backward
compatibility, but marked as deprecated.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/of/overlay.c | 39 +++++++++++++++++++++------------------
 include/of.h         |  3 ++-
 2 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 604ce0998cd8044cca59c40e65f4e9b95bec6112..33a12bd758700baef2d516b22a5445b9e53787d1 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -235,12 +235,12 @@ static struct of_overlay_filter *of_overlay_find_filter(const char *name)
 	return NULL;
 }
 
-static bool of_overlay_matches_filter(const char *filename, struct device_node *ovl)
+static bool of_overlay_matches_filter(const char *pattern, struct device_node *ovl)
 {
 	struct of_overlay_filter *filter;
 	char *p, *path, *n;
 	bool apply = false;
-	bool have_filename_filter = false;
+	bool have_pattern_filter = false;
 	bool have_content_filter = false;
 
 	p = path = strdup(of_overlay_filter);
@@ -257,14 +257,16 @@ static bool of_overlay_matches_filter(const char *filename, struct device_node *
 			continue;
 		}
 
-		if (filter->filter_filename)
-			have_filename_filter = true;
+		if (filter->filter_pattern || filter->filter_filename)
+			have_pattern_filter = true;
 		if (filter->filter_content)
 			have_content_filter = true;
 
-		if (filename) {
-			if (filter->filter_filename &&
-			    filter->filter_filename(filter, kbasename(filename)))
+		if (pattern) {
+			if ((filter->filter_pattern &&
+			     filter->filter_pattern(filter, kbasename(pattern))) ||
+			    (filter->filter_filename &&
+			     filter->filter_filename(filter, kbasename(pattern))))
 				score++;
 		} else {
 			score++;
@@ -287,11 +289,11 @@ static bool of_overlay_matches_filter(const char *filename, struct device_node *
 	free(path);
 
 	/* No filter found at all, no match */
-	if (!have_filename_filter && !have_content_filter)
+	if (!have_pattern_filter && !have_content_filter)
 		return false;
 
-	/* Want to match filename, but we do not have a filename_filter */
-	if (filename && !have_filename_filter)
+	/* Want to match pattern, but we do not have a filename_filter */
+	if (pattern && !have_pattern_filter)
 		return true;
 
 	/* Want to match content, but we do not have a content_filter */
@@ -299,12 +301,12 @@ static bool of_overlay_matches_filter(const char *filename, struct device_node *
 		return true;
 
 	if (apply)
-		pr_debug("filename %s, overlay %p: match against filter %s\n",
-			 filename ?: "<NONE>",
+		pr_debug("pattern %s, overlay %p: match against filter %s\n",
+			 pattern ?: "<NONE>",
 			 ovl, filter->name);
 	else
-		pr_debug("filename %s, overlay %p: no match\n",
-			 filename ?: "<NONE>", ovl);
+		pr_debug("pattern %s, overlay %p: no match\n",
+			 pattern ?: "<NONE>", ovl);
 
 	return apply;
 }
@@ -602,14 +604,15 @@ static int of_overlay_global_fixup(struct device_node *root, void *data)
  * @filter: The new filter
  *
  * Register a new overlay filter. A filter can either match on
- * the filename or on the content of an overlay, but not on both.
+ * a pattern or on the content of an overlay, but not on both.
  * If that's desired two filters have to be registered.
  *
  * @return: 0 for success, negative error code otherwise
  */
 int of_overlay_register_filter(struct of_overlay_filter *filter)
 {
-	if (filter->filter_filename && filter->filter_content)
+	if ((filter->filter_pattern || filter->filter_filename) &&
+	    filter->filter_content)
 		return -EINVAL;
 
 	list_add_tail(&filter->list, &of_overlay_filters);
@@ -659,7 +662,7 @@ static bool of_overlay_filter_pattern(struct of_overlay_filter *f,
 
 static struct of_overlay_filter of_overlay_pattern_filter = {
 	.name = "pattern",
-	.filter_filename = of_overlay_filter_pattern,
+	.filter_pattern = of_overlay_filter_pattern,
 };
 
 static bool of_overlay_filter_filename(struct of_overlay_filter *f,
@@ -671,7 +674,7 @@ static bool of_overlay_filter_filename(struct of_overlay_filter *f,
 
 static struct of_overlay_filter of_overlay_filepattern_filter = {
 	.name = "filepattern",
-	.filter_filename = of_overlay_filter_filename,
+	.filter_pattern = of_overlay_filter_filename,
 };
 
 /**
diff --git a/include/of.h b/include/of.h
index 2258cd501b727797ac00fc4cce1a6fdcfc529d44..1c7c0c867700fcf1aa2316ed1e1702b93aa13011 100644
--- a/include/of.h
+++ b/include/of.h
@@ -1384,7 +1384,8 @@ static inline struct device_node *of_dup_root_node_for_boot(void)
 }
 
 struct of_overlay_filter {
-	bool (*filter_filename)(struct of_overlay_filter *, const char *filename);
+	bool (*filter_filename)(struct of_overlay_filter *, const char *filename); /* deprecated */
+	bool (*filter_pattern)(struct of_overlay_filter *, const char *pattern);
 	bool (*filter_content)(struct of_overlay_filter *, struct device_node *);
 	const char *name;
 	struct list_head list;

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 09/11] FIT: fit_open: make filename handling more robust
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
                   ` (7 preceding siblings ...)
  2025-07-29 15:34 ` [PATCH v4 08/11] of: overlay: replace filename with an more unique name Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 10/11] FIT: fit_open: save the filename Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 11/11] FIT: add support to cache opened fit images Marco Felsch
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

To make the filename handling more robust we need to resolve any
possible link to get an abosulte path. Furthermore the filename shall be
absolut, e.g. must start with the root '/'.

This is in preparation of adding cached fit_open support.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 common/image-fit.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 0067f46e60bc954b418aef3398e2c10856b41c02..1cb407d4d86cb3d0a643149bb08c46caadcd56fe 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -972,12 +972,25 @@ struct fit_handle *fit_open_buf(const void *buf, size_t size, bool verbose,
  *
  * Return: A handle to a FIT image or a ERR_PTR
  */
-struct fit_handle *fit_open(const char *filename, bool verbose,
+struct fit_handle *fit_open(const char *_filename, bool verbose,
 			    enum bootm_verify verify, loff_t max_size)
 {
 	struct fit_handle *handle;
+	char *filename;
 	int ret;
 
+	if (*_filename != '/') {
+		pr_err("The FIT filename must start with '/'\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	/* dirfd is ignored, since _filename is absolute */
+	filename = canonicalize_path(AT_FDCWD, _filename);
+	if (!filename) {
+		pr_err("Failed to resolve %s with %s\n", _filename, strerror(errno));
+		return ERR_PTR(-errno);
+	}
+
 	handle = xzalloc(sizeof(struct fit_handle));
 
 	handle->verbose = verbose;
@@ -988,9 +1001,12 @@ struct fit_handle *fit_open(const char *filename, bool verbose,
 	if (ret && ret != -EFBIG) {
 		pr_err("unable to read %s: %pe\n", filename, ERR_PTR(ret));
 		free(handle);
+		free(filename);
 		return ERR_PTR(ret);
 	}
 
+	free(filename);
+
 	handle->fit = handle->fit_alloc;
 
 	ret = fit_do_open(handle);

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 10/11] FIT: fit_open: save the filename
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
                   ` (8 preceding siblings ...)
  2025-07-29 15:34 ` [PATCH v4 09/11] FIT: fit_open: make filename handling more robust Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  2025-07-29 15:34 ` [PATCH v4 11/11] FIT: add support to cache opened fit images Marco Felsch
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

This is in preparation of buffering fit_open() calls to not load the
same fit twice if it is still open.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 common/image-fit.c  | 5 +++--
 include/image-fit.h | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 1cb407d4d86cb3d0a643149bb08c46caadcd56fe..e4b0a8bd5d1a7283239556dd4532eccd5333e90a 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1005,9 +1005,8 @@ struct fit_handle *fit_open(const char *_filename, bool verbose,
 		return ERR_PTR(ret);
 	}
 
-	free(filename);
-
 	handle->fit = handle->fit_alloc;
+	handle->filename = filename;
 
 	ret = fit_do_open(handle);
 	if (ret) {
@@ -1022,6 +1021,8 @@ static void __fit_close(struct fit_handle *handle)
 {
 	if (handle->root)
 		of_delete_node(handle->root);
+
+	free(handle->filename);
 	free(handle->fit_alloc);
 }
 
diff --git a/include/image-fit.h b/include/image-fit.h
index f8321aa87e11fcea642593e790a37df72a2e93b1..68f70f4365cb7a650596263086f7de2209d5957e 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -13,6 +13,7 @@ struct fit_handle {
 	const void *fit;
 	void *fit_alloc;
 	size_t size;
+	char *filename;
 
 	bool verbose;
 	enum bootm_verify verify;

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4 11/11] FIT: add support to cache opened fit images
  2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
                   ` (9 preceding siblings ...)
  2025-07-29 15:34 ` [PATCH v4 10/11] FIT: fit_open: save the filename Marco Felsch
@ 2025-07-29 15:34 ` Marco Felsch
  10 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-07-29 15:34 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch

Cache the FIT image fit_open() calls to avoid loading the same FIT image
twice. This is very useful if the same FIT image is used to provide the
base devicetree, kernel and initrd as well as devicetree overlays.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 common/image-fit.c  | 32 ++++++++++++++++++++++++++++++++
 include/image-fit.h |  4 ++++
 2 files changed, 36 insertions(+)

diff --git a/common/image-fit.c b/common/image-fit.c
index e4b0a8bd5d1a7283239556dd4532eccd5333e90a..23fcbfee3a5ab6c9deec67b4297da986521c114a 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -16,6 +16,7 @@
 #include <fs.h>
 #include <malloc.h>
 #include <linux/ctype.h>
+#include <linux/refcount.h>
 #include <asm/byteorder.h>
 #include <errno.h>
 #include <linux/err.h>
@@ -33,6 +34,8 @@
 #define CHECK_LEVEL_SIG 2
 #define CHECK_LEVEL_MAX 3
 
+static LIST_HEAD(open_fits);
+
 static uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, int size)
 {
 	dt += size;
@@ -902,6 +905,18 @@ void *fit_open_configuration(struct fit_handle *handle, const char *name,
 	return conf_node;
 }
 
+static struct fit_handle *fit_get_handle(const char *filename)
+{
+	struct fit_handle *handle;
+
+	list_for_each_entry(handle, &open_fits, entry) {
+		if (!strcmp(filename, handle->filename))
+			return handle;
+	}
+
+	return NULL;
+}
+
 static int fit_do_open(struct fit_handle *handle)
 {
 	const char *desc = "(no description)";
@@ -951,6 +966,8 @@ struct fit_handle *fit_open_buf(const void *buf, size_t size, bool verbose,
 	handle->size = size;
 	handle->verify = verify;
 
+	refcount_set(&handle->users, 1);
+
 	ret = fit_do_open(handle);
 	if (ret) {
 		fit_close(handle);
@@ -991,6 +1008,12 @@ struct fit_handle *fit_open(const char *_filename, bool verbose,
 		return ERR_PTR(-errno);
 	}
 
+	handle = fit_get_handle(filename);
+	if (handle) {
+		refcount_inc(&handle->users);
+		return handle;
+	}
+
 	handle = xzalloc(sizeof(struct fit_handle));
 
 	handle->verbose = verbose;
@@ -1008,6 +1031,9 @@ struct fit_handle *fit_open(const char *_filename, bool verbose,
 	handle->fit = handle->fit_alloc;
 	handle->filename = filename;
 
+	refcount_set(&handle->users, 1);
+	list_add(&handle->entry, &open_fits);
+
 	ret = fit_do_open(handle);
 	if (ret) {
 		fit_close(handle);
@@ -1019,9 +1045,15 @@ struct fit_handle *fit_open(const char *_filename, bool verbose,
 
 static void __fit_close(struct fit_handle *handle)
 {
+	if (!refcount_dec_and_test(&handle->users))
+		return;
+
 	if (handle->root)
 		of_delete_node(handle->root);
 
+	if (handle->filename)
+		list_del(&handle->entry);
+
 	free(handle->filename);
 	free(handle->fit_alloc);
 }
diff --git a/include/image-fit.h b/include/image-fit.h
index 68f70f4365cb7a650596263086f7de2209d5957e..f9791ff251c554eda56bf3af98c8abceb056a176 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -7,6 +7,7 @@
 #define __IMAGE_FIT_H__
 
 #include <linux/types.h>
+#include <linux/refcount.h>
 #include <bootm.h>
 
 struct fit_handle {
@@ -15,6 +16,9 @@ struct fit_handle {
 	size_t size;
 	char *filename;
 
+	struct list_head entry;
+	refcount_t users;
+
 	bool verbose;
 	enum bootm_verify verify;
 

-- 
2.39.5




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 07/11] of: overlay: add FIT image overlay support
  2025-07-29 15:34 ` [PATCH v4 07/11] of: overlay: add FIT image overlay support Marco Felsch
@ 2025-08-05 10:57   ` Sascha Hauer
  2025-08-05 20:14     ` Marco Felsch
  0 siblings, 1 reply; 14+ messages in thread
From: Sascha Hauer @ 2025-08-05 10:57 UTC (permalink / raw)
  To: Marco Felsch; +Cc: BAREBOX

On Tue, Jul 29, 2025 at 05:34:32PM +0200, Marco Felsch wrote:
> This adds the support to load devicetree overlays from a FIT image.
> There are a few options to handle FIT overlays since the FIT overlay
> spec is not very strict.
> 
> This implements the most configurable case where each overlay does have
> its own config node (including the optional signature).
> 
> - The "pattern" filter matches the config-node names (the node names
>   below the configurations node), not the overlay image names (the node
>   names below the images node).
> 
> - The "compatible" filter check doesn't differ from the file based overlay
>   handling.
> 
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
>  Documentation/user/devicetree.rst |  19 +++---
>  drivers/of/overlay.c              | 132 +++++++++++++++++++++++++++++++++++---
>  2 files changed, 134 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index f02a12d44f0d53db3fb7bb065461c0ef193d0ab3..604ce0998cd8044cca59c40e65f4e9b95bec6112 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -8,10 +8,13 @@
>   */
>  #define pr_fmt(fmt) "of_overlay: " fmt
>  
> +#include <bootm.h>
>  #include <common.h>
>  #include <of.h>
>  #include <errno.h>
> +#include <filetype.h>
>  #include <globalvar.h>
> +#include <image-fit.h>
>  #include <magicvar.h>
>  #include <string.h>
>  #include <libfile.h>
> @@ -463,8 +466,99 @@ static int of_overlay_apply_dir(struct device_node *root, const char *dirname,
>  	return ret;
>  }
>  
> +static int of_overlay_apply_fit(struct device_node *root, struct fit_handle *fit,
> +				struct device_node *config)
> +{
> +	const char *name = config->name;
> +	struct device_node *overlay;
> +	unsigned long ovl_sz;
> +	const void *ovl;
> +	int ret;
> +
> +	if (!of_overlay_matches_filter(name, NULL))
> +		return 0;
> +
> +	ret = fit_open_image(fit, config, "fdt", &ovl, &ovl_sz);
> +	if (ret)
> +		return ret;
> +
> +	overlay = of_unflatten_dtb(ovl, ovl_sz);
> +
> +	if (!of_overlay_matches_filter(NULL, overlay)) {
> +		ret = 0;
> +		goto out;
> +	}
> +
> +	ret = of_overlay_apply_tree(root, overlay);
> +	if (ret == -ENODEV)
> +		pr_debug("Not applied %s (not compatible)\n", name);
> +	else if (ret)
> +		pr_err("Cannot apply %s: %s\n", name, strerror(-ret));
> +	else
> +		pr_info("Applied %s\n", name);
> +
> +out:
> +	of_delete_node(overlay);
> +
> +	return ret;
> +}
> +
> +static bool of_overlay_valid_config(struct fit_handle *fit,
> +				    struct device_node *config)
> +{
> +	/*
> +	 * Either kernel or firmware is marked as mandatory by U-Boot
> +	 * (doc/usage/fit/source_file_format.rst) except for overlays
> +	 * (doc/usage/fit/overlay-fdt-boot.rst). Therefore we need to ensure
> +	 * that only "fdt" config nodes are recognized as overlay config node.
> +	 */
> +	if (!fit_has_image(fit, config, "fdt") ||
> +	    fit_has_image(fit, config, "kernel") ||
> +	    fit_has_image(fit, config, "firmware"))
> +		return false;
> +
> +	return true;
> +}
> +
> +static int of_overlay_global_fixup_fit(struct device_node *root,
> +				       const char *fit_path, loff_t fit_size)
> +{
> +	enum bootm_verify verify = bootm_get_verify_mode();
> +	struct device_node *conf_node;
> +	struct fit_handle *fit;
> +	int ret;
> +
> +	if (!IS_ENABLED(CONFIG_FITIMAGE))
> +		return 0;

The comments in https://lore.barebox.org/barebox/ZpT3h0o089tae2WS@pengutronix.de/
do not seem to be addressed here.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4 07/11] of: overlay: add FIT image overlay support
  2025-08-05 10:57   ` Sascha Hauer
@ 2025-08-05 20:14     ` Marco Felsch
  0 siblings, 0 replies; 14+ messages in thread
From: Marco Felsch @ 2025-08-05 20:14 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: BAREBOX

On 25-08-05, Sascha Hauer wrote:
> On Tue, Jul 29, 2025 at 05:34:32PM +0200, Marco Felsch wrote:
> > This adds the support to load devicetree overlays from a FIT image.
> > There are a few options to handle FIT overlays since the FIT overlay
> > spec is not very strict.
> > 
> > This implements the most configurable case where each overlay does have
> > its own config node (including the optional signature).
> > 
> > - The "pattern" filter matches the config-node names (the node names
> >   below the configurations node), not the overlay image names (the node
> >   names below the images node).
> > 
> > - The "compatible" filter check doesn't differ from the file based overlay
> >   handling.
> > 
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> >  Documentation/user/devicetree.rst |  19 +++---
> >  drivers/of/overlay.c              | 132 +++++++++++++++++++++++++++++++++++---
> >  2 files changed, 134 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> > index f02a12d44f0d53db3fb7bb065461c0ef193d0ab3..604ce0998cd8044cca59c40e65f4e9b95bec6112 100644
> > --- a/drivers/of/overlay.c
> > +++ b/drivers/of/overlay.c
> > @@ -8,10 +8,13 @@
> >   */
> >  #define pr_fmt(fmt) "of_overlay: " fmt
> >  
> > +#include <bootm.h>
> >  #include <common.h>
> >  #include <of.h>
> >  #include <errno.h>
> > +#include <filetype.h>
> >  #include <globalvar.h>
> > +#include <image-fit.h>
> >  #include <magicvar.h>
> >  #include <string.h>
> >  #include <libfile.h>
> > @@ -463,8 +466,99 @@ static int of_overlay_apply_dir(struct device_node *root, const char *dirname,
> >  	return ret;
> >  }
> >  
> > +static int of_overlay_apply_fit(struct device_node *root, struct fit_handle *fit,
> > +				struct device_node *config)
> > +{
> > +	const char *name = config->name;
> > +	struct device_node *overlay;
> > +	unsigned long ovl_sz;
> > +	const void *ovl;
> > +	int ret;
> > +
> > +	if (!of_overlay_matches_filter(name, NULL))
> > +		return 0;
> > +
> > +	ret = fit_open_image(fit, config, "fdt", &ovl, &ovl_sz);
> > +	if (ret)
> > +		return ret;
> > +
> > +	overlay = of_unflatten_dtb(ovl, ovl_sz);
> > +
> > +	if (!of_overlay_matches_filter(NULL, overlay)) {
> > +		ret = 0;
> > +		goto out;
> > +	}
> > +
> > +	ret = of_overlay_apply_tree(root, overlay);
> > +	if (ret == -ENODEV)
> > +		pr_debug("Not applied %s (not compatible)\n", name);
> > +	else if (ret)
> > +		pr_err("Cannot apply %s: %s\n", name, strerror(-ret));
> > +	else
> > +		pr_info("Applied %s\n", name);
> > +
> > +out:
> > +	of_delete_node(overlay);
> > +
> > +	return ret;
> > +}
> > +
> > +static bool of_overlay_valid_config(struct fit_handle *fit,
> > +				    struct device_node *config)
> > +{
> > +	/*
> > +	 * Either kernel or firmware is marked as mandatory by U-Boot
> > +	 * (doc/usage/fit/source_file_format.rst) except for overlays
> > +	 * (doc/usage/fit/overlay-fdt-boot.rst). Therefore we need to ensure
> > +	 * that only "fdt" config nodes are recognized as overlay config node.
> > +	 */
> > +	if (!fit_has_image(fit, config, "fdt") ||
> > +	    fit_has_image(fit, config, "kernel") ||
> > +	    fit_has_image(fit, config, "firmware"))
> > +		return false;
> > +
> > +	return true;
> > +}
> > +
> > +static int of_overlay_global_fixup_fit(struct device_node *root,
> > +				       const char *fit_path, loff_t fit_size)
> > +{
> > +	enum bootm_verify verify = bootm_get_verify_mode();
> > +	struct device_node *conf_node;
> > +	struct fit_handle *fit;
> > +	int ret;
> > +
> > +	if (!IS_ENABLED(CONFIG_FITIMAGE))
> > +		return 0;
> 
> The comments in https://lore.barebox.org/barebox/ZpT3h0o089tae2WS@pengutronix.de/
> do not seem to be addressed here.

Sorry, I missed your comments. I will answer them first on the old
Mail-Thread and send a new version afterwards.

Thanks,
  Marco

> 
> Sascha
> 
> -- 
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 



^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-08-05 20:15 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-29 15:34 [PATCH v4 00/11] Add FIT image overlay support Marco Felsch
2025-07-29 15:34 ` [PATCH v4 01/11] FIT: fix missing free in fit_open error path Marco Felsch
2025-07-29 15:34 ` [PATCH v4 02/11] FIT: fit_open_configuration: add match function support Marco Felsch
2025-07-29 15:34 ` [PATCH v4 03/11] of: overlay: make the pattern match function more generic Marco Felsch
2025-07-29 15:34 ` [PATCH v4 04/11] of: overlay: make search dir " Marco Felsch
2025-07-29 15:34 ` [PATCH v4 05/11] of: overlay: refactor of_overlay_global_fixup Marco Felsch
2025-07-29 15:34 ` [PATCH v4 06/11] FIT: make fit_config_verify_signature public Marco Felsch
2025-07-29 15:34 ` [PATCH v4 07/11] of: overlay: add FIT image overlay support Marco Felsch
2025-08-05 10:57   ` Sascha Hauer
2025-08-05 20:14     ` Marco Felsch
2025-07-29 15:34 ` [PATCH v4 08/11] of: overlay: replace filename with an more unique name Marco Felsch
2025-07-29 15:34 ` [PATCH v4 09/11] FIT: fit_open: make filename handling more robust Marco Felsch
2025-07-29 15:34 ` [PATCH v4 10/11] FIT: fit_open: save the filename Marco Felsch
2025-07-29 15:34 ` [PATCH v4 11/11] FIT: add support to cache opened fit images Marco Felsch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox