[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240718035444.2977105-4-ruanjinjie@huawei.com>
Date: Thu, 18 Jul 2024 11:54:44 +0800
From: Jinjie Ruan <ruanjinjie@...wei.com>
To: <linux@...linux.org.uk>, <catalin.marinas@....com>, <will@...nel.org>,
<paul.walmsley@...ive.com>, <palmer@...belt.com>, <aou@...s.berkeley.edu>,
<tglx@...utronix.de>, <mingo@...hat.com>, <bp@...en8.de>,
<dave.hansen@...ux.intel.com>, <hpa@...or.com>, <bhe@...hat.com>,
<vgoyal@...hat.com>, <dyoung@...hat.com>, <arnd@...db.de>, <afd@...com>,
<linus.walleij@...aro.org>, <akpm@...ux-foundation.org>,
<eric.devolder@...cle.com>, <gregkh@...uxfoundation.org>,
<javierm@...hat.com>, <deller@....de>, <robh@...nel.org>,
<hbathini@...ux.ibm.com>, <thunder.leizhen@...wei.com>,
<chenjiahao16@...wei.com>, <linux-kernel@...r.kernel.org>,
<kexec@...ts.infradead.org>, <linux-arm-kernel@...ts.infradead.org>,
<linux-riscv@...ts.infradead.org>
CC: <ruanjinjie@...wei.com>
Subject: [PATCH v3 3/3] ARM: Use generic interface to simplify crashkernel reservation
Currently, x86, arm64, riscv and loongarch has been switched to generic
crashkernel reservation, which is also ready for 32bit system.
So 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@...8000000 // ok
13) crashkernel=256M@...8000000 // ok
14) crashkernel=512M@...8000000 // ok
Signed-off-by: Jinjie Ruan <ruanjinjie@...wei.com>
Tested-by: Jinjie Ruan <ruanjinjie@...wei.com>
---
v3:
- Update the commit message.
---
arch/arm/Kconfig | 3 ++
arch/arm/include/asm/crash_reserve.h | 24 +++++++++++
arch/arm/kernel/setup.c | 63 ++++------------------------
3 files changed, 36 insertions(+), 54 deletions(-)
create mode 100644 arch/arm/include/asm/crash_reserve.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f434afff4a2c..3f198ae63950 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1597,6 +1597,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 e6a857bf0ce6..fc0ada003f6d 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,60 +987,25 @@ 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 crash_size, crash_base, 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 */
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()) {
/*
@@ -1064,9 +1022,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)
{
@@ -1189,7 +1144,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
Powered by blists - more mailing lists