This commit is contained in:
Pascal Vizeli 2018-06-03 23:46:05 +00:00
parent 9ec32eda85
commit d647590d98

View File

@ -1,18 +1,18 @@
From 4232fb9cd5303696ed8487763702fbe84421db57 Mon Sep 17 00:00:00 2001 From 6c7c35474f066f53b6f63cc0cc5eaefac2bc69dd Mon Sep 17 00:00:00 2001
From: Pascal Vizeli <pvizeli@syshack.ch> From: Pascal Vizeli <pvizeli@syshack.ch>
Date: Sat, 2 Jun 2018 20:53:51 +0000 Date: Sat, 2 Jun 2018 20:53:51 +0000
Subject: [PATCH 3/3] drivers: of: bugfix local fixups resolving Subject: [PATCH 3/3] drivers: of: bugfix local fixups resolving
Signed-off-by: Pascal Vizeli <pvizeli@syshack.ch> Signed-off-by: Pascal Vizeli <pvizeli@syshack.ch>
--- ---
drivers/of/resolver.c | 144 +++++++++++++++++------------------------- drivers/of/resolver.c | 147 +++++++++++++++++-------------------------
1 file changed, 58 insertions(+), 86 deletions(-) 1 file changed, 60 insertions(+), 87 deletions(-)
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index 62476093c..03c61e959 100644 index 62476093c..fbab565c5 100644
--- a/drivers/of/resolver.c --- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c +++ b/drivers/of/resolver.c
@@ -66,108 +66,72 @@ static void of_adjust_tree_phandles(struct device_node *node, @@ -66,108 +66,73 @@ static void of_adjust_tree_phandles(struct device_node *node,
* of the tree. Does not take any devtree locks so make sure you * of the tree. Does not take any devtree locks so make sure you
* call this on a tree which is at the detached state. * call this on a tree which is at the detached state.
*/ */
@ -27,13 +27,13 @@ index 62476093c..03c61e959 100644
- char *propval, *propcur, *propend, *nodestr, *propstr, *s; - char *propval, *propcur, *propend, *nodestr, *propstr, *s;
- int offset, propcurlen; - int offset, propcurlen;
- int err; - int err;
- bool found = false;
+ struct device_node *child, *overlay_child; + struct device_node *child, *overlay_child;
+ struct property *fixprop, *prop; + struct property *fixprop, *prop;
+ int i, count, err; + int i, count, err;
+ unsigned int off; + unsigned int off;
bool found = false;
/* locate the symbols & fixups nodes on resolve */ - /* locate the symbols & fixups nodes on resolve */
- for_each_child_of_node(node, child) - for_each_child_of_node(node, child)
- if (of_node_cmp(child->name, "__local_fixups__") == 0) { - if (of_node_cmp(child->name, "__local_fixups__") == 0) {
- found = true; - found = true;
@ -42,17 +42,16 @@ index 62476093c..03c61e959 100644
- -
- /* no local fixups */ - /* no local fixups */
- if (!found) - if (!found)
+ if (!local_fixups) - return 0;
return 0; -
- /* find the local fixups property */ - /* find the local fixups property */
- for_each_property_of_node(child, rprop) { - for_each_property_of_node(child, rprop) {
+ for_each_property_of_node(local_fixups, fixprop) { + for_each_property_of_node(local_fixups, fixprop) {
/* skip properties added automatically */ /* skip properties added automatically */
- if (of_prop_cmp(rprop->name, "name") == 0) - if (of_prop_cmp(rprop->name, "name") == 0)
+ if (of_prop_cmp(fixprop->name, "name") == 0 || + if (!of_prop_cmp(fixprop->name, "name") ||
+ of_prop_cmp(fixprop->name, "phandle") == 0 || + !of_prop_cmp(fixprop->name, "phandle") ||
+ of_prop_cmp(fixprop->name, "linux,phandle") == 0) + !of_prop_cmp(fixprop->name, "linux,phandle"))
continue; continue;
- /* make a copy */ - /* make a copy */
@ -67,7 +66,10 @@ index 62476093c..03c61e959 100644
- propend = propval + rprop->length; - propend = propval + rprop->length;
- for (propcur = propval; propcur < propend; - for (propcur = propval; propcur < propend;
- propcur += propcurlen + 1) { - propcur += propcurlen + 1) {
- + if ((fixprop->length % 4) != 0 || fixprop->length == 0)
+ return -EINVAL;
+ count = fixprop->length / sizeof(uint32_t);
- propcurlen = strlen(propcur); - propcurlen = strlen(propcur);
- -
- nodestr = propcur; - nodestr = propcur;
@ -79,10 +81,7 @@ index 62476093c..03c61e959 100644
- goto err_fail; - goto err_fail;
- } - }
- *s++ = '\0'; - *s++ = '\0';
+ if ((fixprop->length % 4) != 0 || fixprop->length == 0) -
+ return -EINVAL;
+ count = fixprop->length / sizeof(uint32_t);
- propstr = s; - propstr = s;
- s = strchr(s, ':'); - s = strchr(s, ':');
- if (s == NULL) { - if (s == NULL) {
@ -90,14 +89,17 @@ index 62476093c..03c61e959 100644
- __func__, (char *)rprop->value); - __func__, (char *)rprop->value);
- err = -EINVAL; - err = -EINVAL;
- goto err_fail; - goto err_fail;
- } + for_each_property_of_node(overlay, prop) {
- + if (!of_prop_cmp(fixprop->name, prop->name)) {
+ found = true;
+ break;
}
+ }
- *s++ = '\0'; - *s++ = '\0';
- offset = simple_strtoul(s, NULL, 10); - offset = simple_strtoul(s, NULL, 10);
+ for_each_property_of_node(overlay, prop) { + if (!found)
+ if (!of_prop_cmp(fixprop->name, prop->name)) + return -EINVAL;
+ break;
+ }
- /* look into the resolve node for the full path */ - /* look into the resolve node for the full path */
- refnode = of_find_node_by_path_from(node, nodestr); - refnode = of_find_node_by_path_from(node, nodestr);
@ -106,7 +108,9 @@ index 62476093c..03c61e959 100644
- __func__, (char *)rprop->value); - __func__, (char *)rprop->value);
- continue; - continue;
- } - }
+ if (!prop) + for (i=0; i < count; i++) {
+ off = be32_to_cpu(((uint32_t *)fixprop->value)[i]);
+ if ((off + 4) > prop->length)
+ return -EINVAL; + return -EINVAL;
- /* now find the property */ - /* now find the property */
@ -116,29 +120,17 @@ index 62476093c..03c61e959 100644
- found = true; - found = true;
- break; - break;
- } - }
+ for (i=0; i < count; i++) { + phandle = be32_to_cpu(*(uint32_t *)(prop->value + off));
+ off = be32_to_cpu(((uint32_t *)fixprop->value)[i]); + phandle += phandle_delta;
+ if ((off + 4) > prop->length) + *(uint32_t *)(prop->value + off) = cpu_to_be32(phandle);
+ return -EINVAL; + }
+ }
- if (!found) { - if (!found) {
- pr_err("%s: Could not find property '%s'\n", - pr_err("%s: Could not find property '%s'\n",
- __func__, (char *)rprop->value); - __func__, (char *)rprop->value);
- err = -ENOENT; - err = -ENOENT;
- goto err_fail; - goto err_fail;
- }
-
- phandle = be32_to_cpu(*(uint32_t *)
- (sprop->value + offset));
- *(uint32_t *)(sprop->value + offset) =
- cpu_to_be32(phandle + phandle_delta);
+ phandle = be32_to_cpu(*(uint32_t *)(prop->value + off));
+ phandle += phandle_delta;
+ *(uint32_t *)(prop->value + off) = cpu_to_be32(phandle);
}
+ }
- kfree(propval);
+ /* + /*
+ * These nested loops recurse down two subtrees in parallel, where the + * These nested loops recurse down two subtrees in parallel, where the
+ * node names in the two subtrees match. + * node names in the two subtrees match.
@ -149,12 +141,20 @@ index 62476093c..03c61e959 100644
+ for_each_child_of_node(local_fixups, child) { + for_each_child_of_node(local_fixups, child) {
+ +
+ for_each_child_of_node(overlay, overlay_child) + for_each_child_of_node(overlay, overlay_child)
+ if (!of_node_cmp(child->name, overlay_child->name)) + if (!of_node_cmp(child->name, overlay_child->name)) {
+ found = true;
+ break; + break;
+ }
+ if (!overlay_child)
- phandle = be32_to_cpu(*(uint32_t *)
- (sprop->value + offset));
- *(uint32_t *)(sprop->value + offset) =
- cpu_to_be32(phandle + phandle_delta);
- }
+ if (!found)
+ return -EINVAL; + return -EINVAL;
+
- kfree(propval);
+ err = of_adjust_tree_phandle_references(child, overlay_child, + err = of_adjust_tree_phandle_references(child, overlay_child,
+ phandle_delta); + phandle_delta);
+ if (err) + if (err)
@ -169,7 +169,7 @@ index 62476093c..03c61e959 100644
} }
/** /**
@@ -185,7 +149,7 @@ err_fail: @@ -185,7 +150,7 @@ err_fail:
*/ */
int of_resolve(struct device_node *resolve) int of_resolve(struct device_node *resolve)
{ {
@ -178,23 +178,27 @@ index 62476093c..03c61e959 100644
struct device_node *root_sym, *resolve_sym, *resolve_fix; struct device_node *root_sym, *resolve_sym, *resolve_fix;
struct property *rprop, *sprop; struct property *rprop, *sprop;
const char *refpath; const char *refpath;
@@ -203,7 +167,15 @@ int of_resolve(struct device_node *resolve) @@ -203,9 +168,17 @@ int of_resolve(struct device_node *resolve)
/* first we need to adjust the phandles */ /* first we need to adjust the phandles */
phandle_delta = of_get_tree_max_phandle(NULL) + 1; phandle_delta = of_get_tree_max_phandle(NULL) + 1;
of_adjust_tree_phandles(resolve, phandle_delta); of_adjust_tree_phandles(resolve, phandle_delta);
- err = of_adjust_tree_phandle_references(resolve, phandle_delta); - err = of_adjust_tree_phandle_references(resolve, phandle_delta);
- if (err != 0)
- return err;
+ +
+ /* second we need lookup local fixups of phandles */ + /* second we need lookup local fixups of phandles */
+ for_each_child_of_node(resolve, local_fixups) { + for_each_child_of_node(resolve, local_fixups) {
+ if (!of_node_cmp(local_fixups->name, "__local_fixups__")) + if (!of_node_cmp(local_fixups->name, "__local_fixups__")) {
+ err = of_adjust_tree_phandle_references(local_fixups,
+ resolve, phandle_delta);
+ if (err != 0)
+ return err;
+ break; + break;
+ } + }
+ + }
+ err = of_adjust_tree_phandle_references(local_fixups, resolve,
+ phandle_delta);
if (err != 0)
return err;
root_sym = NULL;
resolve_sym = NULL;
-- --
2.17.0 2.17.0