0001
0002
0003
0004
0005
0006
0007
0008
0009 #define pr_fmt(fmt) "OF: overlay: " fmt
0010
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/of_device.h>
0015 #include <linux/of_fdt.h>
0016 #include <linux/string.h>
0017 #include <linux/ctype.h>
0018 #include <linux/errno.h>
0019 #include <linux/slab.h>
0020 #include <linux/libfdt.h>
0021 #include <linux/err.h>
0022 #include <linux/idr.h>
0023
0024 #include "of_private.h"
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 struct target {
0042 struct device_node *np;
0043 bool in_livetree;
0044 };
0045
0046
0047
0048
0049
0050
0051 struct fragment {
0052 struct device_node *overlay;
0053 struct device_node *target;
0054 };
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 struct overlay_changeset {
0070 int id;
0071 struct list_head ovcs_list;
0072 const void *new_fdt;
0073 const void *overlay_mem;
0074 struct device_node *overlay_root;
0075 enum of_overlay_notify_action notify_state;
0076 int count;
0077 struct fragment *fragments;
0078 bool symbols_fragment;
0079 struct of_changeset cset;
0080 };
0081
0082
0083 static int devicetree_state_flags;
0084 #define DTSF_APPLY_FAIL 0x01
0085 #define DTSF_REVERT_FAIL 0x02
0086
0087
0088
0089
0090
0091
0092 static int devicetree_corrupt(void)
0093 {
0094 return devicetree_state_flags &
0095 (DTSF_APPLY_FAIL | DTSF_REVERT_FAIL);
0096 }
0097
0098 static int build_changeset_next_level(struct overlay_changeset *ovcs,
0099 struct target *target, const struct device_node *overlay_node);
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110 static DEFINE_MUTEX(of_overlay_phandle_mutex);
0111
0112 void of_overlay_mutex_lock(void)
0113 {
0114 mutex_lock(&of_overlay_phandle_mutex);
0115 }
0116
0117 void of_overlay_mutex_unlock(void)
0118 {
0119 mutex_unlock(&of_overlay_phandle_mutex);
0120 }
0121
0122 static LIST_HEAD(ovcs_list);
0123 static DEFINE_IDR(ovcs_idr);
0124
0125 static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain);
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 int of_overlay_notifier_register(struct notifier_block *nb)
0140 {
0141 return blocking_notifier_chain_register(&overlay_notify_chain, nb);
0142 }
0143 EXPORT_SYMBOL_GPL(of_overlay_notifier_register);
0144
0145
0146
0147
0148
0149 int of_overlay_notifier_unregister(struct notifier_block *nb)
0150 {
0151 return blocking_notifier_chain_unregister(&overlay_notify_chain, nb);
0152 }
0153 EXPORT_SYMBOL_GPL(of_overlay_notifier_unregister);
0154
0155 static int overlay_notify(struct overlay_changeset *ovcs,
0156 enum of_overlay_notify_action action)
0157 {
0158 struct of_overlay_notify_data nd;
0159 int i, ret;
0160
0161 ovcs->notify_state = action;
0162
0163 for (i = 0; i < ovcs->count; i++) {
0164 struct fragment *fragment = &ovcs->fragments[i];
0165
0166 nd.target = fragment->target;
0167 nd.overlay = fragment->overlay;
0168
0169 ret = blocking_notifier_call_chain(&overlay_notify_chain,
0170 action, &nd);
0171 if (notifier_to_errno(ret)) {
0172 ret = notifier_to_errno(ret);
0173 pr_err("overlay changeset %s notifier error %d, target: %pOF\n",
0174 of_overlay_action_name(action), ret, nd.target);
0175 return ret;
0176 }
0177 }
0178
0179 return 0;
0180 }
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 static struct property *dup_and_fixup_symbol_prop(
0196 struct overlay_changeset *ovcs, const struct property *prop)
0197 {
0198 struct fragment *fragment;
0199 struct property *new_prop;
0200 struct device_node *fragment_node;
0201 struct device_node *overlay_node;
0202 const char *path;
0203 const char *path_tail;
0204 const char *target_path;
0205 int k;
0206 int overlay_name_len;
0207 int path_len;
0208 int path_tail_len;
0209 int target_path_len;
0210
0211 if (!prop->value)
0212 return NULL;
0213 if (strnlen(prop->value, prop->length) >= prop->length)
0214 return NULL;
0215 path = prop->value;
0216 path_len = strlen(path);
0217
0218 if (path_len < 1)
0219 return NULL;
0220 fragment_node = __of_find_node_by_path(ovcs->overlay_root, path + 1);
0221 overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/");
0222 of_node_put(fragment_node);
0223 of_node_put(overlay_node);
0224
0225 for (k = 0; k < ovcs->count; k++) {
0226 fragment = &ovcs->fragments[k];
0227 if (fragment->overlay == overlay_node)
0228 break;
0229 }
0230 if (k >= ovcs->count)
0231 return NULL;
0232
0233 overlay_name_len = snprintf(NULL, 0, "%pOF", fragment->overlay);
0234
0235 if (overlay_name_len > path_len)
0236 return NULL;
0237 path_tail = path + overlay_name_len;
0238 path_tail_len = strlen(path_tail);
0239
0240 target_path = kasprintf(GFP_KERNEL, "%pOF", fragment->target);
0241 if (!target_path)
0242 return NULL;
0243 target_path_len = strlen(target_path);
0244
0245 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
0246 if (!new_prop)
0247 goto err_free_target_path;
0248
0249 new_prop->name = kstrdup(prop->name, GFP_KERNEL);
0250 new_prop->length = target_path_len + path_tail_len + 1;
0251 new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
0252 if (!new_prop->name || !new_prop->value)
0253 goto err_free_new_prop;
0254
0255 strcpy(new_prop->value, target_path);
0256 strcpy(new_prop->value + target_path_len, path_tail);
0257
0258 of_property_set_flag(new_prop, OF_DYNAMIC);
0259
0260 kfree(target_path);
0261
0262 return new_prop;
0263
0264 err_free_new_prop:
0265 kfree(new_prop->name);
0266 kfree(new_prop->value);
0267 kfree(new_prop);
0268 err_free_target_path:
0269 kfree(target_path);
0270
0271 return NULL;
0272 }
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 static int add_changeset_property(struct overlay_changeset *ovcs,
0301 struct target *target, struct property *overlay_prop,
0302 bool is_symbols_prop)
0303 {
0304 struct property *new_prop = NULL, *prop;
0305 int ret = 0;
0306
0307 if (target->in_livetree)
0308 if (!of_prop_cmp(overlay_prop->name, "name") ||
0309 !of_prop_cmp(overlay_prop->name, "phandle") ||
0310 !of_prop_cmp(overlay_prop->name, "linux,phandle"))
0311 return 0;
0312
0313 if (target->in_livetree)
0314 prop = of_find_property(target->np, overlay_prop->name, NULL);
0315 else
0316 prop = NULL;
0317
0318 if (prop) {
0319 if (!of_prop_cmp(prop->name, "#address-cells")) {
0320 if (!of_prop_val_eq(prop, overlay_prop)) {
0321 pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n",
0322 target->np);
0323 ret = -EINVAL;
0324 }
0325 return ret;
0326
0327 } else if (!of_prop_cmp(prop->name, "#size-cells")) {
0328 if (!of_prop_val_eq(prop, overlay_prop)) {
0329 pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n",
0330 target->np);
0331 ret = -EINVAL;
0332 }
0333 return ret;
0334 }
0335 }
0336
0337 if (is_symbols_prop) {
0338 if (prop)
0339 return -EINVAL;
0340 new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop);
0341 } else {
0342 new_prop = __of_prop_dup(overlay_prop, GFP_KERNEL);
0343 }
0344
0345 if (!new_prop)
0346 return -ENOMEM;
0347
0348 if (!prop) {
0349 if (!target->in_livetree) {
0350 new_prop->next = target->np->deadprops;
0351 target->np->deadprops = new_prop;
0352 }
0353 ret = of_changeset_add_property(&ovcs->cset, target->np,
0354 new_prop);
0355 } else {
0356 ret = of_changeset_update_property(&ovcs->cset, target->np,
0357 new_prop);
0358 }
0359
0360 if (!of_node_check_flag(target->np, OF_OVERLAY))
0361 pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n",
0362 target->np, new_prop->name);
0363
0364 if (ret) {
0365 kfree(new_prop->name);
0366 kfree(new_prop->value);
0367 kfree(new_prop);
0368 }
0369 return ret;
0370 }
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405 static int add_changeset_node(struct overlay_changeset *ovcs,
0406 struct target *target, struct device_node *node)
0407 {
0408 const char *node_kbasename;
0409 const __be32 *phandle;
0410 struct device_node *tchild;
0411 struct target target_child;
0412 int ret = 0, size;
0413
0414 node_kbasename = kbasename(node->full_name);
0415
0416 for_each_child_of_node(target->np, tchild)
0417 if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name)))
0418 break;
0419
0420 if (!tchild) {
0421 tchild = __of_node_dup(NULL, node_kbasename);
0422 if (!tchild)
0423 return -ENOMEM;
0424
0425 tchild->parent = target->np;
0426 tchild->name = __of_get_property(node, "name", NULL);
0427
0428 if (!tchild->name)
0429 tchild->name = "<NULL>";
0430
0431
0432 phandle = __of_get_property(node, "phandle", &size);
0433 if (phandle && (size == 4))
0434 tchild->phandle = be32_to_cpup(phandle);
0435
0436 of_node_set_flag(tchild, OF_OVERLAY);
0437
0438 ret = of_changeset_attach_node(&ovcs->cset, tchild);
0439 if (ret)
0440 return ret;
0441
0442 target_child.np = tchild;
0443 target_child.in_livetree = false;
0444
0445 ret = build_changeset_next_level(ovcs, &target_child, node);
0446 of_node_put(tchild);
0447 return ret;
0448 }
0449
0450 if (node->phandle && tchild->phandle) {
0451 ret = -EINVAL;
0452 } else {
0453 target_child.np = tchild;
0454 target_child.in_livetree = target->in_livetree;
0455 ret = build_changeset_next_level(ovcs, &target_child, node);
0456 }
0457 of_node_put(tchild);
0458
0459 return ret;
0460 }
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 static int build_changeset_next_level(struct overlay_changeset *ovcs,
0478 struct target *target, const struct device_node *overlay_node)
0479 {
0480 struct device_node *child;
0481 struct property *prop;
0482 int ret;
0483
0484 for_each_property_of_node(overlay_node, prop) {
0485 ret = add_changeset_property(ovcs, target, prop, 0);
0486 if (ret) {
0487 pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
0488 target->np, prop->name, ret);
0489 return ret;
0490 }
0491 }
0492
0493 for_each_child_of_node(overlay_node, child) {
0494 ret = add_changeset_node(ovcs, target, child);
0495 if (ret) {
0496 pr_debug("Failed to apply node @%pOF/%pOFn, err=%d\n",
0497 target->np, child, ret);
0498 of_node_put(child);
0499 return ret;
0500 }
0501 }
0502
0503 return 0;
0504 }
0505
0506
0507
0508
0509 static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
0510 struct target *target,
0511 const struct device_node *overlay_symbols_node)
0512 {
0513 struct property *prop;
0514 int ret;
0515
0516 for_each_property_of_node(overlay_symbols_node, prop) {
0517 ret = add_changeset_property(ovcs, target, prop, 1);
0518 if (ret) {
0519 pr_debug("Failed to apply symbols prop @%pOF/%s, err=%d\n",
0520 target->np, prop->name, ret);
0521 return ret;
0522 }
0523 }
0524
0525 return 0;
0526 }
0527
0528 static int find_dup_cset_node_entry(struct overlay_changeset *ovcs,
0529 struct of_changeset_entry *ce_1)
0530 {
0531 struct of_changeset_entry *ce_2;
0532 char *fn_1, *fn_2;
0533 int node_path_match;
0534
0535 if (ce_1->action != OF_RECONFIG_ATTACH_NODE &&
0536 ce_1->action != OF_RECONFIG_DETACH_NODE)
0537 return 0;
0538
0539 ce_2 = ce_1;
0540 list_for_each_entry_continue(ce_2, &ovcs->cset.entries, node) {
0541 if ((ce_2->action != OF_RECONFIG_ATTACH_NODE &&
0542 ce_2->action != OF_RECONFIG_DETACH_NODE) ||
0543 of_node_cmp(ce_1->np->full_name, ce_2->np->full_name))
0544 continue;
0545
0546 fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
0547 fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
0548 node_path_match = !strcmp(fn_1, fn_2);
0549 kfree(fn_1);
0550 kfree(fn_2);
0551 if (node_path_match) {
0552 pr_err("ERROR: multiple fragments add and/or delete node %pOF\n",
0553 ce_1->np);
0554 return -EINVAL;
0555 }
0556 }
0557
0558 return 0;
0559 }
0560
0561 static int find_dup_cset_prop(struct overlay_changeset *ovcs,
0562 struct of_changeset_entry *ce_1)
0563 {
0564 struct of_changeset_entry *ce_2;
0565 char *fn_1, *fn_2;
0566 int node_path_match;
0567
0568 if (ce_1->action != OF_RECONFIG_ADD_PROPERTY &&
0569 ce_1->action != OF_RECONFIG_REMOVE_PROPERTY &&
0570 ce_1->action != OF_RECONFIG_UPDATE_PROPERTY)
0571 return 0;
0572
0573 ce_2 = ce_1;
0574 list_for_each_entry_continue(ce_2, &ovcs->cset.entries, node) {
0575 if ((ce_2->action != OF_RECONFIG_ADD_PROPERTY &&
0576 ce_2->action != OF_RECONFIG_REMOVE_PROPERTY &&
0577 ce_2->action != OF_RECONFIG_UPDATE_PROPERTY) ||
0578 of_node_cmp(ce_1->np->full_name, ce_2->np->full_name))
0579 continue;
0580
0581 fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
0582 fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
0583 node_path_match = !strcmp(fn_1, fn_2);
0584 kfree(fn_1);
0585 kfree(fn_2);
0586 if (node_path_match &&
0587 !of_prop_cmp(ce_1->prop->name, ce_2->prop->name)) {
0588 pr_err("ERROR: multiple fragments add, update, and/or delete property %pOF/%s\n",
0589 ce_1->np, ce_1->prop->name);
0590 return -EINVAL;
0591 }
0592 }
0593
0594 return 0;
0595 }
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607 static int changeset_dup_entry_check(struct overlay_changeset *ovcs)
0608 {
0609 struct of_changeset_entry *ce_1;
0610 int dup_entry = 0;
0611
0612 list_for_each_entry(ce_1, &ovcs->cset.entries, node) {
0613 dup_entry |= find_dup_cset_node_entry(ovcs, ce_1);
0614 dup_entry |= find_dup_cset_prop(ovcs, ce_1);
0615 }
0616
0617 return dup_entry ? -EINVAL : 0;
0618 }
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632 static int build_changeset(struct overlay_changeset *ovcs)
0633 {
0634 struct fragment *fragment;
0635 struct target target;
0636 int fragments_count, i, ret;
0637
0638
0639
0640
0641
0642 if (ovcs->symbols_fragment)
0643 fragments_count = ovcs->count - 1;
0644 else
0645 fragments_count = ovcs->count;
0646
0647 for (i = 0; i < fragments_count; i++) {
0648 fragment = &ovcs->fragments[i];
0649
0650 target.np = fragment->target;
0651 target.in_livetree = true;
0652 ret = build_changeset_next_level(ovcs, &target,
0653 fragment->overlay);
0654 if (ret) {
0655 pr_debug("fragment apply failed '%pOF'\n",
0656 fragment->target);
0657 return ret;
0658 }
0659 }
0660
0661 if (ovcs->symbols_fragment) {
0662 fragment = &ovcs->fragments[ovcs->count - 1];
0663
0664 target.np = fragment->target;
0665 target.in_livetree = true;
0666 ret = build_changeset_symbols_node(ovcs, &target,
0667 fragment->overlay);
0668 if (ret) {
0669 pr_debug("symbols fragment apply failed '%pOF'\n",
0670 fragment->target);
0671 return ret;
0672 }
0673 }
0674
0675 return changeset_dup_entry_check(ovcs);
0676 }
0677
0678
0679
0680
0681
0682
0683
0684
0685 static struct device_node *find_target(struct device_node *info_node)
0686 {
0687 struct device_node *node;
0688 const char *path;
0689 u32 val;
0690 int ret;
0691
0692 ret = of_property_read_u32(info_node, "target", &val);
0693 if (!ret) {
0694 node = of_find_node_by_phandle(val);
0695 if (!node)
0696 pr_err("find target, node: %pOF, phandle 0x%x not found\n",
0697 info_node, val);
0698 return node;
0699 }
0700
0701 ret = of_property_read_string(info_node, "target-path", &path);
0702 if (!ret) {
0703 node = of_find_node_by_path(path);
0704 if (!node)
0705 pr_err("find target, node: %pOF, path '%s' not found\n",
0706 info_node, path);
0707 return node;
0708 }
0709
0710 pr_err("find target, node: %pOF, no target property\n", info_node);
0711
0712 return NULL;
0713 }
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728 static int init_overlay_changeset(struct overlay_changeset *ovcs)
0729 {
0730 struct device_node *node, *overlay_node;
0731 struct fragment *fragment;
0732 struct fragment *fragments;
0733 int cnt, ret;
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746 if (!of_node_check_flag(ovcs->overlay_root, OF_DYNAMIC))
0747 pr_debug("%s() ovcs->overlay_root is not dynamic\n", __func__);
0748
0749 if (!of_node_check_flag(ovcs->overlay_root, OF_DETACHED))
0750 pr_debug("%s() ovcs->overlay_root is not detached\n", __func__);
0751
0752 if (!of_node_is_root(ovcs->overlay_root))
0753 pr_debug("%s() ovcs->overlay_root is not root\n", __func__);
0754
0755 of_changeset_init(&ovcs->cset);
0756
0757 cnt = 0;
0758
0759
0760 for_each_child_of_node(ovcs->overlay_root, node) {
0761 overlay_node = of_get_child_by_name(node, "__overlay__");
0762 if (overlay_node) {
0763 cnt++;
0764 of_node_put(overlay_node);
0765 }
0766 }
0767
0768 node = of_get_child_by_name(ovcs->overlay_root, "__symbols__");
0769 if (node) {
0770 cnt++;
0771 of_node_put(node);
0772 }
0773
0774 fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL);
0775 if (!fragments) {
0776 ret = -ENOMEM;
0777 goto err_out;
0778 }
0779 ovcs->fragments = fragments;
0780
0781 cnt = 0;
0782 for_each_child_of_node(ovcs->overlay_root, node) {
0783 overlay_node = of_get_child_by_name(node, "__overlay__");
0784 if (!overlay_node)
0785 continue;
0786
0787 fragment = &fragments[cnt];
0788 fragment->overlay = overlay_node;
0789 fragment->target = find_target(node);
0790 if (!fragment->target) {
0791 of_node_put(fragment->overlay);
0792 ret = -EINVAL;
0793 of_node_put(node);
0794 goto err_out;
0795 }
0796
0797 cnt++;
0798 }
0799
0800
0801
0802
0803
0804 node = of_get_child_by_name(ovcs->overlay_root, "__symbols__");
0805 if (node) {
0806 ovcs->symbols_fragment = 1;
0807 fragment = &fragments[cnt];
0808 fragment->overlay = node;
0809 fragment->target = of_find_node_by_path("/__symbols__");
0810
0811 if (!fragment->target) {
0812 pr_err("symbols in overlay, but not in live tree\n");
0813 ret = -EINVAL;
0814 goto err_out;
0815 }
0816
0817 cnt++;
0818 }
0819
0820 if (!cnt) {
0821 pr_err("no fragments or symbols in overlay\n");
0822 ret = -EINVAL;
0823 goto err_out;
0824 }
0825
0826 ovcs->count = cnt;
0827
0828 return 0;
0829
0830 err_out:
0831 pr_err("%s() failed, ret = %d\n", __func__, ret);
0832
0833 return ret;
0834 }
0835
0836 static void free_overlay_changeset(struct overlay_changeset *ovcs)
0837 {
0838 int i;
0839
0840 if (ovcs->cset.entries.next)
0841 of_changeset_destroy(&ovcs->cset);
0842
0843 if (ovcs->id) {
0844 idr_remove(&ovcs_idr, ovcs->id);
0845 list_del(&ovcs->ovcs_list);
0846 ovcs->id = 0;
0847 }
0848
0849
0850 for (i = 0; i < ovcs->count; i++) {
0851 of_node_put(ovcs->fragments[i].target);
0852 of_node_put(ovcs->fragments[i].overlay);
0853 }
0854 kfree(ovcs->fragments);
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866 if (ovcs->notify_state == OF_OVERLAY_INIT ||
0867 ovcs->notify_state == OF_OVERLAY_POST_REMOVE) {
0868 kfree(ovcs->overlay_mem);
0869 kfree(ovcs->new_fdt);
0870 }
0871 kfree(ovcs);
0872 }
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902 static int of_overlay_apply(struct overlay_changeset *ovcs)
0903 {
0904 int ret = 0, ret_revert, ret_tmp;
0905
0906 ret = of_resolve_phandles(ovcs->overlay_root);
0907 if (ret)
0908 goto out;
0909
0910 ret = init_overlay_changeset(ovcs);
0911 if (ret)
0912 goto out;
0913
0914 ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
0915 if (ret)
0916 goto out;
0917
0918 ret = build_changeset(ovcs);
0919 if (ret)
0920 goto out;
0921
0922 ret_revert = 0;
0923 ret = __of_changeset_apply_entries(&ovcs->cset, &ret_revert);
0924 if (ret) {
0925 if (ret_revert) {
0926 pr_debug("overlay changeset revert error %d\n",
0927 ret_revert);
0928 devicetree_state_flags |= DTSF_APPLY_FAIL;
0929 }
0930 goto out;
0931 }
0932
0933 ret = __of_changeset_apply_notify(&ovcs->cset);
0934 if (ret)
0935 pr_err("overlay apply changeset entry notify error %d\n", ret);
0936
0937
0938 ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_APPLY);
0939 if (ret_tmp)
0940 if (!ret)
0941 ret = ret_tmp;
0942
0943 out:
0944 pr_debug("%s() err=%d\n", __func__, ret);
0945
0946 return ret;
0947 }
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968 int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
0969 int *ret_ovcs_id)
0970 {
0971 void *new_fdt;
0972 void *new_fdt_align;
0973 void *overlay_mem;
0974 int ret;
0975 u32 size;
0976 struct overlay_changeset *ovcs;
0977
0978 *ret_ovcs_id = 0;
0979
0980 if (devicetree_corrupt()) {
0981 pr_err("devicetree state suspect, refuse to apply overlay\n");
0982 return -EBUSY;
0983 }
0984
0985 if (overlay_fdt_size < sizeof(struct fdt_header) ||
0986 fdt_check_header(overlay_fdt)) {
0987 pr_err("Invalid overlay_fdt header\n");
0988 return -EINVAL;
0989 }
0990
0991 size = fdt_totalsize(overlay_fdt);
0992 if (overlay_fdt_size < size)
0993 return -EINVAL;
0994
0995 ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL);
0996 if (!ovcs)
0997 return -ENOMEM;
0998
0999 of_overlay_mutex_lock();
1000 mutex_lock(&of_mutex);
1001
1002
1003
1004
1005
1006
1007 ovcs->id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL);
1008 if (ovcs->id <= 0) {
1009 ret = ovcs->id;
1010 goto err_free_ovcs;
1011 }
1012
1013 INIT_LIST_HEAD(&ovcs->ovcs_list);
1014 list_add_tail(&ovcs->ovcs_list, &ovcs_list);
1015
1016
1017
1018
1019
1020 new_fdt = kmalloc(size + FDT_ALIGN_SIZE, GFP_KERNEL);
1021 if (!new_fdt) {
1022 ret = -ENOMEM;
1023 goto err_free_ovcs;
1024 }
1025 ovcs->new_fdt = new_fdt;
1026
1027 new_fdt_align = PTR_ALIGN(new_fdt, FDT_ALIGN_SIZE);
1028 memcpy(new_fdt_align, overlay_fdt, size);
1029
1030 overlay_mem = of_fdt_unflatten_tree(new_fdt_align, NULL,
1031 &ovcs->overlay_root);
1032 if (!overlay_mem) {
1033 pr_err("unable to unflatten overlay_fdt\n");
1034 ret = -EINVAL;
1035 goto err_free_ovcs;
1036 }
1037 ovcs->overlay_mem = overlay_mem;
1038
1039 ret = of_overlay_apply(ovcs);
1040
1041
1042
1043
1044
1045
1046 *ret_ovcs_id = ovcs->id;
1047 goto out_unlock;
1048
1049 err_free_ovcs:
1050 free_overlay_changeset(ovcs);
1051
1052 out_unlock:
1053 mutex_unlock(&of_mutex);
1054 of_overlay_mutex_unlock();
1055 return ret;
1056 }
1057 EXPORT_SYMBOL_GPL(of_overlay_fdt_apply);
1058
1059
1060
1061
1062
1063
1064 static int find_node(struct device_node *tree, struct device_node *np)
1065 {
1066 struct device_node *child;
1067
1068 if (tree == np)
1069 return 1;
1070
1071 for_each_child_of_node(tree, child) {
1072 if (find_node(child, np)) {
1073 of_node_put(child);
1074 return 1;
1075 }
1076 }
1077
1078 return 0;
1079 }
1080
1081
1082
1083
1084
1085
1086
1087 static int node_overlaps_later_cs(struct overlay_changeset *remove_ovcs,
1088 struct device_node *remove_ce_node)
1089 {
1090 struct overlay_changeset *ovcs;
1091 struct of_changeset_entry *ce;
1092
1093 list_for_each_entry_reverse(ovcs, &ovcs_list, ovcs_list) {
1094 if (ovcs == remove_ovcs)
1095 break;
1096
1097 list_for_each_entry(ce, &ovcs->cset.entries, node) {
1098 if (find_node(ce->np, remove_ce_node)) {
1099 pr_err("%s: #%d overlaps with #%d @%pOF\n",
1100 __func__, remove_ovcs->id, ovcs->id,
1101 remove_ce_node);
1102 return 1;
1103 }
1104 if (find_node(remove_ce_node, ce->np)) {
1105 pr_err("%s: #%d overlaps with #%d @%pOF\n",
1106 __func__, remove_ovcs->id, ovcs->id,
1107 remove_ce_node);
1108 return 1;
1109 }
1110 }
1111 }
1112
1113 return 0;
1114 }
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126 static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
1127 {
1128 struct of_changeset_entry *remove_ce;
1129
1130 list_for_each_entry(remove_ce, &remove_ovcs->cset.entries, node) {
1131 if (node_overlaps_later_cs(remove_ovcs, remove_ce->np)) {
1132 pr_err("overlay #%d is not topmost\n", remove_ovcs->id);
1133 return 0;
1134 }
1135 }
1136
1137 return 1;
1138 }
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174 int of_overlay_remove(int *ovcs_id)
1175 {
1176 struct overlay_changeset *ovcs;
1177 int ret, ret_apply, ret_tmp;
1178
1179 if (devicetree_corrupt()) {
1180 pr_err("suspect devicetree state, refuse to remove overlay\n");
1181 ret = -EBUSY;
1182 goto out;
1183 }
1184
1185 mutex_lock(&of_mutex);
1186
1187 ovcs = idr_find(&ovcs_idr, *ovcs_id);
1188 if (!ovcs) {
1189 ret = -ENODEV;
1190 pr_err("remove: Could not find overlay #%d\n", *ovcs_id);
1191 goto err_unlock;
1192 }
1193
1194 if (!overlay_removal_is_ok(ovcs)) {
1195 ret = -EBUSY;
1196 goto err_unlock;
1197 }
1198
1199 ret = overlay_notify(ovcs, OF_OVERLAY_PRE_REMOVE);
1200 if (ret)
1201 goto err_unlock;
1202
1203 ret_apply = 0;
1204 ret = __of_changeset_revert_entries(&ovcs->cset, &ret_apply);
1205 if (ret) {
1206 if (ret_apply)
1207 devicetree_state_flags |= DTSF_REVERT_FAIL;
1208 goto err_unlock;
1209 }
1210
1211 ret = __of_changeset_revert_notify(&ovcs->cset);
1212 if (ret)
1213 pr_err("overlay remove changeset entry notify error %d\n", ret);
1214
1215
1216 *ovcs_id = 0;
1217
1218
1219
1220
1221
1222
1223 ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_REMOVE);
1224 if (ret_tmp)
1225 if (!ret)
1226 ret = ret_tmp;
1227
1228 free_overlay_changeset(ovcs);
1229
1230 err_unlock:
1231
1232
1233
1234
1235
1236 mutex_unlock(&of_mutex);
1237
1238 out:
1239 pr_debug("%s() err=%d\n", __func__, ret);
1240
1241 return ret;
1242 }
1243 EXPORT_SYMBOL_GPL(of_overlay_remove);
1244
1245
1246
1247
1248
1249
1250
1251
1252 int of_overlay_remove_all(void)
1253 {
1254 struct overlay_changeset *ovcs, *ovcs_n;
1255 int ret;
1256
1257
1258 list_for_each_entry_safe_reverse(ovcs, ovcs_n, &ovcs_list, ovcs_list) {
1259 ret = of_overlay_remove(&ovcs->id);
1260 if (ret)
1261 return ret;
1262 }
1263
1264 return 0;
1265 }
1266 EXPORT_SYMBOL_GPL(of_overlay_remove_all);