*       a live devicetree created from Open Firmware.
  *
  * NOTE_2: Multiple mods of created nodes not supported.
- *       If more than one fragment contains a node that does not already exist
- *       in the live tree, then for each fragment of_changeset_attach_node()
- *       will add a changeset entry to add the node.  When the changeset is
- *       applied, __of_attach_node() will attach the node twice (once for
- *       each fragment).  At this point the device tree will be corrupted.
- *
- *       TODO: add integrity check to ensure that multiple fragments do not
- *             create the same node.
  *
  * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
  * invalid @overlay.
        return 0;
 }
 
+/**
+ * check_changeset_dup_add_node() - changeset validation: duplicate add node
+ * @ovcs:      Overlay changeset
+ *
+ * Check changeset @ovcs->cset for multiple add node entries for the same
+ * node.
+ *
+ * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid overlay in @ovcs->fragments[].
+ */
+static int check_changeset_dup_add_node(struct overlay_changeset *ovcs)
+{
+       struct of_changeset_entry *ce_1, *ce_2;
+       char *fn_1, *fn_2;
+       int name_match;
+
+       list_for_each_entry(ce_1, &ovcs->cset.entries, node) {
+
+               if (ce_1->action == OF_RECONFIG_ATTACH_NODE ||
+                   ce_1->action == OF_RECONFIG_DETACH_NODE) {
+
+                       ce_2 = ce_1;
+                       list_for_each_entry_continue(ce_2, &ovcs->cset.entries, node) {
+                               if (ce_2->action == OF_RECONFIG_ATTACH_NODE ||
+                                   ce_2->action == OF_RECONFIG_DETACH_NODE) {
+                                       /* inexpensive name compare */
+                                       if (!of_node_cmp(ce_1->np->full_name,
+                                           ce_2->np->full_name)) {
+                                               /* expensive full path name compare */
+                                               fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
+                                               fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
+                                               name_match = !strcmp(fn_1, fn_2);
+                                               kfree(fn_1);
+                                               kfree(fn_2);
+                                               if (name_match) {
+                                                       pr_err("ERROR: multiple overlay fragments add and/or delete node %pOF\n",
+                                                              ce_1->np);
+                                                       return -EINVAL;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
 /**
  * build_changeset() - populate overlay changeset in @ovcs from @ovcs->fragments
  * @ovcs:      Overlay changeset
                }
        }
 
-       return 0;
+       return check_changeset_dup_add_node(ovcs);
 }
 
 /*