Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762474AbcLSCSK (ORCPT ); Sun, 18 Dec 2016 21:18:10 -0500 Received: from mail-lf0-f65.google.com ([209.85.215.65]:33821 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761858AbcLSCID (ORCPT ); Sun, 18 Dec 2016 21:08:03 -0500 From: Serge Semin To: ralf@linux-mips.org, paul.burton@imgtec.com, rabinv@axis.com, matt.redfearn@imgtec.com, james.hogan@imgtec.com, alexander.sverdlin@nokia.com, robh+dt@kernel.org, frowand.list@gmail.com Cc: Sergey.Semin@t-platforms.ru, linux-mips@linux-mips.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Serge Semin Subject: [PATCH 07/21] MIPS memblock: Alter elfcorehdr parameters parser Date: Mon, 19 Dec 2016 05:07:32 +0300 Message-Id: <1482113266-13207-8-git-send-email-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.6.6 In-Reply-To: <1482113266-13207-1-git-send-email-fancer.lancer@gmail.com> References: <1482113266-13207-1-git-send-email-fancer.lancer@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4191 Lines: 137 Memblock API can be successfully used to verify whether elfcorehdr memory region belongs to lowmemory, then it can be reserved within memblock allocator. There is also available default method for early parameters parser in kernel/crash_dump.c: setup_elfcorehdr(), so it's wise to use one instead of creating our own doing actually the same thing. Signed-off-by: Serge Semin --- arch/mips/kernel/setup.c | 91 +++++++++++++++++------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index cc6d06b..52205fb 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -426,6 +426,55 @@ static void __init mips_reserve_initrd_mem(void) { } #endif +/* + * Reserve memory occupied by elfcorehdr + */ +static void __init mips_reserve_elfcorehdr(void) +{ +#ifdef CONFIG_PROC_VMCORE + /* + * Don't reserve anything if kernel isn't booting after a panic and + * vmcore is usable (see linux/crash_dump.h for details) + */ + if (!is_vmcore_usable()) + return; + + /* Check whether the passed address belongs to low memory */ + if (elfcorehdr_addr + elfcorehdr_size >= mips_lowmem_limit) { + pr_err("Elfcorehdr %08zx @ %pa doesn't belong to low memory", + (size_t)elfcorehdr_size, &elfcorehdr_addr); + return; + } + + /* + * If elfcorehdr_size hasn't been specified, then try to reserve upto + * low memory limit + */ + if (!elfcorehdr_size) + elfcorehdr_size = mips_lowmem_limit - elfcorehdr_addr; + + /* Check the region belongs to actual memory (size can be zero) */ + if (!memblock_is_region_memory(elfcorehdr_addr, elfcorehdr_size)) { + pr_err("Elfcorehdr %08zx @ %pa is not a memory region", + (size_t)elfcorehdr_size, &elfcorehdr_addr); + return; + } + + /* Check whether elfcorehdr region is free */ + if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) { + pr_err("Elfcorehdr %08zx @ %pa overlaps in-use memory", + (size_t)elfcorehdr_size, &elfcorehdr_addr); + return; + } + + /* Reserve elfcorehdr within memblock */ + memblock_reserve(elfcorehdr_addr, PAGE_ALIGN(elfcorehdr_size)); + + pr_info("Reserved memory for kdump at %08zx @ %pa\n", + (size_t)elfcorehdr_size, &elfcorehdr_addr); +#endif /* CONFIG_PROC_VMCORE */ +} + #ifdef CONFIG_KEXEC /* * Parse passed crashkernel parameter and reserve corresponding memory @@ -499,6 +548,9 @@ static void __init bootmem_init(void) /* Check and reserve memory occupied by initrd */ mips_reserve_initrd_mem(); + /* Reserve memory for elfcorehdr */ + mips_reserve_elfcorehdr(); + /* Parse crashkernel parameter */ mips_parse_crashkernel(); @@ -719,37 +771,6 @@ static void __init bootmem_init(void) * initialization hook for anything else was introduced. */ -#ifdef CONFIG_PROC_VMCORE -unsigned long setup_elfcorehdr, setup_elfcorehdr_size; -static int __init early_parse_elfcorehdr(char *p) -{ - int i; - - setup_elfcorehdr = memparse(p, &p); - - for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long start = boot_mem_map.map[i].addr; - unsigned long end = (boot_mem_map.map[i].addr + - boot_mem_map.map[i].size); - if (setup_elfcorehdr >= start && setup_elfcorehdr < end) { - /* - * Reserve from the elf core header to the end of - * the memory segment, that should all be kdump - * reserved memory. - */ - setup_elfcorehdr_size = end - setup_elfcorehdr; - break; - } - } - /* - * If we don't find it in the memory map, then we shouldn't - * have to worry about it, as the new kernel won't use it. - */ - return 0; -} -early_param("elfcorehdr", early_parse_elfcorehdr); -#endif - static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type) { phys_addr_t size; @@ -833,14 +854,6 @@ static void __init arch_mem_init(char **cmdline_p) parse_early_param(); bootmem_init(); -#ifdef CONFIG_PROC_VMCORE - if (setup_elfcorehdr && setup_elfcorehdr_size) { - printk(KERN_INFO "kdump reserved memory at %lx-%lx\n", - setup_elfcorehdr, setup_elfcorehdr_size); - reserve_bootmem(setup_elfcorehdr, setup_elfcorehdr_size, - BOOTMEM_DEFAULT); - } -#endif device_tree_init(); sparse_init(); -- 2.6.6