[PATCH 07/21] MIPS memblock: Alter elfcorehdr parameters parser

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <fancer.lancer@xxxxxxxxx>
---
 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





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux