From: Yu Chen <yu.ch...@zte.com.cn> memblock reserved regions are not reported via /proc/iomem on ARM, kexec's user-space doesn't know about memblock_reserve()d regions and thus possible for kexec to overwrite with the new kernel or initrd.
[ 0.000000] Booting Linux on physical CPU 0xf00 [ 0.000000] Linux version 4.9.115-rt93-dirty (yuchen@localhost.localdomain) (gcc version 6.2.0 (ZTE Embsys-TSP V3.07.2 0) ) #62 SMP PREEMPT Fri Sep 20 10:39:29 CST 2019 [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=30c5387d [ 0.000000] CPU: div instructions available: patching division code [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] OF: fdt:Machine model: LS1021A TWR Board [ 0.000000] INITRD: 0x80f7f000+0x03695e40 overlaps in-use memory region - disabling initrd Signed-off-by: Yu Chen <yu.ch...@zte.com.cn> Reviewed-by: Junhua Huang <huang.jun...@zte.com.cn> --- arch/arm/kernel/setup.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index d0a464e..606d1ac 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -911,6 +911,34 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) request_resource(&ioport_resource, &lp2); } +static int __init reserve_memblock_reserved_regions(void) +{ + u64 i, j; + + for (i = 0; i < num_standard_resources; ++i) { + struct resource *mem = &standard_resources[i]; + phys_addr_t r_start, r_end, mem_size = resource_size(mem); + + if (!memblock_is_region_reserved(mem->start, mem_size)) + continue; + + for_each_reserved_mem_region(j, &r_start, &r_end) { + resource_size_t start, end; + + start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start); + end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end); + + if (start > mem->end || end < mem->start) + continue; + + reserve_region_with_split(mem, start, end, "reserved"); + } + } + + return 0; +} +arch_initcall(reserve_memblock_reserved_regions); + #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) || \ defined(CONFIG_EFI) struct screen_info screen_info = { -- 2.7.4