Skip to content

Commit c168263

Browse files
committed
of: overlay: check prevents multiple fragments add or delete same node
Multiple overlay fragments adding or deleting the same node is not supported. Replace code comment of such, with check to detect the attempt and fail the overlay apply. Devicetree unittest where multiple fragments added the same node was added in the previous patch in the series. After applying this patch the unittest messages will no longer include: Duplicate name in motor-1, renamed to "controller#1" OF: overlay: of_overlay_apply() err=0 ### dt-test ### of_overlay_fdt_apply() expected -22, ret=0, overlay_bad_add_dup_node ### dt-test ### FAIL of_unittest_overlay_high_level():2419 Adding overlay 'overlay_bad_add_dup_node' failed ... ### dt-test ### end of unittest - 210 passed, 1 failed but will instead include: OF: overlay: ERROR: multiple overlay fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller ... ### dt-test ### end of unittest - 211 passed, 0 failed Tested-by: Alan Tull <atull@kernel.org> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
1 parent a68238a commit c168263

File tree

1 file changed

+49
-9
lines changed

1 file changed

+49
-9
lines changed

drivers/of/overlay.c

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -392,14 +392,6 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
392392
* a live devicetree created from Open Firmware.
393393
*
394394
* NOTE_2: Multiple mods of created nodes not supported.
395-
* If more than one fragment contains a node that does not already exist
396-
* in the live tree, then for each fragment of_changeset_attach_node()
397-
* will add a changeset entry to add the node. When the changeset is
398-
* applied, __of_attach_node() will attach the node twice (once for
399-
* each fragment). At this point the device tree will be corrupted.
400-
*
401-
* TODO: add integrity check to ensure that multiple fragments do not
402-
* create the same node.
403395
*
404396
* Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
405397
* invalid @overlay.
@@ -516,6 +508,54 @@ static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
516508
return 0;
517509
}
518510

511+
/**
512+
* check_changeset_dup_add_node() - changeset validation: duplicate add node
513+
* @ovcs: Overlay changeset
514+
*
515+
* Check changeset @ovcs->cset for multiple add node entries for the same
516+
* node.
517+
*
518+
* Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
519+
* invalid overlay in @ovcs->fragments[].
520+
*/
521+
static int check_changeset_dup_add_node(struct overlay_changeset *ovcs)
522+
{
523+
struct of_changeset_entry *ce_1, *ce_2;
524+
char *fn_1, *fn_2;
525+
int name_match;
526+
527+
list_for_each_entry(ce_1, &ovcs->cset.entries, node) {
528+
529+
if (ce_1->action == OF_RECONFIG_ATTACH_NODE ||
530+
ce_1->action == OF_RECONFIG_DETACH_NODE) {
531+
532+
ce_2 = ce_1;
533+
list_for_each_entry_continue(ce_2, &ovcs->cset.entries, node) {
534+
if (ce_2->action == OF_RECONFIG_ATTACH_NODE ||
535+
ce_2->action == OF_RECONFIG_DETACH_NODE) {
536+
/* inexpensive name compare */
537+
if (!of_node_cmp(ce_1->np->full_name,
538+
ce_2->np->full_name)) {
539+
/* expensive full path name compare */
540+
fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
541+
fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
542+
name_match = !strcmp(fn_1, fn_2);
543+
kfree(fn_1);
544+
kfree(fn_2);
545+
if (name_match) {
546+
pr_err("ERROR: multiple overlay fragments add and/or delete node %pOF\n",
547+
ce_1->np);
548+
return -EINVAL;
549+
}
550+
}
551+
}
552+
}
553+
}
554+
}
555+
556+
return 0;
557+
}
558+
519559
/**
520560
* build_changeset() - populate overlay changeset in @ovcs from @ovcs->fragments
521561
* @ovcs: Overlay changeset
@@ -571,7 +611,7 @@ static int build_changeset(struct overlay_changeset *ovcs)
571611
}
572612
}
573613

574-
return 0;
614+
return check_changeset_dup_add_node(ovcs);
575615
}
576616

577617
/*

0 commit comments

Comments
 (0)