static struct property *dlpar_clone_property(struct property *prop, u32 prop_size) { struct property *new_prop; new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); if (!new_prop) return NULL; new_prop->name = kstrdup(prop->name, GFP_KERNEL); new_prop->value = kzalloc(prop_size, GFP_KERNEL); if (!new_prop->name || !new_prop->value) { dlpar_free_property(new_prop); return NULL; } memcpy(new_prop->value, prop->value, prop->length); new_prop->length = prop_size; of_property_set_flag(new_prop, OF_DYNAMIC); return new_prop; }
static struct property *clone_property(struct property *prop, u32 prop_sz) { struct property *new_prop; new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); if (!new_prop) return NULL; new_prop->name = kstrdup(prop->name, GFP_KERNEL); new_prop->value = kzalloc(prop_sz, GFP_KERNEL); if (!new_prop->name || !new_prop->value) { kfree(new_prop->name); kfree(new_prop->value); kfree(new_prop); return NULL; } new_prop->length = prop_sz; #if defined(CONFIG_OF_DYNAMIC) of_property_set_flag(new_prop, OF_DYNAMIC); #endif return new_prop; }
/* * The values of properties in the "/__symbols__" node are paths in * the ovcs->overlay_tree. When duplicating the properties, the paths * need to be adjusted to be the correct path for the live device tree. * * The paths refer to a node in the subtree of a fragment node's "__overlay__" * node, for example "/fragment@0/__overlay__/symbol_path_tail", * where symbol_path_tail can be a single node or it may be a multi-node path. * * The duplicated property value will be modified by replacing the * "/fragment_name/__overlay/" portion of the value with the target * path from the fragment node. */ static struct property *dup_and_fixup_symbol_prop( struct overlay_changeset *ovcs, const struct property *prop) { struct fragment *fragment; struct property *new_prop; struct device_node *fragment_node; struct device_node *overlay_node; const char *path; const char *path_tail; const char *target_path; int k; int overlay_name_len; int path_len; int path_tail_len; int target_path_len; if (!prop->value) return NULL; if (strnlen(prop->value, prop->length) >= prop->length) return NULL; path = prop->value; path_len = strlen(path); if (path_len < 1) return NULL; fragment_node = __of_find_node_by_path(ovcs->overlay_tree, path + 1); overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/"); of_node_put(fragment_node); of_node_put(overlay_node); for (k = 0; k < ovcs->count; k++) { fragment = &ovcs->fragments[k]; if (fragment->overlay == overlay_node) break; } if (k >= ovcs->count) return NULL; overlay_name_len = snprintf(NULL, 0, "%pOF", fragment->overlay); if (overlay_name_len > path_len) return NULL; path_tail = path + overlay_name_len; path_tail_len = strlen(path_tail); target_path = kasprintf(GFP_KERNEL, "%pOF", fragment->target); if (!target_path) return NULL; target_path_len = strlen(target_path); new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); if (!new_prop) goto err_free_target_path; new_prop->name = kstrdup(prop->name, GFP_KERNEL); new_prop->length = target_path_len + path_tail_len + 1; new_prop->value = kzalloc(new_prop->length, GFP_KERNEL); if (!new_prop->name || !new_prop->value) goto err_free_new_prop; strcpy(new_prop->value, target_path); strcpy(new_prop->value + target_path_len, path_tail); of_property_set_flag(new_prop, OF_DYNAMIC); return new_prop; err_free_new_prop: kfree(new_prop->name); kfree(new_prop->value); kfree(new_prop); err_free_target_path: kfree(target_path); return NULL; }