* [PATCH] fdt: Allow stacked overlays phandle references
@ 2017-07-31 17:09 Pantelis Antoniou
[not found] ` <1501520996-3366-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Pantelis Antoniou @ 2017-07-31 17:09 UTC (permalink / raw)
To: David Gibson
Cc: Tom Rini, Nishanth Menon, Tero Kristo, Frank Rowand, Rob Herring,
Simon Glass, Devicetree Compiler,
devicetree-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou
This patch enables an overlay to refer to a previous overlay's
labels by performing a merge of symbol information at application
time.
In a nutshell it allows an overlay to refer to a symbol that a previous
overlay has defined. It requires both the base and all the overlays
to be compiled with the -@ command line switch so that symbol
information is included.
base.dts
--------
/dts-v1/;
/ {
foo: foonode {
foo-property;
};
};
$ dtc -@ -I dts -O dtb -o base.dtb base.dts
bar.dts
-------
/dts-v1/;
/plugin/;
/ {
fragment@1 {
target = <&foo>;
__overlay__ {
overlay-1-property;
bar: barnode {
bar-property;
};
};
};
};
$ dtc -@ -I dts -O dtb -o bar.dtb bar.dts
baz.dts
-------
/dts-v1/;
/plugin/;
/ {
fragment@1 {
target = <&bar>;
__overlay__ {
overlay-2-property;
baz: baznode {
baz-property;
};
};
};
};
$ dtc -@ -I dts -O dtb -o baz.dtb baz.dts
Applying the overlays:
$ fdtoverlay -i base.dtb -o target.dtb bar.dtb baz.dtb
Dumping:
$ fdtdump target.dtb
/ {
foonode {
overlay-1-property;
foo-property;
linux,phandle = <0x00000001>;
phandle = <0x00000001>;
barnode {
overlay-2-property;
phandle = <0x00000002>;
linux,phandle = <0x00000002>;
bar-property;
baznode {
phandle = <0x00000003>;
linux,phandle = <0x00000003>;
baz-property;
};
};
};
__symbols__ {
baz = "/foonode/barnode/baznode";
bar = "/foonode/barnode";
foo = "/foonode";
};
};
Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
---
libfdt/fdt_overlay.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 203 insertions(+), 22 deletions(-)
diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
index ceb9687..a4f81f0 100644
--- a/libfdt/fdt_overlay.c
+++ b/libfdt/fdt_overlay.c
@@ -39,6 +39,7 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
* @fdt: Base device tree blob
* @fdto: Device tree overlay blob
* @fragment: node offset of the fragment in the overlay
+ * @pathp: pointer which receives the path of the target (or NULL)
*
* overlay_get_target() retrieves the target offset in the base
* device tree of a fragment, no matter how the actual targetting is
@@ -49,37 +50,47 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
* Negative error code on error
*/
static int overlay_get_target(const void *fdt, const void *fdto,
- int fragment)
+ int fragment, char const **pathp)
{
uint32_t phandle;
- const char *path;
- int path_len;
+ const char *path = NULL;
+ int path_len = 0, ret;
/* Try first to do a phandle based lookup */
phandle = overlay_get_target_phandle(fdto, fragment);
if (phandle == (uint32_t)-1)
return -FDT_ERR_BADPHANDLE;
- if (phandle)
- return fdt_node_offset_by_phandle(fdt, phandle);
+ /* no phandle, try path */
+ if (!phandle) {
+ /* And then a path based lookup */
+ path = fdt_getprop(fdto, fragment, "target-path", &path_len);
+ if (path)
+ ret = fdt_path_offset(fdt, path);
+ else
+ ret = path_len;
+ } else
+ ret = fdt_node_offset_by_phandle(fdt, phandle);
- /* And then a path based lookup */
- path = fdt_getprop(fdto, fragment, "target-path", &path_len);
- if (!path) {
- /*
- * If we haven't found either a target or a
- * target-path property in a node that contains a
- * __overlay__ subnode (we wouldn't be called
- * otherwise), consider it a improperly written
- * overlay
- */
- if (path_len == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_BADOVERLAY;
+ /*
+ * If we haven't found either a target or a
+ * target-path property in a node that contains a
+ * __overlay__ subnode (we wouldn't be called
+ * otherwise), consider it a improperly written
+ * overlay
+ */
+ if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
+ ret = -FDT_ERR_BADOVERLAY;
+
+ /* return on error */
+ if (ret < 0)
+ return ret;
- return path_len;
- }
+ /* return pointer to path (if available) */
+ if (pathp)
+ *pathp = path ? path : NULL;
- return fdt_path_offset(fdt, path);
+ return ret;
}
/**
@@ -590,7 +601,7 @@ static int overlay_apply_node(void *fdt, int target,
*
* overlay_merge() merges an overlay into its base device tree.
*
- * This is the final step in the device tree overlay application
+ * This is the next to last step in the device tree overlay application
* process, when all the phandles have been adjusted and resolved and
* you just have to merge overlay into the base device tree.
*
@@ -618,7 +629,7 @@ static int overlay_merge(void *fdt, void *fdto)
if (overlay < 0)
return overlay;
- target = overlay_get_target(fdt, fdto, fragment);
+ target = overlay_get_target(fdt, fdto, fragment, NULL);
if (target < 0)
return target;
@@ -630,6 +641,172 @@ static int overlay_merge(void *fdt, void *fdto)
return 0;
}
+static int get_path_len(const void *fdt, int nodeoffset)
+{
+ int len = 0, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER(fdt);
+
+ for (;;) {
+ name = fdt_get_name(fdt, nodeoffset, &namelen);
+ if (!name)
+ return namelen;
+
+ /* root? we're done */
+ if (namelen == 0)
+ break;
+
+ nodeoffset = fdt_parent_offset(fdt, nodeoffset);
+ if (nodeoffset < 0)
+ return nodeoffset;
+ len += namelen + 1;
+ }
+
+ /* in case of root pretend it's "/" */
+ if (len == 0)
+ len++;
+ return len;
+}
+
+/**
+ * overlay_symbol_update - Update the symbols of base tree after a merge
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_symbol_update() updates the symbols of the base tree with the
+ * symbols of the applied overlay
+ *
+ * This is the last step in the device tree overlay application
+ * process, allowing the reference of overlay symbols by subsequent
+ * overlay operations.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_symbol_update(void *fdt, void *fdto)
+{
+ int root_sym, ov_sym, prop, path_len, fragment, target;
+ int len, frag_name_len, ret, rel_path_len;
+ const char *s;
+ const char *path;
+ const char *name;
+ const char *frag_name;
+ const char *rel_path;
+ const char *target_path;
+ char *buf;
+ void *p;
+
+ ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
+
+ /* if no overlay symbols exist no problem */
+ if (ov_sym < 0)
+ return 0;
+
+ root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
+
+ /* it no root symbols exist we should create them */
+ if (root_sym < 0) {
+ root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
+ if (root_sym < 0)
+ return root_sym;
+ }
+
+ /* iterate over each overlay symbol */
+ fdt_for_each_property_offset(prop, fdto, ov_sym) {
+ path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
+ if (!path)
+ return path_len;
+
+ /* verify it's a string property (terminated by a single \0) */
+ if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
+ return -FDT_ERR_BADVALUE;
+
+ /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
+
+ if (*path != '/')
+ return -FDT_ERR_BADVALUE;
+
+ /* verify that no stray \0 exist in the property */
+ if (strlen(path) != path_len - 1)
+ return -FDT_ERR_BADOVERLAY;
+
+ /* get fragment name first */
+ s = strchr(path + 1, '/');
+ if (!s)
+ return -FDT_ERR_BADOVERLAY;
+
+ frag_name = path + 1;
+ frag_name_len = s - path - 1;
+
+ /* verify format; safe since "s" lies in \0 terminated prop */
+ len = strlen("/__overlay__/");
+ if (strlen(s) < len || memcmp(s, "/__overlay__/", len))
+ return -FDT_ERR_NOTFOUND;
+
+ rel_path = s + len;
+ rel_path_len = strlen(rel_path);
+
+ /* find the fragment index in which the symbol lies */
+ ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
+ frag_name_len);
+ /* not found? */
+ if (ret < 0)
+ return ret;
+ fragment = ret;
+
+ /* an __overlay__ subnode must exist */
+ ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
+ if (ret < 0)
+ return ret;
+
+ /* get the target of the fragment */
+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+ if (ret < 0)
+ return ret;
+ target = ret;
+
+ /* if we have a target path use */
+ if (!target_path) {
+ ret = get_path_len(fdt, target);
+ if (ret < 0)
+ return ret;
+ len = ret;
+ } else
+ len = strlen(target_path);
+
+ ret = fdt_setprop_placeholder(fdt, root_sym, name,
+ len + (len > 1) + rel_path_len + 1, &p);
+ if (ret < 0)
+ return ret;
+
+ /* again in case setprop_placeholder changed it */
+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+ if (ret < 0)
+ return ret;
+ target = ret;
+
+ buf = p;
+ if (len > 1) { /* target is not root */
+ if (!target_path) {
+ ret = fdt_get_path(fdt, target, buf, len + 1);
+ if (ret < 0)
+ return ret;
+ } else
+ memcpy(buf, target_path, len + 1);
+
+ } else
+ len--;
+
+ buf[len] = '/';
+ memcpy(buf + len + 1, rel_path, rel_path_len);
+ buf[len + 1 + rel_path_len] = '\0';
+ }
+
+ return 0;
+}
+
int fdt_overlay_apply(void *fdt, void *fdto)
{
uint32_t delta = fdt_get_max_phandle(fdt);
@@ -654,6 +831,10 @@ int fdt_overlay_apply(void *fdt, void *fdto)
if (ret)
goto err;
+ ret = overlay_symbol_update(fdt, fdto);
+ if (ret)
+ goto err;
+
/*
* The overlay has been damaged, erase its magic.
*/
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] fdt: Allow stacked overlays phandle references
[not found] ` <1501520996-3366-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
@ 2017-08-07 5:01 ` David Gibson
0 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2017-08-07 5:01 UTC (permalink / raw)
To: Pantelis Antoniou
Cc: Tom Rini, Nishanth Menon, Tero Kristo, Frank Rowand, Rob Herring,
Simon Glass, Devicetree Compiler,
devicetree-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 11650 bytes --]
On Mon, Jul 31, 2017 at 08:09:56PM +0300, Pantelis Antoniou wrote:
> This patch enables an overlay to refer to a previous overlay's
> labels by performing a merge of symbol information at application
> time.
>
> In a nutshell it allows an overlay to refer to a symbol that a previous
> overlay has defined. It requires both the base and all the overlays
> to be compiled with the -@ command line switch so that symbol
> information is included.
>
> base.dts
> --------
>
> /dts-v1/;
> / {
> foo: foonode {
> foo-property;
> };
> };
>
> $ dtc -@ -I dts -O dtb -o base.dtb base.dts
>
> bar.dts
> -------
>
> /dts-v1/;
> /plugin/;
> / {
> fragment@1 {
> target = <&foo>;
> __overlay__ {
> overlay-1-property;
> bar: barnode {
> bar-property;
> };
> };
> };
> };
>
> $ dtc -@ -I dts -O dtb -o bar.dtb bar.dts
>
> baz.dts
> -------
>
> /dts-v1/;
> /plugin/;
> / {
> fragment@1 {
> target = <&bar>;
> __overlay__ {
> overlay-2-property;
> baz: baznode {
> baz-property;
> };
> };
> };
> };
>
> $ dtc -@ -I dts -O dtb -o baz.dtb baz.dts
>
> Applying the overlays:
>
> $ fdtoverlay -i base.dtb -o target.dtb bar.dtb baz.dtb
>
> Dumping:
>
> $ fdtdump target.dtb
> / {
> foonode {
> overlay-1-property;
> foo-property;
> linux,phandle = <0x00000001>;
> phandle = <0x00000001>;
> barnode {
> overlay-2-property;
> phandle = <0x00000002>;
> linux,phandle = <0x00000002>;
> bar-property;
> baznode {
> phandle = <0x00000003>;
> linux,phandle = <0x00000003>;
> baz-property;
> };
> };
> };
> __symbols__ {
> baz = "/foonode/barnode/baznode";
> bar = "/foonode/barnode";
> foo = "/foonode";
> };
> };
>
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
> libfdt/fdt_overlay.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 203 insertions(+), 22 deletions(-)
>
> diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
> index ceb9687..a4f81f0 100644
> --- a/libfdt/fdt_overlay.c
> +++ b/libfdt/fdt_overlay.c
> @@ -39,6 +39,7 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
> * @fdt: Base device tree blob
> * @fdto: Device tree overlay blob
> * @fragment: node offset of the fragment in the overlay
> + * @pathp: pointer which receives the path of the target (or NULL)
> *
> * overlay_get_target() retrieves the target offset in the base
> * device tree of a fragment, no matter how the actual targetting is
> @@ -49,37 +50,47 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
> * Negative error code on error
> */
> static int overlay_get_target(const void *fdt, const void *fdto,
> - int fragment)
> + int fragment, char const **pathp)
> {
> uint32_t phandle;
> - const char *path;
> - int path_len;
> + const char *path = NULL;
> + int path_len = 0, ret;
>
> /* Try first to do a phandle based lookup */
> phandle = overlay_get_target_phandle(fdto, fragment);
> if (phandle == (uint32_t)-1)
> return -FDT_ERR_BADPHANDLE;
>
> - if (phandle)
> - return fdt_node_offset_by_phandle(fdt, phandle);
> + /* no phandle, try path */
> + if (!phandle) {
> + /* And then a path based lookup */
> + path = fdt_getprop(fdto, fragment, "target-path", &path_len);
> + if (path)
> + ret = fdt_path_offset(fdt, path);
> + else
> + ret = path_len;
> + } else
> + ret = fdt_node_offset_by_phandle(fdt, phandle);
>
> - /* And then a path based lookup */
> - path = fdt_getprop(fdto, fragment, "target-path", &path_len);
> - if (!path) {
> - /*
> - * If we haven't found either a target or a
> - * target-path property in a node that contains a
> - * __overlay__ subnode (we wouldn't be called
> - * otherwise), consider it a improperly written
> - * overlay
> - */
> - if (path_len == -FDT_ERR_NOTFOUND)
> - return -FDT_ERR_BADOVERLAY;
> + /*
> + * If we haven't found either a target or a
> + * target-path property in a node that contains a
> + * __overlay__ subnode (we wouldn't be called
> + * otherwise), consider it a improperly written
> + * overlay
> + */
> + if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
> + ret = -FDT_ERR_BADOVERLAY;
> +
> + /* return on error */
> + if (ret < 0)
> + return ret;
>
> - return path_len;
> - }
> + /* return pointer to path (if available) */
> + if (pathp)
> + *pathp = path ? path : NULL;
>
> - return fdt_path_offset(fdt, path);
> + return ret;
> }
>
> /**
> @@ -590,7 +601,7 @@ static int overlay_apply_node(void *fdt, int target,
> *
> * overlay_merge() merges an overlay into its base device tree.
> *
> - * This is the final step in the device tree overlay application
> + * This is the next to last step in the device tree overlay application
> * process, when all the phandles have been adjusted and resolved and
> * you just have to merge overlay into the base device tree.
> *
> @@ -618,7 +629,7 @@ static int overlay_merge(void *fdt, void *fdto)
> if (overlay < 0)
> return overlay;
>
> - target = overlay_get_target(fdt, fdto, fragment);
> + target = overlay_get_target(fdt, fdto, fragment, NULL);
> if (target < 0)
> return target;
>
> @@ -630,6 +641,172 @@ static int overlay_merge(void *fdt, void *fdto)
> return 0;
> }
>
> +static int get_path_len(const void *fdt, int nodeoffset)
> +{
> + int len = 0, namelen;
> + const char *name;
> +
> + FDT_CHECK_HEADER(fdt);
> +
> + for (;;) {
> + name = fdt_get_name(fdt, nodeoffset, &namelen);
> + if (!name)
> + return namelen;
> +
> + /* root? we're done */
> + if (namelen == 0)
> + break;
> +
> + nodeoffset = fdt_parent_offset(fdt, nodeoffset);
> + if (nodeoffset < 0)
> + return nodeoffset;
> + len += namelen + 1;
> + }
> +
> + /* in case of root pretend it's "/" */
> + if (len == 0)
> + len++;
> + return len;
> +}
> +
> +/**
> + * overlay_symbol_update - Update the symbols of base tree after a merge
> + * @fdt: Base Device Tree blob
> + * @fdto: Device tree overlay blob
> + *
> + * overlay_symbol_update() updates the symbols of the base tree with the
> + * symbols of the applied overlay
> + *
> + * This is the last step in the device tree overlay application
> + * process, allowing the reference of overlay symbols by subsequent
> + * overlay operations.
> + *
> + * returns:
> + * 0 on success
> + * Negative error code on failure
> + */
> +static int overlay_symbol_update(void *fdt, void *fdto)
> +{
> + int root_sym, ov_sym, prop, path_len, fragment, target;
> + int len, frag_name_len, ret, rel_path_len;
> + const char *s;
> + const char *path;
> + const char *name;
> + const char *frag_name;
> + const char *rel_path;
> + const char *target_path;
> + char *buf;
> + void *p;
> +
> + ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
> +
> + /* if no overlay symbols exist no problem */
> + if (ov_sym < 0)
> + return 0;
> +
> + root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
> +
> + /* it no root symbols exist we should create them */
> + if (root_sym < 0) {
Should only do this for root_sym == NOTFOUND, not for other error
conditions.
> + root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
> + if (root_sym < 0)
> + return root_sym;
> + }
> +
> + /* iterate over each overlay symbol */
> + fdt_for_each_property_offset(prop, fdto, ov_sym) {
> + path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
> + if (!path)
> + return path_len;
> +
> + /* verify it's a string property (terminated by a single \0) */
> + if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
> + return -FDT_ERR_BADVALUE;
> +
> + /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
> +
> + if (*path != '/')
> + return -FDT_ERR_BADVALUE;
> +
> + /* verify that no stray \0 exist in the property */
> + if (strlen(path) != path_len - 1)
> + return -FDT_ERR_BADOVERLAY;
Redundant with the revised string check above.
> + /* get fragment name first */
> + s = strchr(path + 1, '/');
> + if (!s)
> + return -FDT_ERR_BADOVERLAY;
> +
> + frag_name = path + 1;
> + frag_name_len = s - path - 1;
> +
> + /* verify format; safe since "s" lies in \0 terminated prop */
> + len = strlen("/__overlay__/");
> + if (strlen(s) < len || memcmp(s, "/__overlay__/", len))
You can derive strlen(s) from path_len and frag_name_len, to avoid the
call to strlen().
> + return -FDT_ERR_NOTFOUND;
Should be BADOVERLAY.
> +
> + rel_path = s + len;
> + rel_path_len = strlen(rel_path);
Again, you can avoid this strlen().
> +
> + /* find the fragment index in which the symbol lies */
> + ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
> + frag_name_len);
> + /* not found? */
> + if (ret < 0)
> + return ret;
NOTFOUND should become BADOVERLAY here.
> + fragment = ret;
> +
> + /* an __overlay__ subnode must exist */
> + ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
> + if (ret < 0)
> + return ret;
And here.
> +
> + /* get the target of the fragment */
> + ret = overlay_get_target(fdt, fdto, fragment, &target_path);
> + if (ret < 0)
> + return ret;
> + target = ret;
> +
> + /* if we have a target path use */
> + if (!target_path) {
> + ret = get_path_len(fdt, target);
> + if (ret < 0)
> + return ret;
> + len = ret;
> + } else
> + len = strlen(target_path);
Braces around both if/else branches, if they're around either, please.
> +
> + ret = fdt_setprop_placeholder(fdt, root_sym, name,
> + len + (len > 1) + rel_path_len + 1, &p);
> + if (ret < 0)
> + return ret;
> +
> + /* again in case setprop_placeholder changed it */
> + ret = overlay_get_target(fdt, fdto, fragment, &target_path);
You only need to do this if !target_path - if you already have the
target_path, you don't actually need the offset of the target.
> + if (ret < 0)
> + return ret;
> + target = ret;
> +
> + buf = p;
> + if (len > 1) { /* target is not root */
> + if (!target_path) {
> + ret = fdt_get_path(fdt, target, buf, len + 1);
> + if (ret < 0)
> + return ret;
> + } else
> + memcpy(buf, target_path, len + 1);
> +
> + } else
> + len--;
> +
> + buf[len] = '/';
> + memcpy(buf + len + 1, rel_path, rel_path_len);
> + buf[len + 1 + rel_path_len] = '\0';
> + }
> +
> + return 0;
> +}
> +
> int fdt_overlay_apply(void *fdt, void *fdto)
> {
> uint32_t delta = fdt_get_max_phandle(fdt);
> @@ -654,6 +831,10 @@ int fdt_overlay_apply(void *fdt, void *fdto)
> if (ret)
> goto err;
>
> + ret = overlay_symbol_update(fdt, fdto);
> + if (ret)
> + goto err;
> +
> /*
> * The overlay has been damaged, erase its magic.
> */
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] fdt: Allow stacked overlays phandle references
@ 2017-08-07 12:26 Pantelis Antoniou
[not found] ` <1502108769-11203-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Pantelis Antoniou @ 2017-08-07 12:26 UTC (permalink / raw)
To: David Gibson
Cc: Tom Rini, Nishanth Menon, Tero Kristo, Frank Rowand, Rob Herring,
Simon Glass, Devicetree Compiler,
devicetree-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou
This patch enables an overlay to refer to a previous overlay's
labels by performing a merge of symbol information at application
time.
In a nutshell it allows an overlay to refer to a symbol that a previous
overlay has defined. It requires both the base and all the overlays
to be compiled with the -@ command line switch so that symbol
information is included.
base.dts
--------
/dts-v1/;
/ {
foo: foonode {
foo-property;
};
};
$ dtc -@ -I dts -O dtb -o base.dtb base.dts
bar.dts
-------
/dts-v1/;
/plugin/;
/ {
fragment@1 {
target = <&foo>;
__overlay__ {
overlay-1-property;
bar: barnode {
bar-property;
};
};
};
};
$ dtc -@ -I dts -O dtb -o bar.dtb bar.dts
baz.dts
-------
/dts-v1/;
/plugin/;
/ {
fragment@1 {
target = <&bar>;
__overlay__ {
overlay-2-property;
baz: baznode {
baz-property;
};
};
};
};
$ dtc -@ -I dts -O dtb -o baz.dtb baz.dts
Applying the overlays:
$ fdtoverlay -i base.dtb -o target.dtb bar.dtb baz.dtb
Dumping:
$ fdtdump target.dtb
/ {
foonode {
overlay-1-property;
foo-property;
linux,phandle = <0x00000001>;
phandle = <0x00000001>;
barnode {
overlay-2-property;
phandle = <0x00000002>;
linux,phandle = <0x00000002>;
bar-property;
baznode {
phandle = <0x00000003>;
linux,phandle = <0x00000003>;
baz-property;
};
};
};
__symbols__ {
baz = "/foonode/barnode/baznode";
bar = "/foonode/barnode";
foo = "/foonode";
};
};
Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
---
libfdt/fdt_overlay.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 206 insertions(+), 22 deletions(-)
diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
index ceb9687..bd81241 100644
--- a/libfdt/fdt_overlay.c
+++ b/libfdt/fdt_overlay.c
@@ -39,6 +39,7 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
* @fdt: Base device tree blob
* @fdto: Device tree overlay blob
* @fragment: node offset of the fragment in the overlay
+ * @pathp: pointer which receives the path of the target (or NULL)
*
* overlay_get_target() retrieves the target offset in the base
* device tree of a fragment, no matter how the actual targetting is
@@ -49,37 +50,47 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
* Negative error code on error
*/
static int overlay_get_target(const void *fdt, const void *fdto,
- int fragment)
+ int fragment, char const **pathp)
{
uint32_t phandle;
- const char *path;
- int path_len;
+ const char *path = NULL;
+ int path_len = 0, ret;
/* Try first to do a phandle based lookup */
phandle = overlay_get_target_phandle(fdto, fragment);
if (phandle == (uint32_t)-1)
return -FDT_ERR_BADPHANDLE;
- if (phandle)
- return fdt_node_offset_by_phandle(fdt, phandle);
+ /* no phandle, try path */
+ if (!phandle) {
+ /* And then a path based lookup */
+ path = fdt_getprop(fdto, fragment, "target-path", &path_len);
+ if (path)
+ ret = fdt_path_offset(fdt, path);
+ else
+ ret = path_len;
+ } else
+ ret = fdt_node_offset_by_phandle(fdt, phandle);
- /* And then a path based lookup */
- path = fdt_getprop(fdto, fragment, "target-path", &path_len);
- if (!path) {
- /*
- * If we haven't found either a target or a
- * target-path property in a node that contains a
- * __overlay__ subnode (we wouldn't be called
- * otherwise), consider it a improperly written
- * overlay
- */
- if (path_len == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_BADOVERLAY;
+ /*
+ * If we haven't found either a target or a
+ * target-path property in a node that contains a
+ * __overlay__ subnode (we wouldn't be called
+ * otherwise), consider it a improperly written
+ * overlay
+ */
+ if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
+ ret = -FDT_ERR_BADOVERLAY;
+
+ /* return on error */
+ if (ret < 0)
+ return ret;
- return path_len;
- }
+ /* return pointer to path (if available) */
+ if (pathp)
+ *pathp = path ? path : NULL;
- return fdt_path_offset(fdt, path);
+ return ret;
}
/**
@@ -590,7 +601,7 @@ static int overlay_apply_node(void *fdt, int target,
*
* overlay_merge() merges an overlay into its base device tree.
*
- * This is the final step in the device tree overlay application
+ * This is the next to last step in the device tree overlay application
* process, when all the phandles have been adjusted and resolved and
* you just have to merge overlay into the base device tree.
*
@@ -618,7 +629,7 @@ static int overlay_merge(void *fdt, void *fdto)
if (overlay < 0)
return overlay;
- target = overlay_get_target(fdt, fdto, fragment);
+ target = overlay_get_target(fdt, fdto, fragment, NULL);
if (target < 0)
return target;
@@ -630,6 +641,175 @@ static int overlay_merge(void *fdt, void *fdto)
return 0;
}
+static int get_path_len(const void *fdt, int nodeoffset)
+{
+ int len = 0, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER(fdt);
+
+ for (;;) {
+ name = fdt_get_name(fdt, nodeoffset, &namelen);
+ if (!name)
+ return namelen;
+
+ /* root? we're done */
+ if (namelen == 0)
+ break;
+
+ nodeoffset = fdt_parent_offset(fdt, nodeoffset);
+ if (nodeoffset < 0)
+ return nodeoffset;
+ len += namelen + 1;
+ }
+
+ /* in case of root pretend it's "/" */
+ if (len == 0)
+ len++;
+ return len;
+}
+
+/**
+ * overlay_symbol_update - Update the symbols of base tree after a merge
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_symbol_update() updates the symbols of the base tree with the
+ * symbols of the applied overlay
+ *
+ * This is the last step in the device tree overlay application
+ * process, allowing the reference of overlay symbols by subsequent
+ * overlay operations.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_symbol_update(void *fdt, void *fdto)
+{
+ int root_sym, ov_sym, prop, path_len, fragment, target;
+ int len, frag_name_len, ret, rel_path_len;
+ const char *s, *e;
+ const char *path;
+ const char *name;
+ const char *frag_name;
+ const char *rel_path;
+ const char *target_path;
+ char *buf;
+ void *p;
+
+ ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
+
+ /* if no overlay symbols exist no problem */
+ if (ov_sym < 0)
+ return 0;
+
+ root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
+
+ /* it no root symbols exist we should create them */
+ if (root_sym == -FDT_ERR_NOTFOUND)
+ root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
+
+ /* any error is fatal now */
+ if (root_sym < 0)
+ return root_sym;
+
+ /* iterate over each overlay symbol */
+ fdt_for_each_property_offset(prop, fdto, ov_sym) {
+ path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
+ if (!path)
+ return path_len;
+
+ /* verify it's a string property (terminated by a single \0) */
+ if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
+ return -FDT_ERR_BADVALUE;
+
+ /* keep end marker to avoid strlen() */
+ e = path + path_len;
+
+ /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
+
+ if (*path != '/')
+ return -FDT_ERR_BADVALUE;
+
+ /* get fragment name first */
+ s = strchr(path + 1, '/');
+ if (!s)
+ return -FDT_ERR_BADOVERLAY;
+
+ frag_name = path + 1;
+ frag_name_len = s - path - 1;
+
+ /* verify format; safe since "s" lies in \0 terminated prop */
+ len = sizeof("/__overlay__/") - 1;
+ if ((e - s) < len || memcmp(s, "/__overlay__/", len))
+ return -FDT_ERR_BADOVERLAY;
+
+ rel_path = s + len;
+ rel_path_len = e - rel_path;
+
+ /* find the fragment index in which the symbol lies */
+ ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
+ frag_name_len);
+ /* not found? */
+ if (ret < 0)
+ return -FDT_ERR_BADOVERLAY;
+ fragment = ret;
+
+ /* an __overlay__ subnode must exist */
+ ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
+ if (ret < 0)
+ return -FDT_ERR_BADOVERLAY;
+
+ /* get the target of the fragment */
+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+ if (ret < 0)
+ return ret;
+ target = ret;
+
+ /* if we have a target path use */
+ if (!target_path) {
+ ret = get_path_len(fdt, target);
+ if (ret < 0)
+ return ret;
+ len = ret;
+ } else {
+ len = strlen(target_path);
+ }
+
+ ret = fdt_setprop_placeholder(fdt, root_sym, name,
+ len + (len > 1) + rel_path_len + 1, &p);
+ if (ret < 0)
+ return ret;
+
+ if (!target_path) {
+ /* again in case setprop_placeholder changed it */
+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+ if (ret < 0)
+ return ret;
+ target = ret;
+ }
+
+ buf = p;
+ if (len > 1) { /* target is not root */
+ if (!target_path) {
+ ret = fdt_get_path(fdt, target, buf, len + 1);
+ if (ret < 0)
+ return ret;
+ } else
+ memcpy(buf, target_path, len + 1);
+
+ } else
+ len--;
+
+ buf[len] = '/';
+ memcpy(buf + len + 1, rel_path, rel_path_len);
+ buf[len + 1 + rel_path_len] = '\0';
+ }
+
+ return 0;
+}
+
int fdt_overlay_apply(void *fdt, void *fdto)
{
uint32_t delta = fdt_get_max_phandle(fdt);
@@ -654,6 +834,10 @@ int fdt_overlay_apply(void *fdt, void *fdto)
if (ret)
goto err;
+ ret = overlay_symbol_update(fdt, fdto);
+ if (ret)
+ goto err;
+
/*
* The overlay has been damaged, erase its magic.
*/
--
2.1.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] fdt: Allow stacked overlays phandle references
[not found] ` <1502108769-11203-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
@ 2017-08-09 7:29 ` David Gibson
0 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2017-08-09 7:29 UTC (permalink / raw)
To: Pantelis Antoniou
Cc: Tom Rini, Nishanth Menon, Tero Kristo, Frank Rowand, Rob Herring,
Simon Glass, Devicetree Compiler,
devicetree-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 11174 bytes --]
On Mon, Aug 07, 2017 at 03:26:09PM +0300, Pantelis Antoniou wrote:
> This patch enables an overlay to refer to a previous overlay's
> labels by performing a merge of symbol information at application
> time.
>
> In a nutshell it allows an overlay to refer to a symbol that a previous
> overlay has defined. It requires both the base and all the overlays
> to be compiled with the -@ command line switch so that symbol
> information is included.
Applied, thanks.
>
> base.dts
> --------
>
> /dts-v1/;
> / {
> foo: foonode {
> foo-property;
> };
> };
>
> $ dtc -@ -I dts -O dtb -o base.dtb base.dts
>
> bar.dts
> -------
>
> /dts-v1/;
> /plugin/;
> / {
> fragment@1 {
> target = <&foo>;
> __overlay__ {
> overlay-1-property;
> bar: barnode {
> bar-property;
> };
> };
> };
> };
>
> $ dtc -@ -I dts -O dtb -o bar.dtb bar.dts
>
> baz.dts
> -------
>
> /dts-v1/;
> /plugin/;
> / {
> fragment@1 {
> target = <&bar>;
> __overlay__ {
> overlay-2-property;
> baz: baznode {
> baz-property;
> };
> };
> };
> };
>
> $ dtc -@ -I dts -O dtb -o baz.dtb baz.dts
>
> Applying the overlays:
>
> $ fdtoverlay -i base.dtb -o target.dtb bar.dtb baz.dtb
>
> Dumping:
>
> $ fdtdump target.dtb
> / {
> foonode {
> overlay-1-property;
> foo-property;
> linux,phandle = <0x00000001>;
> phandle = <0x00000001>;
> barnode {
> overlay-2-property;
> phandle = <0x00000002>;
> linux,phandle = <0x00000002>;
> bar-property;
> baznode {
> phandle = <0x00000003>;
> linux,phandle = <0x00000003>;
> baz-property;
> };
> };
> };
> __symbols__ {
> baz = "/foonode/barnode/baznode";
> bar = "/foonode/barnode";
> foo = "/foonode";
> };
> };
>
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
> libfdt/fdt_overlay.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 206 insertions(+), 22 deletions(-)
>
> diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
> index ceb9687..bd81241 100644
> --- a/libfdt/fdt_overlay.c
> +++ b/libfdt/fdt_overlay.c
> @@ -39,6 +39,7 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
> * @fdt: Base device tree blob
> * @fdto: Device tree overlay blob
> * @fragment: node offset of the fragment in the overlay
> + * @pathp: pointer which receives the path of the target (or NULL)
> *
> * overlay_get_target() retrieves the target offset in the base
> * device tree of a fragment, no matter how the actual targetting is
> @@ -49,37 +50,47 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
> * Negative error code on error
> */
> static int overlay_get_target(const void *fdt, const void *fdto,
> - int fragment)
> + int fragment, char const **pathp)
> {
> uint32_t phandle;
> - const char *path;
> - int path_len;
> + const char *path = NULL;
> + int path_len = 0, ret;
>
> /* Try first to do a phandle based lookup */
> phandle = overlay_get_target_phandle(fdto, fragment);
> if (phandle == (uint32_t)-1)
> return -FDT_ERR_BADPHANDLE;
>
> - if (phandle)
> - return fdt_node_offset_by_phandle(fdt, phandle);
> + /* no phandle, try path */
> + if (!phandle) {
> + /* And then a path based lookup */
> + path = fdt_getprop(fdto, fragment, "target-path", &path_len);
> + if (path)
> + ret = fdt_path_offset(fdt, path);
> + else
> + ret = path_len;
> + } else
> + ret = fdt_node_offset_by_phandle(fdt, phandle);
>
> - /* And then a path based lookup */
> - path = fdt_getprop(fdto, fragment, "target-path", &path_len);
> - if (!path) {
> - /*
> - * If we haven't found either a target or a
> - * target-path property in a node that contains a
> - * __overlay__ subnode (we wouldn't be called
> - * otherwise), consider it a improperly written
> - * overlay
> - */
> - if (path_len == -FDT_ERR_NOTFOUND)
> - return -FDT_ERR_BADOVERLAY;
> + /*
> + * If we haven't found either a target or a
> + * target-path property in a node that contains a
> + * __overlay__ subnode (we wouldn't be called
> + * otherwise), consider it a improperly written
> + * overlay
> + */
> + if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
> + ret = -FDT_ERR_BADOVERLAY;
> +
> + /* return on error */
> + if (ret < 0)
> + return ret;
>
> - return path_len;
> - }
> + /* return pointer to path (if available) */
> + if (pathp)
> + *pathp = path ? path : NULL;
>
> - return fdt_path_offset(fdt, path);
> + return ret;
> }
>
> /**
> @@ -590,7 +601,7 @@ static int overlay_apply_node(void *fdt, int target,
> *
> * overlay_merge() merges an overlay into its base device tree.
> *
> - * This is the final step in the device tree overlay application
> + * This is the next to last step in the device tree overlay application
> * process, when all the phandles have been adjusted and resolved and
> * you just have to merge overlay into the base device tree.
> *
> @@ -618,7 +629,7 @@ static int overlay_merge(void *fdt, void *fdto)
> if (overlay < 0)
> return overlay;
>
> - target = overlay_get_target(fdt, fdto, fragment);
> + target = overlay_get_target(fdt, fdto, fragment, NULL);
> if (target < 0)
> return target;
>
> @@ -630,6 +641,175 @@ static int overlay_merge(void *fdt, void *fdto)
> return 0;
> }
>
> +static int get_path_len(const void *fdt, int nodeoffset)
> +{
> + int len = 0, namelen;
> + const char *name;
> +
> + FDT_CHECK_HEADER(fdt);
> +
> + for (;;) {
> + name = fdt_get_name(fdt, nodeoffset, &namelen);
> + if (!name)
> + return namelen;
> +
> + /* root? we're done */
> + if (namelen == 0)
> + break;
> +
> + nodeoffset = fdt_parent_offset(fdt, nodeoffset);
> + if (nodeoffset < 0)
> + return nodeoffset;
> + len += namelen + 1;
> + }
> +
> + /* in case of root pretend it's "/" */
> + if (len == 0)
> + len++;
> + return len;
> +}
> +
> +/**
> + * overlay_symbol_update - Update the symbols of base tree after a merge
> + * @fdt: Base Device Tree blob
> + * @fdto: Device tree overlay blob
> + *
> + * overlay_symbol_update() updates the symbols of the base tree with the
> + * symbols of the applied overlay
> + *
> + * This is the last step in the device tree overlay application
> + * process, allowing the reference of overlay symbols by subsequent
> + * overlay operations.
> + *
> + * returns:
> + * 0 on success
> + * Negative error code on failure
> + */
> +static int overlay_symbol_update(void *fdt, void *fdto)
> +{
> + int root_sym, ov_sym, prop, path_len, fragment, target;
> + int len, frag_name_len, ret, rel_path_len;
> + const char *s, *e;
> + const char *path;
> + const char *name;
> + const char *frag_name;
> + const char *rel_path;
> + const char *target_path;
> + char *buf;
> + void *p;
> +
> + ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
> +
> + /* if no overlay symbols exist no problem */
> + if (ov_sym < 0)
> + return 0;
> +
> + root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
> +
> + /* it no root symbols exist we should create them */
> + if (root_sym == -FDT_ERR_NOTFOUND)
> + root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
> +
> + /* any error is fatal now */
> + if (root_sym < 0)
> + return root_sym;
> +
> + /* iterate over each overlay symbol */
> + fdt_for_each_property_offset(prop, fdto, ov_sym) {
> + path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
> + if (!path)
> + return path_len;
> +
> + /* verify it's a string property (terminated by a single \0) */
> + if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
> + return -FDT_ERR_BADVALUE;
> +
> + /* keep end marker to avoid strlen() */
> + e = path + path_len;
> +
> + /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
> +
> + if (*path != '/')
> + return -FDT_ERR_BADVALUE;
> +
> + /* get fragment name first */
> + s = strchr(path + 1, '/');
> + if (!s)
> + return -FDT_ERR_BADOVERLAY;
> +
> + frag_name = path + 1;
> + frag_name_len = s - path - 1;
> +
> + /* verify format; safe since "s" lies in \0 terminated prop */
> + len = sizeof("/__overlay__/") - 1;
> + if ((e - s) < len || memcmp(s, "/__overlay__/", len))
> + return -FDT_ERR_BADOVERLAY;
> +
> + rel_path = s + len;
> + rel_path_len = e - rel_path;
> +
> + /* find the fragment index in which the symbol lies */
> + ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
> + frag_name_len);
> + /* not found? */
> + if (ret < 0)
> + return -FDT_ERR_BADOVERLAY;
> + fragment = ret;
> +
> + /* an __overlay__ subnode must exist */
> + ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
> + if (ret < 0)
> + return -FDT_ERR_BADOVERLAY;
> +
> + /* get the target of the fragment */
> + ret = overlay_get_target(fdt, fdto, fragment, &target_path);
> + if (ret < 0)
> + return ret;
> + target = ret;
> +
> + /* if we have a target path use */
> + if (!target_path) {
> + ret = get_path_len(fdt, target);
> + if (ret < 0)
> + return ret;
> + len = ret;
> + } else {
> + len = strlen(target_path);
> + }
> +
> + ret = fdt_setprop_placeholder(fdt, root_sym, name,
> + len + (len > 1) + rel_path_len + 1, &p);
> + if (ret < 0)
> + return ret;
> +
> + if (!target_path) {
> + /* again in case setprop_placeholder changed it */
> + ret = overlay_get_target(fdt, fdto, fragment, &target_path);
> + if (ret < 0)
> + return ret;
> + target = ret;
> + }
> +
> + buf = p;
> + if (len > 1) { /* target is not root */
> + if (!target_path) {
> + ret = fdt_get_path(fdt, target, buf, len + 1);
> + if (ret < 0)
> + return ret;
> + } else
> + memcpy(buf, target_path, len + 1);
> +
> + } else
> + len--;
> +
> + buf[len] = '/';
> + memcpy(buf + len + 1, rel_path, rel_path_len);
> + buf[len + 1 + rel_path_len] = '\0';
> + }
> +
> + return 0;
> +}
> +
> int fdt_overlay_apply(void *fdt, void *fdto)
> {
> uint32_t delta = fdt_get_max_phandle(fdt);
> @@ -654,6 +834,10 @@ int fdt_overlay_apply(void *fdt, void *fdto)
> if (ret)
> goto err;
>
> + ret = overlay_symbol_update(fdt, fdto);
> + if (ret)
> + goto err;
> +
> /*
> * The overlay has been damaged, erase its magic.
> */
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-08-09 7:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-31 17:09 [PATCH] fdt: Allow stacked overlays phandle references Pantelis Antoniou
[not found] ` <1501520996-3366-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
2017-08-07 5:01 ` David Gibson
-- strict thread matches above, loose matches on Subject: below --
2017-08-07 12:26 Pantelis Antoniou
[not found] ` <1502108769-11203-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
2017-08-09 7:29 ` David Gibson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).