Currently, x86, arm64, riscv and loongarch has been switched to generic
crashkernel reservation. With the help of function parse_crashkernel()
and generic reserve_crashkernel_generic(), arm32 crashkernel reservation
can also be simplified by steps:

1) Add a new header file <asm/crash_reserve.h>, and define CRASH_ALIGN,
   CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX in it;

2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
   reserve_crashkernel_generic();

3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
   arch/arm/Kconfig.

The old reserve_crashkernel() can be removed.

Following test cases have been performed as expected on QEMU vexpress-a9
(1GB system memory):

1) crashkernel=4G,high                          // invalid
2) crashkernel=1G,high                          // invalid
3) crashkernel=1G,high crashkernel=0M,low       // invalid
4) crashkernel=256M,high                        // invalid
5) crashkernel=256M,low                         // invalid
6) crashkernel=256M crashkernel=256M,high       // high is ignored, ok
7) crashkernel=256M crashkernel=256M,low        // low is ignored, ok
8) crashkernel=256M,high crashkernel=256M,low   // invalid
9) crashkernel=256M,high crashkernel=4G,low     // invalid
10) crashkernel=256M                            // ok
11) crashkernel=512M                            // ok
12) crashkernel=256M@0x88000000                 // ok
13) crashkernel=256M@0x78000000                 // ok
14) crashkernel=512M@0x78000000                 // ok

Signed-off-by: Jinjie Ruan <ruanjin...@huawei.com>
---
 arch/arm/Kconfig                     |  3 ++
 arch/arm/include/asm/crash_reserve.h | 24 +++++++++++
 arch/arm/kernel/setup.c              | 62 ++++------------------------
 3 files changed, 36 insertions(+), 53 deletions(-)
 create mode 100644 arch/arm/include/asm/crash_reserve.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 68990e1645d5..02e620e185c0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1596,6 +1596,9 @@ config ATAGS_PROC
 config ARCH_SUPPORTS_CRASH_DUMP
        def_bool y
 
+config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
+       def_bool CRASH_RESERVE
+
 config AUTO_ZRELADDR
        bool "Auto calculation of the decompressed kernel image address" if 
!ARCH_MULTIPLATFORM
        default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100)
diff --git a/arch/arm/include/asm/crash_reserve.h 
b/arch/arm/include/asm/crash_reserve.h
new file mode 100644
index 000000000000..85c9298bd3b7
--- /dev/null
+++ b/arch/arm/include/asm/crash_reserve.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ARM_CRASH_RESERVE_H
+#define _ARM_CRASH_RESERVE_H
+
+/*
+ * The crash region must be aligned to 128MB to avoid
+ * zImage relocating below the reserved region.
+ */
+#define CRASH_ALIGN                    (128 << 20)
+
+#define CRASH_ADDR_LOW_MAX             crash_addr_low_max()
+#define CRASH_ADDR_HIGH_MAX            memblock_end_of_DRAM()
+
+static inline unsigned long crash_addr_low_max(void)
+{
+       unsigned long long crash_max = idmap_to_phys((u32)~0);
+       unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
+
+       return (crash_max > lowmem_max) ? lowmem_max : crash_max;
+}
+
+
+#define HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY
+#endif
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 59e1a13b5cf6..3a8b6f08f4ec 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -979,13 +979,6 @@ static int __init init_machine_late(void)
 }
 late_initcall(init_machine_late);
 
-#ifdef CONFIG_CRASH_RESERVE
-/*
- * The crash region must be aligned to 128MB to avoid
- * zImage relocating below the reserved region.
- */
-#define CRASH_ALIGN    (128 << 20)
-
 static inline unsigned long long get_total_mem(void)
 {
        unsigned long total;
@@ -994,61 +987,27 @@ static inline unsigned long long get_total_mem(void)
        return total << PAGE_SHIFT;
 }
 
-/**
- * reserve_crashkernel() - reserves memory are for crash kernel
- *
- * This function reserves memory area given in "crashkernel=" kernel command
- * line parameter. The memory reserved is used by a dump capture kernel when
- * primary kernel is crashing.
- */
-static void __init reserve_crashkernel(void)
+static void __init arch_reserve_crashkernel(void)
 {
        unsigned long long crash_size, crash_base;
+       unsigned long long low_size = 0;
        unsigned long long total_mem;
+       bool high = false;
        int ret;
 
+       if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+               return;
+
        total_mem = get_total_mem();
        ret = parse_crashkernel(boot_command_line, total_mem,
                                &crash_size, &crash_base,
-                               NULL, NULL);
+                               &low_size, &high);
        /* invalid value specified or crashkernel=0 */
        crash_size = (phys_addr_t)crash_size;
        if (ret || !crash_size)
                return;
 
-       if (crash_base <= 0) {
-               unsigned long long crash_max = idmap_to_phys((u32)~0);
-               unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
-               if (crash_max > lowmem_max)
-                       crash_max = lowmem_max;
-
-               crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
-                                                      CRASH_ALIGN, crash_max);
-               if (!crash_base) {
-                       pr_err("crashkernel reservation failed - No suitable 
area found.\n");
-                       return;
-               }
-       } else {
-               unsigned long long crash_max = crash_base + crash_size;
-               unsigned long long start;
-
-               start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
-                                                 crash_base, crash_max);
-               if (!start) {
-                       pr_err("crashkernel reservation failed - memory is in 
use.\n");
-                       return;
-               }
-       }
-
-       pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
-               (unsigned long)(crash_size >> 20),
-               (unsigned long)(crash_base >> 20),
-               (unsigned long)(total_mem >> 20));
-
-       /* The crashk resource must always be located in normal mem */
-       crashk_res.start = crash_base;
-       crashk_res.end = crash_base + crash_size - 1;
-       insert_resource(&iomem_resource, &crashk_res);
+       reserve_crashkernel_generic(boot_command_line, crash_size, crash_base, 
low_size, high);
 
        if (arm_has_idmap_alias()) {
                /*
@@ -1065,9 +1024,6 @@ static void __init reserve_crashkernel(void)
                insert_resource(&iomem_resource, &crashk_boot_res);
        }
 }
-#else
-static inline void reserve_crashkernel(void) {}
-#endif /* CONFIG_CRASH_RESERVE*/
 
 void __init hyp_mode_check(void)
 {
@@ -1190,7 +1146,7 @@ void __init setup_arch(char **cmdline_p)
        if (!is_smp())
                hyp_mode_check();
 
-       reserve_crashkernel();
+       arch_reserve_crashkernel();
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
-- 
2.34.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to