From 237cd0c50a669af3aff4e804d19b785f7515179d Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 20 Feb 2018 13:35:58 +0800 Subject: core: Fix mismatched names between reserved memory nodes & properties OPAL exposes reserved memory regions through the device tree in both new (nodes) and old (properties) formats. However, the names used for these don't match - we use a generated cell address for the nodes, but the plain region name for the properties. This change, heavily based on code from Oliver O'Halloran , reworks the dt-generation code to firstly generate the new-format nodes, then uses those same names to generate the property data. Reported-by: Deb McLemore CC: Oliver O'Halloran Signed-off-by: Jeremy Kerr [stewart: fix test case] Signed-off-by: Stewart Smith --- core/mem_region.c | 34 +++++++++++++++++++-------------- core/test/run-mem_region_reservations.c | 5 ++++- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/core/mem_region.c b/core/mem_region.c index 3c93cd4..4479a23 100644 --- a/core/mem_region.c +++ b/core/mem_region.c @@ -1232,32 +1232,39 @@ void mem_region_add_dt_reserved(void) dt_add_property(node, "ranges", NULL, 0); } - /* First pass: calculate length of property data */ + prlog(PR_INFO, "Reserved regions:\n"); + + /* First pass, create /reserved-memory/ nodes for each reservation, + * and calculate the length for the /reserved-names and + * /reserved-ranges properties */ list_for_each(®ions, region, list) { if (!region_is_reservable(region)) continue; - names_len += strlen(region->name) + 1; + + prlog(PR_INFO, " 0x%012llx..%012llx : %s\n", + (long long)region->start, + (long long)(region->start + region->len - 1), + region->name); + + mem_region_add_dt_reserved_node(node, region); + + /* calculate the size of the properties populated later */ + names_len += strlen(region->node->name) + 1; ranges_len += 2 * sizeof(uint64_t); } name = names = malloc(names_len); range = ranges = malloc(ranges_len); - prlog(PR_INFO, "Reserved regions:\n"); - /* Second pass: populate property data */ + /* Second pass: populate the old-style reserved-names and + * reserved-regions arrays based on the node data */ list_for_each(®ions, region, list) { if (!region_is_reservable(region)) continue; - len = strlen(region->name) + 1; - memcpy(name, region->name, len); - name += len; - - prlog(PR_INFO, " 0x%012llx..%012llx : %s\n", - (long long)region->start, - (long long)(region->start + region->len - 1), - region->name); - mem_region_add_dt_reserved_node(node, region); + len = strlen(region->node->name) + 1; + memcpy(name, region->node->name, len); + name += len; range[0] = cpu_to_fdt64(region->start); range[1] = cpu_to_fdt64(region->len); @@ -1265,7 +1272,6 @@ void mem_region_add_dt_reserved(void) } unlock(&mem_region_lock); - prop = dt_find_property(dt_root, "reserved-names"); if (prop) dt_del_property(dt_root, (struct dt_property *)prop); diff --git a/core/test/run-mem_region_reservations.c b/core/test/run-mem_region_reservations.c index f593d9a..ae88582 100644 --- a/core/test/run-mem_region_reservations.c +++ b/core/test/run-mem_region_reservations.c @@ -119,6 +119,7 @@ static void check_property_reservations(void) unsigned int i, l; const char *name; uint64_t *rangep; + const char *at; /* check dt properties */ names = dt_find_property(dt_root, "reserved-names"); @@ -137,7 +138,9 @@ static void check_property_reservations(void) l = strlen(name) + 1; for (i = 0; i < ARRAY_SIZE(test_regions); i++) { - if (strcmp(test_regions[i].name, name)) + at = strchr(name, '@'); + if (strncmp(test_regions[i].name, name, + at ? at-name: strlen(name))) continue; assert(test_regions[i].addr == addr); assert(!test_regions[i].found); -- cgit v1.1