This source file includes following definitions.
- devicetree_corrupt
- of_overlay_mutex_lock
- of_overlay_mutex_unlock
- of_overlay_notifier_register
- of_overlay_notifier_unregister
- overlay_notify
- dup_and_fixup_symbol_prop
- add_changeset_property
- add_changeset_node
- build_changeset_next_level
- build_changeset_symbols_node
- find_dup_cset_node_entry
- find_dup_cset_prop
- changeset_dup_entry_check
- build_changeset
- find_target
- init_overlay_changeset
- free_overlay_changeset
- of_overlay_apply
- of_overlay_fdt_apply
- find_node
- node_overlaps_later_cs
- overlay_removal_is_ok
- of_overlay_remove
- of_overlay_remove_all
1
2
3
4
5
6
7
8
9 #define pr_fmt(fmt) "OF: overlay: " fmt
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/of_device.h>
15 #include <linux/of_fdt.h>
16 #include <linux/string.h>
17 #include <linux/ctype.h>
18 #include <linux/errno.h>
19 #include <linux/slab.h>
20 #include <linux/libfdt.h>
21 #include <linux/err.h>
22 #include <linux/idr.h>
23
24 #include "of_private.h"
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 struct target {
42 struct device_node *np;
43 bool in_livetree;
44 };
45
46
47
48
49
50
51 struct fragment {
52 struct device_node *overlay;
53 struct device_node *target;
54 };
55
56
57
58
59
60
61
62
63
64
65
66
67 struct overlay_changeset {
68 int id;
69 struct list_head ovcs_list;
70 const void *fdt;
71 struct device_node *overlay_tree;
72 int count;
73 struct fragment *fragments;
74 bool symbols_fragment;
75 struct of_changeset cset;
76 };
77
78
79 static int devicetree_state_flags;
80 #define DTSF_APPLY_FAIL 0x01
81 #define DTSF_REVERT_FAIL 0x02
82
83
84
85
86
87
88 static int devicetree_corrupt(void)
89 {
90 return devicetree_state_flags &
91 (DTSF_APPLY_FAIL | DTSF_REVERT_FAIL);
92 }
93
94 static int build_changeset_next_level(struct overlay_changeset *ovcs,
95 struct target *target, const struct device_node *overlay_node);
96
97
98
99
100
101
102
103
104
105
106 static DEFINE_MUTEX(of_overlay_phandle_mutex);
107
108 void of_overlay_mutex_lock(void)
109 {
110 mutex_lock(&of_overlay_phandle_mutex);
111 }
112
113 void of_overlay_mutex_unlock(void)
114 {
115 mutex_unlock(&of_overlay_phandle_mutex);
116 }
117
118
119 static LIST_HEAD(ovcs_list);
120 static DEFINE_IDR(ovcs_idr);
121
122 static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain);
123
124
125
126
127
128
129
130
131
132
133
134
135
136 int of_overlay_notifier_register(struct notifier_block *nb)
137 {
138 return blocking_notifier_chain_register(&overlay_notify_chain, nb);
139 }
140 EXPORT_SYMBOL_GPL(of_overlay_notifier_register);
141
142
143
144
145
146 int of_overlay_notifier_unregister(struct notifier_block *nb)
147 {
148 return blocking_notifier_chain_unregister(&overlay_notify_chain, nb);
149 }
150 EXPORT_SYMBOL_GPL(of_overlay_notifier_unregister);
151
152 static char *of_overlay_action_name[] = {
153 "pre-apply",
154 "post-apply",
155 "pre-remove",
156 "post-remove",
157 };
158
159 static int overlay_notify(struct overlay_changeset *ovcs,
160 enum of_overlay_notify_action action)
161 {
162 struct of_overlay_notify_data nd;
163 int i, ret;
164
165 for (i = 0; i < ovcs->count; i++) {
166 struct fragment *fragment = &ovcs->fragments[i];
167
168 nd.target = fragment->target;
169 nd.overlay = fragment->overlay;
170
171 ret = blocking_notifier_call_chain(&overlay_notify_chain,
172 action, &nd);
173 if (ret == NOTIFY_OK || ret == NOTIFY_STOP)
174 return 0;
175 if (ret) {
176 ret = notifier_to_errno(ret);
177 pr_err("overlay changeset %s notifier error %d, target: %pOF\n",
178 of_overlay_action_name[action], ret, nd.target);
179 return ret;
180 }
181 }
182
183 return 0;
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 static struct property *dup_and_fixup_symbol_prop(
200 struct overlay_changeset *ovcs, const struct property *prop)
201 {
202 struct fragment *fragment;
203 struct property *new_prop;
204 struct device_node *fragment_node;
205 struct device_node *overlay_node;
206 const char *path;
207 const char *path_tail;
208 const char *target_path;
209 int k;
210 int overlay_name_len;
211 int path_len;
212 int path_tail_len;
213 int target_path_len;
214
215 if (!prop->value)
216 return NULL;
217 if (strnlen(prop->value, prop->length) >= prop->length)
218 return NULL;
219 path = prop->value;
220 path_len = strlen(path);
221
222 if (path_len < 1)
223 return NULL;
224 fragment_node = __of_find_node_by_path(ovcs->overlay_tree, path + 1);
225 overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/");
226 of_node_put(fragment_node);
227 of_node_put(overlay_node);
228
229 for (k = 0; k < ovcs->count; k++) {
230 fragment = &ovcs->fragments[k];
231 if (fragment->overlay == overlay_node)
232 break;
233 }
234 if (k >= ovcs->count)
235 return NULL;
236
237 overlay_name_len = snprintf(NULL, 0, "%pOF", fragment->overlay);
238
239 if (overlay_name_len > path_len)
240 return NULL;
241 path_tail = path + overlay_name_len;
242 path_tail_len = strlen(path_tail);
243
244 target_path = kasprintf(GFP_KERNEL, "%pOF", fragment->target);
245 if (!target_path)
246 return NULL;
247 target_path_len = strlen(target_path);
248
249 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
250 if (!new_prop)
251 goto err_free_target_path;
252
253 new_prop->name = kstrdup(prop->name, GFP_KERNEL);
254 new_prop->length = target_path_len + path_tail_len + 1;
255 new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
256 if (!new_prop->name || !new_prop->value)
257 goto err_free_new_prop;
258
259 strcpy(new_prop->value, target_path);
260 strcpy(new_prop->value + target_path_len, path_tail);
261
262 of_property_set_flag(new_prop, OF_DYNAMIC);
263
264 kfree(target_path);
265
266 return new_prop;
267
268 err_free_new_prop:
269 kfree(new_prop->name);
270 kfree(new_prop->value);
271 kfree(new_prop);
272 err_free_target_path:
273 kfree(target_path);
274
275 return NULL;
276 }
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304 static int add_changeset_property(struct overlay_changeset *ovcs,
305 struct target *target, struct property *overlay_prop,
306 bool is_symbols_prop)
307 {
308 struct property *new_prop = NULL, *prop;
309 int ret = 0;
310
311 if (target->in_livetree)
312 if (!of_prop_cmp(overlay_prop->name, "name") ||
313 !of_prop_cmp(overlay_prop->name, "phandle") ||
314 !of_prop_cmp(overlay_prop->name, "linux,phandle"))
315 return 0;
316
317 if (target->in_livetree)
318 prop = of_find_property(target->np, overlay_prop->name, NULL);
319 else
320 prop = NULL;
321
322 if (prop) {
323 if (!of_prop_cmp(prop->name, "#address-cells")) {
324 if (!of_prop_val_eq(prop, overlay_prop)) {
325 pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n",
326 target->np);
327 ret = -EINVAL;
328 }
329 return ret;
330
331 } else if (!of_prop_cmp(prop->name, "#size-cells")) {
332 if (!of_prop_val_eq(prop, overlay_prop)) {
333 pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n",
334 target->np);
335 ret = -EINVAL;
336 }
337 return ret;
338 }
339 }
340
341 if (is_symbols_prop) {
342 if (prop)
343 return -EINVAL;
344 new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop);
345 } else {
346 new_prop = __of_prop_dup(overlay_prop, GFP_KERNEL);
347 }
348
349 if (!new_prop)
350 return -ENOMEM;
351
352 if (!prop) {
353 if (!target->in_livetree) {
354 new_prop->next = target->np->deadprops;
355 target->np->deadprops = new_prop;
356 }
357 ret = of_changeset_add_property(&ovcs->cset, target->np,
358 new_prop);
359 } else {
360 ret = of_changeset_update_property(&ovcs->cset, target->np,
361 new_prop);
362 }
363
364 if (!of_node_check_flag(target->np, OF_OVERLAY))
365 pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n",
366 target->np, new_prop->name);
367
368 if (ret) {
369 kfree(new_prop->name);
370 kfree(new_prop->value);
371 kfree(new_prop);
372 }
373 return ret;
374 }
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409 static int add_changeset_node(struct overlay_changeset *ovcs,
410 struct target *target, struct device_node *node)
411 {
412 const char *node_kbasename;
413 const __be32 *phandle;
414 struct device_node *tchild;
415 struct target target_child;
416 int ret = 0, size;
417
418 node_kbasename = kbasename(node->full_name);
419
420 for_each_child_of_node(target->np, tchild)
421 if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name)))
422 break;
423
424 if (!tchild) {
425 tchild = __of_node_dup(NULL, node_kbasename);
426 if (!tchild)
427 return -ENOMEM;
428
429 tchild->parent = target->np;
430 tchild->name = __of_get_property(node, "name", NULL);
431
432 if (!tchild->name)
433 tchild->name = "<NULL>";
434
435
436 phandle = __of_get_property(node, "phandle", &size);
437 if (phandle && (size == 4))
438 tchild->phandle = be32_to_cpup(phandle);
439
440 of_node_set_flag(tchild, OF_OVERLAY);
441
442 ret = of_changeset_attach_node(&ovcs->cset, tchild);
443 if (ret)
444 return ret;
445
446 target_child.np = tchild;
447 target_child.in_livetree = false;
448
449 ret = build_changeset_next_level(ovcs, &target_child, node);
450 of_node_put(tchild);
451 return ret;
452 }
453
454 if (node->phandle && tchild->phandle) {
455 ret = -EINVAL;
456 } else {
457 target_child.np = tchild;
458 target_child.in_livetree = target->in_livetree;
459 ret = build_changeset_next_level(ovcs, &target_child, node);
460 }
461 of_node_put(tchild);
462
463 return ret;
464 }
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481 static int build_changeset_next_level(struct overlay_changeset *ovcs,
482 struct target *target, const struct device_node *overlay_node)
483 {
484 struct device_node *child;
485 struct property *prop;
486 int ret;
487
488 for_each_property_of_node(overlay_node, prop) {
489 ret = add_changeset_property(ovcs, target, prop, 0);
490 if (ret) {
491 pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
492 target->np, prop->name, ret);
493 return ret;
494 }
495 }
496
497 for_each_child_of_node(overlay_node, child) {
498 ret = add_changeset_node(ovcs, target, child);
499 if (ret) {
500 pr_debug("Failed to apply node @%pOF/%pOFn, err=%d\n",
501 target->np, child, ret);
502 of_node_put(child);
503 return ret;
504 }
505 }
506
507 return 0;
508 }
509
510
511
512
513 static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
514 struct target *target,
515 const struct device_node *overlay_symbols_node)
516 {
517 struct property *prop;
518 int ret;
519
520 for_each_property_of_node(overlay_symbols_node, prop) {
521 ret = add_changeset_property(ovcs, target, prop, 1);
522 if (ret) {
523 pr_debug("Failed to apply symbols prop @%pOF/%s, err=%d\n",
524 target->np, prop->name, ret);
525 return ret;
526 }
527 }
528
529 return 0;
530 }
531
532 static int find_dup_cset_node_entry(struct overlay_changeset *ovcs,
533 struct of_changeset_entry *ce_1)
534 {
535 struct of_changeset_entry *ce_2;
536 char *fn_1, *fn_2;
537 int node_path_match;
538
539 if (ce_1->action != OF_RECONFIG_ATTACH_NODE &&
540 ce_1->action != OF_RECONFIG_DETACH_NODE)
541 return 0;
542
543 ce_2 = ce_1;
544 list_for_each_entry_continue(ce_2, &ovcs->cset.entries, node) {
545 if ((ce_2->action != OF_RECONFIG_ATTACH_NODE &&
546 ce_2->action != OF_RECONFIG_DETACH_NODE) ||
547 of_node_cmp(ce_1->np->full_name, ce_2->np->full_name))
548 continue;
549
550 fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
551 fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
552 node_path_match = !strcmp(fn_1, fn_2);
553 kfree(fn_1);
554 kfree(fn_2);
555 if (node_path_match) {
556 pr_err("ERROR: multiple fragments add and/or delete node %pOF\n",
557 ce_1->np);
558 return -EINVAL;
559 }
560 }
561
562 return 0;
563 }
564
565 static int find_dup_cset_prop(struct overlay_changeset *ovcs,
566 struct of_changeset_entry *ce_1)
567 {
568 struct of_changeset_entry *ce_2;
569 char *fn_1, *fn_2;
570 int node_path_match;
571
572 if (ce_1->action != OF_RECONFIG_ADD_PROPERTY &&
573 ce_1->action != OF_RECONFIG_REMOVE_PROPERTY &&
574 ce_1->action != OF_RECONFIG_UPDATE_PROPERTY)
575 return 0;
576
577 ce_2 = ce_1;
578 list_for_each_entry_continue(ce_2, &ovcs->cset.entries, node) {
579 if ((ce_2->action != OF_RECONFIG_ADD_PROPERTY &&
580 ce_2->action != OF_RECONFIG_REMOVE_PROPERTY &&
581 ce_2->action != OF_RECONFIG_UPDATE_PROPERTY) ||
582 of_node_cmp(ce_1->np->full_name, ce_2->np->full_name))
583 continue;
584
585 fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
586 fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
587 node_path_match = !strcmp(fn_1, fn_2);
588 kfree(fn_1);
589 kfree(fn_2);
590 if (node_path_match &&
591 !of_prop_cmp(ce_1->prop->name, ce_2->prop->name)) {
592 pr_err("ERROR: multiple fragments add, update, and/or delete property %pOF/%s\n",
593 ce_1->np, ce_1->prop->name);
594 return -EINVAL;
595 }
596 }
597
598 return 0;
599 }
600
601
602
603
604
605
606
607
608
609
610
611 static int changeset_dup_entry_check(struct overlay_changeset *ovcs)
612 {
613 struct of_changeset_entry *ce_1;
614 int dup_entry = 0;
615
616 list_for_each_entry(ce_1, &ovcs->cset.entries, node) {
617 dup_entry |= find_dup_cset_node_entry(ovcs, ce_1);
618 dup_entry |= find_dup_cset_prop(ovcs, ce_1);
619 }
620
621 return dup_entry ? -EINVAL : 0;
622 }
623
624
625
626
627
628
629
630
631
632
633
634
635
636 static int build_changeset(struct overlay_changeset *ovcs)
637 {
638 struct fragment *fragment;
639 struct target target;
640 int fragments_count, i, ret;
641
642
643
644
645
646 if (ovcs->symbols_fragment)
647 fragments_count = ovcs->count - 1;
648 else
649 fragments_count = ovcs->count;
650
651 for (i = 0; i < fragments_count; i++) {
652 fragment = &ovcs->fragments[i];
653
654 target.np = fragment->target;
655 target.in_livetree = true;
656 ret = build_changeset_next_level(ovcs, &target,
657 fragment->overlay);
658 if (ret) {
659 pr_debug("fragment apply failed '%pOF'\n",
660 fragment->target);
661 return ret;
662 }
663 }
664
665 if (ovcs->symbols_fragment) {
666 fragment = &ovcs->fragments[ovcs->count - 1];
667
668 target.np = fragment->target;
669 target.in_livetree = true;
670 ret = build_changeset_symbols_node(ovcs, &target,
671 fragment->overlay);
672 if (ret) {
673 pr_debug("symbols fragment apply failed '%pOF'\n",
674 fragment->target);
675 return ret;
676 }
677 }
678
679 return changeset_dup_entry_check(ovcs);
680 }
681
682
683
684
685
686
687
688
689 static struct device_node *find_target(struct device_node *info_node)
690 {
691 struct device_node *node;
692 const char *path;
693 u32 val;
694 int ret;
695
696 ret = of_property_read_u32(info_node, "target", &val);
697 if (!ret) {
698 node = of_find_node_by_phandle(val);
699 if (!node)
700 pr_err("find target, node: %pOF, phandle 0x%x not found\n",
701 info_node, val);
702 return node;
703 }
704
705 ret = of_property_read_string(info_node, "target-path", &path);
706 if (!ret) {
707 node = of_find_node_by_path(path);
708 if (!node)
709 pr_err("find target, node: %pOF, path '%s' not found\n",
710 info_node, path);
711 return node;
712 }
713
714 pr_err("find target, node: %pOF, no target property\n", info_node);
715
716 return NULL;
717 }
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732 static int init_overlay_changeset(struct overlay_changeset *ovcs,
733 const void *fdt, struct device_node *tree)
734 {
735 struct device_node *node, *overlay_node;
736 struct fragment *fragment;
737 struct fragment *fragments;
738 int cnt, id, ret;
739
740
741
742
743
744 if (!of_node_check_flag(tree, OF_DYNAMIC))
745 pr_debug("%s() tree is not dynamic\n", __func__);
746
747 if (!of_node_check_flag(tree, OF_DETACHED))
748 pr_debug("%s() tree is not detached\n", __func__);
749
750 if (!of_node_is_root(tree))
751 pr_debug("%s() tree is not root\n", __func__);
752
753 ovcs->overlay_tree = tree;
754 ovcs->fdt = fdt;
755
756 INIT_LIST_HEAD(&ovcs->ovcs_list);
757
758 of_changeset_init(&ovcs->cset);
759
760 id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL);
761 if (id <= 0)
762 return id;
763
764 cnt = 0;
765
766
767 for_each_child_of_node(tree, node) {
768 overlay_node = of_get_child_by_name(node, "__overlay__");
769 if (overlay_node) {
770 cnt++;
771 of_node_put(overlay_node);
772 }
773 }
774
775 node = of_get_child_by_name(tree, "__symbols__");
776 if (node) {
777 cnt++;
778 of_node_put(node);
779 }
780
781 fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL);
782 if (!fragments) {
783 ret = -ENOMEM;
784 goto err_free_idr;
785 }
786
787 cnt = 0;
788 for_each_child_of_node(tree, node) {
789 overlay_node = of_get_child_by_name(node, "__overlay__");
790 if (!overlay_node)
791 continue;
792
793 fragment = &fragments[cnt];
794 fragment->overlay = overlay_node;
795 fragment->target = find_target(node);
796 if (!fragment->target) {
797 of_node_put(fragment->overlay);
798 ret = -EINVAL;
799 goto err_free_fragments;
800 }
801
802 cnt++;
803 }
804
805
806
807
808
809 node = of_get_child_by_name(tree, "__symbols__");
810 if (node) {
811 ovcs->symbols_fragment = 1;
812 fragment = &fragments[cnt];
813 fragment->overlay = node;
814 fragment->target = of_find_node_by_path("/__symbols__");
815
816 if (!fragment->target) {
817 pr_err("symbols in overlay, but not in live tree\n");
818 ret = -EINVAL;
819 goto err_free_fragments;
820 }
821
822 cnt++;
823 }
824
825 if (!cnt) {
826 pr_err("no fragments or symbols in overlay\n");
827 ret = -EINVAL;
828 goto err_free_fragments;
829 }
830
831 ovcs->id = id;
832 ovcs->count = cnt;
833 ovcs->fragments = fragments;
834
835 return 0;
836
837 err_free_fragments:
838 kfree(fragments);
839 err_free_idr:
840 idr_remove(&ovcs_idr, id);
841
842 pr_err("%s() failed, ret = %d\n", __func__, ret);
843
844 return ret;
845 }
846
847 static void free_overlay_changeset(struct overlay_changeset *ovcs)
848 {
849 int i;
850
851 if (ovcs->cset.entries.next)
852 of_changeset_destroy(&ovcs->cset);
853
854 if (ovcs->id)
855 idr_remove(&ovcs_idr, ovcs->id);
856
857 for (i = 0; i < ovcs->count; i++) {
858 of_node_put(ovcs->fragments[i].target);
859 of_node_put(ovcs->fragments[i].overlay);
860 }
861 kfree(ovcs->fragments);
862
863
864
865
866
867 kfree(ovcs->overlay_tree);
868 kfree(ovcs->fdt);
869 kfree(ovcs);
870 }
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915 static int of_overlay_apply(const void *fdt, struct device_node *tree,
916 int *ovcs_id)
917 {
918 struct overlay_changeset *ovcs;
919 int ret = 0, ret_revert, ret_tmp;
920
921
922
923
924
925
926 if (devicetree_corrupt()) {
927 pr_err("devicetree state suspect, refuse to apply overlay\n");
928 kfree(fdt);
929 kfree(tree);
930 ret = -EBUSY;
931 goto out;
932 }
933
934 ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL);
935 if (!ovcs) {
936 kfree(fdt);
937 kfree(tree);
938 ret = -ENOMEM;
939 goto out;
940 }
941
942 of_overlay_mutex_lock();
943 mutex_lock(&of_mutex);
944
945 ret = of_resolve_phandles(tree);
946 if (ret)
947 goto err_free_tree;
948
949 ret = init_overlay_changeset(ovcs, fdt, tree);
950 if (ret)
951 goto err_free_tree;
952
953
954
955
956
957
958 ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
959 if (ret) {
960 pr_err("overlay changeset pre-apply notify error %d\n", ret);
961 goto err_free_overlay_changeset;
962 }
963
964 ret = build_changeset(ovcs);
965 if (ret)
966 goto err_free_overlay_changeset;
967
968 ret_revert = 0;
969 ret = __of_changeset_apply_entries(&ovcs->cset, &ret_revert);
970 if (ret) {
971 if (ret_revert) {
972 pr_debug("overlay changeset revert error %d\n",
973 ret_revert);
974 devicetree_state_flags |= DTSF_APPLY_FAIL;
975 }
976 goto err_free_overlay_changeset;
977 }
978
979 of_populate_phandle_cache();
980
981 ret = __of_changeset_apply_notify(&ovcs->cset);
982 if (ret)
983 pr_err("overlay apply changeset entry notify error %d\n", ret);
984
985
986 list_add_tail(&ovcs->ovcs_list, &ovcs_list);
987 *ovcs_id = ovcs->id;
988
989 ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_APPLY);
990 if (ret_tmp) {
991 pr_err("overlay changeset post-apply notify error %d\n",
992 ret_tmp);
993 if (!ret)
994 ret = ret_tmp;
995 }
996
997 goto out_unlock;
998
999 err_free_tree:
1000 kfree(fdt);
1001 kfree(tree);
1002
1003 err_free_overlay_changeset:
1004 free_overlay_changeset(ovcs);
1005
1006 out_unlock:
1007 mutex_unlock(&of_mutex);
1008 of_overlay_mutex_unlock();
1009
1010 out:
1011 pr_debug("%s() err=%d\n", __func__, ret);
1012
1013 return ret;
1014 }
1015
1016 int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
1017 int *ovcs_id)
1018 {
1019 const void *new_fdt;
1020 int ret;
1021 u32 size;
1022 struct device_node *overlay_root;
1023
1024 *ovcs_id = 0;
1025 ret = 0;
1026
1027 if (overlay_fdt_size < sizeof(struct fdt_header) ||
1028 fdt_check_header(overlay_fdt)) {
1029 pr_err("Invalid overlay_fdt header\n");
1030 return -EINVAL;
1031 }
1032
1033 size = fdt_totalsize(overlay_fdt);
1034 if (overlay_fdt_size < size)
1035 return -EINVAL;
1036
1037
1038
1039
1040
1041 new_fdt = kmemdup(overlay_fdt, size, GFP_KERNEL);
1042 if (!new_fdt)
1043 return -ENOMEM;
1044
1045 of_fdt_unflatten_tree(new_fdt, NULL, &overlay_root);
1046 if (!overlay_root) {
1047 pr_err("unable to unflatten overlay_fdt\n");
1048 ret = -EINVAL;
1049 goto out_free_new_fdt;
1050 }
1051
1052 ret = of_overlay_apply(new_fdt, overlay_root, ovcs_id);
1053 if (ret < 0) {
1054
1055
1056
1057
1058
1059 goto out;
1060 }
1061
1062 return 0;
1063
1064
1065 out_free_new_fdt:
1066 kfree(new_fdt);
1067
1068 out:
1069 return ret;
1070 }
1071 EXPORT_SYMBOL_GPL(of_overlay_fdt_apply);
1072
1073
1074
1075
1076
1077
1078 static int find_node(struct device_node *tree, struct device_node *np)
1079 {
1080 struct device_node *child;
1081
1082 if (tree == np)
1083 return 1;
1084
1085 for_each_child_of_node(tree, child) {
1086 if (find_node(child, np)) {
1087 of_node_put(child);
1088 return 1;
1089 }
1090 }
1091
1092 return 0;
1093 }
1094
1095
1096
1097
1098
1099
1100
1101 static int node_overlaps_later_cs(struct overlay_changeset *remove_ovcs,
1102 struct device_node *remove_ce_node)
1103 {
1104 struct overlay_changeset *ovcs;
1105 struct of_changeset_entry *ce;
1106
1107 list_for_each_entry_reverse(ovcs, &ovcs_list, ovcs_list) {
1108 if (ovcs == remove_ovcs)
1109 break;
1110
1111 list_for_each_entry(ce, &ovcs->cset.entries, node) {
1112 if (find_node(ce->np, remove_ce_node)) {
1113 pr_err("%s: #%d overlaps with #%d @%pOF\n",
1114 __func__, remove_ovcs->id, ovcs->id,
1115 remove_ce_node);
1116 return 1;
1117 }
1118 if (find_node(remove_ce_node, ce->np)) {
1119 pr_err("%s: #%d overlaps with #%d @%pOF\n",
1120 __func__, remove_ovcs->id, ovcs->id,
1121 remove_ce_node);
1122 return 1;
1123 }
1124 }
1125 }
1126
1127 return 0;
1128 }
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140 static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
1141 {
1142 struct of_changeset_entry *remove_ce;
1143
1144 list_for_each_entry(remove_ce, &remove_ovcs->cset.entries, node) {
1145 if (node_overlaps_later_cs(remove_ovcs, remove_ce->np)) {
1146 pr_err("overlay #%d is not topmost\n", remove_ovcs->id);
1147 return 0;
1148 }
1149 }
1150
1151 return 1;
1152 }
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188 int of_overlay_remove(int *ovcs_id)
1189 {
1190 struct overlay_changeset *ovcs;
1191 int ret, ret_apply, ret_tmp;
1192
1193 ret = 0;
1194
1195 if (devicetree_corrupt()) {
1196 pr_err("suspect devicetree state, refuse to remove overlay\n");
1197 ret = -EBUSY;
1198 goto out;
1199 }
1200
1201 mutex_lock(&of_mutex);
1202
1203 ovcs = idr_find(&ovcs_idr, *ovcs_id);
1204 if (!ovcs) {
1205 ret = -ENODEV;
1206 pr_err("remove: Could not find overlay #%d\n", *ovcs_id);
1207 goto out_unlock;
1208 }
1209
1210 if (!overlay_removal_is_ok(ovcs)) {
1211 ret = -EBUSY;
1212 goto out_unlock;
1213 }
1214
1215 ret = overlay_notify(ovcs, OF_OVERLAY_PRE_REMOVE);
1216 if (ret) {
1217 pr_err("overlay changeset pre-remove notify error %d\n", ret);
1218 goto out_unlock;
1219 }
1220
1221 list_del(&ovcs->ovcs_list);
1222
1223
1224
1225
1226
1227 of_free_phandle_cache();
1228
1229 ret_apply = 0;
1230 ret = __of_changeset_revert_entries(&ovcs->cset, &ret_apply);
1231
1232 of_populate_phandle_cache();
1233
1234 if (ret) {
1235 if (ret_apply)
1236 devicetree_state_flags |= DTSF_REVERT_FAIL;
1237 goto out_unlock;
1238 }
1239
1240 ret = __of_changeset_revert_notify(&ovcs->cset);
1241 if (ret)
1242 pr_err("overlay remove changeset entry notify error %d\n", ret);
1243
1244
1245 *ovcs_id = 0;
1246
1247 ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_REMOVE);
1248 if (ret_tmp) {
1249 pr_err("overlay changeset post-remove notify error %d\n",
1250 ret_tmp);
1251 if (!ret)
1252 ret = ret_tmp;
1253 }
1254
1255 free_overlay_changeset(ovcs);
1256
1257 out_unlock:
1258 mutex_unlock(&of_mutex);
1259
1260 out:
1261 pr_debug("%s() err=%d\n", __func__, ret);
1262
1263 return ret;
1264 }
1265 EXPORT_SYMBOL_GPL(of_overlay_remove);
1266
1267
1268
1269
1270
1271
1272
1273
1274 int of_overlay_remove_all(void)
1275 {
1276 struct overlay_changeset *ovcs, *ovcs_n;
1277 int ret;
1278
1279
1280 list_for_each_entry_safe_reverse(ovcs, ovcs_n, &ovcs_list, ovcs_list) {
1281 ret = of_overlay_remove(&ovcs->id);
1282 if (ret)
1283 return ret;
1284 }
1285
1286 return 0;
1287 }
1288 EXPORT_SYMBOL_GPL(of_overlay_remove_all);