diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2015-05-12 18:12:20 +0800 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-05-21 14:37:22 +1000 |
commit | 8fe651c4425afd2f75faec6c3dd7415bf0aa388c (patch) | |
tree | cc6f0d4deb96749d61ab50ef7dad32e0b4dbed61 /core/mem_region.c | |
parent | 48a3a132ec5f47951a103ad317d383204fa41d38 (diff) | |
download | blackbird-skiboot-8fe651c4425afd2f75faec6c3dd7415bf0aa388c.tar.gz blackbird-skiboot-8fe651c4425afd2f75faec6c3dd7415bf0aa388c.zip |
core: Prevent adding new regions after mem_region_add_dt_reserved
If we reserve any memory after mem_region_add_dt_reserved, that
reservation won't appear in the device tree. Ensure that we can't
add new regions after this point.
Also, add a testcase for the finalise, including some basic
reserved-ranges property checks.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/mem_region.c')
-rw-r--r-- | core/mem_region.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/core/mem_region.c b/core/mem_region.c index afffe990..a5a11f51 100644 --- a/core/mem_region.c +++ b/core/mem_region.c @@ -47,6 +47,8 @@ struct lock mem_region_lock = LOCK_UNLOCKED; static struct list_head regions = LIST_HEAD_INIT(regions); +static bool mem_regions_finalised = false; + unsigned long top_of_ram = SKIBOOT_BASE + SKIBOOT_SIZE; static struct mem_region skiboot_os_reserve = { @@ -637,6 +639,12 @@ static bool add_region(struct mem_region *region) { struct mem_region *r; + if (mem_regions_finalised) { + prerror("MEM: add_region(%s@0x%llx) called after finalise!\n", + region->name, region->start); + return false; + } + /* First split any regions which intersect. */ list_for_each(®ions, r, list) if (!maybe_split(r, region->start) || @@ -876,6 +884,7 @@ void mem_region_release_unused(void) struct mem_region *r; lock(&mem_region_lock); + assert(!mem_regions_finalised); printf("Releasing unused memory:\n"); list_for_each(®ions, r, list) { @@ -929,7 +938,11 @@ void mem_region_add_dt_reserved(void) names_len = 0; ranges_len = 0; + /* Finalise the region list, so we know that the regions list won't be + * altered after this point. The regions' free lists may change after + * we drop the lock, but we don't access those. */ lock(&mem_region_lock); + mem_regions_finalised = true; /* First pass: calculate length of property data */ list_for_each(®ions, region, list) { |