From c68516381214ee2bd1797fc35582829197faa5ee Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 6 Jun 2019 21:55:40 +0200 Subject: [PATCH] 4.19-stable patches added patches: of-overlay-set-node-fields-from-properties-when-add-new-overlay-node.patch of-overlay-validate-overlay-properties-address-cells-and-size-cells.patch --- ...properties-when-add-new-overlay-node.patch | 133 ++++++++++++++++++ ...perties-address-cells-and-size-cells.patch | 101 +++++++++++++ queue-4.19/series | 2 + 3 files changed, 236 insertions(+) create mode 100644 queue-4.19/of-overlay-set-node-fields-from-properties-when-add-new-overlay-node.patch create mode 100644 queue-4.19/of-overlay-validate-overlay-properties-address-cells-and-size-cells.patch diff --git a/queue-4.19/of-overlay-set-node-fields-from-properties-when-add-new-overlay-node.patch b/queue-4.19/of-overlay-set-node-fields-from-properties-when-add-new-overlay-node.patch new file mode 100644 index 00000000000..27d98bcc70a --- /dev/null +++ b/queue-4.19/of-overlay-set-node-fields-from-properties-when-add-new-overlay-node.patch @@ -0,0 +1,133 @@ +From f96278810150fc39085d1872e5b39ea06366d03e Mon Sep 17 00:00:00 2001 +From: Frank Rowand +Date: Fri, 12 Oct 2018 19:21:16 -0700 +Subject: of: overlay: set node fields from properties when add new overlay node + +From: Frank Rowand + +commit f96278810150fc39085d1872e5b39ea06366d03e upstream. + +Overlay nodes added by add_changeset_node() do not have the node +fields name, phandle, and type set. + +The node passed to __of_attach_node() when the add node changeset +entry is processed does not contain any properties. The node's +properties are located in add property changeset entries that will +be processed after the add node changeset is applied. + +Set the node's fields in the node contained in the add node +changeset entry and do not set them to incorrect values in +add_changeset_node(). + +A visible symptom that is fixed by this patch is the names of nodes +added by overlays that have an entry in /sys/bus/platform/drivers/*/ +will contain the unit-address but the node-name will be , for +example, "fc4ab000.". After applying the patch the name, in +this example, for node restart@fc4ab000 is "fc4ab000.restart". + +Tested-by: Alan Tull +Signed-off-by: Frank Rowand +Cc: Phil Elwell +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/dynamic.c | 25 +++++++++++++++++-------- + drivers/of/overlay.c | 29 ++++++++++++++++++++++++----- + 2 files changed, 41 insertions(+), 13 deletions(-) + +--- a/drivers/of/dynamic.c ++++ b/drivers/of/dynamic.c +@@ -205,15 +205,24 @@ static void __of_attach_node(struct devi + const __be32 *phandle; + int sz; + +- np->name = __of_get_property(np, "name", NULL) ? : ""; +- np->type = __of_get_property(np, "device_type", NULL) ? : ""; ++ if (!of_node_check_flag(np, OF_OVERLAY)) { ++ np->name = __of_get_property(np, "name", NULL); ++ np->type = __of_get_property(np, "device_type", NULL); ++ if (!np->name) ++ np->name = ""; ++ if (!np->type) ++ np->type = ""; + +- phandle = __of_get_property(np, "phandle", &sz); +- if (!phandle) +- phandle = __of_get_property(np, "linux,phandle", &sz); +- if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle) +- phandle = __of_get_property(np, "ibm,phandle", &sz); +- np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0; ++ phandle = __of_get_property(np, "phandle", &sz); ++ if (!phandle) ++ phandle = __of_get_property(np, "linux,phandle", &sz); ++ if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle) ++ phandle = __of_get_property(np, "ibm,phandle", &sz); ++ if (phandle && (sz >= 4)) ++ np->phandle = be32_to_cpup(phandle); ++ else ++ np->phandle = 0; ++ } + + np->child = NULL; + np->sibling = np->parent->child; +--- a/drivers/of/overlay.c ++++ b/drivers/of/overlay.c +@@ -307,10 +307,11 @@ static int add_changeset_property(struct + int ret = 0; + bool check_for_non_overlay_node = false; + +- if (!of_prop_cmp(overlay_prop->name, "name") || +- !of_prop_cmp(overlay_prop->name, "phandle") || +- !of_prop_cmp(overlay_prop->name, "linux,phandle")) +- return 0; ++ if (target->in_livetree) ++ if (!of_prop_cmp(overlay_prop->name, "name") || ++ !of_prop_cmp(overlay_prop->name, "phandle") || ++ !of_prop_cmp(overlay_prop->name, "linux,phandle")) ++ return 0; + + if (target->in_livetree) + prop = of_find_property(target->np, overlay_prop->name, NULL); +@@ -330,6 +331,10 @@ static int add_changeset_property(struct + + if (!prop) { + check_for_non_overlay_node = true; ++ if (!target->in_livetree) { ++ new_prop->next = target->np->deadprops; ++ target->np->deadprops = new_prop; ++ } + ret = of_changeset_add_property(&ovcs->cset, target->np, + new_prop); + } else if (!of_prop_cmp(prop->name, "#address-cells")) { +@@ -408,9 +413,10 @@ static int add_changeset_node(struct ove + struct target *target, struct device_node *node) + { + const char *node_kbasename; ++ const __be32 *phandle; + struct device_node *tchild; + struct target target_child; +- int ret = 0; ++ int ret = 0, size; + + node_kbasename = kbasename(node->full_name); + +@@ -424,6 +430,19 @@ static int add_changeset_node(struct ove + return -ENOMEM; + + tchild->parent = target->np; ++ tchild->name = __of_get_property(node, "name", NULL); ++ tchild->type = __of_get_property(node, "device_type", NULL); ++ ++ if (!tchild->name) ++ tchild->name = ""; ++ if (!tchild->type) ++ tchild->type = ""; ++ ++ /* ignore obsolete "linux,phandle" */ ++ phandle = __of_get_property(node, "phandle", &size); ++ if (phandle && (size == 4)) ++ tchild->phandle = be32_to_cpup(phandle); ++ + of_node_set_flag(tchild, OF_OVERLAY); + + ret = of_changeset_attach_node(&ovcs->cset, tchild); diff --git a/queue-4.19/of-overlay-validate-overlay-properties-address-cells-and-size-cells.patch b/queue-4.19/of-overlay-validate-overlay-properties-address-cells-and-size-cells.patch new file mode 100644 index 00000000000..b5da5c1bd16 --- /dev/null +++ b/queue-4.19/of-overlay-validate-overlay-properties-address-cells-and-size-cells.patch @@ -0,0 +1,101 @@ +From 6f75118800acf77f8ad6afec61ca1b2349ade371 Mon Sep 17 00:00:00 2001 +From: Frank Rowand +Date: Thu, 4 Oct 2018 20:32:04 -0700 +Subject: of: overlay: validate overlay properties #address-cells and #size-cells + +From: Frank Rowand + +commit 6f75118800acf77f8ad6afec61ca1b2349ade371 upstream. + +If overlay properties #address-cells or #size-cells are already in +the live devicetree for any given node, then the values in the +overlay must match the values in the live tree. + +If the properties are already in the live tree then there is no +need to create a changeset entry to add them since they must +have the same value. This reduces the memory used by the +changeset and eliminates a possible memory leak. + +Tested-by: Alan Tull +Signed-off-by: Frank Rowand +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/overlay.c | 32 +++++++++++++++++++++++++++++--- + include/linux/of.h | 6 ++++++ + 2 files changed, 35 insertions(+), 3 deletions(-) + +--- a/drivers/of/overlay.c ++++ b/drivers/of/overlay.c +@@ -287,7 +287,12 @@ err_free_target_path: + * @target may be either in the live devicetree or in a new subtree that + * is contained in the changeset. + * +- * Some special properties are not updated (no error returned). ++ * Some special properties are not added or updated (no error returned): ++ * "name", "phandle", "linux,phandle". ++ * ++ * Properties "#address-cells" and "#size-cells" are not updated if they ++ * are already in the live tree, but if present in the live tree, the values ++ * in the overlay must match the values in the live tree. + * + * Update of property in symbols node is not allowed. + * +@@ -300,6 +305,7 @@ static int add_changeset_property(struct + { + struct property *new_prop = NULL, *prop; + int ret = 0; ++ bool check_for_non_overlay_node = false; + + if (!of_prop_cmp(overlay_prop->name, "name") || + !of_prop_cmp(overlay_prop->name, "phandle") || +@@ -322,12 +328,32 @@ static int add_changeset_property(struct + if (!new_prop) + return -ENOMEM; + +- if (!prop) ++ if (!prop) { ++ check_for_non_overlay_node = true; + ret = of_changeset_add_property(&ovcs->cset, target->np, + new_prop); +- else ++ } else if (!of_prop_cmp(prop->name, "#address-cells")) { ++ if (!of_prop_val_eq(prop, new_prop)) { ++ pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n", ++ target->np); ++ ret = -EINVAL; ++ } ++ } else if (!of_prop_cmp(prop->name, "#size-cells")) { ++ if (!of_prop_val_eq(prop, new_prop)) { ++ pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n", ++ target->np); ++ ret = -EINVAL; ++ } ++ } else { ++ check_for_non_overlay_node = true; + ret = of_changeset_update_property(&ovcs->cset, target->np, + new_prop); ++ } ++ ++ if (check_for_non_overlay_node && ++ !of_node_check_flag(target->np, OF_OVERLAY)) ++ pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n", ++ target->np, new_prop->name); + + if (ret) { + kfree(new_prop->name); +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -968,6 +968,12 @@ static inline int of_cpu_node_to_id(stru + #define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) + #endif + ++static inline int of_prop_val_eq(struct property *p1, struct property *p2) ++{ ++ return p1->length == p2->length && ++ !memcmp(p1->value, p2->value, (size_t)p1->length); ++} ++ + #if defined(CONFIG_OF) && defined(CONFIG_NUMA) + extern int of_node_to_nid(struct device_node *np); + #else diff --git a/queue-4.19/series b/queue-4.19/series index a5cd9b963d3..1e7092b97b6 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -68,3 +68,5 @@ x86-ftrace-do-not-call-function-graph-from-dynamic-t.patch x86-ftrace-set-trampoline-pages-as-executable.patch x86-kprobes-set-instruction-page-as-executable.patch scsi-lpfc-fix-backport-of-faf5a744f4f8-scsi-lpfc-avoid-uninitialized-variable-warning.patch +of-overlay-validate-overlay-properties-address-cells-and-size-cells.patch +of-overlay-set-node-fields-from-properties-when-add-new-overlay-node.patch -- 2.47.2