From: Wandun Chen <[email protected]> Prepare for storing /memreserve/ entries in the reserved_mem array. alloc_reserved_mem_array was skipped if the device tree lacks a /reserved-memory node, pointer 'reserved_mem' continues to reference the reserved_mem_array which lives in __initdata, storing /memreserve/ entries into reserved_mem_array would result in metadata loss, and an out-of-bounds memory access will occur if the device tree contains more than MAX_RESERVED_REGIONS /memreserve/ entries.
So split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late(), and call alloc_reserved_mem_array() whether or not there is a /reserved-memory node. No functional change. The actual /memreserve/ population is added in a follow-up patch. Signed-off-by: Wandun Chen <[email protected]> --- drivers/of/fdt.c | 7 +++++-- drivers/of/of_private.h | 1 + drivers/of/of_reserved_mem.c | 11 ++--------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 26f66046cc32..b97775f6c9d4 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -1282,8 +1282,11 @@ void __init unflatten_device_tree(void) { void *fdt = initial_boot_params; - /* Save the statically-placed regions in the reserved_mem array */ - fdt_scan_reserved_mem_late(); + /* Attempt dynamic allocation of a new reserved_mem array */ + if (!alloc_reserved_mem_array()) { + /* Save the statically-placed regions in the reserved_mem array */ + fdt_scan_reserved_mem_late(); + } /* Populate an empty root node when bootloader doesn't provide one */ if (!fdt) { diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 0ae16da066e2..81c8ec9378b9 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -187,6 +187,7 @@ static inline struct device_node *__of_get_dma_parent(const struct device_node * int fdt_scan_reserved_mem(void); void __init fdt_scan_reserved_mem_late(void); +int __init alloc_reserved_mem_array(void); bool of_fdt_device_is_available(const void *blob, unsigned long node); diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index e1bd35115cc1..f6c02b37deb7 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -69,13 +69,13 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, * the initial static array is copied over to this new array and * the new array is used from this point on. */ -static int __init alloc_reserved_mem_array(void) +int __init alloc_reserved_mem_array(void) { struct reserved_mem *new_array; size_t alloc_size, copy_size, memset_size; int ret; - if (!total_reserved_mem_cnt) + if (!initial_boot_params || !total_reserved_mem_cnt) return -ENODEV; alloc_size = array_size(total_reserved_mem_cnt, sizeof(*new_array)); @@ -266,17 +266,10 @@ void __init fdt_scan_reserved_mem_late(void) phys_addr_t base, size; int node, child; - if (!fdt) - return; - node = fdt_path_offset(fdt, "/reserved-memory"); if (node < 0) return; - /* Attempt dynamic allocation of a new reserved_mem array */ - if (alloc_reserved_mem_array()) - return; - if (__reserved_mem_check_root(node)) return; -- 2.43.0
