2024-01-19 14:53:08

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

Motivation:
=============
Previously, LKP reported a building error. When investigating, it can't
be resolved reasonablly with the present messy kdump config items.

https://lore.kernel.org/oe-kbuild-all/[email protected]/

The kdump (crash dumping) related config items could causes confusions:

Firstly,
---
CRASH_CORE enables codes including
- crashkernel reservation;
- elfcorehdr updating;
- vmcoreinfo exporting;
- crash hotplug handling;

Now fadump of powerpc, kcore dynamic debugging and kdump all selects
CRASH_CORE, while fadump
- fadump needs crashkernel parsing, vmcoreinfo exporting, and accessing
global variable 'elfcorehdr_addr';
- kcore only needs vmcoreinfo exporting;
- kdump needs all of the current kernel/crash_core.c.

So only enabling PROC_CORE or FA_DUMP will enable CRASH_CORE, this
mislead people that we enable crash dumping, actual it's not.

Secondly,
---
It's not reasonable to allow KEXEC_CORE select CRASH_CORE.

Because KEXEC_CORE enables codes which allocate control pages, copy
kexec/kdump segments, and prepare for switching. These codes are
shared by both kexec reboot and kdump. We could want kexec reboot,
but disable kdump. In that case, CRASH_CORE should not be selected.

--------------------
CONFIG_CRASH_CORE=y
CONFIG_KEXEC_CORE=y
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
---------------------

Thirdly,
---
It's not reasonable to allow CRASH_DUMP select KEXEC_CORE.

That could make KEXEC_CORE, CRASH_DUMP are enabled independently from
KEXEC or KEXEC_FILE. However, w/o KEXEC or KEXEC_FILE, the KEXEC_CORE
code built in doesn't make any sense because no kernel loading or
switching will happen to utilize the KEXEC_CORE code.
---------------------
CONFIG_CRASH_CORE=y
CONFIG_KEXEC_CORE=y
CONFIG_CRASH_DUMP=y
---------------------

In this case, what is worse, on arch sh and arm, KEXEC relies on MMU,
while CRASH_DUMP can still be enabled when !MMU, then compiling error is
seen as the lkp test robot reported in above link.

------arch/sh/Kconfig------
config ARCH_SUPPORTS_KEXEC
def_bool MMU

config ARCH_SUPPORTS_CRASH_DUMP
def_bool BROKEN_ON_SMP
---------------------------

Changes:
===========
1, split out crash_reserve.c from crash_core.c;
2, split out vmcore_infoc. from crash_core.c;
3, move crash related codes in kexec_core.c into crash_core.c;
4, remove dependency of FA_DUMP on CRASH_DUMP;
5, clean up kdump related config items;
6, wrap up crash codes in crash related ifdefs on all 9 arch-es
which support crash dumping;

Achievement:
===========
With above changes, I can rearrange the config item logic as below (the right
item depends on or is selected by the left item):

PROC_KCORE -----------> VMCORE_INFO

|----------> VMCORE_INFO
FA_DUMP----|
|----------> CRASH_RESERVE

---->VMCORE_INFO
/
|---->CRASH_RESERVE
KEXEC --| /|
|--> KEXEC_CORE--> CRASH_DUMP-->/-|---->PROC_VMCORE
KEXEC_FILE --| \ |
\---->CRASH_HOTPLUG


KEXEC --|
|--> KEXEC_CORE (for kexec reboot only)
KEXEC_FILE --|

Test
========
On all 8 architectures, including x86_64, arm64, s390x, sh, arm, mips,
riscv, loongarch, I did below three cases of config item setting and
building all passed. Let me take configs on x86_64 as exampmle here:

(1) Both CONFIG_KEXEC and KEXEC_FILE is unset, then all kexec/kdump
items are unset automatically:
# Kexec and crash features
# CONFIG_KEXEC is not set
# CONFIG_KEXEC_FILE is not set
# end of Kexec and crash features

(2) set CONFIG_KEXEC_FILE and 'make olddefconfig':
---------------
# Kexec and crash features
CONFIG_CRASH_RESERVE=y
CONFIG_VMCORE_INFO=y
CONFIG_KEXEC_CORE=y
CONFIG_KEXEC_FILE=y
CONFIG_CRASH_DUMP=y
CONFIG_CRASH_HOTPLUG=y
CONFIG_CRASH_MAX_MEMORY_RANGES=8192
# end of Kexec and crash features
---------------

(3) unset CONFIG_CRASH_DUMP in case 2 and execute 'make olddefconfig':
------------------------
# Kexec and crash features
CONFIG_KEXEC_CORE=y
CONFIG_KEXEC_FILE=y
# end of Kexec and crash features
------------------------

Note:
For ppc, it needs investigation to make clear how to split out crash
code in arch folder. Hope Hari and Pingfan can help have a look, see if
it's doable. Now, I make it either have both kexec and crash enabled, or
disable both of them altogether.

Baoquan He (14):
kexec: split crashkernel reservation code out from crash_core.c
crash: split vmcoreinfo exporting code out from crash_core.c
crash: remove dependency of FA_DUMP on CRASH_DUMP
crash: split crash dumping code out from kexec_core.c
crash: clean up kdump related config items
x86, crash: wrap crash dumping code into crash related ifdefs
arm64, crash: wrap crash dumping code into crash related ifdefs
ppc, crash: enforce KEXEC and KEXEC_FILE to select CRASH_DUMP
s390, crash: wrap crash dumping code into crash related ifdefs
sh, crash: wrap crash dumping code into crash related ifdefs
arm, crash: wrap crash dumping code into crash related ifdefs
mips, crash: wrap crash dumping code into crash related ifdefs
riscv, crash: wrap crash dumping code into crash related ifdefs
loongarch, crash: wrap crash dumping code into crash related ifdefs

arch/arm/kernel/setup.c | 7 +-
arch/arm64/Kconfig | 2 +-
.../asm/{crash_core.h => crash_reserve.h} | 4 +-
arch/arm64/include/asm/kexec.h | 2 +-
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/machine_kexec.c | 2 +-
arch/arm64/kernel/machine_kexec_file.c | 10 +-
.../kernel/{crash_core.c => vmcore_info.c} | 2 +-
arch/loongarch/kernel/setup.c | 7 +-
arch/mips/kernel/setup.c | 17 +-
arch/powerpc/Kconfig | 9 +-
arch/powerpc/kernel/setup-common.c | 2 +-
arch/powerpc/mm/nohash/kaslr_booke.c | 4 +-
arch/powerpc/platforms/powernv/opal-core.c | 2 +-
arch/riscv/Kconfig | 2 +-
.../asm/{crash_core.h => crash_reserve.h} | 4 +-
arch/riscv/kernel/Makefile | 2 +-
arch/riscv/kernel/elf_kexec.c | 9 +-
.../kernel/{crash_core.c => vmcore_info.c} | 2 +-
arch/riscv/mm/init.c | 2 +-
arch/s390/kernel/kexec_elf.c | 2 +
arch/s390/kernel/kexec_image.c | 2 +
arch/s390/kernel/machine_kexec_file.c | 10 +
arch/sh/kernel/machine_kexec.c | 3 +
arch/sh/kernel/setup.c | 2 +-
arch/x86/Kconfig | 2 +-
.../asm/{crash_core.h => crash_reserve.h} | 6 +-
arch/x86/kernel/Makefile | 6 +-
arch/x86/kernel/cpu/mshyperv.c | 4 +
arch/x86/kernel/kexec-bzimage64.c | 4 +
arch/x86/kernel/kvm.c | 4 +-
arch/x86/kernel/machine_kexec_64.c | 3 +
arch/x86/kernel/reboot.c | 2 +-
arch/x86/kernel/setup.c | 2 +-
arch/x86/kernel/smp.c | 2 +-
.../{crash_core_32.c => vmcore_info_32.c} | 2 +-
.../{crash_core_64.c => vmcore_info_64.c} | 2 +-
arch/x86/xen/enlighten_hvm.c | 4 +
drivers/base/cpu.c | 6 +-
drivers/firmware/qemu_fw_cfg.c | 14 +-
fs/proc/Kconfig | 2 +-
fs/proc/kcore.c | 2 +-
include/linux/buildid.h | 2 +-
include/linux/crash_core.h | 152 ++--
include/linux/crash_reserve.h | 48 ++
include/linux/kexec.h | 47 +-
include/linux/vmcore_info.h | 81 ++
init/initramfs.c | 2 +-
kernel/Kconfig.kexec | 12 +-
kernel/Makefile | 5 +-
kernel/crash_core.c | 764 +++++-------------
kernel/crash_reserve.c | 464 +++++++++++
kernel/{crash_dump.c => elfcorehdr.c} | 0
kernel/kexec.c | 11 +-
kernel/kexec_core.c | 250 +-----
kernel/kexec_file.c | 13 +-
kernel/kexec_internal.h | 2 +
kernel/ksysfs.c | 10 +-
kernel/printk/printk.c | 4 +-
kernel/vmcore_info.c | 233 ++++++
lib/buildid.c | 2 +-
61 files changed, 1233 insertions(+), 1048 deletions(-)
rename arch/arm64/include/asm/{crash_core.h => crash_reserve.h} (81%)
rename arch/arm64/kernel/{crash_core.c => vmcore_info.c} (97%)
rename arch/riscv/include/asm/{crash_core.h => crash_reserve.h} (78%)
rename arch/riscv/kernel/{crash_core.c => vmcore_info.c} (96%)
rename arch/x86/include/asm/{crash_core.h => crash_reserve.h} (92%)
rename arch/x86/kernel/{crash_core_32.c => vmcore_info_32.c} (90%)
rename arch/x86/kernel/{crash_core_64.c => vmcore_info_64.c} (94%)
create mode 100644 include/linux/crash_reserve.h
create mode 100644 include/linux/vmcore_info.h
create mode 100644 kernel/crash_reserve.c
rename kernel/{crash_dump.c => elfcorehdr.c} (100%)
create mode 100644 kernel/vmcore_info.c

--
2.41.0



2024-01-19 14:53:26

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 01/14] kexec: split crashkernel reservation code out from crash_core.c

Both kdump and fa_dump of ppc rely on crashkernel reservation. Move the
relevant codes into separate files:
crash_reserve.c, include/linux/crash_reserve.h.

And also add config item CRASH_RESERVE to control its enabling of the
codes. And update config items which has relationship with crashkernel
reservation.

And also change ifdeffery from CONFIG_CRASH_CORE to CONFIG_CRASH_RESERVE
when those scopes are only crashkernel reservation related.

And also rename arch/XXX/include/asm/{crash_core.h => crash_reserve.h}
on arm64, x86 and risc-v because those architectures' crash_core.h
is only related to crashkernel reservation.

Signed-off-by: Baoquan He <[email protected]>
---
arch/arm64/Kconfig | 2 +-
.../asm/{crash_core.h => crash_reserve.h} | 4 +-
arch/powerpc/Kconfig | 1 +
arch/powerpc/mm/nohash/kaslr_booke.c | 4 +-
arch/riscv/Kconfig | 2 +-
.../asm/{crash_core.h => crash_reserve.h} | 4 +-
arch/x86/Kconfig | 2 +-
.../asm/{crash_core.h => crash_reserve.h} | 6 +-
include/linux/crash_core.h | 40 --
include/linux/crash_reserve.h | 48 ++
include/linux/kexec.h | 1 +
kernel/Kconfig.kexec | 5 +-
kernel/Makefile | 1 +
kernel/crash_core.c | 438 -----------------
kernel/crash_reserve.c | 464 ++++++++++++++++++
15 files changed, 531 insertions(+), 491 deletions(-)
rename arch/arm64/include/asm/{crash_core.h => crash_reserve.h} (81%)
rename arch/riscv/include/asm/{crash_core.h => crash_reserve.h} (78%)
rename arch/x86/include/asm/{crash_core.h => crash_reserve.h} (92%)
create mode 100644 include/linux/crash_reserve.h
create mode 100644 kernel/crash_reserve.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ea01a2c43efa..d96bc3c67ec6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1501,7 +1501,7 @@ config ARCH_SUPPORTS_CRASH_DUMP
def_bool y

config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
- def_bool CRASH_CORE
+ def_bool CRASH_RESERVE

config TRANS_TABLE
def_bool y
diff --git a/arch/arm64/include/asm/crash_core.h b/arch/arm64/include/asm/crash_reserve.h
similarity index 81%
rename from arch/arm64/include/asm/crash_core.h
rename to arch/arm64/include/asm/crash_reserve.h
index 9f5c8d339f44..4afe027a4e7b 100644
--- a/arch/arm64/include/asm/crash_core.h
+++ b/arch/arm64/include/asm/crash_reserve.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#ifndef _ARM64_CRASH_CORE_H
-#define _ARM64_CRASH_CORE_H
+#ifndef _ARM64_CRASH_RESERVE_H
+#define _ARM64_CRASH_RESERVE_H

/* Current arm64 boot protocol requires 2MB alignment */
#define CRASH_ALIGN SZ_2M
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 414b978b8010..6aeab95f0edd 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -691,6 +691,7 @@ config FA_DUMP
bool "Firmware-assisted dump"
depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
select CRASH_CORE
+ select CRASH_RESERVE
select CRASH_DUMP
help
A robust mechanism to get reliable kernel crash dump with
diff --git a/arch/powerpc/mm/nohash/kaslr_booke.c b/arch/powerpc/mm/nohash/kaslr_booke.c
index b4f2786a7d2b..cdff129abb14 100644
--- a/arch/powerpc/mm/nohash/kaslr_booke.c
+++ b/arch/powerpc/mm/nohash/kaslr_booke.c
@@ -13,7 +13,7 @@
#include <linux/delay.h>
#include <linux/memblock.h>
#include <linux/libfdt.h>
-#include <linux/crash_core.h>
+#include <linux/crash_reserve.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <asm/cacheflush.h>
@@ -173,7 +173,7 @@ static __init bool overlaps_region(const void *fdt, u32 start,

static void __init get_crash_kernel(void *fdt, unsigned long size)
{
-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_CRASH_RESERVE
unsigned long long crash_size, crash_base;
int ret;

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index b549499eb363..37a438c23deb 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -712,7 +712,7 @@ config ARCH_SUPPORTS_CRASH_DUMP
def_bool y

config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
- def_bool CRASH_CORE
+ def_bool CRASH_RESERVE

config COMPAT
bool "Kernel support for 32-bit U-mode"
diff --git a/arch/riscv/include/asm/crash_core.h b/arch/riscv/include/asm/crash_reserve.h
similarity index 78%
rename from arch/riscv/include/asm/crash_core.h
rename to arch/riscv/include/asm/crash_reserve.h
index e1874b23feaf..013962e63587 100644
--- a/arch/riscv/include/asm/crash_core.h
+++ b/arch/riscv/include/asm/crash_reserve.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#ifndef _RISCV_CRASH_CORE_H
-#define _RISCV_CRASH_CORE_H
+#ifndef _RISCV_CRASH_RESERVE_H
+#define _RISCV_CRASH_RESERVE_H

#define CRASH_ALIGN PMD_SIZE

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5edec175b9bf..71417c5b228c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2106,7 +2106,7 @@ config ARCH_SUPPORTS_CRASH_HOTPLUG
def_bool y

config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
- def_bool CRASH_CORE
+ def_bool CRASH_RESEERVE

config PHYSICAL_START
hex "Physical address where the kernel is loaded" if (EXPERT || CRASH_DUMP)
diff --git a/arch/x86/include/asm/crash_core.h b/arch/x86/include/asm/crash_reserve.h
similarity index 92%
rename from arch/x86/include/asm/crash_core.h
rename to arch/x86/include/asm/crash_reserve.h
index 76af98f4e801..152239f95541 100644
--- a/arch/x86/include/asm/crash_core.h
+++ b/arch/x86/include/asm/crash_reserve.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _X86_CRASH_CORE_H
-#define _X86_CRASH_CORE_H
+#ifndef _X86_CRASH_RESERVE_H
+#define _X86_CRASH_RESERVE_H

/* 16M alignment for crash kernel regions */
#define CRASH_ALIGN SZ_16M
@@ -39,4 +39,4 @@ static inline unsigned long crash_low_size_default(void)
#endif
}

-#endif /* _X86_CRASH_CORE_H */
+#endif /* _X86_CRASH_RESERVE_H */
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 9eaeaafe0cad..1fde49246fa6 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -5,14 +5,6 @@
#include <linux/linkage.h>
#include <linux/elfcore.h>
#include <linux/elf.h>
-#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
-#include <asm/crash_core.h>
-#endif
-
-/* Location of a reserved region to hold the crash kernel.
- */
-extern struct resource crashk_res;
-extern struct resource crashk_low_res;

#define CRASH_CORE_NOTE_NAME "CORE"
#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
@@ -87,38 +79,6 @@ Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
void *data, size_t data_len);
void final_note(Elf_Word *buf);

-int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
- unsigned long long *crash_size, unsigned long long *crash_base,
- unsigned long long *low_size, bool *high);
-
-#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
-#ifndef DEFAULT_CRASH_KERNEL_LOW_SIZE
-#define DEFAULT_CRASH_KERNEL_LOW_SIZE (128UL << 20)
-#endif
-#ifndef CRASH_ALIGN
-#define CRASH_ALIGN SZ_2M
-#endif
-#ifndef CRASH_ADDR_LOW_MAX
-#define CRASH_ADDR_LOW_MAX SZ_4G
-#endif
-#ifndef CRASH_ADDR_HIGH_MAX
-#define CRASH_ADDR_HIGH_MAX memblock_end_of_DRAM()
-#endif
-
-void __init reserve_crashkernel_generic(char *cmdline,
- unsigned long long crash_size,
- unsigned long long crash_base,
- unsigned long long crash_low_size,
- bool high);
-#else
-static inline void __init reserve_crashkernel_generic(char *cmdline,
- unsigned long long crash_size,
- unsigned long long crash_base,
- unsigned long long crash_low_size,
- bool high)
-{}
-#endif
-
/* Alignment required for elf header segment */
#define ELF_CORE_HEADER_ALIGN 4096

diff --git a/include/linux/crash_reserve.h b/include/linux/crash_reserve.h
new file mode 100644
index 000000000000..5a9df944fb80
--- /dev/null
+++ b/include/linux/crash_reserve.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef LINUX_CRASH_RESERVE_H
+#define LINUX_CRASH_RESERVE_H
+
+#include <linux/linkage.h>
+#include <linux/elfcore.h>
+#include <linux/elf.h>
+#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
+#include <asm/crash_reserve.h>
+#endif
+
+/* Location of a reserved region to hold the crash kernel.
+ */
+extern struct resource crashk_res;
+extern struct resource crashk_low_res;
+
+int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
+ unsigned long long *crash_size, unsigned long long *crash_base,
+ unsigned long long *low_size, bool *high);
+
+#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
+#ifndef DEFAULT_CRASH_KERNEL_LOW_SIZE
+#define DEFAULT_CRASH_KERNEL_LOW_SIZE (128UL << 20)
+#endif
+#ifndef CRASH_ALIGN
+#define CRASH_ALIGN SZ_2M
+#endif
+#ifndef CRASH_ADDR_LOW_MAX
+#define CRASH_ADDR_LOW_MAX SZ_4G
+#endif
+#ifndef CRASH_ADDR_HIGH_MAX
+#define CRASH_ADDR_HIGH_MAX memblock_end_of_DRAM()
+#endif
+
+void __init reserve_crashkernel_generic(char *cmdline,
+ unsigned long long crash_size,
+ unsigned long long crash_base,
+ unsigned long long crash_low_size,
+ bool high);
+#else
+static inline void __init reserve_crashkernel_generic(char *cmdline,
+ unsigned long long crash_size,
+ unsigned long long crash_base,
+ unsigned long long crash_low_size,
+ bool high)
+{}
+#endif
+#endif /* LINUX_CRASH_RESERVE_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 400cb6c02176..6d79bfb52e5b 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -16,6 +16,7 @@
#if !defined(__ASSEMBLY__)

#include <linux/crash_core.h>
+#include <linux/crash_reserve.h>
#include <asm/io.h>
#include <linux/range.h>

diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
index 946dffa048b7..8b7be71edd85 100644
--- a/kernel/Kconfig.kexec
+++ b/kernel/Kconfig.kexec
@@ -2,11 +2,15 @@

menu "Kexec and crash features"

+config CRASH_RESERVE
+ bool
+
config CRASH_CORE
bool

config KEXEC_CORE
select CRASH_CORE
+ select CRASH_RESERVE
bool

config KEXEC_ELF
@@ -96,7 +100,6 @@ config KEXEC_JUMP
config CRASH_DUMP
bool "kernel crash dumps"
depends on ARCH_SUPPORTS_CRASH_DUMP
- select CRASH_CORE
select KEXEC_CORE
help
Generate crash dump after being started by kexec.
diff --git a/kernel/Makefile b/kernel/Makefile
index ce105a5558fc..05fa88b3ab74 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_KALLSYMS_SELFTEST) += kallsyms_selftest.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_CRASH_CORE) += crash_core.o
+obj-$(CONFIG_CRASH_RESERVE) += crash_reserve.o
obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 75cd6a736d03..055859c62f19 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -34,444 +34,6 @@ u32 *vmcoreinfo_note;
/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
static unsigned char *vmcoreinfo_data_safecopy;

-/* Location of the reserved area for the crash kernel */
-struct resource crashk_res = {
- .name = "Crash kernel",
- .start = 0,
- .end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
- .desc = IORES_DESC_CRASH_KERNEL
-};
-struct resource crashk_low_res = {
- .name = "Crash kernel",
- .start = 0,
- .end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
- .desc = IORES_DESC_CRASH_KERNEL
-};
-
-/*
- * parsing the "crashkernel" commandline
- *
- * this code is intended to be called from architecture specific code
- */
-
-
-/*
- * This function parses command lines in the format
- *
- * crashkernel=ramsize-range:size[,...][@offset]
- *
- * The function returns 0 on success and -EINVAL on failure.
- */
-static int __init parse_crashkernel_mem(char *cmdline,
- unsigned long long system_ram,
- unsigned long long *crash_size,
- unsigned long long *crash_base)
-{
- char *cur = cmdline, *tmp;
- unsigned long long total_mem = system_ram;
-
- /*
- * Firmware sometimes reserves some memory regions for its own use,
- * so the system memory size is less than the actual physical memory
- * size. Work around this by rounding up the total size to 128M,
- * which is enough for most test cases.
- */
- total_mem = roundup(total_mem, SZ_128M);
-
- /* for each entry of the comma-separated list */
- do {
- unsigned long long start, end = ULLONG_MAX, size;
-
- /* get the start of the range */
- start = memparse(cur, &tmp);
- if (cur == tmp) {
- pr_warn("crashkernel: Memory value expected\n");
- return -EINVAL;
- }
- cur = tmp;
- if (*cur != '-') {
- pr_warn("crashkernel: '-' expected\n");
- return -EINVAL;
- }
- cur++;
-
- /* if no ':' is here, than we read the end */
- if (*cur != ':') {
- end = memparse(cur, &tmp);
- if (cur == tmp) {
- pr_warn("crashkernel: Memory value expected\n");
- return -EINVAL;
- }
- cur = tmp;
- if (end <= start) {
- pr_warn("crashkernel: end <= start\n");
- return -EINVAL;
- }
- }
-
- if (*cur != ':') {
- pr_warn("crashkernel: ':' expected\n");
- return -EINVAL;
- }
- cur++;
-
- size = memparse(cur, &tmp);
- if (cur == tmp) {
- pr_warn("Memory value expected\n");
- return -EINVAL;
- }
- cur = tmp;
- if (size >= total_mem) {
- pr_warn("crashkernel: invalid size\n");
- return -EINVAL;
- }
-
- /* match ? */
- if (total_mem >= start && total_mem < end) {
- *crash_size = size;
- break;
- }
- } while (*cur++ == ',');
-
- if (*crash_size > 0) {
- while (*cur && *cur != ' ' && *cur != '@')
- cur++;
- if (*cur == '@') {
- cur++;
- *crash_base = memparse(cur, &tmp);
- if (cur == tmp) {
- pr_warn("Memory value expected after '@'\n");
- return -EINVAL;
- }
- }
- } else
- pr_info("crashkernel size resulted in zero bytes\n");
-
- return 0;
-}
-
-/*
- * That function parses "simple" (old) crashkernel command lines like
- *
- * crashkernel=size[@offset]
- *
- * It returns 0 on success and -EINVAL on failure.
- */
-static int __init parse_crashkernel_simple(char *cmdline,
- unsigned long long *crash_size,
- unsigned long long *crash_base)
-{
- char *cur = cmdline;
-
- *crash_size = memparse(cmdline, &cur);
- if (cmdline == cur) {
- pr_warn("crashkernel: memory value expected\n");
- return -EINVAL;
- }
-
- if (*cur == '@')
- *crash_base = memparse(cur+1, &cur);
- else if (*cur != ' ' && *cur != '\0') {
- pr_warn("crashkernel: unrecognized char: %c\n", *cur);
- return -EINVAL;
- }
-
- return 0;
-}
-
-#define SUFFIX_HIGH 0
-#define SUFFIX_LOW 1
-#define SUFFIX_NULL 2
-static __initdata char *suffix_tbl[] = {
- [SUFFIX_HIGH] = ",high",
- [SUFFIX_LOW] = ",low",
- [SUFFIX_NULL] = NULL,
-};
-
-/*
- * That function parses "suffix" crashkernel command lines like
- *
- * crashkernel=size,[high|low]
- *
- * It returns 0 on success and -EINVAL on failure.
- */
-static int __init parse_crashkernel_suffix(char *cmdline,
- unsigned long long *crash_size,
- const char *suffix)
-{
- char *cur = cmdline;
-
- *crash_size = memparse(cmdline, &cur);
- if (cmdline == cur) {
- pr_warn("crashkernel: memory value expected\n");
- return -EINVAL;
- }
-
- /* check with suffix */
- if (strncmp(cur, suffix, strlen(suffix))) {
- pr_warn("crashkernel: unrecognized char: %c\n", *cur);
- return -EINVAL;
- }
- cur += strlen(suffix);
- if (*cur != ' ' && *cur != '\0') {
- pr_warn("crashkernel: unrecognized char: %c\n", *cur);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static __init char *get_last_crashkernel(char *cmdline,
- const char *name,
- const char *suffix)
-{
- char *p = cmdline, *ck_cmdline = NULL;
-
- /* find crashkernel and use the last one if there are more */
- p = strstr(p, name);
- while (p) {
- char *end_p = strchr(p, ' ');
- char *q;
-
- if (!end_p)
- end_p = p + strlen(p);
-
- if (!suffix) {
- int i;
-
- /* skip the one with any known suffix */
- for (i = 0; suffix_tbl[i]; i++) {
- q = end_p - strlen(suffix_tbl[i]);
- if (!strncmp(q, suffix_tbl[i],
- strlen(suffix_tbl[i])))
- goto next;
- }
- ck_cmdline = p;
- } else {
- q = end_p - strlen(suffix);
- if (!strncmp(q, suffix, strlen(suffix)))
- ck_cmdline = p;
- }
-next:
- p = strstr(p+1, name);
- }
-
- return ck_cmdline;
-}
-
-static int __init __parse_crashkernel(char *cmdline,
- unsigned long long system_ram,
- unsigned long long *crash_size,
- unsigned long long *crash_base,
- const char *suffix)
-{
- char *first_colon, *first_space;
- char *ck_cmdline;
- char *name = "crashkernel=";
-
- BUG_ON(!crash_size || !crash_base);
- *crash_size = 0;
- *crash_base = 0;
-
- ck_cmdline = get_last_crashkernel(cmdline, name, suffix);
- if (!ck_cmdline)
- return -ENOENT;
-
- ck_cmdline += strlen(name);
-
- if (suffix)
- return parse_crashkernel_suffix(ck_cmdline, crash_size,
- suffix);
- /*
- * if the commandline contains a ':', then that's the extended
- * syntax -- if not, it must be the classic syntax
- */
- first_colon = strchr(ck_cmdline, ':');
- first_space = strchr(ck_cmdline, ' ');
- if (first_colon && (!first_space || first_colon < first_space))
- return parse_crashkernel_mem(ck_cmdline, system_ram,
- crash_size, crash_base);
-
- return parse_crashkernel_simple(ck_cmdline, crash_size, crash_base);
-}
-
-/*
- * That function is the entry point for command line parsing and should be
- * called from the arch-specific code.
- *
- * If crashkernel=,high|low is supported on architecture, non-NULL values
- * should be passed to parameters 'low_size' and 'high'.
- */
-int __init parse_crashkernel(char *cmdline,
- unsigned long long system_ram,
- unsigned long long *crash_size,
- unsigned long long *crash_base,
- unsigned long long *low_size,
- bool *high)
-{
- int ret;
-
- /* crashkernel=X[@offset] */
- ret = __parse_crashkernel(cmdline, system_ram, crash_size,
- crash_base, NULL);
-#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
- /*
- * If non-NULL 'high' passed in and no normal crashkernel
- * setting detected, try parsing crashkernel=,high|low.
- */
- if (high && ret == -ENOENT) {
- ret = __parse_crashkernel(cmdline, 0, crash_size,
- crash_base, suffix_tbl[SUFFIX_HIGH]);
- if (ret || !*crash_size)
- return -EINVAL;
-
- /*
- * crashkernel=Y,low can be specified or not, but invalid value
- * is not allowed.
- */
- ret = __parse_crashkernel(cmdline, 0, low_size,
- crash_base, suffix_tbl[SUFFIX_LOW]);
- if (ret == -ENOENT) {
- *low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
- ret = 0;
- } else if (ret) {
- return ret;
- }
-
- *high = true;
- }
-#endif
- if (!*crash_size)
- ret = -EINVAL;
-
- return ret;
-}
-
-/*
- * Add a dummy early_param handler to mark crashkernel= as a known command line
- * parameter and suppress incorrect warnings in init/main.c.
- */
-static int __init parse_crashkernel_dummy(char *arg)
-{
- return 0;
-}
-early_param("crashkernel", parse_crashkernel_dummy);
-
-#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
-static int __init reserve_crashkernel_low(unsigned long long low_size)
-{
-#ifdef CONFIG_64BIT
- unsigned long long low_base;
-
- low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX);
- if (!low_base) {
- pr_err("cannot allocate crashkernel low memory (size:0x%llx).\n", low_size);
- return -ENOMEM;
- }
-
- pr_info("crashkernel low memory reserved: 0x%08llx - 0x%08llx (%lld MB)\n",
- low_base, low_base + low_size, low_size >> 20);
-
- crashk_low_res.start = low_base;
- crashk_low_res.end = low_base + low_size - 1;
-#endif
- return 0;
-}
-
-void __init reserve_crashkernel_generic(char *cmdline,
- unsigned long long crash_size,
- unsigned long long crash_base,
- unsigned long long crash_low_size,
- bool high)
-{
- unsigned long long search_end = CRASH_ADDR_LOW_MAX, search_base = 0;
- bool fixed_base = false;
-
- /* User specifies base address explicitly. */
- if (crash_base) {
- fixed_base = true;
- search_base = crash_base;
- search_end = crash_base + crash_size;
- } else if (high) {
- search_base = CRASH_ADDR_LOW_MAX;
- search_end = CRASH_ADDR_HIGH_MAX;
- }
-
-retry:
- crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
- search_base, search_end);
- if (!crash_base) {
- /*
- * For crashkernel=size[KMG]@offset[KMG], print out failure
- * message if can't reserve the specified region.
- */
- if (fixed_base) {
- pr_warn("crashkernel reservation failed - memory is in use.\n");
- return;
- }
-
- /*
- * For crashkernel=size[KMG], if the first attempt was for
- * low memory, fall back to high memory, the minimum required
- * low memory will be reserved later.
- */
- if (!high && search_end == CRASH_ADDR_LOW_MAX) {
- search_end = CRASH_ADDR_HIGH_MAX;
- search_base = CRASH_ADDR_LOW_MAX;
- crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
- goto retry;
- }
-
- /*
- * For crashkernel=size[KMG],high, if the first attempt was
- * for high memory, fall back to low memory.
- */
- if (high && search_end == CRASH_ADDR_HIGH_MAX) {
- search_end = CRASH_ADDR_LOW_MAX;
- search_base = 0;
- goto retry;
- }
- pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
- crash_size);
- return;
- }
-
- if ((crash_base >= CRASH_ADDR_LOW_MAX) &&
- crash_low_size && reserve_crashkernel_low(crash_low_size)) {
- memblock_phys_free(crash_base, crash_size);
- return;
- }
-
- pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
- crash_base, crash_base + crash_size, crash_size >> 20);
-
- /*
- * The crashkernel memory will be removed from the kernel linear
- * map. Inform kmemleak so that it won't try to access it.
- */
- kmemleak_ignore_phys(crash_base);
- if (crashk_low_res.end)
- kmemleak_ignore_phys(crashk_low_res.start);
-
- crashk_res.start = crash_base;
- crashk_res.end = crash_base + crash_size - 1;
-}
-
-static __init int insert_crashkernel_resources(void)
-{
- if (crashk_res.start < crashk_res.end)
- insert_resource(&iomem_resource, &crashk_res);
-
- if (crashk_low_res.start < crashk_low_res.end)
- insert_resource(&iomem_resource, &crashk_low_res);
-
- return 0;
-}
-early_initcall(insert_crashkernel_resources);
-#endif
-
int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
void **addr, unsigned long *sz)
{
diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
new file mode 100644
index 000000000000..bbb6c3cb00e4
--- /dev/null
+++ b/kernel/crash_reserve.c
@@ -0,0 +1,464 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * crash.c - kernel crash support code.
+ * Copyright (C) 2002-2004 Eric Biederman <[email protected]>
+ */
+
+#include <linux/buildid.h>
+#include <linux/init.h>
+#include <linux/utsname.h>
+#include <linux/vmalloc.h>
+#include <linux/sizes.h>
+#include <linux/kexec.h>
+#include <linux/memory.h>
+#include <linux/cpuhotplug.h>
+#include <linux/memblock.h>
+#include <linux/kexec.h>
+#include <linux/kmemleak.h>
+
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <crypto/sha1.h>
+
+#include "kallsyms_internal.h"
+#include "kexec_internal.h"
+
+/* Location of the reserved area for the crash kernel */
+struct resource crashk_res = {
+ .name = "Crash kernel",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
+ .desc = IORES_DESC_CRASH_KERNEL
+};
+struct resource crashk_low_res = {
+ .name = "Crash kernel",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
+ .desc = IORES_DESC_CRASH_KERNEL
+};
+
+/*
+ * parsing the "crashkernel" commandline
+ *
+ * this code is intended to be called from architecture specific code
+ */
+
+
+/*
+ * This function parses command lines in the format
+ *
+ * crashkernel=ramsize-range:size[,...][@offset]
+ *
+ * The function returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_mem(char *cmdline,
+ unsigned long long system_ram,
+ unsigned long long *crash_size,
+ unsigned long long *crash_base)
+{
+ char *cur = cmdline, *tmp;
+ unsigned long long total_mem = system_ram;
+
+ /*
+ * Firmware sometimes reserves some memory regions for its own use,
+ * so the system memory size is less than the actual physical memory
+ * size. Work around this by rounding up the total size to 128M,
+ * which is enough for most test cases.
+ */
+ total_mem = roundup(total_mem, SZ_128M);
+
+ /* for each entry of the comma-separated list */
+ do {
+ unsigned long long start, end = ULLONG_MAX, size;
+
+ /* get the start of the range */
+ start = memparse(cur, &tmp);
+ if (cur == tmp) {
+ pr_warn("crashkernel: Memory value expected\n");
+ return -EINVAL;
+ }
+ cur = tmp;
+ if (*cur != '-') {
+ pr_warn("crashkernel: '-' expected\n");
+ return -EINVAL;
+ }
+ cur++;
+
+ /* if no ':' is here, than we read the end */
+ if (*cur != ':') {
+ end = memparse(cur, &tmp);
+ if (cur == tmp) {
+ pr_warn("crashkernel: Memory value expected\n");
+ return -EINVAL;
+ }
+ cur = tmp;
+ if (end <= start) {
+ pr_warn("crashkernel: end <= start\n");
+ return -EINVAL;
+ }
+ }
+
+ if (*cur != ':') {
+ pr_warn("crashkernel: ':' expected\n");
+ return -EINVAL;
+ }
+ cur++;
+
+ size = memparse(cur, &tmp);
+ if (cur == tmp) {
+ pr_warn("Memory value expected\n");
+ return -EINVAL;
+ }
+ cur = tmp;
+ if (size >= total_mem) {
+ pr_warn("crashkernel: invalid size\n");
+ return -EINVAL;
+ }
+
+ /* match ? */
+ if (total_mem >= start && total_mem < end) {
+ *crash_size = size;
+ break;
+ }
+ } while (*cur++ == ',');
+
+ if (*crash_size > 0) {
+ while (*cur && *cur != ' ' && *cur != '@')
+ cur++;
+ if (*cur == '@') {
+ cur++;
+ *crash_base = memparse(cur, &tmp);
+ if (cur == tmp) {
+ pr_warn("Memory value expected after '@'\n");
+ return -EINVAL;
+ }
+ }
+ } else
+ pr_info("crashkernel size resulted in zero bytes\n");
+
+ return 0;
+}
+
+/*
+ * That function parses "simple" (old) crashkernel command lines like
+ *
+ * crashkernel=size[@offset]
+ *
+ * It returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_simple(char *cmdline,
+ unsigned long long *crash_size,
+ unsigned long long *crash_base)
+{
+ char *cur = cmdline;
+
+ *crash_size = memparse(cmdline, &cur);
+ if (cmdline == cur) {
+ pr_warn("crashkernel: memory value expected\n");
+ return -EINVAL;
+ }
+
+ if (*cur == '@')
+ *crash_base = memparse(cur+1, &cur);
+ else if (*cur != ' ' && *cur != '\0') {
+ pr_warn("crashkernel: unrecognized char: %c\n", *cur);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#define SUFFIX_HIGH 0
+#define SUFFIX_LOW 1
+#define SUFFIX_NULL 2
+static __initdata char *suffix_tbl[] = {
+ [SUFFIX_HIGH] = ",high",
+ [SUFFIX_LOW] = ",low",
+ [SUFFIX_NULL] = NULL,
+};
+
+/*
+ * That function parses "suffix" crashkernel command lines like
+ *
+ * crashkernel=size,[high|low]
+ *
+ * It returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_suffix(char *cmdline,
+ unsigned long long *crash_size,
+ const char *suffix)
+{
+ char *cur = cmdline;
+
+ *crash_size = memparse(cmdline, &cur);
+ if (cmdline == cur) {
+ pr_warn("crashkernel: memory value expected\n");
+ return -EINVAL;
+ }
+
+ /* check with suffix */
+ if (strncmp(cur, suffix, strlen(suffix))) {
+ pr_warn("crashkernel: unrecognized char: %c\n", *cur);
+ return -EINVAL;
+ }
+ cur += strlen(suffix);
+ if (*cur != ' ' && *cur != '\0') {
+ pr_warn("crashkernel: unrecognized char: %c\n", *cur);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static __init char *get_last_crashkernel(char *cmdline,
+ const char *name,
+ const char *suffix)
+{
+ char *p = cmdline, *ck_cmdline = NULL;
+
+ /* find crashkernel and use the last one if there are more */
+ p = strstr(p, name);
+ while (p) {
+ char *end_p = strchr(p, ' ');
+ char *q;
+
+ if (!end_p)
+ end_p = p + strlen(p);
+
+ if (!suffix) {
+ int i;
+
+ /* skip the one with any known suffix */
+ for (i = 0; suffix_tbl[i]; i++) {
+ q = end_p - strlen(suffix_tbl[i]);
+ if (!strncmp(q, suffix_tbl[i],
+ strlen(suffix_tbl[i])))
+ goto next;
+ }
+ ck_cmdline = p;
+ } else {
+ q = end_p - strlen(suffix);
+ if (!strncmp(q, suffix, strlen(suffix)))
+ ck_cmdline = p;
+ }
+next:
+ p = strstr(p+1, name);
+ }
+
+ return ck_cmdline;
+}
+
+static int __init __parse_crashkernel(char *cmdline,
+ unsigned long long system_ram,
+ unsigned long long *crash_size,
+ unsigned long long *crash_base,
+ const char *suffix)
+{
+ char *first_colon, *first_space;
+ char *ck_cmdline;
+ char *name = "crashkernel=";
+
+ BUG_ON(!crash_size || !crash_base);
+ *crash_size = 0;
+ *crash_base = 0;
+
+ ck_cmdline = get_last_crashkernel(cmdline, name, suffix);
+ if (!ck_cmdline)
+ return -ENOENT;
+
+ ck_cmdline += strlen(name);
+
+ if (suffix)
+ return parse_crashkernel_suffix(ck_cmdline, crash_size,
+ suffix);
+ /*
+ * if the commandline contains a ':', then that's the extended
+ * syntax -- if not, it must be the classic syntax
+ */
+ first_colon = strchr(ck_cmdline, ':');
+ first_space = strchr(ck_cmdline, ' ');
+ if (first_colon && (!first_space || first_colon < first_space))
+ return parse_crashkernel_mem(ck_cmdline, system_ram,
+ crash_size, crash_base);
+
+ return parse_crashkernel_simple(ck_cmdline, crash_size, crash_base);
+}
+
+/*
+ * That function is the entry point for command line parsing and should be
+ * called from the arch-specific code.
+ *
+ * If crashkernel=,high|low is supported on architecture, non-NULL values
+ * should be passed to parameters 'low_size' and 'high'.
+ */
+int __init parse_crashkernel(char *cmdline,
+ unsigned long long system_ram,
+ unsigned long long *crash_size,
+ unsigned long long *crash_base,
+ unsigned long long *low_size,
+ bool *high)
+{
+ int ret;
+
+ /* crashkernel=X[@offset] */
+ ret = __parse_crashkernel(cmdline, system_ram, crash_size,
+ crash_base, NULL);
+#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
+ /*
+ * If non-NULL 'high' passed in and no normal crashkernel
+ * setting detected, try parsing crashkernel=,high|low.
+ */
+ if (high && ret == -ENOENT) {
+ ret = __parse_crashkernel(cmdline, 0, crash_size,
+ crash_base, suffix_tbl[SUFFIX_HIGH]);
+ if (ret || !*crash_size)
+ return -EINVAL;
+
+ /*
+ * crashkernel=Y,low can be specified or not, but invalid value
+ * is not allowed.
+ */
+ ret = __parse_crashkernel(cmdline, 0, low_size,
+ crash_base, suffix_tbl[SUFFIX_LOW]);
+ if (ret == -ENOENT) {
+ *low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
+ ret = 0;
+ } else if (ret) {
+ return ret;
+ }
+
+ *high = true;
+ }
+#endif
+ if (!*crash_size)
+ ret = -EINVAL;
+
+ return ret;
+}
+
+/*
+ * Add a dummy early_param handler to mark crashkernel= as a known command line
+ * parameter and suppress incorrect warnings in init/main.c.
+ */
+static int __init parse_crashkernel_dummy(char *arg)
+{
+ return 0;
+}
+early_param("crashkernel", parse_crashkernel_dummy);
+
+#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
+static int __init reserve_crashkernel_low(unsigned long long low_size)
+{
+#ifdef CONFIG_64BIT
+ unsigned long long low_base;
+
+ low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX);
+ if (!low_base) {
+ pr_err("cannot allocate crashkernel low memory (size:0x%llx).\n", low_size);
+ return -ENOMEM;
+ }
+
+ pr_info("crashkernel low memory reserved: 0x%08llx - 0x%08llx (%lld MB)\n",
+ low_base, low_base + low_size, low_size >> 20);
+
+ crashk_low_res.start = low_base;
+ crashk_low_res.end = low_base + low_size - 1;
+ insert_resource(&iomem_resource, &crashk_low_res);
+#endif
+ return 0;
+}
+
+void __init reserve_crashkernel_generic(char *cmdline,
+ unsigned long long crash_size,
+ unsigned long long crash_base,
+ unsigned long long crash_low_size,
+ bool high)
+{
+ unsigned long long search_end = CRASH_ADDR_LOW_MAX, search_base = 0;
+ bool fixed_base = false;
+
+ /* User specifies base address explicitly. */
+ if (crash_base) {
+ fixed_base = true;
+ search_base = crash_base;
+ search_end = crash_base + crash_size;
+ } else if (high) {
+ search_base = CRASH_ADDR_LOW_MAX;
+ search_end = CRASH_ADDR_HIGH_MAX;
+ }
+
+retry:
+ crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+ search_base, search_end);
+ if (!crash_base) {
+ /*
+ * For crashkernel=size[KMG]@offset[KMG], print out failure
+ * message if can't reserve the specified region.
+ */
+ if (fixed_base) {
+ pr_warn("crashkernel reservation failed - memory is in use.\n");
+ return;
+ }
+
+ /*
+ * For crashkernel=size[KMG], if the first attempt was for
+ * low memory, fall back to high memory, the minimum required
+ * low memory will be reserved later.
+ */
+ if (!high && search_end == CRASH_ADDR_LOW_MAX) {
+ search_end = CRASH_ADDR_HIGH_MAX;
+ search_base = CRASH_ADDR_LOW_MAX;
+ crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
+ goto retry;
+ }
+
+ /*
+ * For crashkernel=size[KMG],high, if the first attempt was
+ * for high memory, fall back to low memory.
+ */
+ if (high && search_end == CRASH_ADDR_HIGH_MAX) {
+ search_end = CRASH_ADDR_LOW_MAX;
+ search_base = 0;
+ goto retry;
+ }
+ pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
+ crash_size);
+ return;
+ }
+
+ if ((crash_base >= CRASH_ADDR_LOW_MAX) &&
+ crash_low_size && reserve_crashkernel_low(crash_low_size)) {
+ memblock_phys_free(crash_base, crash_size);
+ return;
+ }
+
+ pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
+ crash_base, crash_base + crash_size, crash_size >> 20);
+
+ /*
+ * The crashkernel memory will be removed from the kernel linear
+ * map. Inform kmemleak so that it won't try to access it.
+ */
+ kmemleak_ignore_phys(crash_base);
+ if (crashk_low_res.end)
+ kmemleak_ignore_phys(crashk_low_res.start);
+
+ crashk_res.start = crash_base;
+ crashk_res.end = crash_base + crash_size - 1;
+}
+
+static __init int insert_crashkernel_resources(void)
+{
+ if (crashk_res.start < crashk_res.end)
+ insert_resource(&iomem_resource, &crashk_res);
+
+ if (crashk_low_res.start < crashk_low_res.end)
+ insert_resource(&iomem_resource, &crashk_low_res);
+
+ return 0;
+}
+early_initcall(insert_crashkernel_resources);
+#endif
--
2.41.0


2024-01-19 14:53:41

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 02/14] crash: split vmcoreinfo exporting code out from crash_core.c

Now move the relevant codes into separate files:
kernel/crash_reserve.c, include/linux/crash_reserve.h.

And add config item CRASH_RESERVE to control its enabling.

And also update the old ifdeffery of CONFIG_CRASH_CORE, including of
<linux/crash_core.h> and config item dependency on CRASH_CORE
accordingly.

And also do renaming as follows:
- arch/xxx/kernel/{crash_core.c => vmcore_info.c}
because they are only related to vmcoreinfo exporting on x86, arm64,
riscv.

And also Remove config item CRASH_CORE, and rely on CONFIG_KEXEC_CORE to
decide if build in crash_core.c.

Signed-off-by: Baoquan He <[email protected]>
---
arch/arm64/kernel/Makefile | 2 +-
.../kernel/{crash_core.c => vmcore_info.c} | 2 +-
arch/powerpc/Kconfig | 2 +-
arch/powerpc/kernel/setup-common.c | 2 +-
arch/powerpc/platforms/powernv/opal-core.c | 2 +-
arch/riscv/kernel/Makefile | 2 +-
.../kernel/{crash_core.c => vmcore_info.c} | 2 +-
arch/x86/kernel/Makefile | 2 +-
.../{crash_core_32.c => vmcore_info_32.c} | 2 +-
.../{crash_core_64.c => vmcore_info_64.c} | 2 +-
drivers/firmware/qemu_fw_cfg.c | 14 +-
fs/proc/Kconfig | 2 +-
fs/proc/kcore.c | 2 +-
include/linux/buildid.h | 2 +-
include/linux/crash_core.h | 73 ------
include/linux/kexec.h | 1 +
include/linux/vmcore_info.h | 81 ++++++
kernel/Kconfig.kexec | 4 +-
kernel/Makefile | 4 +-
kernel/crash_core.c | 208 ----------------
kernel/ksysfs.c | 6 +-
kernel/printk/printk.c | 4 +-
kernel/vmcore_info.c | 233 ++++++++++++++++++
lib/buildid.c | 2 +-
24 files changed, 345 insertions(+), 311 deletions(-)
rename arch/arm64/kernel/{crash_core.c => vmcore_info.c} (97%)
rename arch/riscv/kernel/{crash_core.c => vmcore_info.c} (96%)
rename arch/x86/kernel/{crash_core_32.c => vmcore_info_32.c} (90%)
rename arch/x86/kernel/{crash_core_64.c => vmcore_info_64.c} (94%)
create mode 100644 include/linux/vmcore_info.h
create mode 100644 kernel/vmcore_info.c

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index d95b3d6b471a..bcf89587a549 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -66,7 +66,7 @@ obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
-obj-$(CONFIG_CRASH_CORE) += crash_core.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
obj-$(CONFIG_ARM64_MTE) += mte.o
diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/vmcore_info.c
similarity index 97%
rename from arch/arm64/kernel/crash_core.c
rename to arch/arm64/kernel/vmcore_info.c
index 66cde752cd74..a5abf7186922 100644
--- a/arch/arm64/kernel/crash_core.c
+++ b/arch/arm64/kernel/vmcore_info.c
@@ -4,7 +4,7 @@
* Copyright (C) Huawei Futurewei Technologies.
*/

-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <asm/cpufeature.h>
#include <asm/memory.h>
#include <asm/pgtable-hwdef.h>
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 6aeab95f0edd..1520146d7c2c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -690,7 +690,7 @@ config ARCH_SELECTS_CRASH_DUMP
config FA_DUMP
bool "Firmware-assisted dump"
depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
- select CRASH_CORE
+ select VMCORE_INFO
select CRASH_RESERVE
select CRASH_DUMP
help
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 9b142b9d5187..733f210ffda1 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -109,7 +109,7 @@ int ppc_do_canonicalize_irqs;
EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
#endif

-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_VMCORE_INFO
/* This keeps a track of which one is the crashing cpu. */
int crashing_cpu = -1;
#endif
diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
index bb7657115f1d..c9a9b759cc92 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c
@@ -16,7 +16,7 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/of.h>

#include <asm/page.h>
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index c92c623b311e..63a36539ea1a 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -91,7 +91,7 @@ obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o
obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
-obj-$(CONFIG_CRASH_CORE) += crash_core.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o

obj-$(CONFIG_JUMP_LABEL) += jump_label.o

diff --git a/arch/riscv/kernel/crash_core.c b/arch/riscv/kernel/vmcore_info.c
similarity index 96%
rename from arch/riscv/kernel/crash_core.c
rename to arch/riscv/kernel/vmcore_info.c
index 8706736fd4e2..e8ad57a60a2f 100644
--- a/arch/riscv/kernel/crash_core.c
+++ b/arch/riscv/kernel/vmcore_info.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only

-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/pagemap.h>

void arch_crash_save_vmcoreinfo(void)
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0000325ab98f..913d4022131e 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -98,7 +98,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_X86_TSC) += trace_clock.o
obj-$(CONFIG_TRACING) += trace.o
obj-$(CONFIG_RETHOOK) += rethook.o
-obj-$(CONFIG_CRASH_CORE) += crash_core_$(BITS).o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info_$(BITS).o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o
obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o
obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o
diff --git a/arch/x86/kernel/crash_core_32.c b/arch/x86/kernel/vmcore_info_32.c
similarity index 90%
rename from arch/x86/kernel/crash_core_32.c
rename to arch/x86/kernel/vmcore_info_32.c
index 8a89c109e20a..5995a749288a 100644
--- a/arch/x86/kernel/crash_core_32.c
+++ b/arch/x86/kernel/vmcore_info_32.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only

-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/pgtable.h>

#include <asm/setup.h>
diff --git a/arch/x86/kernel/crash_core_64.c b/arch/x86/kernel/vmcore_info_64.c
similarity index 94%
rename from arch/x86/kernel/crash_core_64.c
rename to arch/x86/kernel/vmcore_info_64.c
index 7d255f882afe..0dec7d868754 100644
--- a/arch/x86/kernel/crash_core_64.c
+++ b/arch/x86/kernel/vmcore_info_64.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only

-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/pgtable.h>

#include <asm/setup.h>
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index 03da9a4354f8..5f43dfa22f79 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -37,7 +37,7 @@
#include <uapi/linux/qemu_fw_cfg.h>
#include <linux/delay.h>
#include <linux/crash_dump.h>
-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>

MODULE_AUTHOR("Gabriel L. Somlo <[email protected]>");
MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
@@ -67,7 +67,7 @@ static void fw_cfg_sel_endianness(u16 key)
iowrite16(key, fw_cfg_reg_ctrl);
}

-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_VMCORE_INFO
static inline bool fw_cfg_dma_enabled(void)
{
return (fw_cfg_rev & FW_CFG_VERSION_DMA) && fw_cfg_reg_dma;
@@ -156,7 +156,7 @@ static ssize_t fw_cfg_read_blob(u16 key,
return count;
}

-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_VMCORE_INFO
/* write chunk of given fw_cfg blob (caller responsible for sanity-check) */
static ssize_t fw_cfg_write_blob(u16 key,
void *buf, loff_t pos, size_t count)
@@ -195,7 +195,7 @@ static ssize_t fw_cfg_write_blob(u16 key,

return ret;
}
-#endif /* CONFIG_CRASH_CORE */
+#endif /* CONFIG_VMCORE_INFO */

/* clean up fw_cfg device i/o */
static void fw_cfg_io_cleanup(void)
@@ -319,7 +319,7 @@ struct fw_cfg_sysfs_entry {
struct list_head list;
};

-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_VMCORE_INFO
static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
{
static struct fw_cfg_vmcoreinfo *data;
@@ -343,7 +343,7 @@ static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
kfree(data);
return ret;
}
-#endif /* CONFIG_CRASH_CORE */
+#endif /* CONFIG_VMCORE_INFO */

/* get fw_cfg_sysfs_entry from kobject member */
static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj)
@@ -583,7 +583,7 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)
int err;
struct fw_cfg_sysfs_entry *entry;

-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_VMCORE_INFO
if (fw_cfg_dma_enabled() &&
strcmp(f->name, FW_CFG_VMCOREINFO_FILENAME) == 0 &&
!is_kdump_kernel()) {
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
index 32b1116ae137..d80a1431ef7b 100644
--- a/fs/proc/Kconfig
+++ b/fs/proc/Kconfig
@@ -32,7 +32,7 @@ config PROC_FS
config PROC_KCORE
bool "/proc/kcore support" if !ARM
depends on PROC_FS && MMU
- select CRASH_CORE
+ select VMCORE_INFO
help
Provides a virtual ELF core file of the live kernel. This can
be read with gdb and other ELF tools. No modifications can be
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 6422e569b080..8e08a9a1b7ed 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -10,7 +10,7 @@
* Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <[email protected]>
*/

-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/kcore.h>
diff --git a/include/linux/buildid.h b/include/linux/buildid.h
index 8a582d242f06..20aa3c2d89f7 100644
--- a/include/linux/buildid.h
+++ b/include/linux/buildid.h
@@ -11,7 +11,7 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
__u32 *size);
int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size);

-#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
+#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
extern unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX];
void init_vmlinux_build_id(void);
#else
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 1fde49246fa6..7f19f62018ef 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -6,79 +6,6 @@
#include <linux/elfcore.h>
#include <linux/elf.h>

-#define CRASH_CORE_NOTE_NAME "CORE"
-#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
-#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
-#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
-
-/*
- * The per-cpu notes area is a list of notes terminated by a "NULL"
- * note header. For kdump, the code in vmcore.c runs in the context
- * of the second kernel to combine them into one note.
- */
-#define CRASH_CORE_NOTE_BYTES ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
- CRASH_CORE_NOTE_NAME_BYTES + \
- CRASH_CORE_NOTE_DESC_BYTES)
-
-#define VMCOREINFO_BYTES PAGE_SIZE
-#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
-#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
-#define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
- VMCOREINFO_NOTE_NAME_BYTES + \
- VMCOREINFO_BYTES)
-
-typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
-/* Per cpu memory for storing cpu states in case of system crash. */
-extern note_buf_t __percpu *crash_notes;
-
-void crash_update_vmcoreinfo_safecopy(void *ptr);
-void crash_save_vmcoreinfo(void);
-void arch_crash_save_vmcoreinfo(void);
-__printf(1, 2)
-void vmcoreinfo_append_str(const char *fmt, ...);
-phys_addr_t paddr_vmcoreinfo_note(void);
-
-#define VMCOREINFO_OSRELEASE(value) \
- vmcoreinfo_append_str("OSRELEASE=%s\n", value)
-#define VMCOREINFO_BUILD_ID() \
- ({ \
- static_assert(sizeof(vmlinux_build_id) == 20); \
- vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
- })
-
-#define VMCOREINFO_PAGESIZE(value) \
- vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
-#define VMCOREINFO_SYMBOL(name) \
- vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
-#define VMCOREINFO_SYMBOL_ARRAY(name) \
- vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
-#define VMCOREINFO_SIZE(name) \
- vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
- (unsigned long)sizeof(name))
-#define VMCOREINFO_STRUCT_SIZE(name) \
- vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
- (unsigned long)sizeof(struct name))
-#define VMCOREINFO_OFFSET(name, field) \
- vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
- (unsigned long)offsetof(struct name, field))
-#define VMCOREINFO_TYPE_OFFSET(name, field) \
- vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
- (unsigned long)offsetof(name, field))
-#define VMCOREINFO_LENGTH(name, value) \
- vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
-#define VMCOREINFO_NUMBER(name) \
- vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
-#define VMCOREINFO_CONFIG(name) \
- vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
-
-extern unsigned char *vmcoreinfo_data;
-extern size_t vmcoreinfo_size;
-extern u32 *vmcoreinfo_note;
-
-Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
- void *data, size_t data_len);
-void final_note(Elf_Word *buf);
-
/* Alignment required for elf header segment */
#define ELF_CORE_HEADER_ALIGN 4096

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 6d79bfb52e5b..9c7bb8b56ed6 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -16,6 +16,7 @@
#if !defined(__ASSEMBLY__)

#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/crash_reserve.h>
#include <asm/io.h>
#include <linux/range.h>
diff --git a/include/linux/vmcore_info.h b/include/linux/vmcore_info.h
new file mode 100644
index 000000000000..e1dec1a6a749
--- /dev/null
+++ b/include/linux/vmcore_info.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef LINUX_VMCORE_INFO_H
+#define LINUX_VMCORE_INFO_H
+
+#include <linux/linkage.h>
+#include <linux/elfcore.h>
+#include <linux/elf.h>
+
+#define CRASH_CORE_NOTE_NAME "CORE"
+#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
+#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
+#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
+
+/*
+ * The per-cpu notes area is a list of notes terminated by a "NULL"
+ * note header. For kdump, the code in vmcore.c runs in the context
+ * of the second kernel to combine them into one note.
+ */
+#define CRASH_CORE_NOTE_BYTES ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
+ CRASH_CORE_NOTE_NAME_BYTES + \
+ CRASH_CORE_NOTE_DESC_BYTES)
+
+#define VMCOREINFO_BYTES PAGE_SIZE
+#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
+#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
+#define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
+ VMCOREINFO_NOTE_NAME_BYTES + \
+ VMCOREINFO_BYTES)
+
+typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
+/* Per cpu memory for storing cpu states in case of system crash. */
+extern note_buf_t __percpu *crash_notes;
+
+void crash_update_vmcoreinfo_safecopy(void *ptr);
+void crash_save_vmcoreinfo(void);
+void arch_crash_save_vmcoreinfo(void);
+__printf(1, 2)
+void vmcoreinfo_append_str(const char *fmt, ...);
+phys_addr_t paddr_vmcoreinfo_note(void);
+
+#define VMCOREINFO_OSRELEASE(value) \
+ vmcoreinfo_append_str("OSRELEASE=%s\n", value)
+#define VMCOREINFO_BUILD_ID() \
+ ({ \
+ static_assert(sizeof(vmlinux_build_id) == 20); \
+ vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
+ })
+
+#define VMCOREINFO_PAGESIZE(value) \
+ vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
+#define VMCOREINFO_SYMBOL(name) \
+ vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
+#define VMCOREINFO_SYMBOL_ARRAY(name) \
+ vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
+#define VMCOREINFO_SIZE(name) \
+ vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
+ (unsigned long)sizeof(name))
+#define VMCOREINFO_STRUCT_SIZE(name) \
+ vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
+ (unsigned long)sizeof(struct name))
+#define VMCOREINFO_OFFSET(name, field) \
+ vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
+ (unsigned long)offsetof(struct name, field))
+#define VMCOREINFO_TYPE_OFFSET(name, field) \
+ vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
+ (unsigned long)offsetof(name, field))
+#define VMCOREINFO_LENGTH(name, value) \
+ vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
+#define VMCOREINFO_NUMBER(name) \
+ vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
+#define VMCOREINFO_CONFIG(name) \
+ vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
+
+extern unsigned char *vmcoreinfo_data;
+extern size_t vmcoreinfo_size;
+extern u32 *vmcoreinfo_note;
+
+Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
+ void *data, size_t data_len);
+void final_note(Elf_Word *buf);
+#endif /* LINUX_VMCORE_INFO_H */
diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
index 8b7be71edd85..8faf27043432 100644
--- a/kernel/Kconfig.kexec
+++ b/kernel/Kconfig.kexec
@@ -5,11 +5,11 @@ menu "Kexec and crash features"
config CRASH_RESERVE
bool

-config CRASH_CORE
+config VMCORE_INFO
bool

config KEXEC_CORE
- select CRASH_CORE
+ select VMCORE_INFO
select CRASH_RESERVE
bool

diff --git a/kernel/Makefile b/kernel/Makefile
index 05fa88b3ab74..649272a1d6b9 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -68,9 +68,9 @@ obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_KALLSYMS_SELFTEST) += kallsyms_selftest.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
-obj-$(CONFIG_CRASH_CORE) += crash_core.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_CRASH_RESERVE) += crash_reserve.o
-obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
+obj-$(CONFIG_KEXEC_CORE) += kexec_core.o crash_core.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 055859c62f19..2f4df1fe6f7a 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -26,14 +26,6 @@
/* Per cpu memory for storing cpu states in case of system crash. */
note_buf_t __percpu *crash_notes;

-/* vmcoreinfo stuff */
-unsigned char *vmcoreinfo_data;
-size_t vmcoreinfo_size;
-u32 *vmcoreinfo_note;
-
-/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
-static unsigned char *vmcoreinfo_data_safecopy;
-
int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
void **addr, unsigned long *sz)
{
@@ -195,206 +187,6 @@ int crash_exclude_mem_range(struct crash_mem *mem,
return 0;
}

-Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
- void *data, size_t data_len)
-{
- struct elf_note *note = (struct elf_note *)buf;
-
- note->n_namesz = strlen(name) + 1;
- note->n_descsz = data_len;
- note->n_type = type;
- buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
- memcpy(buf, name, note->n_namesz);
- buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
- memcpy(buf, data, data_len);
- buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
-
- return buf;
-}
-
-void final_note(Elf_Word *buf)
-{
- memset(buf, 0, sizeof(struct elf_note));
-}
-
-static void update_vmcoreinfo_note(void)
-{
- u32 *buf = vmcoreinfo_note;
-
- if (!vmcoreinfo_size)
- return;
- buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
- vmcoreinfo_size);
- final_note(buf);
-}
-
-void crash_update_vmcoreinfo_safecopy(void *ptr)
-{
- if (ptr)
- memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
-
- vmcoreinfo_data_safecopy = ptr;
-}
-
-void crash_save_vmcoreinfo(void)
-{
- if (!vmcoreinfo_note)
- return;
-
- /* Use the safe copy to generate vmcoreinfo note if have */
- if (vmcoreinfo_data_safecopy)
- vmcoreinfo_data = vmcoreinfo_data_safecopy;
-
- vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
- update_vmcoreinfo_note();
-}
-
-void vmcoreinfo_append_str(const char *fmt, ...)
-{
- va_list args;
- char buf[0x50];
- size_t r;
-
- va_start(args, fmt);
- r = vscnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
-
- r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
-
- memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
-
- vmcoreinfo_size += r;
-
- WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
- "vmcoreinfo data exceeds allocated size, truncating");
-}
-
-/*
- * provide an empty default implementation here -- architecture
- * code may override this
- */
-void __weak arch_crash_save_vmcoreinfo(void)
-{}
-
-phys_addr_t __weak paddr_vmcoreinfo_note(void)
-{
- return __pa(vmcoreinfo_note);
-}
-EXPORT_SYMBOL(paddr_vmcoreinfo_note);
-
-static int __init crash_save_vmcoreinfo_init(void)
-{
- vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
- if (!vmcoreinfo_data) {
- pr_warn("Memory allocation for vmcoreinfo_data failed\n");
- return -ENOMEM;
- }
-
- vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
- GFP_KERNEL | __GFP_ZERO);
- if (!vmcoreinfo_note) {
- free_page((unsigned long)vmcoreinfo_data);
- vmcoreinfo_data = NULL;
- pr_warn("Memory allocation for vmcoreinfo_note failed\n");
- return -ENOMEM;
- }
-
- VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
- VMCOREINFO_BUILD_ID();
- VMCOREINFO_PAGESIZE(PAGE_SIZE);
-
- VMCOREINFO_SYMBOL(init_uts_ns);
- VMCOREINFO_OFFSET(uts_namespace, name);
- VMCOREINFO_SYMBOL(node_online_map);
-#ifdef CONFIG_MMU
- VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
-#endif
- VMCOREINFO_SYMBOL(_stext);
- VMCOREINFO_SYMBOL(vmap_area_list);
-
-#ifndef CONFIG_NUMA
- VMCOREINFO_SYMBOL(mem_map);
- VMCOREINFO_SYMBOL(contig_page_data);
-#endif
-#ifdef CONFIG_SPARSEMEM
- VMCOREINFO_SYMBOL_ARRAY(mem_section);
- VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
- VMCOREINFO_STRUCT_SIZE(mem_section);
- VMCOREINFO_OFFSET(mem_section, section_mem_map);
- VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
- VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
-#endif
- VMCOREINFO_STRUCT_SIZE(page);
- VMCOREINFO_STRUCT_SIZE(pglist_data);
- VMCOREINFO_STRUCT_SIZE(zone);
- VMCOREINFO_STRUCT_SIZE(free_area);
- VMCOREINFO_STRUCT_SIZE(list_head);
- VMCOREINFO_SIZE(nodemask_t);
- VMCOREINFO_OFFSET(page, flags);
- VMCOREINFO_OFFSET(page, _refcount);
- VMCOREINFO_OFFSET(page, mapping);
- VMCOREINFO_OFFSET(page, lru);
- VMCOREINFO_OFFSET(page, _mapcount);
- VMCOREINFO_OFFSET(page, private);
- VMCOREINFO_OFFSET(page, compound_head);
- VMCOREINFO_OFFSET(pglist_data, node_zones);
- VMCOREINFO_OFFSET(pglist_data, nr_zones);
-#ifdef CONFIG_FLATMEM
- VMCOREINFO_OFFSET(pglist_data, node_mem_map);
-#endif
- VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
- VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
- VMCOREINFO_OFFSET(pglist_data, node_id);
- VMCOREINFO_OFFSET(zone, free_area);
- VMCOREINFO_OFFSET(zone, vm_stat);
- VMCOREINFO_OFFSET(zone, spanned_pages);
- VMCOREINFO_OFFSET(free_area, free_list);
- VMCOREINFO_OFFSET(list_head, next);
- VMCOREINFO_OFFSET(list_head, prev);
- VMCOREINFO_OFFSET(vmap_area, va_start);
- VMCOREINFO_OFFSET(vmap_area, list);
- VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
- log_buf_vmcoreinfo_setup();
- VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
- VMCOREINFO_NUMBER(NR_FREE_PAGES);
- VMCOREINFO_NUMBER(PG_lru);
- VMCOREINFO_NUMBER(PG_private);
- VMCOREINFO_NUMBER(PG_swapcache);
- VMCOREINFO_NUMBER(PG_swapbacked);
- VMCOREINFO_NUMBER(PG_slab);
-#ifdef CONFIG_MEMORY_FAILURE
- VMCOREINFO_NUMBER(PG_hwpoison);
-#endif
- VMCOREINFO_NUMBER(PG_head_mask);
-#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
- VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
-#ifdef CONFIG_HUGETLB_PAGE
- VMCOREINFO_NUMBER(PG_hugetlb);
-#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
- VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
-#endif
-
-#ifdef CONFIG_KALLSYMS
- VMCOREINFO_SYMBOL(kallsyms_names);
- VMCOREINFO_SYMBOL(kallsyms_num_syms);
- VMCOREINFO_SYMBOL(kallsyms_token_table);
- VMCOREINFO_SYMBOL(kallsyms_token_index);
-#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
- VMCOREINFO_SYMBOL(kallsyms_offsets);
- VMCOREINFO_SYMBOL(kallsyms_relative_base);
-#else
- VMCOREINFO_SYMBOL(kallsyms_addresses);
-#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
-#endif /* CONFIG_KALLSYMS */
-
- arch_crash_save_vmcoreinfo();
- update_vmcoreinfo_note();
-
- return 0;
-}
-
-subsys_initcall(crash_save_vmcoreinfo_init);
-
static int __init crash_notes_memory_init(void)
{
/* Allocate memory for saving cpu registers. */
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 1d4bc493b2f4..11526fc42bc2 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -154,7 +154,7 @@ KERNEL_ATTR_RW(kexec_crash_size);

#endif /* CONFIG_KEXEC_CORE */

-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_VMCORE_INFO

static ssize_t vmcoreinfo_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
@@ -177,7 +177,7 @@ KERNEL_ATTR_RO(crash_elfcorehdr_size);

#endif

-#endif /* CONFIG_CRASH_CORE */
+#endif /* CONFIG_VMCORE_INFO */

/* whether file capabilities are enabled */
static ssize_t fscaps_show(struct kobject *kobj,
@@ -265,7 +265,7 @@ static struct attribute * kernel_attrs[] = {
&kexec_crash_loaded_attr.attr,
&kexec_crash_size_attr.attr,
#endif
-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_VMCORE_INFO
&vmcoreinfo_attr.attr,
#ifdef CONFIG_CRASH_HOTPLUG
&crash_elfcorehdr_size_attr.attr,
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index f2444b581e16..7d74b000b43a 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -34,7 +34,7 @@
#include <linux/security.h>
#include <linux/memblock.h>
#include <linux/syscalls.h>
-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/ratelimit.h>
#include <linux/kmsg_dump.h>
#include <linux/syslog.h>
@@ -951,7 +951,7 @@ const struct file_operations kmsg_fops = {
.release = devkmsg_release,
};

-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_VMCORE_INFO
/*
* This appends the listed symbols to /proc/vmcore
*
diff --git a/kernel/vmcore_info.c b/kernel/vmcore_info.c
new file mode 100644
index 000000000000..84f3663530c8
--- /dev/null
+++ b/kernel/vmcore_info.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * crash.c - kernel crash support code.
+ * Copyright (C) 2002-2004 Eric Biederman <[email protected]>
+ */
+
+#include <linux/buildid.h>
+#include <linux/init.h>
+#include <linux/utsname.h>
+#include <linux/vmalloc.h>
+#include <linux/sizes.h>
+#include <linux/kexec.h>
+#include <linux/memory.h>
+#include <linux/cpuhotplug.h>
+#include <linux/memblock.h>
+#include <linux/kexec.h>
+#include <linux/kmemleak.h>
+
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <crypto/sha1.h>
+
+#include "kallsyms_internal.h"
+#include "kexec_internal.h"
+
+/* vmcoreinfo stuff */
+unsigned char *vmcoreinfo_data;
+size_t vmcoreinfo_size;
+u32 *vmcoreinfo_note;
+
+/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
+static unsigned char *vmcoreinfo_data_safecopy;
+
+Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
+ void *data, size_t data_len)
+{
+ struct elf_note *note = (struct elf_note *)buf;
+
+ note->n_namesz = strlen(name) + 1;
+ note->n_descsz = data_len;
+ note->n_type = type;
+ buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
+ memcpy(buf, name, note->n_namesz);
+ buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
+ memcpy(buf, data, data_len);
+ buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
+
+ return buf;
+}
+
+void final_note(Elf_Word *buf)
+{
+ memset(buf, 0, sizeof(struct elf_note));
+}
+
+static void update_vmcoreinfo_note(void)
+{
+ u32 *buf = vmcoreinfo_note;
+
+ if (!vmcoreinfo_size)
+ return;
+ buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
+ vmcoreinfo_size);
+ final_note(buf);
+}
+
+void crash_update_vmcoreinfo_safecopy(void *ptr)
+{
+ if (ptr)
+ memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
+
+ vmcoreinfo_data_safecopy = ptr;
+}
+
+void crash_save_vmcoreinfo(void)
+{
+ if (!vmcoreinfo_note)
+ return;
+
+ /* Use the safe copy to generate vmcoreinfo note if have */
+ if (vmcoreinfo_data_safecopy)
+ vmcoreinfo_data = vmcoreinfo_data_safecopy;
+
+ vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
+ update_vmcoreinfo_note();
+}
+
+void vmcoreinfo_append_str(const char *fmt, ...)
+{
+ va_list args;
+ char buf[0x50];
+ size_t r;
+
+ va_start(args, fmt);
+ r = vscnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
+
+ memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
+
+ vmcoreinfo_size += r;
+
+ WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
+ "vmcoreinfo data exceeds allocated size, truncating");
+}
+
+/*
+ * provide an empty default implementation here -- architecture
+ * code may override this
+ */
+void __weak arch_crash_save_vmcoreinfo(void)
+{}
+
+phys_addr_t __weak paddr_vmcoreinfo_note(void)
+{
+ return __pa(vmcoreinfo_note);
+}
+EXPORT_SYMBOL(paddr_vmcoreinfo_note);
+
+static int __init crash_save_vmcoreinfo_init(void)
+{
+ vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
+ if (!vmcoreinfo_data) {
+ pr_warn("Memory allocation for vmcoreinfo_data failed\n");
+ return -ENOMEM;
+ }
+
+ vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
+ GFP_KERNEL | __GFP_ZERO);
+ if (!vmcoreinfo_note) {
+ free_page((unsigned long)vmcoreinfo_data);
+ vmcoreinfo_data = NULL;
+ pr_warn("Memory allocation for vmcoreinfo_note failed\n");
+ return -ENOMEM;
+ }
+
+ VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
+ VMCOREINFO_BUILD_ID();
+ VMCOREINFO_PAGESIZE(PAGE_SIZE);
+
+ VMCOREINFO_SYMBOL(init_uts_ns);
+ VMCOREINFO_OFFSET(uts_namespace, name);
+ VMCOREINFO_SYMBOL(node_online_map);
+#ifdef CONFIG_MMU
+ VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
+#endif
+ VMCOREINFO_SYMBOL(_stext);
+ VMCOREINFO_SYMBOL(vmap_area_list);
+
+#ifndef CONFIG_NUMA
+ VMCOREINFO_SYMBOL(mem_map);
+ VMCOREINFO_SYMBOL(contig_page_data);
+#endif
+#ifdef CONFIG_SPARSEMEM
+ VMCOREINFO_SYMBOL_ARRAY(mem_section);
+ VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
+ VMCOREINFO_STRUCT_SIZE(mem_section);
+ VMCOREINFO_OFFSET(mem_section, section_mem_map);
+ VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
+ VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
+#endif
+ VMCOREINFO_STRUCT_SIZE(page);
+ VMCOREINFO_STRUCT_SIZE(pglist_data);
+ VMCOREINFO_STRUCT_SIZE(zone);
+ VMCOREINFO_STRUCT_SIZE(free_area);
+ VMCOREINFO_STRUCT_SIZE(list_head);
+ VMCOREINFO_SIZE(nodemask_t);
+ VMCOREINFO_OFFSET(page, flags);
+ VMCOREINFO_OFFSET(page, _refcount);
+ VMCOREINFO_OFFSET(page, mapping);
+ VMCOREINFO_OFFSET(page, lru);
+ VMCOREINFO_OFFSET(page, _mapcount);
+ VMCOREINFO_OFFSET(page, private);
+ VMCOREINFO_OFFSET(page, compound_head);
+ VMCOREINFO_OFFSET(pglist_data, node_zones);
+ VMCOREINFO_OFFSET(pglist_data, nr_zones);
+#ifdef CONFIG_FLATMEM
+ VMCOREINFO_OFFSET(pglist_data, node_mem_map);
+#endif
+ VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
+ VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
+ VMCOREINFO_OFFSET(pglist_data, node_id);
+ VMCOREINFO_OFFSET(zone, free_area);
+ VMCOREINFO_OFFSET(zone, vm_stat);
+ VMCOREINFO_OFFSET(zone, spanned_pages);
+ VMCOREINFO_OFFSET(free_area, free_list);
+ VMCOREINFO_OFFSET(list_head, next);
+ VMCOREINFO_OFFSET(list_head, prev);
+ VMCOREINFO_OFFSET(vmap_area, va_start);
+ VMCOREINFO_OFFSET(vmap_area, list);
+ VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
+ log_buf_vmcoreinfo_setup();
+ VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
+ VMCOREINFO_NUMBER(NR_FREE_PAGES);
+ VMCOREINFO_NUMBER(PG_lru);
+ VMCOREINFO_NUMBER(PG_private);
+ VMCOREINFO_NUMBER(PG_swapcache);
+ VMCOREINFO_NUMBER(PG_swapbacked);
+ VMCOREINFO_NUMBER(PG_slab);
+#ifdef CONFIG_MEMORY_FAILURE
+ VMCOREINFO_NUMBER(PG_hwpoison);
+#endif
+ VMCOREINFO_NUMBER(PG_head_mask);
+#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
+ VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
+#ifdef CONFIG_HUGETLB_PAGE
+ VMCOREINFO_NUMBER(PG_hugetlb);
+#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
+ VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
+#endif
+
+#ifdef CONFIG_KALLSYMS
+ VMCOREINFO_SYMBOL(kallsyms_names);
+ VMCOREINFO_SYMBOL(kallsyms_num_syms);
+ VMCOREINFO_SYMBOL(kallsyms_token_table);
+ VMCOREINFO_SYMBOL(kallsyms_token_index);
+#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
+ VMCOREINFO_SYMBOL(kallsyms_offsets);
+ VMCOREINFO_SYMBOL(kallsyms_relative_base);
+#else
+ VMCOREINFO_SYMBOL(kallsyms_addresses);
+#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
+#endif /* CONFIG_KALLSYMS */
+
+ arch_crash_save_vmcoreinfo();
+ update_vmcoreinfo_note();
+
+ return 0;
+}
+
+subsys_initcall(crash_save_vmcoreinfo_init);
diff --git a/lib/buildid.c b/lib/buildid.c
index e3a7acdeef0e..3e6868c86b45 100644
--- a/lib/buildid.c
+++ b/lib/buildid.c
@@ -174,7 +174,7 @@ int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size)
return parse_build_id_buf(build_id, NULL, buf, buf_size);
}

-#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
+#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX] __ro_after_init;

/**
--
2.41.0


2024-01-19 14:53:53

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 03/14] crash: remove dependency of FA_DUMP on CRASH_DUMP

In kdump kernel, /proc/vmcore is an elf file mapping the crashed kernel's
old memory content. Its elf header is constructed in 1st kernel and passed
to kdump kernel via elfcorehdr_addr. Config CRASH_DUMP enables the code
of 1st kernel's old memory accessing in different architectures.

Currently, config FA_DUMP has dependency on CRASH_DUMP because fadump
needs access global variable 'elfcorehdr_addr' to judge if it's in
kdump kernel within function is_kdump_kernel(). In the current
kernel/crash_dump.c, variable 'elfcorehdr_addr' is defined, and function
setup_elfcorehdr() used to parse kernel parameter to fetch the passed
value of elfcorehdr_addr. Only for accessing elfcorehdr_addr, FA_DUMP
really doesn't have to depends on CRASH_DUMP.

To remove the dependency of FA_DUMP on CRASH_DUMP to avoid confusion,
rename kernel/crash_dump.c to kernel/elfcorehdr.c, and build it when
CONFIG_VMCORE_INFO is ebabled. With this, FA_DUMP doesn't need to depend
on CRASH_DUMP.

Signed-off-by: Baoquan He <[email protected]>
---
arch/powerpc/Kconfig | 1 -
kernel/Makefile | 3 +--
kernel/{crash_dump.c => elfcorehdr.c} | 0
kernel/kexec_internal.h | 2 ++
4 files changed, 3 insertions(+), 3 deletions(-)
rename kernel/{crash_dump.c => elfcorehdr.c} (100%)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1520146d7c2c..1cdb8fdd3735 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -692,7 +692,6 @@ config FA_DUMP
depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
select VMCORE_INFO
select CRASH_RESERVE
- select CRASH_DUMP
help
A robust mechanism to get reliable kernel crash dump with
assistance from firmware. This approach does not use kexec,
diff --git a/kernel/Makefile b/kernel/Makefile
index 649272a1d6b9..35abc65e1f1a 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -68,7 +68,7 @@ obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_KALLSYMS_SELFTEST) += kallsyms_selftest.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
-obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o elfcorehdr.o
obj-$(CONFIG_CRASH_RESERVE) += crash_reserve.o
obj-$(CONFIG_KEXEC_CORE) += kexec_core.o crash_core.o
obj-$(CONFIG_KEXEC) += kexec.o
@@ -121,7 +121,6 @@ obj-$(CONFIG_PERF_EVENTS) += events/

obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
obj-$(CONFIG_PADATA) += padata.o
-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
obj-$(CONFIG_TORTURE_TEST) += torture.o
diff --git a/kernel/crash_dump.c b/kernel/elfcorehdr.c
similarity index 100%
rename from kernel/crash_dump.c
rename to kernel/elfcorehdr.c
diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h
index 74da1409cd14..2595defe8c0d 100644
--- a/kernel/kexec_internal.h
+++ b/kernel/kexec_internal.h
@@ -4,6 +4,8 @@

#include <linux/kexec.h>

+struct kexec_segment;
+
struct kimage *do_kimage_alloc_init(void);
int sanity_check_segment_list(struct kimage *image);
void kimage_free_page_list(struct list_head *list);
--
2.41.0


2024-01-19 14:54:17

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 04/14] crash: split crash dumping code out from kexec_core.c

Currently, KEXEC_CORE select CRASH_CORE automatically because crash codes
need be built in to avoid compiling error when building kexec code even
though the crash dumping functionality is not enabled. E.g
--------------------
CONFIG_CRASH_CORE=y
CONFIG_KEXEC_CORE=y
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
---------------------

After splitting out crashkernel reservation code and vmcoreinfo exporting
code, there's only crash related code left in kernel/crash_core.c. Now
move crash related codes from kexec_core.c to crash_core.c and only build it
in when CONFIG_CRASH_DUMP=y.

And also wrap up crash codes inside CONFIG_CRASH_DUMP ifdeffery scope,
or replace inappropriate CONFIG_KEXEC_CORE ifdef with CONFIG_CRASH_DUMP
ifdef in generic kernel files.

With these changes, crash_core codes are abstracted from kexec codes and
can be disabled at all if only kexec reboot feature is wanted.

Signed-off-by: Baoquan He <[email protected]>
---
drivers/base/cpu.c | 6 +-
include/linux/crash_core.h | 61 +++++++++
include/linux/kexec.h | 45 +------
init/initramfs.c | 2 +-
kernel/Makefile | 3 +-
kernel/crash_core.c | 256 +++++++++++++++++++++++++++++++++++++
kernel/kexec.c | 11 +-
kernel/kexec_core.c | 250 ++----------------------------------
kernel/kexec_file.c | 13 +-
kernel/ksysfs.c | 4 +
10 files changed, 359 insertions(+), 292 deletions(-)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 47de0f140ba6..b621a0fc75e1 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -144,7 +144,7 @@ static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
#endif /* CONFIG_HOTPLUG_CPU */

-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
#include <linux/kexec.h>

static ssize_t crash_notes_show(struct device *dev,
@@ -189,14 +189,14 @@ static const struct attribute_group crash_note_cpu_attr_group = {
#endif

static const struct attribute_group *common_cpu_attr_groups[] = {
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
&crash_note_cpu_attr_group,
#endif
NULL
};

static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
&crash_note_cpu_attr_group,
#endif
NULL
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 7f19f62018ef..23270b16e1db 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -6,6 +6,48 @@
#include <linux/elfcore.h>
#include <linux/elf.h>

+struct kimage;
+
+#ifdef CONFIG_CRASH_DUMP
+
+int crash_shrink_memory(unsigned long new_size);
+ssize_t crash_get_memory_size(void);
+
+#ifndef arch_kexec_protect_crashkres
+/*
+ * Protection mechanism for crashkernel reserved memory after
+ * the kdump kernel is loaded.
+ *
+ * Provide an empty default implementation here -- architecture
+ * code may override this
+ */
+static inline void arch_kexec_protect_crashkres(void) { }
+#endif
+
+#ifndef arch_kexec_unprotect_crashkres
+static inline void arch_kexec_unprotect_crashkres(void) { }
+#endif
+
+
+
+#ifndef arch_crash_handle_hotplug_event
+static inline void arch_crash_handle_hotplug_event(struct kimage *image) { }
+#endif
+
+int crash_check_update_elfcorehdr(void);
+
+#ifndef crash_hotplug_cpu_support
+static inline int crash_hotplug_cpu_support(void) { return 0; }
+#endif
+
+#ifndef crash_hotplug_memory_support
+static inline int crash_hotplug_memory_support(void) { return 0; }
+#endif
+
+#ifndef crash_get_elfcorehdr_size
+static inline unsigned int crash_get_elfcorehdr_size(void) { return 0; }
+#endif
+
/* Alignment required for elf header segment */
#define ELF_CORE_HEADER_ALIGN 4096

@@ -31,4 +73,23 @@ struct kexec_segment;
#define KEXEC_CRASH_HP_REMOVE_MEMORY 4
#define KEXEC_CRASH_HP_INVALID_CPU -1U

+extern void __crash_kexec(struct pt_regs *regs);
+extern void crash_kexec(struct pt_regs *regs);
+int kexec_should_crash(struct task_struct *p);
+int kexec_crash_loaded(void);
+void crash_save_cpu(struct pt_regs *regs, int cpu);
+extern int kimage_crash_copy_vmcoreinfo(struct kimage *image);
+
+#else /* !CONFIG_CRASH_DUMP*/
+struct pt_regs;
+struct task_struct;
+struct kimage;
+static inline void __crash_kexec(struct pt_regs *regs) { }
+static inline void crash_kexec(struct pt_regs *regs) { }
+static inline int kexec_should_crash(struct task_struct *p) { return 0; }
+static inline int kexec_crash_loaded(void) { return 0; }
+static inline void crash_save_cpu(struct pt_regs *regs, int cpu) {};
+static inline int kimage_crash_copy_vmcoreinfo(struct kimage *image) { return 0; };
+#endif /* CONFIG_CRASH_DUMP*/
+
#endif /* LINUX_CRASH_CORE_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 9c7bb8b56ed6..060835bb82d5 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -15,7 +15,6 @@

#if !defined(__ASSEMBLY__)

-#include <linux/crash_core.h>
#include <linux/vmcore_info.h>
#include <linux/crash_reserve.h>
#include <asm/io.h>
@@ -33,6 +32,7 @@ extern note_buf_t __percpu *crash_notes;
#include <linux/module.h>
#include <linux/highmem.h>
#include <asm/kexec.h>
+#include <linux/crash_core.h>

/* Verify architecture specific macros are defined */

@@ -380,13 +380,6 @@ extern struct page *kimage_alloc_control_pages(struct kimage *image,
static inline int machine_kexec_post_load(struct kimage *image) { return 0; }
#endif

-extern void __crash_kexec(struct pt_regs *);
-extern void crash_kexec(struct pt_regs *);
-int kexec_should_crash(struct task_struct *);
-int kexec_crash_loaded(void);
-void crash_save_cpu(struct pt_regs *regs, int cpu);
-extern int kimage_crash_copy_vmcoreinfo(struct kimage *image);
-
extern struct kimage *kexec_image;
extern struct kimage *kexec_crash_image;

@@ -410,24 +403,6 @@ bool kexec_load_permitted(int kexec_image_type);
/* flag to track if kexec reboot is in progress */
extern bool kexec_in_progress;

-int crash_shrink_memory(unsigned long new_size);
-ssize_t crash_get_memory_size(void);
-
-#ifndef arch_kexec_protect_crashkres
-/*
- * Protection mechanism for crashkernel reserved memory after
- * the kdump kernel is loaded.
- *
- * Provide an empty default implementation here -- architecture
- * code may override this
- */
-static inline void arch_kexec_protect_crashkres(void) { }
-#endif
-
-#ifndef arch_kexec_unprotect_crashkres
-static inline void arch_kexec_unprotect_crashkres(void) { }
-#endif
-
#ifndef page_to_boot_pfn
static inline unsigned long page_to_boot_pfn(struct page *page)
{
@@ -484,24 +459,6 @@ static inline int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, g
static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { }
#endif

-#ifndef arch_crash_handle_hotplug_event
-static inline void arch_crash_handle_hotplug_event(struct kimage *image) { }
-#endif
-
-int crash_check_update_elfcorehdr(void);
-
-#ifndef crash_hotplug_cpu_support
-static inline int crash_hotplug_cpu_support(void) { return 0; }
-#endif
-
-#ifndef crash_hotplug_memory_support
-static inline int crash_hotplug_memory_support(void) { return 0; }
-#endif
-
-#ifndef crash_get_elfcorehdr_size
-static inline unsigned int crash_get_elfcorehdr_size(void) { return 0; }
-#endif
-
extern bool kexec_file_dbg_print;

#define kexec_dprintk(fmt, ...) \
diff --git a/init/initramfs.c b/init/initramfs.c
index 76deb48c38cb..6f095f54eec9 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -642,7 +642,7 @@ void __weak __init free_initrd_mem(unsigned long start, unsigned long end)
"initrd");
}

-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_RESERVE
static bool __init kexec_free_initrd(void)
{
unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
diff --git a/kernel/Makefile b/kernel/Makefile
index 35abc65e1f1a..3c13240dfc9f 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -70,7 +70,8 @@ obj-$(CONFIG_KALLSYMS_SELFTEST) += kallsyms_selftest.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o elfcorehdr.o
obj-$(CONFIG_CRASH_RESERVE) += crash_reserve.o
-obj-$(CONFIG_KEXEC_CORE) += kexec_core.o crash_core.o
+obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
+obj-$(CONFIG_CRASH_DUMP) += crash_core.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 2f4df1fe6f7a..78b5dc7cee3a 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -11,9 +11,14 @@
#include <linux/sizes.h>
#include <linux/kexec.h>
#include <linux/memory.h>
+#include <linux/mm.h>
#include <linux/cpuhotplug.h>
#include <linux/memblock.h>
#include <linux/kmemleak.h>
+#include <linux/crash_core.h>
+#include <linux/reboot.h>
+#include <linux/btf.h>
+#include <linux/objtool.h>

#include <asm/page.h>
#include <asm/sections.h>
@@ -26,6 +31,131 @@
/* Per cpu memory for storing cpu states in case of system crash. */
note_buf_t __percpu *crash_notes;

+#ifdef CONFIG_CRASH_DUMP
+
+int kimage_crash_copy_vmcoreinfo(struct kimage *image)
+{
+ struct page *vmcoreinfo_page;
+ void *safecopy;
+
+ if (!IS_ENABLED(CONFIG_CRASH_DUMP))
+ return 0;
+ if (image->type != KEXEC_TYPE_CRASH)
+ return 0;
+
+ /*
+ * For kdump, allocate one vmcoreinfo safe copy from the
+ * crash memory. as we have arch_kexec_protect_crashkres()
+ * after kexec syscall, we naturally protect it from write
+ * (even read) access under kernel direct mapping. But on
+ * the other hand, we still need to operate it when crash
+ * happens to generate vmcoreinfo note, hereby we rely on
+ * vmap for this purpose.
+ */
+ vmcoreinfo_page = kimage_alloc_control_pages(image, 0);
+ if (!vmcoreinfo_page) {
+ pr_warn("Could not allocate vmcoreinfo buffer\n");
+ return -ENOMEM;
+ }
+ safecopy = vmap(&vmcoreinfo_page, 1, VM_MAP, PAGE_KERNEL);
+ if (!safecopy) {
+ pr_warn("Could not vmap vmcoreinfo buffer\n");
+ return -ENOMEM;
+ }
+
+ image->vmcoreinfo_data_copy = safecopy;
+ crash_update_vmcoreinfo_safecopy(safecopy);
+
+ return 0;
+}
+
+
+
+int kexec_should_crash(struct task_struct *p)
+{
+ /*
+ * If crash_kexec_post_notifiers is enabled, don't run
+ * crash_kexec() here yet, which must be run after panic
+ * notifiers in panic().
+ */
+ if (crash_kexec_post_notifiers)
+ return 0;
+ /*
+ * There are 4 panic() calls in make_task_dead() path, each of which
+ * corresponds to each of these 4 conditions.
+ */
+ if (in_interrupt() || !p->pid || is_global_init(p) || panic_on_oops)
+ return 1;
+ return 0;
+}
+
+int kexec_crash_loaded(void)
+{
+ return !!kexec_crash_image;
+}
+EXPORT_SYMBOL_GPL(kexec_crash_loaded);
+
+/*
+ * No panic_cpu check version of crash_kexec(). This function is called
+ * only when panic_cpu holds the current CPU number; this is the only CPU
+ * which processes crash_kexec routines.
+ */
+void __noclone __crash_kexec(struct pt_regs *regs)
+{
+ /* Take the kexec_lock here to prevent sys_kexec_load
+ * running on one cpu from replacing the crash kernel
+ * we are using after a panic on a different cpu.
+ *
+ * If the crash kernel was not located in a fixed area
+ * of memory the xchg(&kexec_crash_image) would be
+ * sufficient. But since I reuse the memory...
+ */
+ if (kexec_trylock()) {
+ if (kexec_crash_image) {
+ struct pt_regs fixed_regs;
+
+ crash_setup_regs(&fixed_regs, regs);
+ crash_save_vmcoreinfo();
+ machine_crash_shutdown(&fixed_regs);
+ machine_kexec(kexec_crash_image);
+ }
+ kexec_unlock();
+ }
+}
+STACK_FRAME_NON_STANDARD(__crash_kexec);
+
+__bpf_kfunc void crash_kexec(struct pt_regs *regs)
+{
+ int old_cpu, this_cpu;
+
+ /*
+ * Only one CPU is allowed to execute the crash_kexec() code as with
+ * panic(). Otherwise parallel calls of panic() and crash_kexec()
+ * may stop each other. To exclude them, we use panic_cpu here too.
+ */
+ old_cpu = PANIC_CPU_INVALID;
+ this_cpu = raw_smp_processor_id();
+
+ if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu)) {
+ /* This is the 1st CPU which comes here, so go ahead. */
+ __crash_kexec(regs);
+
+ /*
+ * Reset panic_cpu to allow another panic()/crash_kexec()
+ * call.
+ */
+ atomic_set(&panic_cpu, PANIC_CPU_INVALID);
+ }
+}
+
+static inline resource_size_t crash_resource_size(const struct resource *res)
+{
+ return !res->end ? 0 : resource_size(res);
+}
+
+
+
+
int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
void **addr, unsigned long *sz)
{
@@ -187,6 +317,130 @@ int crash_exclude_mem_range(struct crash_mem *mem,
return 0;
}

+ssize_t crash_get_memory_size(void)
+{
+ ssize_t size = 0;
+
+ if (!kexec_trylock())
+ return -EBUSY;
+
+ size += crash_resource_size(&crashk_res);
+ size += crash_resource_size(&crashk_low_res);
+
+ kexec_unlock();
+ return size;
+}
+
+static int __crash_shrink_memory(struct resource *old_res,
+ unsigned long new_size)
+{
+ struct resource *ram_res;
+
+ ram_res = kzalloc(sizeof(*ram_res), GFP_KERNEL);
+ if (!ram_res)
+ return -ENOMEM;
+
+ ram_res->start = old_res->start + new_size;
+ ram_res->end = old_res->end;
+ ram_res->flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM;
+ ram_res->name = "System RAM";
+
+ if (!new_size) {
+ release_resource(old_res);
+ old_res->start = 0;
+ old_res->end = 0;
+ } else {
+ crashk_res.end = ram_res->start - 1;
+ }
+
+ crash_free_reserved_phys_range(ram_res->start, ram_res->end);
+ insert_resource(&iomem_resource, ram_res);
+
+ return 0;
+}
+
+int crash_shrink_memory(unsigned long new_size)
+{
+ int ret = 0;
+ unsigned long old_size, low_size;
+
+ if (!kexec_trylock())
+ return -EBUSY;
+
+ if (kexec_crash_image) {
+ ret = -ENOENT;
+ goto unlock;
+ }
+
+ low_size = crash_resource_size(&crashk_low_res);
+ old_size = crash_resource_size(&crashk_res) + low_size;
+ new_size = roundup(new_size, KEXEC_CRASH_MEM_ALIGN);
+ if (new_size >= old_size) {
+ ret = (new_size == old_size) ? 0 : -EINVAL;
+ goto unlock;
+ }
+
+ /*
+ * (low_size > new_size) implies that low_size is greater than zero.
+ * This also means that if low_size is zero, the else branch is taken.
+ *
+ * If low_size is greater than 0, (low_size > new_size) indicates that
+ * crashk_low_res also needs to be shrunken. Otherwise, only crashk_res
+ * needs to be shrunken.
+ */
+ if (low_size > new_size) {
+ ret = __crash_shrink_memory(&crashk_res, 0);
+ if (ret)
+ goto unlock;
+
+ ret = __crash_shrink_memory(&crashk_low_res, new_size);
+ } else {
+ ret = __crash_shrink_memory(&crashk_res, new_size - low_size);
+ }
+
+ /* Swap crashk_res and crashk_low_res if needed */
+ if (!crashk_res.end && crashk_low_res.end) {
+ crashk_res.start = crashk_low_res.start;
+ crashk_res.end = crashk_low_res.end;
+ release_resource(&crashk_low_res);
+ crashk_low_res.start = 0;
+ crashk_low_res.end = 0;
+ insert_resource(&iomem_resource, &crashk_res);
+ }
+
+unlock:
+ kexec_unlock();
+ return ret;
+}
+
+void crash_save_cpu(struct pt_regs *regs, int cpu)
+{
+ struct elf_prstatus prstatus;
+ u32 *buf;
+
+ if ((cpu < 0) || (cpu >= nr_cpu_ids))
+ return;
+
+ /* Using ELF notes here is opportunistic.
+ * I need a well defined structure format
+ * for the data I pass, and I need tags
+ * on the data to indicate what information I have
+ * squirrelled away. ELF notes happen to provide
+ * all of that, so there is no need to invent something new.
+ */
+ buf = (u32 *)per_cpu_ptr(crash_notes, cpu);
+ if (!buf)
+ return;
+ memset(&prstatus, 0, sizeof(prstatus));
+ prstatus.common.pr_pid = current->pid;
+ elf_core_copy_regs(&prstatus.pr_reg, regs);
+ buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
+ &prstatus, sizeof(prstatus));
+ final_note(buf);
+}
+
+
+
static int __init crash_notes_memory_init(void)
{
/* Allocate memory for saving cpu registers. */
@@ -220,6 +474,8 @@ static int __init crash_notes_memory_init(void)
}
subsys_initcall(crash_notes_memory_init);

+#endif /*CONFIG_CRASH_DUMP*/
+
#ifdef CONFIG_CRASH_HOTPLUG
#undef pr_fmt
#define pr_fmt(fmt) "crash hp: " fmt
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 8f35a5a42af8..bab542fc1463 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -28,12 +28,14 @@ static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
struct kimage *image;
bool kexec_on_panic = flags & KEXEC_ON_CRASH;

+#ifdef CONFIG_CRASH_DUMP
if (kexec_on_panic) {
/* Verify we have a valid entry point */
if ((entry < phys_to_boot_phys(crashk_res.start)) ||
(entry > phys_to_boot_phys(crashk_res.end)))
return -EADDRNOTAVAIL;
}
+#endif

/* Allocate and initialize a controlling structure */
image = do_kimage_alloc_init();
@@ -44,11 +46,13 @@ static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
image->nr_segments = nr_segments;
memcpy(image->segment, segments, nr_segments * sizeof(*segments));

+#ifdef CONFIG_CRASH_DUMP
if (kexec_on_panic) {
/* Enable special crash kernel control page alloc policy. */
image->control_page = crashk_res.start;
image->type = KEXEC_TYPE_CRASH;
}
+#endif

ret = sanity_check_segment_list(image);
if (ret)
@@ -99,13 +103,14 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
if (!kexec_trylock())
return -EBUSY;

+#ifdef CONFIG_CRASH_DUMP
if (flags & KEXEC_ON_CRASH) {
dest_image = &kexec_crash_image;
if (kexec_crash_image)
arch_kexec_unprotect_crashkres();
- } else {
+ } else
+#endif
dest_image = &kexec_image;
- }

if (nr_segments == 0) {
/* Uninstall image */
@@ -162,8 +167,10 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
image = xchg(dest_image, image);

out:
+#ifdef CONFIG_CRASH_DUMP
if ((flags & KEXEC_ON_CRASH) && kexec_crash_image)
arch_kexec_protect_crashkres();
+#endif

kimage_free(image);
out_unlock:
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index d08fc7b5db97..ce3429e7972c 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -54,30 +54,6 @@ bool kexec_in_progress = false;

bool kexec_file_dbg_print;

-int kexec_should_crash(struct task_struct *p)
-{
- /*
- * If crash_kexec_post_notifiers is enabled, don't run
- * crash_kexec() here yet, which must be run after panic
- * notifiers in panic().
- */
- if (crash_kexec_post_notifiers)
- return 0;
- /*
- * There are 4 panic() calls in make_task_dead() path, each of which
- * corresponds to each of these 4 conditions.
- */
- if (in_interrupt() || !p->pid || is_global_init(p) || panic_on_oops)
- return 1;
- return 0;
-}
-
-int kexec_crash_loaded(void)
-{
- return !!kexec_crash_image;
-}
-EXPORT_SYMBOL_GPL(kexec_crash_loaded);
-
/*
* When kexec transitions to the new kernel there is a one-to-one
* mapping between physical and virtual addresses. On processors
@@ -209,6 +185,7 @@ int sanity_check_segment_list(struct kimage *image)
if (total_pages > nr_pages / 2)
return -EINVAL;

+#ifdef CONFIG_CRASH_DUMP
/*
* Verify we have good destination addresses. Normally
* the caller is responsible for making certain we don't
@@ -231,6 +208,7 @@ int sanity_check_segment_list(struct kimage *image)
return -EADDRNOTAVAIL;
}
}
+#endif

return 0;
}
@@ -403,6 +381,7 @@ static struct page *kimage_alloc_normal_control_pages(struct kimage *image,
return pages;
}

+#ifdef CONFIG_CRASH_DUMP
static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
unsigned int order)
{
@@ -468,6 +447,7 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,

return pages;
}
+#endif


struct page *kimage_alloc_control_pages(struct kimage *image,
@@ -479,48 +459,16 @@ struct page *kimage_alloc_control_pages(struct kimage *image,
case KEXEC_TYPE_DEFAULT:
pages = kimage_alloc_normal_control_pages(image, order);
break;
+#ifdef CONFIG_CRASH_DUMP
case KEXEC_TYPE_CRASH:
pages = kimage_alloc_crash_control_pages(image, order);
break;
+#endif
}

return pages;
}

-int kimage_crash_copy_vmcoreinfo(struct kimage *image)
-{
- struct page *vmcoreinfo_page;
- void *safecopy;
-
- if (image->type != KEXEC_TYPE_CRASH)
- return 0;
-
- /*
- * For kdump, allocate one vmcoreinfo safe copy from the
- * crash memory. as we have arch_kexec_protect_crashkres()
- * after kexec syscall, we naturally protect it from write
- * (even read) access under kernel direct mapping. But on
- * the other hand, we still need to operate it when crash
- * happens to generate vmcoreinfo note, hereby we rely on
- * vmap for this purpose.
- */
- vmcoreinfo_page = kimage_alloc_control_pages(image, 0);
- if (!vmcoreinfo_page) {
- pr_warn("Could not allocate vmcoreinfo buffer\n");
- return -ENOMEM;
- }
- safecopy = vmap(&vmcoreinfo_page, 1, VM_MAP, PAGE_KERNEL);
- if (!safecopy) {
- pr_warn("Could not vmap vmcoreinfo buffer\n");
- return -ENOMEM;
- }
-
- image->vmcoreinfo_data_copy = safecopy;
- crash_update_vmcoreinfo_safecopy(safecopy);
-
- return 0;
-}
-
static int kimage_add_entry(struct kimage *image, kimage_entry_t entry)
{
if (*image->entry != 0)
@@ -603,10 +551,12 @@ void kimage_free(struct kimage *image)
if (!image)
return;

+#ifdef CONFIG_CRASH_DUMP
if (image->vmcoreinfo_data_copy) {
crash_update_vmcoreinfo_safecopy(NULL);
vunmap(image->vmcoreinfo_data_copy);
}
+#endif

kimage_free_extra_pages(image);
for_each_kimage_entry(image, ptr, entry) {
@@ -824,6 +774,7 @@ static int kimage_load_normal_segment(struct kimage *image,
return result;
}

+#ifdef CONFIG_CRASH_DUMP
static int kimage_load_crash_segment(struct kimage *image,
struct kexec_segment *segment)
{
@@ -891,6 +842,7 @@ static int kimage_load_crash_segment(struct kimage *image,
out:
return result;
}
+#endif

int kimage_load_segment(struct kimage *image,
struct kexec_segment *segment)
@@ -901,9 +853,11 @@ int kimage_load_segment(struct kimage *image,
case KEXEC_TYPE_DEFAULT:
result = kimage_load_normal_segment(image, segment);
break;
+#ifdef CONFIG_CRASH_DUMP
case KEXEC_TYPE_CRASH:
result = kimage_load_crash_segment(image, segment);
break;
+#endif
}

return result;
@@ -1027,186 +981,6 @@ bool kexec_load_permitted(int kexec_image_type)
return true;
}

-/*
- * No panic_cpu check version of crash_kexec(). This function is called
- * only when panic_cpu holds the current CPU number; this is the only CPU
- * which processes crash_kexec routines.
- */
-void __noclone __crash_kexec(struct pt_regs *regs)
-{
- /* Take the kexec_lock here to prevent sys_kexec_load
- * running on one cpu from replacing the crash kernel
- * we are using after a panic on a different cpu.
- *
- * If the crash kernel was not located in a fixed area
- * of memory the xchg(&kexec_crash_image) would be
- * sufficient. But since I reuse the memory...
- */
- if (kexec_trylock()) {
- if (kexec_crash_image) {
- struct pt_regs fixed_regs;
-
- crash_setup_regs(&fixed_regs, regs);
- crash_save_vmcoreinfo();
- machine_crash_shutdown(&fixed_regs);
- machine_kexec(kexec_crash_image);
- }
- kexec_unlock();
- }
-}
-STACK_FRAME_NON_STANDARD(__crash_kexec);
-
-__bpf_kfunc void crash_kexec(struct pt_regs *regs)
-{
- int old_cpu, this_cpu;
-
- /*
- * Only one CPU is allowed to execute the crash_kexec() code as with
- * panic(). Otherwise parallel calls of panic() and crash_kexec()
- * may stop each other. To exclude them, we use panic_cpu here too.
- */
- old_cpu = PANIC_CPU_INVALID;
- this_cpu = raw_smp_processor_id();
-
- if (atomic_try_cmpxchg(&panic_cpu, &old_cpu, this_cpu)) {
- /* This is the 1st CPU which comes here, so go ahead. */
- __crash_kexec(regs);
-
- /*
- * Reset panic_cpu to allow another panic()/crash_kexec()
- * call.
- */
- atomic_set(&panic_cpu, PANIC_CPU_INVALID);
- }
-}
-
-static inline resource_size_t crash_resource_size(const struct resource *res)
-{
- return !res->end ? 0 : resource_size(res);
-}
-
-ssize_t crash_get_memory_size(void)
-{
- ssize_t size = 0;
-
- if (!kexec_trylock())
- return -EBUSY;
-
- size += crash_resource_size(&crashk_res);
- size += crash_resource_size(&crashk_low_res);
-
- kexec_unlock();
- return size;
-}
-
-static int __crash_shrink_memory(struct resource *old_res,
- unsigned long new_size)
-{
- struct resource *ram_res;
-
- ram_res = kzalloc(sizeof(*ram_res), GFP_KERNEL);
- if (!ram_res)
- return -ENOMEM;
-
- ram_res->start = old_res->start + new_size;
- ram_res->end = old_res->end;
- ram_res->flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM;
- ram_res->name = "System RAM";
-
- if (!new_size) {
- release_resource(old_res);
- old_res->start = 0;
- old_res->end = 0;
- } else {
- crashk_res.end = ram_res->start - 1;
- }
-
- crash_free_reserved_phys_range(ram_res->start, ram_res->end);
- insert_resource(&iomem_resource, ram_res);
-
- return 0;
-}
-
-int crash_shrink_memory(unsigned long new_size)
-{
- int ret = 0;
- unsigned long old_size, low_size;
-
- if (!kexec_trylock())
- return -EBUSY;
-
- if (kexec_crash_image) {
- ret = -ENOENT;
- goto unlock;
- }
-
- low_size = crash_resource_size(&crashk_low_res);
- old_size = crash_resource_size(&crashk_res) + low_size;
- new_size = roundup(new_size, KEXEC_CRASH_MEM_ALIGN);
- if (new_size >= old_size) {
- ret = (new_size == old_size) ? 0 : -EINVAL;
- goto unlock;
- }
-
- /*
- * (low_size > new_size) implies that low_size is greater than zero.
- * This also means that if low_size is zero, the else branch is taken.
- *
- * If low_size is greater than 0, (low_size > new_size) indicates that
- * crashk_low_res also needs to be shrunken. Otherwise, only crashk_res
- * needs to be shrunken.
- */
- if (low_size > new_size) {
- ret = __crash_shrink_memory(&crashk_res, 0);
- if (ret)
- goto unlock;
-
- ret = __crash_shrink_memory(&crashk_low_res, new_size);
- } else {
- ret = __crash_shrink_memory(&crashk_res, new_size - low_size);
- }
-
- /* Swap crashk_res and crashk_low_res if needed */
- if (!crashk_res.end && crashk_low_res.end) {
- crashk_res.start = crashk_low_res.start;
- crashk_res.end = crashk_low_res.end;
- release_resource(&crashk_low_res);
- crashk_low_res.start = 0;
- crashk_low_res.end = 0;
- insert_resource(&iomem_resource, &crashk_res);
- }
-
-unlock:
- kexec_unlock();
- return ret;
-}
-
-void crash_save_cpu(struct pt_regs *regs, int cpu)
-{
- struct elf_prstatus prstatus;
- u32 *buf;
-
- if ((cpu < 0) || (cpu >= nr_cpu_ids))
- return;
-
- /* Using ELF notes here is opportunistic.
- * I need a well defined structure format
- * for the data I pass, and I need tags
- * on the data to indicate what information I have
- * squirrelled away. ELF notes happen to provide
- * all of that, so there is no need to invent something new.
- */
- buf = (u32 *)per_cpu_ptr(crash_notes, cpu);
- if (!buf)
- return;
- memset(&prstatus, 0, sizeof(prstatus));
- prstatus.common.pr_pid = current->pid;
- elf_core_copy_regs(&prstatus.pr_reg, regs);
- buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
- &prstatus, sizeof(prstatus));
- final_note(buf);
-}
-
/*
* Move into place and start executing a preloaded standalone
* executable. If nothing was preloaded return an error.
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index bef2f6f2571b..ce7ce2ae27cd 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -285,11 +285,13 @@ kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
kexec_file_dbg_print = !!(flags & KEXEC_FILE_DEBUG);
image->file_mode = 1;

+#ifdef CONFIG_CRASH_DUMP
if (kexec_on_panic) {
/* Enable special crash kernel control page alloc policy. */
image->control_page = crashk_res.start;
image->type = KEXEC_TYPE_CRASH;
}
+#endif

ret = kimage_file_prepare_segments(image, kernel_fd, initrd_fd,
cmdline_ptr, cmdline_len, flags);
@@ -349,13 +351,14 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
if (!kexec_trylock())
return -EBUSY;

+#ifdef CONFIG_CRASH_DUMP
if (image_type == KEXEC_TYPE_CRASH) {
dest_image = &kexec_crash_image;
if (kexec_crash_image)
arch_kexec_unprotect_crashkres();
- } else {
+ } else
+#endif
dest_image = &kexec_image;
- }

if (flags & KEXEC_FILE_UNLOAD)
goto exchange;
@@ -419,8 +422,10 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
exchange:
image = xchg(dest_image, image);
out:
+#ifdef CONFIG_CRASH_DUMP
if ((flags & KEXEC_FILE_ON_CRASH) && kexec_crash_image)
arch_kexec_protect_crashkres();
+#endif

kexec_unlock();
kimage_free(image);
@@ -595,12 +600,14 @@ static int kexec_walk_memblock(struct kexec_buf *kbuf,
static int kexec_walk_resources(struct kexec_buf *kbuf,
int (*func)(struct resource *, void *))
{
+#ifdef CONFIG_CRASH_DUMP
if (kbuf->image->type == KEXEC_TYPE_CRASH)
return walk_iomem_res_desc(crashk_res.desc,
IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
crashk_res.start, crashk_res.end,
kbuf, func);
- else if (kbuf->top_down)
+#endif
+ if (kbuf->top_down)
return walk_system_ram_res_rev(0, ULONG_MAX, kbuf, func);
else
return walk_system_ram_res(0, ULONG_MAX, kbuf, func);
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 11526fc42bc2..fe7a517fc4ab 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -120,6 +120,7 @@ static ssize_t kexec_loaded_show(struct kobject *kobj,
}
KERNEL_ATTR_RO(kexec_loaded);

+#ifdef CONFIG_CRASH_DUMP
static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -152,6 +153,7 @@ static ssize_t kexec_crash_size_store(struct kobject *kobj,
}
KERNEL_ATTR_RW(kexec_crash_size);

+#endif /* CONFIG_CRASH_DUMP*/
#endif /* CONFIG_KEXEC_CORE */

#ifdef CONFIG_VMCORE_INFO
@@ -262,9 +264,11 @@ static struct attribute * kernel_attrs[] = {
#endif
#ifdef CONFIG_KEXEC_CORE
&kexec_loaded_attr.attr,
+#ifdef CONFIG_CRASH_DUMP
&kexec_crash_loaded_attr.attr,
&kexec_crash_size_attr.attr,
#endif
+#endif
#ifdef CONFIG_VMCORE_INFO
&vmcoreinfo_attr.attr,
#ifdef CONFIG_CRASH_HOTPLUG
--
2.41.0


2024-01-19 14:54:28

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 05/14] crash: clean up kdump related config items

By splitting CRASH_RESERVE and VMCORE_INFO out from CRASH_CORE, cleaning
up the dependency of FA_DMUMP on CRASH_DUMP, and moving crash codes from
kexec_core.c to crash_core.c, now we can rearrange CRASH_DUMP to
depend on KEXEC_CORE, and make CRASH_DUMP select CRASH_RESERVE and
VMCORE_INFO.

KEXEC_CORE won't select CRASH_RESERVE and VMCORE_INFO any more because
KEXEC_CORE enables codes which allocate control pages, copy
kexec/kdump segments, and prepare for switching. These codes are shared
by both kexec reboot and crash dumping.

Doing this makes codes and the corresponding config items more
logical (the right item depends on or is selected by the left item).

PROC_KCORE -----------> VMCORE_INFO

|----------> VMCORE_INFO
FA_DUMP----|
|----------> CRASH_RESERVE

---->VMCORE_INFO
/
|---->CRASH_RESERVE
KEXEC --| /|
|--> KEXEC_CORE--> CRASH_DUMP-->/-|---->PROC_VMCORE
KEXEC_FILE --| \ |
\---->CRASH_HOTPLUG

KEXEC --|
|--> KEXEC_CORE--> kexec reboot
KEXEC_FILE --|

Signed-off-by: Baoquan He <[email protected]>
---
kernel/Kconfig.kexec | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
index 8faf27043432..6c34e63c88ff 100644
--- a/kernel/Kconfig.kexec
+++ b/kernel/Kconfig.kexec
@@ -9,8 +9,6 @@ config VMCORE_INFO
bool

config KEXEC_CORE
- select VMCORE_INFO
- select CRASH_RESERVE
bool

config KEXEC_ELF
@@ -99,8 +97,11 @@ config KEXEC_JUMP

config CRASH_DUMP
bool "kernel crash dumps"
+ default y
depends on ARCH_SUPPORTS_CRASH_DUMP
- select KEXEC_CORE
+ depends on KEXEC_CORE
+ select VMCORE_INFO
+ select CRASH_RESERVE
help
Generate crash dump after being started by kexec.
This should be normally only set in special crash dump kernels
--
2.41.0


2024-01-19 14:55:06

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 07/14] arm64, crash: wrap crash dumping code into crash related ifdefs

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on arm64 with some adjustments.

Here wrap up crash dumping codes with CONFIG_CRASH_DUMP ifdeffery.

Signed-off-by: Baoquan He <[email protected]>
---
arch/arm64/include/asm/kexec.h | 2 +-
arch/arm64/kernel/machine_kexec.c | 2 +-
arch/arm64/kernel/machine_kexec_file.c | 10 ++++++++--
3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 9ac9572a3bbe..4d9cc7a76d9c 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -80,7 +80,7 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
}
}

-#if defined(CONFIG_KEXEC_CORE) && defined(CONFIG_HIBERNATION)
+#if defined(CONFIG_CRASH_DUMP) && defined(CONFIG_HIBERNATION)
extern bool crash_is_nosave(unsigned long pfn);
extern void crash_prepare_suspend(void);
extern void crash_post_resume(void);
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index b38aae5b488d..82e2203d86a3 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -255,7 +255,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
pr_info("Starting crashdump kernel...\n");
}

-#ifdef CONFIG_HIBERNATION
+#if defined(CONFIG_CRASH_DUMP) && defined(CONFIG_HIBERNATION)
/*
* To preserve the crash dump kernel image, the relevant memory segments
* should be mapped again around the hibernation.
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 0e017358f4ba..af1ca875c52c 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -39,6 +39,7 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
return kexec_image_post_load_cleanup_default(image);
}

+#ifdef CONFIG_CRASH_DUMP
static int prepare_elf_headers(void **addr, unsigned long *sz)
{
struct crash_mem *cmem;
@@ -80,6 +81,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
kfree(cmem);
return ret;
}
+#endif

/*
* Tries to add the initrd and DTB to the image. If it is not possible to find
@@ -93,8 +95,8 @@ int load_other_segments(struct kimage *image,
char *cmdline)
{
struct kexec_buf kbuf;
- void *headers, *dtb = NULL;
- unsigned long headers_sz, initrd_load_addr = 0, dtb_len,
+ void *dtb = NULL;
+ unsigned long initrd_load_addr = 0, dtb_len,
orig_segments = image->nr_segments;
int ret = 0;

@@ -102,7 +104,10 @@ int load_other_segments(struct kimage *image,
/* not allocate anything below the kernel */
kbuf.buf_min = kernel_load_addr + kernel_size;

+#ifdef CONFIG_CRASH_DUMP
/* load elf core header */
+ void *headers;
+ unsigned long headers_sz;
if (image->type == KEXEC_TYPE_CRASH) {
ret = prepare_elf_headers(&headers, &headers_sz);
if (ret) {
@@ -130,6 +135,7 @@ int load_other_segments(struct kimage *image,
kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
}
+#endif

/* load initrd */
if (initrd) {
--
2.41.0


2024-01-19 14:55:20

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 08/14] ppc, crash: enforce KEXEC and KEXEC_FILE to select CRASH_DUMP

In PowerPC, the crash dumping and kexec reboot share code in
arch_kexec_locate_mem_hole(), in which struct crash_mem is used.

Here enfoce enforce KEXEC and KEXEC_FILE to select CRASH_DUMP for now.

Signed-off-by: Baoquan He <[email protected]>
---
arch/powerpc/Kconfig | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1cdb8fdd3735..fc3cd7f4bb73 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -608,6 +608,10 @@ config PPC64_SUPPORTS_MEMORY_FAILURE
config ARCH_SUPPORTS_KEXEC
def_bool PPC_BOOK3S || PPC_E500 || (44x && !SMP)

+config ARCH_SELECTS_KEXEC
+ def_bool y
+ select CRASH_DUMP
+
config ARCH_SUPPORTS_KEXEC_FILE
def_bool PPC64

@@ -618,6 +622,7 @@ config ARCH_SELECTS_KEXEC_FILE
def_bool y
depends on KEXEC_FILE
select KEXEC_ELF
+ select CRASH_DUMP
select HAVE_IMA_KEXEC if IMA

config PPC64_BIG_ENDIAN_ELF_ABI_V2
--
2.41.0


2024-01-19 14:55:33

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 09/14] s390, crash: wrap crash dumping code into crash related ifdefs

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on s390 with some adjustments.

Here wrap up crash dumping codes with CONFIG_CRASH_DUMP ifdeffery.

Signed-off-by: Baoquan He <[email protected]>
---
arch/s390/kernel/kexec_elf.c | 2 ++
arch/s390/kernel/kexec_image.c | 2 ++
arch/s390/kernel/machine_kexec_file.c | 10 ++++++++++
3 files changed, 14 insertions(+)

diff --git a/arch/s390/kernel/kexec_elf.c b/arch/s390/kernel/kexec_elf.c
index 9da6fa30c447..4d364de43799 100644
--- a/arch/s390/kernel/kexec_elf.c
+++ b/arch/s390/kernel/kexec_elf.c
@@ -40,8 +40,10 @@ static int kexec_file_add_kernel_elf(struct kimage *image,
buf.bufsz = phdr->p_filesz;

buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif
buf.memsz = phdr->p_memsz;
data->memsz = ALIGN(data->memsz, phdr->p_align) + buf.memsz;

diff --git a/arch/s390/kernel/kexec_image.c b/arch/s390/kernel/kexec_image.c
index af23eff5774d..a32ce8bea745 100644
--- a/arch/s390/kernel/kexec_image.c
+++ b/arch/s390/kernel/kexec_image.c
@@ -24,8 +24,10 @@ static int kexec_file_add_kernel_image(struct kimage *image,
buf.bufsz = image->kernel_buf_len;

buf.mem = 0;
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif
buf.memsz = buf.bufsz;

data->kernel_buf = image->kernel_buf;
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
index 8d207b82d9fe..c2bac14dd668 100644
--- a/arch/s390/kernel/machine_kexec_file.c
+++ b/arch/s390/kernel/machine_kexec_file.c
@@ -105,6 +105,7 @@ static int kexec_file_update_purgatory(struct kimage *image,
if (ret)
return ret;

+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH) {
u64 crash_size;

@@ -121,6 +122,7 @@ static int kexec_file_update_purgatory(struct kimage *image,
sizeof(crash_size),
false);
}
+#endif
return ret;
}

@@ -134,8 +136,10 @@ static int kexec_file_add_purgatory(struct kimage *image,

data->memsz = ALIGN(data->memsz, PAGE_SIZE);
buf.mem = data->memsz;
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif

ret = kexec_load_purgatory(image, &buf);
if (ret)
@@ -158,8 +162,10 @@ static int kexec_file_add_initrd(struct kimage *image,

data->memsz = ALIGN(data->memsz, PAGE_SIZE);
buf.mem = data->memsz;
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif
buf.memsz = buf.bufsz;

data->parm->initrd_start = data->memsz;
@@ -223,8 +229,10 @@ static int kexec_file_add_ipl_report(struct kimage *image,
data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr);
*lc_ipl_parmblock_ptr = (__u32)buf.mem;

+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif

ret = kexec_add_buffer(&buf);
out:
@@ -268,10 +276,12 @@ void *kexec_file_add_components(struct kimage *image,
memcpy(data.parm->command_line, image->cmdline_buf,
image->cmdline_buf_len);

+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH) {
data.parm->oldmem_base = crashk_res.start;
data.parm->oldmem_size = crashk_res.end - crashk_res.start + 1;
}
+#endif

if (image->initrd_buf) {
ret = kexec_file_add_initrd(image, &data);
--
2.41.0


2024-01-19 14:56:07

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 10/14] sh, crash: wrap crash dumping code into crash related ifdefs

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on SuperH with some adjustments.

Here wrap up crashkernel reservation code inside CONFIG_CRASH_RESERVE
ifdeffery scope.

Signed-off-by: Baoquan He <[email protected]>
---
arch/sh/kernel/machine_kexec.c | 3 +++
arch/sh/kernel/setup.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index fa3a7b36190a..8daa8a6e6fa6 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -153,6 +153,9 @@ void __init reserve_crashkernel(void)
unsigned long long crash_size, crash_base;
int ret;

+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+ return;
+
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
&crash_size, &crash_base, NULL, NULL);
if (ret == 0 && crash_size > 0) {
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index d3175f09b3aa..620e5cf8ae1e 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -220,7 +220,7 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
request_resource(res, &code_resource);
request_resource(res, &data_resource);
request_resource(res, &bss_resource);
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_RESERVE
request_resource(res, &crashk_res);
#endif

--
2.41.0


2024-01-19 14:56:23

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 06/14] x86, crash: wrap crash dumping code into crash related ifdefs

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on x86 with some adjustments.

Here, also change some ifdefs or IS_ENABLED() check to more appropriate
ones, e,g
- #ifdef CONFIG_KEXEC_CORE -> #ifdef CONFIG_CRASH_DUMP
- (!IS_ENABLED(CONFIG_KEXEC_CORE)) - > (!IS_ENABLED(CONFIG_CRASH_RESERVE))

Signed-off-by: Baoquan He <[email protected]>
---
arch/x86/kernel/Makefile | 4 ++--
arch/x86/kernel/cpu/mshyperv.c | 4 ++++
arch/x86/kernel/kexec-bzimage64.c | 4 ++++
arch/x86/kernel/kvm.c | 4 ++--
arch/x86/kernel/machine_kexec_64.c | 3 +++
arch/x86/kernel/reboot.c | 2 +-
arch/x86/kernel/setup.c | 2 +-
arch/x86/kernel/smp.c | 2 +-
arch/x86/xen/enlighten_hvm.c | 4 ++++
9 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 913d4022131e..3668b1edef2d 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -100,9 +100,9 @@ obj-$(CONFIG_TRACING) += trace.o
obj-$(CONFIG_RETHOOK) += rethook.o
obj-$(CONFIG_VMCORE_INFO) += vmcore_info_$(BITS).o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o
-obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o
+obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o
obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o
-obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
+obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o crash.o
obj-y += kprobes/
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_X86_32) += doublefault_32.o
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 01fa06dd06b6..f8163a59026b 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -210,6 +210,7 @@ static void hv_machine_shutdown(void)
hyperv_cleanup();
}

+#ifdef CONFIG_CRASH_DUMP
static void hv_machine_crash_shutdown(struct pt_regs *regs)
{
if (hv_crash_handler)
@@ -221,6 +222,7 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs)
/* Disable the hypercall page when there is only 1 active CPU. */
hyperv_cleanup();
}
+#endif
#endif /* CONFIG_KEXEC_CORE */
#endif /* CONFIG_HYPERV */

@@ -497,7 +499,9 @@ static void __init ms_hyperv_init_platform(void)

#if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE)
machine_ops.shutdown = hv_machine_shutdown;
+#ifdef CONFIG_CRASH_DUMP
machine_ops.crash_shutdown = hv_machine_crash_shutdown;
+#endif
#endif
if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) {
/*
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 2a422e00ed4b..b55737b83a84 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -263,11 +263,13 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
memset(&params->hd0_info, 0, sizeof(params->hd0_info));
memset(&params->hd1_info, 0, sizeof(params->hd1_info));

+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH) {
ret = crash_setup_memmap_entries(image, params);
if (ret)
return ret;
} else
+#endif
setup_e820_entries(params);

nr_e820_entries = params->e820_entries;
@@ -433,12 +435,14 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
return ERR_PTR(-EINVAL);
}

+#ifdef CONFIG_CRASH_DUMP
/* Allocate and load backup region */
if (image->type == KEXEC_TYPE_CRASH) {
ret = crash_load_segments(image);
if (ret)
return ERR_PTR(ret);
}
+#endif

/*
* Load purgatory. For 64bit entry point, purgatory code can be
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index dfe9945b9bec..acfc2d3183bc 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -769,7 +769,7 @@ static struct notifier_block kvm_pv_reboot_nb = {
* won't be valid. In cases like kexec, in which you install a new kernel, this
* means a random memory location will be kept being written.
*/
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
static void kvm_crash_shutdown(struct pt_regs *regs)
{
kvm_guest_cpu_offline(true);
@@ -852,7 +852,7 @@ static void __init kvm_guest_init(void)
kvm_guest_cpu_init();
#endif

-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
machine_ops.crash_shutdown = kvm_crash_shutdown;
#endif

diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index bc0a5348b4a6..b180d8e497c3 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -508,6 +508,8 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
}
#endif /* CONFIG_KEXEC_FILE */

+#ifdef CONFIG_CRASH_DUMP
+
static int
kexec_mark_range(unsigned long start, unsigned long end, bool protect)
{
@@ -552,6 +554,7 @@ void arch_kexec_unprotect_crashkres(void)
{
kexec_mark_crashkres(false);
}
+#endif

/*
* During a traditional boot under SME, SME will encrypt the kernel,
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 830425e6d38e..1287b0d5962f 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -796,7 +796,7 @@ struct machine_ops machine_ops __ro_after_init = {
.emergency_restart = native_machine_emergency_restart,
.restart = native_machine_restart,
.halt = native_machine_halt,
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
.crash_shutdown = native_machine_crash_shutdown,
#endif
};
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 84201071dfac..899d839a2954 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -471,7 +471,7 @@ static void __init arch_reserve_crashkernel(void)
bool high = false;
int ret;

- if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
return;

ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 96a771f9f930..52c3823b7211 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -282,7 +282,7 @@ struct smp_ops smp_ops = {
.smp_cpus_done = native_smp_cpus_done,

.stop_other_cpus = native_stop_other_cpus,
-#if defined(CONFIG_KEXEC_CORE)
+#if defined(CONFIG_CRASH_DUMP)
.crash_stop_other_cpus = kdump_nmi_shootdown_cpus,
#endif
.smp_send_reschedule = native_smp_send_reschedule,
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index 3f8c34707c50..09e3db7ff990 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -149,12 +149,14 @@ static void xen_hvm_shutdown(void)
xen_reboot(SHUTDOWN_soft_reset);
}

+#ifdef CONFIG_CRASH_DUMP
static void xen_hvm_crash_shutdown(struct pt_regs *regs)
{
native_machine_crash_shutdown(regs);
xen_reboot(SHUTDOWN_soft_reset);
}
#endif
+#endif

static int xen_cpu_up_prepare_hvm(unsigned int cpu)
{
@@ -236,8 +238,10 @@ static void __init xen_hvm_guest_init(void)

#ifdef CONFIG_KEXEC_CORE
machine_ops.shutdown = xen_hvm_shutdown;
+#ifdef CONFIG_CRASH_DUMP
machine_ops.crash_shutdown = xen_hvm_crash_shutdown;
#endif
+#endif
}

static __init int xen_parse_nopv(char *arg)
--
2.41.0


2024-01-19 14:56:25

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 12/14] mips, crash: wrap crash dumping code into crash related ifdefs

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on mips with some adjustments.

Here use IS_ENABLED(CONFIG_CRASH_RESERVE) check to decide if compiling
in the crashkernel reservation code.

Signed-off-by: Baoquan He <[email protected]>
---
arch/mips/kernel/setup.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 9c30de151597..12a1a4ffb602 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -442,8 +442,6 @@ static void __init mips_reserve_vmcore(void)
#endif
}

-#ifdef CONFIG_KEXEC
-
/* 64M alignment for crash kernel regions */
#define CRASH_ALIGN SZ_64M
#define CRASH_ADDR_MAX SZ_512M
@@ -454,6 +452,9 @@ static void __init mips_parse_crashkernel(void)
unsigned long long crash_size, crash_base;
int ret;

+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+ return;
+
total_mem = memblock_phys_mem_size();
ret = parse_crashkernel(boot_command_line, total_mem,
&crash_size, &crash_base,
@@ -489,6 +490,9 @@ static void __init request_crashkernel(struct resource *res)
{
int ret;

+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+ return;
+
if (crashk_res.start == crashk_res.end)
return;

@@ -498,15 +502,6 @@ static void __init request_crashkernel(struct resource *res)
(unsigned long)(resource_size(&crashk_res) >> 20),
(unsigned long)(crashk_res.start >> 20));
}
-#else /* !defined(CONFIG_KEXEC) */
-static void __init mips_parse_crashkernel(void)
-{
-}
-
-static void __init request_crashkernel(struct resource *res)
-{
-}
-#endif /* !defined(CONFIG_KEXEC) */

static void __init check_kernel_sections_mem(void)
{
--
2.41.0


2024-01-19 14:56:44

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 13/14] riscv, crash: wrap crash dumping code into crash related ifdefs

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on risc-v with some adjustments.

Here wrap up crash dumping codes with CONFIG_CRASH_DUMP ifdeffery, and
use IS_ENABLED(CONFIG_CRASH_RESERVE) check to decide if compiling
in the crashkernel reservation code.

Signed-off-by: Baoquan He <[email protected]>
---
arch/riscv/kernel/elf_kexec.c | 9 +++++++--
arch/riscv/mm/init.c | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
index 5bd1ec3341fe..54260c16f991 100644
--- a/arch/riscv/kernel/elf_kexec.c
+++ b/arch/riscv/kernel/elf_kexec.c
@@ -117,6 +117,7 @@ static int elf_find_pbase(struct kimage *image, unsigned long kernel_len,
return ret;
}

+#ifdef CONFIG_CRASH_DUMP
static int get_nr_ram_ranges_callback(struct resource *res, void *arg)
{
unsigned int *nr_ranges = arg;
@@ -189,6 +190,7 @@ static char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
cmdline_ptr[COMMAND_LINE_SIZE - 1] = '\0';
return cmdline_ptr;
}
+#endif

static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
unsigned long kernel_len, char *initrd,
@@ -196,12 +198,11 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
unsigned long cmdline_len)
{
int ret;
+ void *fdt;
unsigned long old_kernel_pbase = ULONG_MAX;
unsigned long new_kernel_pbase = 0UL;
unsigned long initrd_pbase = 0UL;
- unsigned long headers_sz;
unsigned long kernel_start;
- void *fdt, *headers;
struct elfhdr ehdr;
struct kexec_buf kbuf;
struct kexec_elf_info elf_info;
@@ -227,8 +228,11 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
kbuf.buf_min = new_kernel_pbase + kernel_len;
kbuf.buf_max = ULONG_MAX;

+#ifdef CONFIG_CRASH_DUMP
/* Add elfcorehdr */
if (image->type == KEXEC_TYPE_CRASH) {
+ void *headers;
+ unsigned long headers_sz;
ret = prepare_elf_headers(&headers, &headers_sz);
if (ret) {
pr_err("Preparing elf core header failed\n");
@@ -264,6 +268,7 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
}
cmdline = modified_cmdline;
}
+#endif

#ifdef CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY
/* Add purgatory to the image */
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index a65937336cdc..f580d1f6ee13 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -1354,7 +1354,7 @@ static void __init arch_reserve_crashkernel(void)
bool high = false;
int ret;

- if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
return;

ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
--
2.41.0


2024-01-19 14:57:33

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 11/14] arm, crash: wrap crash dumping code into crash related ifdefs

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on arm with some adjustments.

Here use IS_ENABLED(CONFIG_CRASH_RESERVE) check to decide if compiling
in the crashkernel reservation code.

Signed-off-by: Baoquan He <[email protected]>
---
arch/arm/kernel/setup.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ff2299ce1ad7..cf0b3798179f 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -979,7 +979,6 @@ static int __init init_machine_late(void)
}
late_initcall(init_machine_late);

-#ifdef CONFIG_KEXEC
/*
* The crash region must be aligned to 128MB to avoid
* zImage relocating below the reserved region.
@@ -1007,6 +1006,9 @@ static void __init reserve_crashkernel(void)
unsigned long long total_mem;
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,
@@ -1064,9 +1066,6 @@ static void __init reserve_crashkernel(void)
insert_resource(&iomem_resource, &crashk_boot_res);
}
}
-#else
-static inline void reserve_crashkernel(void) {}
-#endif /* CONFIG_KEXEC */

void __init hyp_mode_check(void)
{
--
2.41.0


2024-01-19 14:58:10

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 14/14] loongarch, crash: wrap crash dumping code into crash related ifdefs

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on loongarch with some adjustments.

Here wrap up crash dumping codes with CONFIG_CRASH_DUMP ifdeffery, and
use IS_ENABLED(CONFIG_CRASH_RESERVE) check to decide if compiling
in the crashkernel reservation code.

Signed-off-by: Baoquan He <[email protected]>
---
arch/loongarch/kernel/setup.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
index d183a745fb85..61f88dd97947 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -258,11 +258,13 @@ static void __init arch_reserve_vmcore(void)

static void __init arch_parse_crashkernel(void)
{
-#ifdef CONFIG_KEXEC
int ret;
unsigned long long total_mem;
unsigned long long crash_base, crash_size;

+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+ return;
+
total_mem = memblock_phys_mem_size();
ret = parse_crashkernel(boot_command_line, total_mem,
&crash_size, &crash_base,
@@ -283,7 +285,6 @@ static void __init arch_parse_crashkernel(void)

crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
-#endif
}

static void __init fdt_setup(void)
@@ -468,7 +469,7 @@ static void __init resource_init(void)
request_resource(res, &bss_resource);
}

-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_CRASH_RESERVE
if (crashk_res.start < crashk_res.end) {
insert_resource(&iomem_resource, &crashk_res);
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel\n",
--
2.41.0


2024-01-20 12:15:24

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 11/14] arm, crash: wrap crash dumping code into crash related ifdefs

Hi Baoquan,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[cannot apply to tip/x86/core arm64/for-next/core powerpc/next powerpc/fixes v6.7 next-20240119]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec-split-crashkernel-reservation-code-out-from-crash_core-c/20240119-225820
base: linus/master
patch link: https://lore.kernel.org/r/20240119145241.769622-12-bhe%40redhat.com
patch subject: [PATCH v2 11/14] arm, crash: wrap crash dumping code into crash related ifdefs
config: arm-randconfig-001-20240120 (https://download.01.org/0day-ci/archive/20240120/[email protected]/config)
compiler: clang version 18.0.0git (https://github.com/llvm/llvm-project d92ce344bf641e6bb025b41b3f1a77dd25e2b3e9)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240120/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

>> arch/arm/kernel/setup.c:1036:49: error: use of undeclared identifier 'SECTION_SIZE'
1036 | start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
| ^
1 error generated.


vim +/SECTION_SIZE +1036 arch/arm/kernel/setup.c

3c57fb43c8fcbe Mika Westerberg 2010-05-10 995
3c57fb43c8fcbe Mika Westerberg 2010-05-10 996 /**
3c57fb43c8fcbe Mika Westerberg 2010-05-10 997 * reserve_crashkernel() - reserves memory are for crash kernel
3c57fb43c8fcbe Mika Westerberg 2010-05-10 998 *
3c57fb43c8fcbe Mika Westerberg 2010-05-10 999 * This function reserves memory area given in "crashkernel=" kernel command
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1000 * line parameter. The memory reserved is used by a dump capture kernel when
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1001 * primary kernel is crashing.
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1002 */
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1003 static void __init reserve_crashkernel(void)
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1004 {
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1005 unsigned long long crash_size, crash_base;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1006 unsigned long long total_mem;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1007 int ret;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1008
8f460484669cba Baoquan He 2024-01-19 1009 if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
8f460484669cba Baoquan He 2024-01-19 1010 return;
8f460484669cba Baoquan He 2024-01-19 1011
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1012 total_mem = get_total_mem();
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1013 ret = parse_crashkernel(boot_command_line, total_mem,
a9e1a3d84e4a0e Baoquan He 2023-09-14 1014 &crash_size, &crash_base,
a9e1a3d84e4a0e Baoquan He 2023-09-14 1015 NULL, NULL);
9d17f337230642 Austin Kim 2022-04-01 1016 /* invalid value specified or crashkernel=0 */
9d17f337230642 Austin Kim 2022-04-01 1017 if (ret || !crash_size)
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1018 return;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1019
61603016e2122b Russell King 2016-03-14 1020 if (crash_base <= 0) {
d0506a2395eb07 Russell King 2016-04-01 1021 unsigned long long crash_max = idmap_to_phys((u32)~0);
67556d7a851c20 Russell King 2017-07-19 1022 unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
67556d7a851c20 Russell King 2017-07-19 1023 if (crash_max > lowmem_max)
67556d7a851c20 Russell King 2017-07-19 1024 crash_max = lowmem_max;
a7259df7670240 Mike Rapoport 2021-09-02 1025
a7259df7670240 Mike Rapoport 2021-09-02 1026 crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
a7259df7670240 Mike Rapoport 2021-09-02 1027 CRASH_ALIGN, crash_max);
61603016e2122b Russell King 2016-03-14 1028 if (!crash_base) {
61603016e2122b Russell King 2016-03-14 1029 pr_err("crashkernel reservation failed - No suitable area found.\n");
61603016e2122b Russell King 2016-03-14 1030 return;
61603016e2122b Russell King 2016-03-14 1031 }
61603016e2122b Russell King 2016-03-14 1032 } else {
a7259df7670240 Mike Rapoport 2021-09-02 1033 unsigned long long crash_max = crash_base + crash_size;
61603016e2122b Russell King 2016-03-14 1034 unsigned long long start;
61603016e2122b Russell King 2016-03-14 1035
a7259df7670240 Mike Rapoport 2021-09-02 @1036 start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
a7259df7670240 Mike Rapoport 2021-09-02 1037 crash_base, crash_max);
a7259df7670240 Mike Rapoport 2021-09-02 1038 if (!start) {
61603016e2122b Russell King 2016-03-14 1039 pr_err("crashkernel reservation failed - memory is in use.\n");
61603016e2122b Russell King 2016-03-14 1040 return;
61603016e2122b Russell King 2016-03-14 1041 }
61603016e2122b Russell King 2016-03-14 1042 }
61603016e2122b Russell King 2016-03-14 1043
1b0f6681fcbc0e Olof Johansson 2013-12-05 1044 pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1045 (unsigned long)(crash_size >> 20),
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1046 (unsigned long)(crash_base >> 20),
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1047 (unsigned long)(total_mem >> 20));
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1048
f7f0b7dc720f81 Russell King 2016-08-02 1049 /* The crashk resource must always be located in normal mem */
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1050 crashk_res.start = crash_base;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1051 crashk_res.end = crash_base + crash_size - 1;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1052 insert_resource(&iomem_resource, &crashk_res);
f7f0b7dc720f81 Russell King 2016-08-02 1053
f7f0b7dc720f81 Russell King 2016-08-02 1054 if (arm_has_idmap_alias()) {
f7f0b7dc720f81 Russell King 2016-08-02 1055 /*
f7f0b7dc720f81 Russell King 2016-08-02 1056 * If we have a special RAM alias for use at boot, we
f7f0b7dc720f81 Russell King 2016-08-02 1057 * need to advertise to kexec tools where the alias is.
f7f0b7dc720f81 Russell King 2016-08-02 1058 */
f7f0b7dc720f81 Russell King 2016-08-02 1059 static struct resource crashk_boot_res = {
f7f0b7dc720f81 Russell King 2016-08-02 1060 .name = "Crash kernel (boot alias)",
f7f0b7dc720f81 Russell King 2016-08-02 1061 .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
f7f0b7dc720f81 Russell King 2016-08-02 1062 };
f7f0b7dc720f81 Russell King 2016-08-02 1063
f7f0b7dc720f81 Russell King 2016-08-02 1064 crashk_boot_res.start = phys_to_idmap(crash_base);
f7f0b7dc720f81 Russell King 2016-08-02 1065 crashk_boot_res.end = crashk_boot_res.start + crash_size - 1;
f7f0b7dc720f81 Russell King 2016-08-02 1066 insert_resource(&iomem_resource, &crashk_boot_res);
f7f0b7dc720f81 Russell King 2016-08-02 1067 }
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1068 }
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1069

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2024-01-20 13:58:57

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 11/14] arm, crash: wrap crash dumping code into crash related ifdefs

Hi Baoquan,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[cannot apply to tip/x86/core arm64/for-next/core powerpc/next powerpc/fixes v6.7 next-20240119]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec-split-crashkernel-reservation-code-out-from-crash_core-c/20240119-225820
base: linus/master
patch link: https://lore.kernel.org/r/20240119145241.769622-12-bhe%40redhat.com
patch subject: [PATCH v2 11/14] arm, crash: wrap crash dumping code into crash related ifdefs
config: arm-allnoconfig (https://download.01.org/0day-ci/archive/20240120/[email protected]/config)
compiler: arm-linux-gnueabi-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240120/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

arch/arm/kernel/setup.c: In function 'reserve_crashkernel':
>> arch/arm/kernel/setup.c:1036:63: error: 'SECTION_SIZE' undeclared (first use in this function); did you mean 'SECTIONS_SHIFT'?
1036 | start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
| ^~~~~~~~~~~~
| SECTIONS_SHIFT
arch/arm/kernel/setup.c:1036:63: note: each undeclared identifier is reported only once for each function it appears in
In file included from arch/arm/include/asm/efi.h:12,
from arch/arm/kernel/setup.c:37:
arch/arm/include/asm/fixmap.h: At top level:
arch/arm/include/asm/fixmap.h:39:35: warning: '__end_of_fixed_addresses' defined but not used [-Wunused-const-variable=]
39 | static const enum fixed_addresses __end_of_fixed_addresses =
| ^~~~~~~~~~~~~~~~~~~~~~~~


vim +1036 arch/arm/kernel/setup.c

3c57fb43c8fcbe Mika Westerberg 2010-05-10 995
3c57fb43c8fcbe Mika Westerberg 2010-05-10 996 /**
3c57fb43c8fcbe Mika Westerberg 2010-05-10 997 * reserve_crashkernel() - reserves memory are for crash kernel
3c57fb43c8fcbe Mika Westerberg 2010-05-10 998 *
3c57fb43c8fcbe Mika Westerberg 2010-05-10 999 * This function reserves memory area given in "crashkernel=" kernel command
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1000 * line parameter. The memory reserved is used by a dump capture kernel when
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1001 * primary kernel is crashing.
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1002 */
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1003 static void __init reserve_crashkernel(void)
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1004 {
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1005 unsigned long long crash_size, crash_base;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1006 unsigned long long total_mem;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1007 int ret;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1008
8f460484669cba Baoquan He 2024-01-19 1009 if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
8f460484669cba Baoquan He 2024-01-19 1010 return;
8f460484669cba Baoquan He 2024-01-19 1011
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1012 total_mem = get_total_mem();
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1013 ret = parse_crashkernel(boot_command_line, total_mem,
a9e1a3d84e4a0e Baoquan He 2023-09-14 1014 &crash_size, &crash_base,
a9e1a3d84e4a0e Baoquan He 2023-09-14 1015 NULL, NULL);
9d17f337230642 Austin Kim 2022-04-01 1016 /* invalid value specified or crashkernel=0 */
9d17f337230642 Austin Kim 2022-04-01 1017 if (ret || !crash_size)
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1018 return;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1019
61603016e2122b Russell King 2016-03-14 1020 if (crash_base <= 0) {
d0506a2395eb07 Russell King 2016-04-01 1021 unsigned long long crash_max = idmap_to_phys((u32)~0);
67556d7a851c20 Russell King 2017-07-19 1022 unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
67556d7a851c20 Russell King 2017-07-19 1023 if (crash_max > lowmem_max)
67556d7a851c20 Russell King 2017-07-19 1024 crash_max = lowmem_max;
a7259df7670240 Mike Rapoport 2021-09-02 1025
a7259df7670240 Mike Rapoport 2021-09-02 1026 crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
a7259df7670240 Mike Rapoport 2021-09-02 1027 CRASH_ALIGN, crash_max);
61603016e2122b Russell King 2016-03-14 1028 if (!crash_base) {
61603016e2122b Russell King 2016-03-14 1029 pr_err("crashkernel reservation failed - No suitable area found.\n");
61603016e2122b Russell King 2016-03-14 1030 return;
61603016e2122b Russell King 2016-03-14 1031 }
61603016e2122b Russell King 2016-03-14 1032 } else {
a7259df7670240 Mike Rapoport 2021-09-02 1033 unsigned long long crash_max = crash_base + crash_size;
61603016e2122b Russell King 2016-03-14 1034 unsigned long long start;
61603016e2122b Russell King 2016-03-14 1035
a7259df7670240 Mike Rapoport 2021-09-02 @1036 start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
a7259df7670240 Mike Rapoport 2021-09-02 1037 crash_base, crash_max);
a7259df7670240 Mike Rapoport 2021-09-02 1038 if (!start) {
61603016e2122b Russell King 2016-03-14 1039 pr_err("crashkernel reservation failed - memory is in use.\n");
61603016e2122b Russell King 2016-03-14 1040 return;
61603016e2122b Russell King 2016-03-14 1041 }
61603016e2122b Russell King 2016-03-14 1042 }
61603016e2122b Russell King 2016-03-14 1043
1b0f6681fcbc0e Olof Johansson 2013-12-05 1044 pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1045 (unsigned long)(crash_size >> 20),
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1046 (unsigned long)(crash_base >> 20),
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1047 (unsigned long)(total_mem >> 20));
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1048
f7f0b7dc720f81 Russell King 2016-08-02 1049 /* The crashk resource must always be located in normal mem */
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1050 crashk_res.start = crash_base;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1051 crashk_res.end = crash_base + crash_size - 1;
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1052 insert_resource(&iomem_resource, &crashk_res);
f7f0b7dc720f81 Russell King 2016-08-02 1053
f7f0b7dc720f81 Russell King 2016-08-02 1054 if (arm_has_idmap_alias()) {
f7f0b7dc720f81 Russell King 2016-08-02 1055 /*
f7f0b7dc720f81 Russell King 2016-08-02 1056 * If we have a special RAM alias for use at boot, we
f7f0b7dc720f81 Russell King 2016-08-02 1057 * need to advertise to kexec tools where the alias is.
f7f0b7dc720f81 Russell King 2016-08-02 1058 */
f7f0b7dc720f81 Russell King 2016-08-02 1059 static struct resource crashk_boot_res = {
f7f0b7dc720f81 Russell King 2016-08-02 1060 .name = "Crash kernel (boot alias)",
f7f0b7dc720f81 Russell King 2016-08-02 1061 .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
f7f0b7dc720f81 Russell King 2016-08-02 1062 };
f7f0b7dc720f81 Russell King 2016-08-02 1063
f7f0b7dc720f81 Russell King 2016-08-02 1064 crashk_boot_res.start = phys_to_idmap(crash_base);
f7f0b7dc720f81 Russell King 2016-08-02 1065 crashk_boot_res.end = crashk_boot_res.start + crash_size - 1;
f7f0b7dc720f81 Russell King 2016-08-02 1066 insert_resource(&iomem_resource, &crashk_boot_res);
f7f0b7dc720f81 Russell King 2016-08-02 1067 }
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1068 }
3c57fb43c8fcbe Mika Westerberg 2010-05-10 1069

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2024-01-21 01:55:54

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v2 11/14] arm, crash: wrap crash dumping code into crash related ifdefs

On 01/20/24 at 08:13pm, kernel test robot wrote:
> Hi Baoquan,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on linus/master]
> [cannot apply to tip/x86/core arm64/for-next/core powerpc/next powerpc/fixes v6.7 next-20240119]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec-split-crashkernel-reservation-code-out-from-crash_core-c/20240119-225820
> base: linus/master
> patch link: https://lore.kernel.org/r/20240119145241.769622-12-bhe%40redhat.com
> patch subject: [PATCH v2 11/14] arm, crash: wrap crash dumping code into crash related ifdefs
> config: arm-randconfig-001-20240120 (https://download.01.org/0day-ci/archive/20240120/[email protected]/config)
> compiler: clang version 18.0.0git (https://github.com/llvm/llvm-project d92ce344bf641e6bb025b41b3f1a77dd25e2b3e9)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240120/[email protected]/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <[email protected]>
> | Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

Thanks for reporting this, I can reproduce it.

In the provided config, it has:

# CONFIG_MMU is not set
and all kexec/kdump related config items are unset.

The if (!IS_ENABLED(CONFIG_CRASH_RESERVE)) checking will cause funciton
reserve_crashkernel() is compiled, but not built in. With CONFIG_MMU=no,
SECTION_SIZE is undefined on arm. So fix it by wrapping up
reserve_crashkernel() inside CONFIG_CRASH_RESERVE ifdeffery scope.


From d580b65f6aa042233e228aab45609c3de88ab29e Mon Sep 17 00:00:00 2001
From: Baoquan He <[email protected]>
Date: Mon, 15 Jan 2024 22:32:19 -0500
Subject: [PATCH] arm, crash: wrap crash dumping code into crash related ifdefs
Content-type: text/plain

Now crash codes under kernel/ folder has been split out from kexec
code, crash dumping can be separated from kexec reboot in config
items on arm with some adjustments.

Here use CONFIG_CRASH_RESERVE ifdef to replace CONFIG_KEXEC ifdef.

Signed-off-by: Baoquan He <[email protected]>
---
arch/arm/kernel/setup.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ff2299ce1ad7..7b33b157fca0 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -979,7 +979,7 @@ static int __init init_machine_late(void)
}
late_initcall(init_machine_late);

-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_CRASH_RESERVE
/*
* The crash region must be aligned to 128MB to avoid
* zImage relocating below the reserved region.
@@ -1066,7 +1066,7 @@ static void __init reserve_crashkernel(void)
}
#else
static inline void reserve_crashkernel(void) {}
-#endif /* CONFIG_KEXEC */
+#endif /* CONFIG_CRASH_RESERVE*/

void __init hyp_mode_check(void)
{
--
2.41.0


2024-02-02 05:26:11

by Hari Bathini

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

Hi Baoquan,

On 19/01/24 8:22 pm, Baoquan He wrote:
> Motivation:
> =============
> Previously, LKP reported a building error. When investigating, it can't
> be resolved reasonablly with the present messy kdump config items.
>
> https://lore.kernel.org/oe-kbuild-all/[email protected]/
>
> The kdump (crash dumping) related config items could causes confusions:
>
> Firstly,
> ---
> CRASH_CORE enables codes including
> - crashkernel reservation;
> - elfcorehdr updating;
> - vmcoreinfo exporting;
> - crash hotplug handling;
>
> Now fadump of powerpc, kcore dynamic debugging and kdump all selects
> CRASH_CORE, while fadump
> - fadump needs crashkernel parsing, vmcoreinfo exporting, and accessing
> global variable 'elfcorehdr_addr';
> - kcore only needs vmcoreinfo exporting;
> - kdump needs all of the current kernel/crash_core.c.
>
> So only enabling PROC_CORE or FA_DUMP will enable CRASH_CORE, this
> mislead people that we enable crash dumping, actual it's not.
>
> Secondly,
> ---
> It's not reasonable to allow KEXEC_CORE select CRASH_CORE.
>
> Because KEXEC_CORE enables codes which allocate control pages, copy
> kexec/kdump segments, and prepare for switching. These codes are
> shared by both kexec reboot and kdump. We could want kexec reboot,
> but disable kdump. In that case, CRASH_CORE should not be selected.
>
> --------------------
> CONFIG_CRASH_CORE=y
> CONFIG_KEXEC_CORE=y
> CONFIG_KEXEC=y
> CONFIG_KEXEC_FILE=y
> ---------------------
>
> Thirdly,
> ---
> It's not reasonable to allow CRASH_DUMP select KEXEC_CORE.
>
> That could make KEXEC_CORE, CRASH_DUMP are enabled independently from
> KEXEC or KEXEC_FILE. However, w/o KEXEC or KEXEC_FILE, the KEXEC_CORE
> code built in doesn't make any sense because no kernel loading or
> switching will happen to utilize the KEXEC_CORE code.
> ---------------------
> CONFIG_CRASH_CORE=y
> CONFIG_KEXEC_CORE=y
> CONFIG_CRASH_DUMP=y
> ---------------------
>
> In this case, what is worse, on arch sh and arm, KEXEC relies on MMU,
> while CRASH_DUMP can still be enabled when !MMU, then compiling error is
> seen as the lkp test robot reported in above link.
>
> ------arch/sh/Kconfig------
> config ARCH_SUPPORTS_KEXEC
> def_bool MMU
>
> config ARCH_SUPPORTS_CRASH_DUMP
> def_bool BROKEN_ON_SMP
> ---------------------------
>
> Changes:
> ===========
> 1, split out crash_reserve.c from crash_core.c;
> 2, split out vmcore_infoc. from crash_core.c;
> 3, move crash related codes in kexec_core.c into crash_core.c;
> 4, remove dependency of FA_DUMP on CRASH_DUMP;
> 5, clean up kdump related config items;
> 6, wrap up crash codes in crash related ifdefs on all 9 arch-es
> which support crash dumping;
>
> Achievement:
> ===========
> With above changes, I can rearrange the config item logic as below (the right
> item depends on or is selected by the left item):
>
> PROC_KCORE -----------> VMCORE_INFO
>
> |----------> VMCORE_INFO
> FA_DUMP----|
> |----------> CRASH_RESERVE

FA_DUMP also needs PROC_VMCORE (CRASH_DUMP by dependency, I guess).
So, the FA_DUMP related changes here will need a relook..


> ---->VMCORE_INFO
> /
> |---->CRASH_RESERVE
> KEXEC --| /|
> |--> KEXEC_CORE--> CRASH_DUMP-->/-|---->PROC_VMCORE
> KEXEC_FILE --| \ |
> \---->CRASH_HOTPLUG
>
>
> KEXEC --|
> |--> KEXEC_CORE (for kexec reboot only)
> KEXEC_FILE --|
>
> Test
> ========
> On all 8 architectures, including x86_64, arm64, s390x, sh, arm, mips,
> riscv, loongarch, I did below three cases of config item setting and
> building all passed. Let me take configs on x86_64 as exampmle here:
>
> (1) Both CONFIG_KEXEC and KEXEC_FILE is unset, then all kexec/kdump
> items are unset automatically:
> # Kexec and crash features
> # CONFIG_KEXEC is not set
> # CONFIG_KEXEC_FILE is not set
> # end of Kexec and crash features
>
> (2) set CONFIG_KEXEC_FILE and 'make olddefconfig':
> ---------------
> # Kexec and crash features
> CONFIG_CRASH_RESERVE=y
> CONFIG_VMCORE_INFO=y
> CONFIG_KEXEC_CORE=y
> CONFIG_KEXEC_FILE=y
> CONFIG_CRASH_DUMP=y
> CONFIG_CRASH_HOTPLUG=y
> CONFIG_CRASH_MAX_MEMORY_RANGES=8192
> # end of Kexec and crash features
> ---------------
>
> (3) unset CONFIG_CRASH_DUMP in case 2 and execute 'make olddefconfig':
> ------------------------
> # Kexec and crash features
> CONFIG_KEXEC_CORE=y
> CONFIG_KEXEC_FILE=y
> # end of Kexec and crash features
> ------------------------
>
> Note:
> For ppc, it needs investigation to make clear how to split out crash
> code in arch folder.

On powerpc, both kdump and fadump need PROC_VMCORE & CRASH_DUMP.
Hope that clears things. So, patch 3/14 breaks things for FA_DUMP..

> Hope Hari and Pingfan can help have a look, see if
> it's doable. Now, I make it either have both kexec and crash enabled, or
> disable both of them altogether.


Sure. I will take a closer look...

Thanks
Hari

2024-02-04 03:26:31

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

On 02/02/24 at 10:53am, Hari Bathini wrote:
> Hi Baoquan,
>
> On 19/01/24 8:22 pm, Baoquan He wrote:
> > Motivation:
> > =============
> > Previously, LKP reported a building error. When investigating, it can't
> > be resolved reasonablly with the present messy kdump config items.
> >
> > https://lore.kernel.org/oe-kbuild-all/[email protected]/
> >
> > The kdump (crash dumping) related config items could causes confusions:
> >
> > Firstly,
> > ---
> > CRASH_CORE enables codes including
> > - crashkernel reservation;
> > - elfcorehdr updating;
> > - vmcoreinfo exporting;
> > - crash hotplug handling;
> >
> > Now fadump of powerpc, kcore dynamic debugging and kdump all selects
> > CRASH_CORE, while fadump
> > - fadump needs crashkernel parsing, vmcoreinfo exporting, and accessing
> > global variable 'elfcorehdr_addr';
> > - kcore only needs vmcoreinfo exporting;
> > - kdump needs all of the current kernel/crash_core.c.
> >
> > So only enabling PROC_CORE or FA_DUMP will enable CRASH_CORE, this
> > mislead people that we enable crash dumping, actual it's not.
> >
> > Secondly,
> > ---
> > It's not reasonable to allow KEXEC_CORE select CRASH_CORE.
> >
> > Because KEXEC_CORE enables codes which allocate control pages, copy
> > kexec/kdump segments, and prepare for switching. These codes are
> > shared by both kexec reboot and kdump. We could want kexec reboot,
> > but disable kdump. In that case, CRASH_CORE should not be selected.
> >
> > --------------------
> > CONFIG_CRASH_CORE=y
> > CONFIG_KEXEC_CORE=y
> > CONFIG_KEXEC=y
> > CONFIG_KEXEC_FILE=y
> > ---------------------
> >
> > Thirdly,
> > ---
> > It's not reasonable to allow CRASH_DUMP select KEXEC_CORE.
> >
> > That could make KEXEC_CORE, CRASH_DUMP are enabled independently from
> > KEXEC or KEXEC_FILE. However, w/o KEXEC or KEXEC_FILE, the KEXEC_CORE
> > code built in doesn't make any sense because no kernel loading or
> > switching will happen to utilize the KEXEC_CORE code.
> > ---------------------
> > CONFIG_CRASH_CORE=y
> > CONFIG_KEXEC_CORE=y
> > CONFIG_CRASH_DUMP=y
> > ---------------------
> >
> > In this case, what is worse, on arch sh and arm, KEXEC relies on MMU,
> > while CRASH_DUMP can still be enabled when !MMU, then compiling error is
> > seen as the lkp test robot reported in above link.
> >
> > ------arch/sh/Kconfig------
> > config ARCH_SUPPORTS_KEXEC
> > def_bool MMU
> >
> > config ARCH_SUPPORTS_CRASH_DUMP
> > def_bool BROKEN_ON_SMP
> > ---------------------------
> >
> > Changes:
> > ===========
> > 1, split out crash_reserve.c from crash_core.c;
> > 2, split out vmcore_infoc. from crash_core.c;
> > 3, move crash related codes in kexec_core.c into crash_core.c;
> > 4, remove dependency of FA_DUMP on CRASH_DUMP;
> > 5, clean up kdump related config items;
> > 6, wrap up crash codes in crash related ifdefs on all 9 arch-es
> > which support crash dumping;
> >
> > Achievement:
> > ===========
> > With above changes, I can rearrange the config item logic as below (the right
> > item depends on or is selected by the left item):
> >
> > PROC_KCORE -----------> VMCORE_INFO
> >
> > |----------> VMCORE_INFO
> > FA_DUMP----|
> > |----------> CRASH_RESERVE
>
> FA_DUMP also needs PROC_VMCORE (CRASH_DUMP by dependency, I guess).
> So, the FA_DUMP related changes here will need a relook..

Thanks for checking this.

So FA_DUMP needs vmcoreinfo exporting, crashkernel reservation,
/proc/vmcore. Then it's easy to adjust the kernel config item of FA_DUMP
to make it select CRASH_DUMP. Except of this, do you have concern about
the current code and Kconfig refactorying?


---->VMCORE_INFO
/|
FA_DUMP--> CRASH_DUMP-->/-|---->CRASH_RESERVE
\ |
\---->PROC_VMCORE


>
>
> > ---->VMCORE_INFO
> > /
> > |---->CRASH_RESERVE
> > KEXEC --| /|
> > |--> KEXEC_CORE--> CRASH_DUMP-->/-|---->PROC_VMCORE
> > KEXEC_FILE --| \ |
> > \---->CRASH_HOTPLUG
> >
> >
> > KEXEC --|
> > |--> KEXEC_CORE (for kexec reboot only)
> > KEXEC_FILE --|
> >
> > Test
> > ========
> > On all 8 architectures, including x86_64, arm64, s390x, sh, arm, mips,
> > riscv, loongarch, I did below three cases of config item setting and
> > building all passed. Let me take configs on x86_64 as exampmle here:
> >
> > (1) Both CONFIG_KEXEC and KEXEC_FILE is unset, then all kexec/kdump
> > items are unset automatically:
> > # Kexec and crash features
> > # CONFIG_KEXEC is not set
> > # CONFIG_KEXEC_FILE is not set
> > # end of Kexec and crash features
> >
> > (2) set CONFIG_KEXEC_FILE and 'make olddefconfig':
> > ---------------
> > # Kexec and crash features
> > CONFIG_CRASH_RESERVE=y
> > CONFIG_VMCORE_INFO=y
> > CONFIG_KEXEC_CORE=y
> > CONFIG_KEXEC_FILE=y
> > CONFIG_CRASH_DUMP=y
> > CONFIG_CRASH_HOTPLUG=y
> > CONFIG_CRASH_MAX_MEMORY_RANGES=8192
> > # end of Kexec and crash features
> > ---------------
> >
> > (3) unset CONFIG_CRASH_DUMP in case 2 and execute 'make olddefconfig':
> > ------------------------
> > # Kexec and crash features
> > CONFIG_KEXEC_CORE=y
> > CONFIG_KEXEC_FILE=y
> > # end of Kexec and crash features
> > ------------------------
> >
> > Note:
> > For ppc, it needs investigation to make clear how to split out crash
> > code in arch folder.
>
> On powerpc, both kdump and fadump need PROC_VMCORE & CRASH_DUMP.
> Hope that clears things. So, patch 3/14 breaks things for FA_DUMP..

I see it now. We can easily fix that with below patch. What do you
think?

By the way, do you have chance to help test these on powerpc system?
I can find ppc64le machine, while I don't know how to operate to test
fadump.

From fa8e6c3930d4f22f2b3768399c5bf0523c17adde Mon Sep 17 00:00:00 2001
From: Baoquan He <[email protected]>
Date: Sun, 4 Feb 2024 11:06:54 +0800
Subject: [PATCH] power/fadump: make FA_DUMP select CRASH_DUMP
Content-type: text/plain

FA_DUMP which is similar with kdump needs vmcoreinfo exporting,
crashkernel reservation and /proc/vmcore file . After refactoring crash
related codes and Kconfig items, make FA_DUMP select CRASH_DUMP. Now
the dependency layout is like below:

---->VMCORE_INFO
/|
FA_DUMP--> CRASH_DUMP-->/-|---->CRASH_RESERVE
\ |
\---->PROC_VMCORE

Signed-off-by: Baoquan He <[email protected]>
---
arch/powerpc/Kconfig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f182fb354bef..d5d4c890f010 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -695,8 +695,7 @@ config ARCH_SELECTS_CRASH_DUMP
config FA_DUMP
bool "Firmware-assisted dump"
depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
- select VMCORE_INFO
- select CRASH_RESERVE
+ select CRASH_DUMP
help
A robust mechanism to get reliable kernel crash dump with
assistance from firmware. This approach does not use kexec,
--
2.41.0


>
> > Hope Hari and Pingfan can help have a look, see if
> > it's doable. Now, I make it either have both kexec and crash enabled, or
> > disable both of them altogether.
>
>
> Sure. I will take a closer look...

Thanks a lot. Please feel free to post patches to make that, or I can do
it with your support or suggestion.


2024-02-21 05:47:35

by Hari Bathini

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

Hi Baoquan,

On 04/02/24 8:56 am, Baoquan He wrote:
>>> Hope Hari and Pingfan can help have a look, see if
>>> it's doable. Now, I make it either have both kexec and crash enabled, or
>>> disable both of them altogether.
>>
>> Sure. I will take a closer look...
> Thanks a lot. Please feel free to post patches to make that, or I can do
> it with your support or suggestion.

Tested your changes and on top of these changes, came up with the below
changes to get it working for powerpc:


https://lore.kernel.org/all/[email protected]/

Please take a look.

Thanks
Hari

2024-02-21 13:44:21

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

On 02/21/24 at 11:15am, Hari Bathini wrote:
> Hi Baoquan,
>
> On 04/02/24 8:56 am, Baoquan He wrote:
> > > > Hope Hari and Pingfan can help have a look, see if
> > > > it's doable. Now, I make it either have both kexec and crash enabled, or
> > > > disable both of them altogether.
> > >
> > > Sure. I will take a closer look...
> > Thanks a lot. Please feel free to post patches to make that, or I can do
> > it with your support or suggestion.
>
> Tested your changes and on top of these changes, came up with the below
> changes to get it working for powerpc:
>
>
> https://lore.kernel.org/all/[email protected]/
>
> Please take a look.

I added a comment to the patch 1 consulting if the "struct crash_mem" is
appropriate to cover other cases except of kdump memory regions. I am
wondering if its name need be adjusted, or other kind of memory you
mentioned can use other structures or create a new one.

If it's has to be done like that, it's fine.


2024-02-21 17:30:42

by Sourabh Jain

[permalink] [raw]
Subject: Re: [PATCH v2 01/14] kexec: split crashkernel reservation code out from crash_core.c

Hello Baoquan,

Thank you for reorganizing the kexec and kdump code with a well-defined
configuration structure.

While reviewing the patch series, I noticed a few typos.

On 19/01/24 20:22, Baoquan He wrote:
> Both kdump and fa_dump of ppc rely on crashkernel reservation. Move the
> relevant codes into separate files:
> crash_reserve.c, include/linux/crash_reserve.h.
>
> And also add config item CRASH_RESERVE to control its enabling of the
> codes. And update config items which has relationship with crashkernel
> reservation.
>
> And also change ifdeffery from CONFIG_CRASH_CORE to CONFIG_CRASH_RESERVE
> when those scopes are only crashkernel reservation related.
>
> And also rename arch/XXX/include/asm/{crash_core.h => crash_reserve.h}
> on arm64, x86 and risc-v because those architectures' crash_core.h
> is only related to crashkernel reservation.
>
> Signed-off-by: Baoquan He <[email protected]>
> ---
> arch/arm64/Kconfig | 2 +-
> .../asm/{crash_core.h => crash_reserve.h} | 4 +-
> arch/powerpc/Kconfig | 1 +
> arch/powerpc/mm/nohash/kaslr_booke.c | 4 +-
> arch/riscv/Kconfig | 2 +-
> .../asm/{crash_core.h => crash_reserve.h} | 4 +-
> arch/x86/Kconfig | 2 +-
> .../asm/{crash_core.h => crash_reserve.h} | 6 +-
> include/linux/crash_core.h | 40 --
> include/linux/crash_reserve.h | 48 ++
> include/linux/kexec.h | 1 +
> kernel/Kconfig.kexec | 5 +-
> kernel/Makefile | 1 +
> kernel/crash_core.c | 438 -----------------
> kernel/crash_reserve.c | 464 ++++++++++++++++++
> 15 files changed, 531 insertions(+), 491 deletions(-)
> rename arch/arm64/include/asm/{crash_core.h => crash_reserve.h} (81%)
> rename arch/riscv/include/asm/{crash_core.h => crash_reserve.h} (78%)
> rename arch/x86/include/asm/{crash_core.h => crash_reserve.h} (92%)
> create mode 100644 include/linux/crash_reserve.h
> create mode 100644 kernel/crash_reserve.c
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index ea01a2c43efa..d96bc3c67ec6 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1501,7 +1501,7 @@ config ARCH_SUPPORTS_CRASH_DUMP
> def_bool y
>
> config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
> - def_bool CRASH_CORE
> + def_bool CRASH_RESERVE
>
> config TRANS_TABLE
> def_bool y
> diff --git a/arch/arm64/include/asm/crash_core.h b/arch/arm64/include/asm/crash_reserve.h
> similarity index 81%
> rename from arch/arm64/include/asm/crash_core.h
> rename to arch/arm64/include/asm/crash_reserve.h
> index 9f5c8d339f44..4afe027a4e7b 100644
> --- a/arch/arm64/include/asm/crash_core.h
> +++ b/arch/arm64/include/asm/crash_reserve.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> -#ifndef _ARM64_CRASH_CORE_H
> -#define _ARM64_CRASH_CORE_H
> +#ifndef _ARM64_CRASH_RESERVE_H
> +#define _ARM64_CRASH_RESERVE_H
>
> /* Current arm64 boot protocol requires 2MB alignment */
> #define CRASH_ALIGN SZ_2M
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 414b978b8010..6aeab95f0edd 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -691,6 +691,7 @@ config FA_DUMP
> bool "Firmware-assisted dump"
> depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
> select CRASH_CORE
> + select CRASH_RESERVE
> select CRASH_DUMP
> help
> A robust mechanism to get reliable kernel crash dump with
> diff --git a/arch/powerpc/mm/nohash/kaslr_booke.c b/arch/powerpc/mm/nohash/kaslr_booke.c
> index b4f2786a7d2b..cdff129abb14 100644
> --- a/arch/powerpc/mm/nohash/kaslr_booke.c
> +++ b/arch/powerpc/mm/nohash/kaslr_booke.c
> @@ -13,7 +13,7 @@
> #include <linux/delay.h>
> #include <linux/memblock.h>
> #include <linux/libfdt.h>
> -#include <linux/crash_core.h>
> +#include <linux/crash_reserve.h>
> #include <linux/of.h>
> #include <linux/of_fdt.h>
> #include <asm/cacheflush.h>
> @@ -173,7 +173,7 @@ static __init bool overlaps_region(const void *fdt, u32 start,
>
> static void __init get_crash_kernel(void *fdt, unsigned long size)
> {
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_CRASH_RESERVE
> unsigned long long crash_size, crash_base;
> int ret;
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index b549499eb363..37a438c23deb 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -712,7 +712,7 @@ config ARCH_SUPPORTS_CRASH_DUMP
> def_bool y
>
> config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
> - def_bool CRASH_CORE
> + def_bool CRASH_RESERVE
>
> config COMPAT
> bool "Kernel support for 32-bit U-mode"
> diff --git a/arch/riscv/include/asm/crash_core.h b/arch/riscv/include/asm/crash_reserve.h
> similarity index 78%
> rename from arch/riscv/include/asm/crash_core.h
> rename to arch/riscv/include/asm/crash_reserve.h
> index e1874b23feaf..013962e63587 100644
> --- a/arch/riscv/include/asm/crash_core.h
> +++ b/arch/riscv/include/asm/crash_reserve.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> -#ifndef _RISCV_CRASH_CORE_H
> -#define _RISCV_CRASH_CORE_H
> +#ifndef _RISCV_CRASH_RESERVE_H
> +#define _RISCV_CRASH_RESERVE_H
>
> #define CRASH_ALIGN PMD_SIZE
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 5edec175b9bf..71417c5b228c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2106,7 +2106,7 @@ config ARCH_SUPPORTS_CRASH_HOTPLUG
> def_bool y
>
> config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
> - def_bool CRASH_CORE
> + def_bool CRASH_RESEERVE

%s/CRASH_RESEERVE/CRASH_RESERVE? - Sourabh

2024-02-21 17:38:47

by Sourabh Jain

[permalink] [raw]
Subject: Re: [PATCH v2 02/14] crash: split vmcoreinfo exporting code out from crash_core.c

Hello Baoquan,

On 19/01/24 20:22, Baoquan He wrote:
> Now move the relevant codes into separate files:
> kernel/crash_reserve.c, include/linux/crash_reserve.h.
>
> And add config item CRASH_RESERVE to control its enabling.

Feels like this patch is more about vmcore_info.[c|h] and CONFIG_VMCORE_INFO
then the above mentioned files and config.

- Sourabh

>
> And also update the old ifdeffery of CONFIG_CRASH_CORE, including of
> <linux/crash_core.h> and config item dependency on CRASH_CORE
> accordingly.
>
> And also do renaming as follows:
> - arch/xxx/kernel/{crash_core.c => vmcore_info.c}
> because they are only related to vmcoreinfo exporting on x86, arm64,
> riscv.
>
> And also Remove config item CRASH_CORE, and rely on CONFIG_KEXEC_CORE to
> decide if build in crash_core.c.
>
> Signed-off-by: Baoquan He <[email protected]>
> ---
> arch/arm64/kernel/Makefile | 2 +-
> .../kernel/{crash_core.c => vmcore_info.c} | 2 +-
> arch/powerpc/Kconfig | 2 +-
> arch/powerpc/kernel/setup-common.c | 2 +-
> arch/powerpc/platforms/powernv/opal-core.c | 2 +-
> arch/riscv/kernel/Makefile | 2 +-
> .../kernel/{crash_core.c => vmcore_info.c} | 2 +-
> arch/x86/kernel/Makefile | 2 +-
> .../{crash_core_32.c => vmcore_info_32.c} | 2 +-
> .../{crash_core_64.c => vmcore_info_64.c} | 2 +-
> drivers/firmware/qemu_fw_cfg.c | 14 +-
> fs/proc/Kconfig | 2 +-
> fs/proc/kcore.c | 2 +-
> include/linux/buildid.h | 2 +-
> include/linux/crash_core.h | 73 ------
> include/linux/kexec.h | 1 +
> include/linux/vmcore_info.h | 81 ++++++
> kernel/Kconfig.kexec | 4 +-
> kernel/Makefile | 4 +-
> kernel/crash_core.c | 208 ----------------
> kernel/ksysfs.c | 6 +-
> kernel/printk/printk.c | 4 +-
> kernel/vmcore_info.c | 233 ++++++++++++++++++
> lib/buildid.c | 2 +-
> 24 files changed, 345 insertions(+), 311 deletions(-)
> rename arch/arm64/kernel/{crash_core.c => vmcore_info.c} (97%)
> rename arch/riscv/kernel/{crash_core.c => vmcore_info.c} (96%)
> rename arch/x86/kernel/{crash_core_32.c => vmcore_info_32.c} (90%)
> rename arch/x86/kernel/{crash_core_64.c => vmcore_info_64.c} (94%)
> create mode 100644 include/linux/vmcore_info.h
> create mode 100644 kernel/vmcore_info.c
>
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index d95b3d6b471a..bcf89587a549 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -66,7 +66,7 @@ obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
> obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
> arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
> obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
> -obj-$(CONFIG_CRASH_CORE) += crash_core.o
> +obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
> obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
> obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
> obj-$(CONFIG_ARM64_MTE) += mte.o
> diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/vmcore_info.c
> similarity index 97%
> rename from arch/arm64/kernel/crash_core.c
> rename to arch/arm64/kernel/vmcore_info.c
> index 66cde752cd74..a5abf7186922 100644
> --- a/arch/arm64/kernel/crash_core.c
> +++ b/arch/arm64/kernel/vmcore_info.c
> @@ -4,7 +4,7 @@
> * Copyright (C) Huawei Futurewei Technologies.
> */
>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
> #include <asm/cpufeature.h>
> #include <asm/memory.h>
> #include <asm/pgtable-hwdef.h>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 6aeab95f0edd..1520146d7c2c 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -690,7 +690,7 @@ config ARCH_SELECTS_CRASH_DUMP
> config FA_DUMP
> bool "Firmware-assisted dump"
> depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
> - select CRASH_CORE
> + select VMCORE_INFO
> select CRASH_RESERVE
> select CRASH_DUMP
> help
> diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
> index 9b142b9d5187..733f210ffda1 100644
> --- a/arch/powerpc/kernel/setup-common.c
> +++ b/arch/powerpc/kernel/setup-common.c
> @@ -109,7 +109,7 @@ int ppc_do_canonicalize_irqs;
> EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
> #endif
>
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
> /* This keeps a track of which one is the crashing cpu. */
> int crashing_cpu = -1;
> #endif
> diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
> index bb7657115f1d..c9a9b759cc92 100644
> --- a/arch/powerpc/platforms/powernv/opal-core.c
> +++ b/arch/powerpc/platforms/powernv/opal-core.c
> @@ -16,7 +16,7 @@
> #include <linux/kobject.h>
> #include <linux/sysfs.h>
> #include <linux/slab.h>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
> #include <linux/of.h>
>
> #include <asm/page.h>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index c92c623b311e..63a36539ea1a 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -91,7 +91,7 @@ obj-$(CONFIG_KGDB) += kgdb.o
> obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o
> obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o
> obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
> -obj-$(CONFIG_CRASH_CORE) += crash_core.o
> +obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
>
> obj-$(CONFIG_JUMP_LABEL) += jump_label.o
>
> diff --git a/arch/riscv/kernel/crash_core.c b/arch/riscv/kernel/vmcore_info.c
> similarity index 96%
> rename from arch/riscv/kernel/crash_core.c
> rename to arch/riscv/kernel/vmcore_info.c
> index 8706736fd4e2..e8ad57a60a2f 100644
> --- a/arch/riscv/kernel/crash_core.c
> +++ b/arch/riscv/kernel/vmcore_info.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
> #include <linux/pagemap.h>
>
> void arch_crash_save_vmcoreinfo(void)
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index 0000325ab98f..913d4022131e 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -98,7 +98,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
> obj-$(CONFIG_X86_TSC) += trace_clock.o
> obj-$(CONFIG_TRACING) += trace.o
> obj-$(CONFIG_RETHOOK) += rethook.o
> -obj-$(CONFIG_CRASH_CORE) += crash_core_$(BITS).o
> +obj-$(CONFIG_VMCORE_INFO) += vmcore_info_$(BITS).o
> obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o
> obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o
> obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o
> diff --git a/arch/x86/kernel/crash_core_32.c b/arch/x86/kernel/vmcore_info_32.c
> similarity index 90%
> rename from arch/x86/kernel/crash_core_32.c
> rename to arch/x86/kernel/vmcore_info_32.c
> index 8a89c109e20a..5995a749288a 100644
> --- a/arch/x86/kernel/crash_core_32.c
> +++ b/arch/x86/kernel/vmcore_info_32.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
> #include <linux/pgtable.h>
>
> #include <asm/setup.h>
> diff --git a/arch/x86/kernel/crash_core_64.c b/arch/x86/kernel/vmcore_info_64.c
> similarity index 94%
> rename from arch/x86/kernel/crash_core_64.c
> rename to arch/x86/kernel/vmcore_info_64.c
> index 7d255f882afe..0dec7d868754 100644
> --- a/arch/x86/kernel/crash_core_64.c
> +++ b/arch/x86/kernel/vmcore_info_64.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
> #include <linux/pgtable.h>
>
> #include <asm/setup.h>
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index 03da9a4354f8..5f43dfa22f79 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -37,7 +37,7 @@
> #include <uapi/linux/qemu_fw_cfg.h>
> #include <linux/delay.h>
> #include <linux/crash_dump.h>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>
> MODULE_AUTHOR("Gabriel L. Somlo <[email protected]>");
> MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> @@ -67,7 +67,7 @@ static void fw_cfg_sel_endianness(u16 key)
> iowrite16(key, fw_cfg_reg_ctrl);
> }
>
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
> static inline bool fw_cfg_dma_enabled(void)
> {
> return (fw_cfg_rev & FW_CFG_VERSION_DMA) && fw_cfg_reg_dma;
> @@ -156,7 +156,7 @@ static ssize_t fw_cfg_read_blob(u16 key,
> return count;
> }
>
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
> /* write chunk of given fw_cfg blob (caller responsible for sanity-check) */
> static ssize_t fw_cfg_write_blob(u16 key,
> void *buf, loff_t pos, size_t count)
> @@ -195,7 +195,7 @@ static ssize_t fw_cfg_write_blob(u16 key,
>
> return ret;
> }
> -#endif /* CONFIG_CRASH_CORE */
> +#endif /* CONFIG_VMCORE_INFO */
>
> /* clean up fw_cfg device i/o */
> static void fw_cfg_io_cleanup(void)
> @@ -319,7 +319,7 @@ struct fw_cfg_sysfs_entry {
> struct list_head list;
> };
>
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
> static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
> {
> static struct fw_cfg_vmcoreinfo *data;
> @@ -343,7 +343,7 @@ static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
> kfree(data);
> return ret;
> }
> -#endif /* CONFIG_CRASH_CORE */
> +#endif /* CONFIG_VMCORE_INFO */
>
> /* get fw_cfg_sysfs_entry from kobject member */
> static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj)
> @@ -583,7 +583,7 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)
> int err;
> struct fw_cfg_sysfs_entry *entry;
>
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
> if (fw_cfg_dma_enabled() &&
> strcmp(f->name, FW_CFG_VMCOREINFO_FILENAME) == 0 &&
> !is_kdump_kernel()) {
> diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
> index 32b1116ae137..d80a1431ef7b 100644
> --- a/fs/proc/Kconfig
> +++ b/fs/proc/Kconfig
> @@ -32,7 +32,7 @@ config PROC_FS
> config PROC_KCORE
> bool "/proc/kcore support" if !ARM
> depends on PROC_FS && MMU
> - select CRASH_CORE
> + select VMCORE_INFO
> help
> Provides a virtual ELF core file of the live kernel. This can
> be read with gdb and other ELF tools. No modifications can be
> diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
> index 6422e569b080..8e08a9a1b7ed 100644
> --- a/fs/proc/kcore.c
> +++ b/fs/proc/kcore.c
> @@ -10,7 +10,7 @@
> * Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <[email protected]>
> */
>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
> #include <linux/mm.h>
> #include <linux/proc_fs.h>
> #include <linux/kcore.h>
> diff --git a/include/linux/buildid.h b/include/linux/buildid.h
> index 8a582d242f06..20aa3c2d89f7 100644
> --- a/include/linux/buildid.h
> +++ b/include/linux/buildid.h
> @@ -11,7 +11,7 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
> __u32 *size);
> int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size);
>
> -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
> +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
> extern unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX];
> void init_vmlinux_build_id(void);
> #else
> diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
> index 1fde49246fa6..7f19f62018ef 100644
> --- a/include/linux/crash_core.h
> +++ b/include/linux/crash_core.h
> @@ -6,79 +6,6 @@
> #include <linux/elfcore.h>
> #include <linux/elf.h>
>
> -#define CRASH_CORE_NOTE_NAME "CORE"
> -#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
> -#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
> -#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
> -
> -/*
> - * The per-cpu notes area is a list of notes terminated by a "NULL"
> - * note header. For kdump, the code in vmcore.c runs in the context
> - * of the second kernel to combine them into one note.
> - */
> -#define CRASH_CORE_NOTE_BYTES ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
> - CRASH_CORE_NOTE_NAME_BYTES + \
> - CRASH_CORE_NOTE_DESC_BYTES)
> -
> -#define VMCOREINFO_BYTES PAGE_SIZE
> -#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
> -#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
> -#define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
> - VMCOREINFO_NOTE_NAME_BYTES + \
> - VMCOREINFO_BYTES)
> -
> -typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
> -/* Per cpu memory for storing cpu states in case of system crash. */
> -extern note_buf_t __percpu *crash_notes;
> -
> -void crash_update_vmcoreinfo_safecopy(void *ptr);
> -void crash_save_vmcoreinfo(void);
> -void arch_crash_save_vmcoreinfo(void);
> -__printf(1, 2)
> -void vmcoreinfo_append_str(const char *fmt, ...);
> -phys_addr_t paddr_vmcoreinfo_note(void);
> -
> -#define VMCOREINFO_OSRELEASE(value) \
> - vmcoreinfo_append_str("OSRELEASE=%s\n", value)
> -#define VMCOREINFO_BUILD_ID() \
> - ({ \
> - static_assert(sizeof(vmlinux_build_id) == 20); \
> - vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
> - })
> -
> -#define VMCOREINFO_PAGESIZE(value) \
> - vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
> -#define VMCOREINFO_SYMBOL(name) \
> - vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
> -#define VMCOREINFO_SYMBOL_ARRAY(name) \
> - vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
> -#define VMCOREINFO_SIZE(name) \
> - vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> - (unsigned long)sizeof(name))
> -#define VMCOREINFO_STRUCT_SIZE(name) \
> - vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> - (unsigned long)sizeof(struct name))
> -#define VMCOREINFO_OFFSET(name, field) \
> - vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> - (unsigned long)offsetof(struct name, field))
> -#define VMCOREINFO_TYPE_OFFSET(name, field) \
> - vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> - (unsigned long)offsetof(name, field))
> -#define VMCOREINFO_LENGTH(name, value) \
> - vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
> -#define VMCOREINFO_NUMBER(name) \
> - vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
> -#define VMCOREINFO_CONFIG(name) \
> - vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
> -
> -extern unsigned char *vmcoreinfo_data;
> -extern size_t vmcoreinfo_size;
> -extern u32 *vmcoreinfo_note;
> -
> -Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> - void *data, size_t data_len);
> -void final_note(Elf_Word *buf);
> -
> /* Alignment required for elf header segment */
> #define ELF_CORE_HEADER_ALIGN 4096
>
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index 6d79bfb52e5b..9c7bb8b56ed6 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -16,6 +16,7 @@
> #if !defined(__ASSEMBLY__)
>
> #include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
> #include <linux/crash_reserve.h>
> #include <asm/io.h>
> #include <linux/range.h>
> diff --git a/include/linux/vmcore_info.h b/include/linux/vmcore_info.h
> new file mode 100644
> index 000000000000..e1dec1a6a749
> --- /dev/null
> +++ b/include/linux/vmcore_info.h
> @@ -0,0 +1,81 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef LINUX_VMCORE_INFO_H
> +#define LINUX_VMCORE_INFO_H
> +
> +#include <linux/linkage.h>
> +#include <linux/elfcore.h>
> +#include <linux/elf.h>
> +
> +#define CRASH_CORE_NOTE_NAME "CORE"
> +#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
> +#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
> +#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
> +
> +/*
> + * The per-cpu notes area is a list of notes terminated by a "NULL"
> + * note header. For kdump, the code in vmcore.c runs in the context
> + * of the second kernel to combine them into one note.
> + */
> +#define CRASH_CORE_NOTE_BYTES ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
> + CRASH_CORE_NOTE_NAME_BYTES + \
> + CRASH_CORE_NOTE_DESC_BYTES)
> +
> +#define VMCOREINFO_BYTES PAGE_SIZE
> +#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
> +#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
> +#define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
> + VMCOREINFO_NOTE_NAME_BYTES + \
> + VMCOREINFO_BYTES)
> +
> +typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
> +/* Per cpu memory for storing cpu states in case of system crash. */
> +extern note_buf_t __percpu *crash_notes;
> +
> +void crash_update_vmcoreinfo_safecopy(void *ptr);
> +void crash_save_vmcoreinfo(void);
> +void arch_crash_save_vmcoreinfo(void);
> +__printf(1, 2)
> +void vmcoreinfo_append_str(const char *fmt, ...);
> +phys_addr_t paddr_vmcoreinfo_note(void);
> +
> +#define VMCOREINFO_OSRELEASE(value) \
> + vmcoreinfo_append_str("OSRELEASE=%s\n", value)
> +#define VMCOREINFO_BUILD_ID() \
> + ({ \
> + static_assert(sizeof(vmlinux_build_id) == 20); \
> + vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
> + })
> +
> +#define VMCOREINFO_PAGESIZE(value) \
> + vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
> +#define VMCOREINFO_SYMBOL(name) \
> + vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
> +#define VMCOREINFO_SYMBOL_ARRAY(name) \
> + vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
> +#define VMCOREINFO_SIZE(name) \
> + vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> + (unsigned long)sizeof(name))
> +#define VMCOREINFO_STRUCT_SIZE(name) \
> + vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> + (unsigned long)sizeof(struct name))
> +#define VMCOREINFO_OFFSET(name, field) \
> + vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> + (unsigned long)offsetof(struct name, field))
> +#define VMCOREINFO_TYPE_OFFSET(name, field) \
> + vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> + (unsigned long)offsetof(name, field))
> +#define VMCOREINFO_LENGTH(name, value) \
> + vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
> +#define VMCOREINFO_NUMBER(name) \
> + vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
> +#define VMCOREINFO_CONFIG(name) \
> + vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
> +
> +extern unsigned char *vmcoreinfo_data;
> +extern size_t vmcoreinfo_size;
> +extern u32 *vmcoreinfo_note;
> +
> +Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> + void *data, size_t data_len);
> +void final_note(Elf_Word *buf);
> +#endif /* LINUX_VMCORE_INFO_H */
> diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> index 8b7be71edd85..8faf27043432 100644
> --- a/kernel/Kconfig.kexec
> +++ b/kernel/Kconfig.kexec
> @@ -5,11 +5,11 @@ menu "Kexec and crash features"
> config CRASH_RESERVE
> bool
>
> -config CRASH_CORE
> +config VMCORE_INFO
> bool
>
> config KEXEC_CORE
> - select CRASH_CORE
> + select VMCORE_INFO
> select CRASH_RESERVE
> bool
>
> diff --git a/kernel/Makefile b/kernel/Makefile
> index 05fa88b3ab74..649272a1d6b9 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -68,9 +68,9 @@ obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
> obj-$(CONFIG_KALLSYMS) += kallsyms.o
> obj-$(CONFIG_KALLSYMS_SELFTEST) += kallsyms_selftest.o
> obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
> -obj-$(CONFIG_CRASH_CORE) += crash_core.o
> +obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
> obj-$(CONFIG_CRASH_RESERVE) += crash_reserve.o
> -obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
> +obj-$(CONFIG_KEXEC_CORE) += kexec_core.o crash_core.o
> obj-$(CONFIG_KEXEC) += kexec.o
> obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
> obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 055859c62f19..2f4df1fe6f7a 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -26,14 +26,6 @@
> /* Per cpu memory for storing cpu states in case of system crash. */
> note_buf_t __percpu *crash_notes;
>
> -/* vmcoreinfo stuff */
> -unsigned char *vmcoreinfo_data;
> -size_t vmcoreinfo_size;
> -u32 *vmcoreinfo_note;
> -
> -/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
> -static unsigned char *vmcoreinfo_data_safecopy;
> -
> int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
> void **addr, unsigned long *sz)
> {
> @@ -195,206 +187,6 @@ int crash_exclude_mem_range(struct crash_mem *mem,
> return 0;
> }
>
> -Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> - void *data, size_t data_len)
> -{
> - struct elf_note *note = (struct elf_note *)buf;
> -
> - note->n_namesz = strlen(name) + 1;
> - note->n_descsz = data_len;
> - note->n_type = type;
> - buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> - memcpy(buf, name, note->n_namesz);
> - buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
> - memcpy(buf, data, data_len);
> - buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
> -
> - return buf;
> -}
> -
> -void final_note(Elf_Word *buf)
> -{
> - memset(buf, 0, sizeof(struct elf_note));
> -}
> -
> -static void update_vmcoreinfo_note(void)
> -{
> - u32 *buf = vmcoreinfo_note;
> -
> - if (!vmcoreinfo_size)
> - return;
> - buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> - vmcoreinfo_size);
> - final_note(buf);
> -}
> -
> -void crash_update_vmcoreinfo_safecopy(void *ptr)
> -{
> - if (ptr)
> - memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
> -
> - vmcoreinfo_data_safecopy = ptr;
> -}
> -
> -void crash_save_vmcoreinfo(void)
> -{
> - if (!vmcoreinfo_note)
> - return;
> -
> - /* Use the safe copy to generate vmcoreinfo note if have */
> - if (vmcoreinfo_data_safecopy)
> - vmcoreinfo_data = vmcoreinfo_data_safecopy;
> -
> - vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
> - update_vmcoreinfo_note();
> -}
> -
> -void vmcoreinfo_append_str(const char *fmt, ...)
> -{
> - va_list args;
> - char buf[0x50];
> - size_t r;
> -
> - va_start(args, fmt);
> - r = vscnprintf(buf, sizeof(buf), fmt, args);
> - va_end(args);
> -
> - r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
> -
> - memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
> -
> - vmcoreinfo_size += r;
> -
> - WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
> - "vmcoreinfo data exceeds allocated size, truncating");
> -}
> -
> -/*
> - * provide an empty default implementation here -- architecture
> - * code may override this
> - */
> -void __weak arch_crash_save_vmcoreinfo(void)
> -{}
> -
> -phys_addr_t __weak paddr_vmcoreinfo_note(void)
> -{
> - return __pa(vmcoreinfo_note);
> -}
> -EXPORT_SYMBOL(paddr_vmcoreinfo_note);
> -
> -static int __init crash_save_vmcoreinfo_init(void)
> -{
> - vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
> - if (!vmcoreinfo_data) {
> - pr_warn("Memory allocation for vmcoreinfo_data failed\n");
> - return -ENOMEM;
> - }
> -
> - vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
> - GFP_KERNEL | __GFP_ZERO);
> - if (!vmcoreinfo_note) {
> - free_page((unsigned long)vmcoreinfo_data);
> - vmcoreinfo_data = NULL;
> - pr_warn("Memory allocation for vmcoreinfo_note failed\n");
> - return -ENOMEM;
> - }
> -
> - VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
> - VMCOREINFO_BUILD_ID();
> - VMCOREINFO_PAGESIZE(PAGE_SIZE);
> -
> - VMCOREINFO_SYMBOL(init_uts_ns);
> - VMCOREINFO_OFFSET(uts_namespace, name);
> - VMCOREINFO_SYMBOL(node_online_map);
> -#ifdef CONFIG_MMU
> - VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
> -#endif
> - VMCOREINFO_SYMBOL(_stext);
> - VMCOREINFO_SYMBOL(vmap_area_list);
> -
> -#ifndef CONFIG_NUMA
> - VMCOREINFO_SYMBOL(mem_map);
> - VMCOREINFO_SYMBOL(contig_page_data);
> -#endif
> -#ifdef CONFIG_SPARSEMEM
> - VMCOREINFO_SYMBOL_ARRAY(mem_section);
> - VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
> - VMCOREINFO_STRUCT_SIZE(mem_section);
> - VMCOREINFO_OFFSET(mem_section, section_mem_map);
> - VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
> - VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
> -#endif
> - VMCOREINFO_STRUCT_SIZE(page);
> - VMCOREINFO_STRUCT_SIZE(pglist_data);
> - VMCOREINFO_STRUCT_SIZE(zone);
> - VMCOREINFO_STRUCT_SIZE(free_area);
> - VMCOREINFO_STRUCT_SIZE(list_head);
> - VMCOREINFO_SIZE(nodemask_t);
> - VMCOREINFO_OFFSET(page, flags);
> - VMCOREINFO_OFFSET(page, _refcount);
> - VMCOREINFO_OFFSET(page, mapping);
> - VMCOREINFO_OFFSET(page, lru);
> - VMCOREINFO_OFFSET(page, _mapcount);
> - VMCOREINFO_OFFSET(page, private);
> - VMCOREINFO_OFFSET(page, compound_head);
> - VMCOREINFO_OFFSET(pglist_data, node_zones);
> - VMCOREINFO_OFFSET(pglist_data, nr_zones);
> -#ifdef CONFIG_FLATMEM
> - VMCOREINFO_OFFSET(pglist_data, node_mem_map);
> -#endif
> - VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
> - VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
> - VMCOREINFO_OFFSET(pglist_data, node_id);
> - VMCOREINFO_OFFSET(zone, free_area);
> - VMCOREINFO_OFFSET(zone, vm_stat);
> - VMCOREINFO_OFFSET(zone, spanned_pages);
> - VMCOREINFO_OFFSET(free_area, free_list);
> - VMCOREINFO_OFFSET(list_head, next);
> - VMCOREINFO_OFFSET(list_head, prev);
> - VMCOREINFO_OFFSET(vmap_area, va_start);
> - VMCOREINFO_OFFSET(vmap_area, list);
> - VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
> - log_buf_vmcoreinfo_setup();
> - VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
> - VMCOREINFO_NUMBER(NR_FREE_PAGES);
> - VMCOREINFO_NUMBER(PG_lru);
> - VMCOREINFO_NUMBER(PG_private);
> - VMCOREINFO_NUMBER(PG_swapcache);
> - VMCOREINFO_NUMBER(PG_swapbacked);
> - VMCOREINFO_NUMBER(PG_slab);
> -#ifdef CONFIG_MEMORY_FAILURE
> - VMCOREINFO_NUMBER(PG_hwpoison);
> -#endif
> - VMCOREINFO_NUMBER(PG_head_mask);
> -#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
> - VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> -#ifdef CONFIG_HUGETLB_PAGE
> - VMCOREINFO_NUMBER(PG_hugetlb);
> -#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
> - VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
> -#endif
> -
> -#ifdef CONFIG_KALLSYMS
> - VMCOREINFO_SYMBOL(kallsyms_names);
> - VMCOREINFO_SYMBOL(kallsyms_num_syms);
> - VMCOREINFO_SYMBOL(kallsyms_token_table);
> - VMCOREINFO_SYMBOL(kallsyms_token_index);
> -#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
> - VMCOREINFO_SYMBOL(kallsyms_offsets);
> - VMCOREINFO_SYMBOL(kallsyms_relative_base);
> -#else
> - VMCOREINFO_SYMBOL(kallsyms_addresses);
> -#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
> -#endif /* CONFIG_KALLSYMS */
> -
> - arch_crash_save_vmcoreinfo();
> - update_vmcoreinfo_note();
> -
> - return 0;
> -}
> -
> -subsys_initcall(crash_save_vmcoreinfo_init);
> -
> static int __init crash_notes_memory_init(void)
> {
> /* Allocate memory for saving cpu registers. */
> diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
> index 1d4bc493b2f4..11526fc42bc2 100644
> --- a/kernel/ksysfs.c
> +++ b/kernel/ksysfs.c
> @@ -154,7 +154,7 @@ KERNEL_ATTR_RW(kexec_crash_size);
>
> #endif /* CONFIG_KEXEC_CORE */
>
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>
> static ssize_t vmcoreinfo_show(struct kobject *kobj,
> struct kobj_attribute *attr, char *buf)
> @@ -177,7 +177,7 @@ KERNEL_ATTR_RO(crash_elfcorehdr_size);
>
> #endif
>
> -#endif /* CONFIG_CRASH_CORE */
> +#endif /* CONFIG_VMCORE_INFO */
>
> /* whether file capabilities are enabled */
> static ssize_t fscaps_show(struct kobject *kobj,
> @@ -265,7 +265,7 @@ static struct attribute * kernel_attrs[] = {
> &kexec_crash_loaded_attr.attr,
> &kexec_crash_size_attr.attr,
> #endif
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
> &vmcoreinfo_attr.attr,
> #ifdef CONFIG_CRASH_HOTPLUG
> &crash_elfcorehdr_size_attr.attr,
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index f2444b581e16..7d74b000b43a 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -34,7 +34,7 @@
> #include <linux/security.h>
> #include <linux/memblock.h>
> #include <linux/syscalls.h>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
> #include <linux/ratelimit.h>
> #include <linux/kmsg_dump.h>
> #include <linux/syslog.h>
> @@ -951,7 +951,7 @@ const struct file_operations kmsg_fops = {
> .release = devkmsg_release,
> };
>
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
> /*
> * This appends the listed symbols to /proc/vmcore
> *
> diff --git a/kernel/vmcore_info.c b/kernel/vmcore_info.c
> new file mode 100644
> index 000000000000..84f3663530c8
> --- /dev/null
> +++ b/kernel/vmcore_info.c
> @@ -0,0 +1,233 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * crash.c - kernel crash support code.
> + * Copyright (C) 2002-2004 Eric Biederman <[email protected]>
> + */
> +
> +#include <linux/buildid.h>
> +#include <linux/init.h>
> +#include <linux/utsname.h>
> +#include <linux/vmalloc.h>
> +#include <linux/sizes.h>
> +#include <linux/kexec.h>
> +#include <linux/memory.h>
> +#include <linux/cpuhotplug.h>
> +#include <linux/memblock.h>
> +#include <linux/kexec.h>
> +#include <linux/kmemleak.h>
> +
> +#include <asm/page.h>
> +#include <asm/sections.h>
> +
> +#include <crypto/sha1.h>
> +
> +#include "kallsyms_internal.h"
> +#include "kexec_internal.h"
> +
> +/* vmcoreinfo stuff */
> +unsigned char *vmcoreinfo_data;
> +size_t vmcoreinfo_size;
> +u32 *vmcoreinfo_note;
> +
> +/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
> +static unsigned char *vmcoreinfo_data_safecopy;
> +
> +Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> + void *data, size_t data_len)
> +{
> + struct elf_note *note = (struct elf_note *)buf;
> +
> + note->n_namesz = strlen(name) + 1;
> + note->n_descsz = data_len;
> + note->n_type = type;
> + buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> + memcpy(buf, name, note->n_namesz);
> + buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
> + memcpy(buf, data, data_len);
> + buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
> +
> + return buf;
> +}
> +
> +void final_note(Elf_Word *buf)
> +{
> + memset(buf, 0, sizeof(struct elf_note));
> +}
> +
> +static void update_vmcoreinfo_note(void)
> +{
> + u32 *buf = vmcoreinfo_note;
> +
> + if (!vmcoreinfo_size)
> + return;
> + buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> + vmcoreinfo_size);
> + final_note(buf);
> +}
> +
> +void crash_update_vmcoreinfo_safecopy(void *ptr)
> +{
> + if (ptr)
> + memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
> +
> + vmcoreinfo_data_safecopy = ptr;
> +}
> +
> +void crash_save_vmcoreinfo(void)
> +{
> + if (!vmcoreinfo_note)
> + return;
> +
> + /* Use the safe copy to generate vmcoreinfo note if have */
> + if (vmcoreinfo_data_safecopy)
> + vmcoreinfo_data = vmcoreinfo_data_safecopy;
> +
> + vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
> + update_vmcoreinfo_note();
> +}
> +
> +void vmcoreinfo_append_str(const char *fmt, ...)
> +{
> + va_list args;
> + char buf[0x50];
> + size_t r;
> +
> + va_start(args, fmt);
> + r = vscnprintf(buf, sizeof(buf), fmt, args);
> + va_end(args);
> +
> + r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
> +
> + memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
> +
> + vmcoreinfo_size += r;
> +
> + WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
> + "vmcoreinfo data exceeds allocated size, truncating");
> +}
> +
> +/*
> + * provide an empty default implementation here -- architecture
> + * code may override this
> + */
> +void __weak arch_crash_save_vmcoreinfo(void)
> +{}
> +
> +phys_addr_t __weak paddr_vmcoreinfo_note(void)
> +{
> + return __pa(vmcoreinfo_note);
> +}
> +EXPORT_SYMBOL(paddr_vmcoreinfo_note);
> +
> +static int __init crash_save_vmcoreinfo_init(void)
> +{
> + vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
> + if (!vmcoreinfo_data) {
> + pr_warn("Memory allocation for vmcoreinfo_data failed\n");
> + return -ENOMEM;
> + }
> +
> + vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
> + GFP_KERNEL | __GFP_ZERO);
> + if (!vmcoreinfo_note) {
> + free_page((unsigned long)vmcoreinfo_data);
> + vmcoreinfo_data = NULL;
> + pr_warn("Memory allocation for vmcoreinfo_note failed\n");
> + return -ENOMEM;
> + }
> +
> + VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
> + VMCOREINFO_BUILD_ID();
> + VMCOREINFO_PAGESIZE(PAGE_SIZE);
> +
> + VMCOREINFO_SYMBOL(init_uts_ns);
> + VMCOREINFO_OFFSET(uts_namespace, name);
> + VMCOREINFO_SYMBOL(node_online_map);
> +#ifdef CONFIG_MMU
> + VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
> +#endif
> + VMCOREINFO_SYMBOL(_stext);
> + VMCOREINFO_SYMBOL(vmap_area_list);
> +
> +#ifndef CONFIG_NUMA
> + VMCOREINFO_SYMBOL(mem_map);
> + VMCOREINFO_SYMBOL(contig_page_data);
> +#endif
> +#ifdef CONFIG_SPARSEMEM
> + VMCOREINFO_SYMBOL_ARRAY(mem_section);
> + VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
> + VMCOREINFO_STRUCT_SIZE(mem_section);
> + VMCOREINFO_OFFSET(mem_section, section_mem_map);
> + VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
> + VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
> +#endif
> + VMCOREINFO_STRUCT_SIZE(page);
> + VMCOREINFO_STRUCT_SIZE(pglist_data);
> + VMCOREINFO_STRUCT_SIZE(zone);
> + VMCOREINFO_STRUCT_SIZE(free_area);
> + VMCOREINFO_STRUCT_SIZE(list_head);
> + VMCOREINFO_SIZE(nodemask_t);
> + VMCOREINFO_OFFSET(page, flags);
> + VMCOREINFO_OFFSET(page, _refcount);
> + VMCOREINFO_OFFSET(page, mapping);
> + VMCOREINFO_OFFSET(page, lru);
> + VMCOREINFO_OFFSET(page, _mapcount);
> + VMCOREINFO_OFFSET(page, private);
> + VMCOREINFO_OFFSET(page, compound_head);
> + VMCOREINFO_OFFSET(pglist_data, node_zones);
> + VMCOREINFO_OFFSET(pglist_data, nr_zones);
> +#ifdef CONFIG_FLATMEM
> + VMCOREINFO_OFFSET(pglist_data, node_mem_map);
> +#endif
> + VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
> + VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
> + VMCOREINFO_OFFSET(pglist_data, node_id);
> + VMCOREINFO_OFFSET(zone, free_area);
> + VMCOREINFO_OFFSET(zone, vm_stat);
> + VMCOREINFO_OFFSET(zone, spanned_pages);
> + VMCOREINFO_OFFSET(free_area, free_list);
> + VMCOREINFO_OFFSET(list_head, next);
> + VMCOREINFO_OFFSET(list_head, prev);
> + VMCOREINFO_OFFSET(vmap_area, va_start);
> + VMCOREINFO_OFFSET(vmap_area, list);
> + VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
> + log_buf_vmcoreinfo_setup();
> + VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
> + VMCOREINFO_NUMBER(NR_FREE_PAGES);
> + VMCOREINFO_NUMBER(PG_lru);
> + VMCOREINFO_NUMBER(PG_private);
> + VMCOREINFO_NUMBER(PG_swapcache);
> + VMCOREINFO_NUMBER(PG_swapbacked);
> + VMCOREINFO_NUMBER(PG_slab);
> +#ifdef CONFIG_MEMORY_FAILURE
> + VMCOREINFO_NUMBER(PG_hwpoison);
> +#endif
> + VMCOREINFO_NUMBER(PG_head_mask);
> +#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
> + VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> +#ifdef CONFIG_HUGETLB_PAGE
> + VMCOREINFO_NUMBER(PG_hugetlb);
> +#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
> + VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
> +#endif
> +
> +#ifdef CONFIG_KALLSYMS
> + VMCOREINFO_SYMBOL(kallsyms_names);
> + VMCOREINFO_SYMBOL(kallsyms_num_syms);
> + VMCOREINFO_SYMBOL(kallsyms_token_table);
> + VMCOREINFO_SYMBOL(kallsyms_token_index);
> +#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
> + VMCOREINFO_SYMBOL(kallsyms_offsets);
> + VMCOREINFO_SYMBOL(kallsyms_relative_base);
> +#else
> + VMCOREINFO_SYMBOL(kallsyms_addresses);
> +#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
> +#endif /* CONFIG_KALLSYMS */
> +
> + arch_crash_save_vmcoreinfo();
> + update_vmcoreinfo_note();
> +
> + return 0;
> +}
> +
> +subsys_initcall(crash_save_vmcoreinfo_init);
> diff --git a/lib/buildid.c b/lib/buildid.c
> index e3a7acdeef0e..3e6868c86b45 100644
> --- a/lib/buildid.c
> +++ b/lib/buildid.c
> @@ -174,7 +174,7 @@ int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size)
> return parse_build_id_buf(build_id, NULL, buf, buf_size);
> }
>
> -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
> +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
> unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX] __ro_after_init;
>
> /**


2024-02-21 20:12:13

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH v2 01/14] kexec: split crashkernel reservation code out from crash_core.c

On Wed, 21 Feb 2024 22:59:47 +0530 Sourabh Jain <[email protected]> wrote:

> > config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
> > - def_bool CRASH_CORE
> > + def_bool CRASH_RESEERVE
>
> %s/CRASH_RESEERVE/CRASH_RESERVE?

Yes, thanks, this has been addressed in a followon fixup patch
in the mm.git tree.

2024-02-21 20:58:06

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <[email protected]> wrote:

> On 04/02/24 8:56 am, Baoquan He wrote:
> >>> Hope Hari and Pingfan can help have a look, see if
> >>> it's doable. Now, I make it either have both kexec and crash enabled, or
> >>> disable both of them altogether.
> >>
> >> Sure. I will take a closer look...
> > Thanks a lot. Please feel free to post patches to make that, or I can do
> > it with your support or suggestion.
>
> Tested your changes and on top of these changes, came up with the below
> changes to get it working for powerpc:
>
>
> https://lore.kernel.org/all/[email protected]/

So can we take it that you're OK with Baoquan's series as-is?

Baoquan, do you believe the patches in mm-unstable are ready for moving
into mm-stable in preparation for an upstream merge?




2024-02-22 05:18:03

by Hari Bathini

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items



On 22/02/24 2:27 am, Andrew Morton wrote:
> On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <[email protected]> wrote:
>
>> On 04/02/24 8:56 am, Baoquan He wrote:
>>>>> Hope Hari and Pingfan can help have a look, see if
>>>>> it's doable. Now, I make it either have both kexec and crash enabled, or
>>>>> disable both of them altogether.
>>>>
>>>> Sure. I will take a closer look...
>>> Thanks a lot. Please feel free to post patches to make that, or I can do
>>> it with your support or suggestion.
>>
>> Tested your changes and on top of these changes, came up with the below
>> changes to get it working for powerpc:
>>
>>
>> https://lore.kernel.org/all/[email protected]/
>
> So can we take it that you're OK with Baoquan's series as-is?

Hi Andrew,

If you mean

v3 (https://lore.kernel.org/all/[email protected]/)
+
follow-up from Baoquan
(https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv/)

Yes.

My changes are based on top of the above patches..

Thanks
Hari

2024-02-22 07:07:25

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

On 02/21/24 at 12:57pm, Andrew Morton wrote:
> On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <[email protected]> wrote:
>
> > On 04/02/24 8:56 am, Baoquan He wrote:
> > >>> Hope Hari and Pingfan can help have a look, see if
> > >>> it's doable. Now, I make it either have both kexec and crash enabled, or
> > >>> disable both of them altogether.
> > >>
> > >> Sure. I will take a closer look...
> > > Thanks a lot. Please feel free to post patches to make that, or I can do
> > > it with your support or suggestion.
> >
> > Tested your changes and on top of these changes, came up with the below
> > changes to get it working for powerpc:
> >
> >
> > https://lore.kernel.org/all/[email protected]/
>
> So can we take it that you're OK with Baoquan's series as-is?
>
> Baoquan, do you believe the patches in mm-unstable are ready for moving
> into mm-stable in preparation for an upstream merge?

Yeah, I think they are ready to go for merging.

For Hari's patchset, the main part was planned before. And I am not
familiar with fadump in powerpc, the Kconfig fix from Hari is a good
guarantee with the expertise. Surely, I will await Hari's comment on
that.


2024-02-22 07:57:58

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v2 02/14] crash: split vmcoreinfo exporting code out from crash_core.c

On 02/21/24 at 11:07pm, Sourabh Jain wrote:
> Hello Baoquan,
>
> On 19/01/24 20:22, Baoquan He wrote:
> > Now move the relevant codes into separate files:
> > kernel/crash_reserve.c, include/linux/crash_reserve.h.
> >
> > And add config item CRASH_RESERVE to control its enabling.
>
> Feels like this patch is more about vmcore_info.[c|h] and CONFIG_VMCORE_INFO
> then the above mentioned files and config.

You are right. Above lines about crash_reserve should be removed. It's
from v1, and done in patch 1 of v2 and v3. I forgot removing them.

>
> >
> > And also update the old ifdeffery of CONFIG_CRASH_CORE, including of
> > <linux/crash_core.h> and config item dependency on CRASH_CORE
> > accordingly.
> >
> > And also do renaming as follows:
> > - arch/xxx/kernel/{crash_core.c => vmcore_info.c}
> > because they are only related to vmcoreinfo exporting on x86, arm64,
> > riscv.
> >
> > And also Remove config item CRASH_CORE, and rely on CONFIG_KEXEC_CORE to
> > decide if build in crash_core.c.
> >
> > Signed-off-by: Baoquan He <[email protected]>
> > ---
> > arch/arm64/kernel/Makefile | 2 +-
> > .../kernel/{crash_core.c => vmcore_info.c} | 2 +-
> > arch/powerpc/Kconfig | 2 +-
> > arch/powerpc/kernel/setup-common.c | 2 +-
> > arch/powerpc/platforms/powernv/opal-core.c | 2 +-
> > arch/riscv/kernel/Makefile | 2 +-
> > .../kernel/{crash_core.c => vmcore_info.c} | 2 +-
> > arch/x86/kernel/Makefile | 2 +-
> > .../{crash_core_32.c => vmcore_info_32.c} | 2 +-
> > .../{crash_core_64.c => vmcore_info_64.c} | 2 +-
> > drivers/firmware/qemu_fw_cfg.c | 14 +-
> > fs/proc/Kconfig | 2 +-
> > fs/proc/kcore.c | 2 +-
> > include/linux/buildid.h | 2 +-
> > include/linux/crash_core.h | 73 ------
> > include/linux/kexec.h | 1 +
> > include/linux/vmcore_info.h | 81 ++++++
> > kernel/Kconfig.kexec | 4 +-
> > kernel/Makefile | 4 +-
> > kernel/crash_core.c | 208 ----------------
> > kernel/ksysfs.c | 6 +-
> > kernel/printk/printk.c | 4 +-
> > kernel/vmcore_info.c | 233 ++++++++++++++++++
> > lib/buildid.c | 2 +-
> > 24 files changed, 345 insertions(+), 311 deletions(-)
> > rename arch/arm64/kernel/{crash_core.c => vmcore_info.c} (97%)
> > rename arch/riscv/kernel/{crash_core.c => vmcore_info.c} (96%)
> > rename arch/x86/kernel/{crash_core_32.c => vmcore_info_32.c} (90%)
> > rename arch/x86/kernel/{crash_core_64.c => vmcore_info_64.c} (94%)
> > create mode 100644 include/linux/vmcore_info.h
> > create mode 100644 kernel/vmcore_info.c
> >
> > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> > index d95b3d6b471a..bcf89587a549 100644
> > --- a/arch/arm64/kernel/Makefile
> > +++ b/arch/arm64/kernel/Makefile
> > @@ -66,7 +66,7 @@ obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
> > obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
> > arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
> > obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
> > -obj-$(CONFIG_CRASH_CORE) += crash_core.o
> > +obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
> > obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
> > obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
> > obj-$(CONFIG_ARM64_MTE) += mte.o
> > diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/vmcore_info.c
> > similarity index 97%
> > rename from arch/arm64/kernel/crash_core.c
> > rename to arch/arm64/kernel/vmcore_info.c
> > index 66cde752cd74..a5abf7186922 100644
> > --- a/arch/arm64/kernel/crash_core.c
> > +++ b/arch/arm64/kernel/vmcore_info.c
> > @@ -4,7 +4,7 @@
> > * Copyright (C) Huawei Futurewei Technologies.
> > */
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > #include <asm/cpufeature.h>
> > #include <asm/memory.h>
> > #include <asm/pgtable-hwdef.h>
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index 6aeab95f0edd..1520146d7c2c 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -690,7 +690,7 @@ config ARCH_SELECTS_CRASH_DUMP
> > config FA_DUMP
> > bool "Firmware-assisted dump"
> > depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
> > - select CRASH_CORE
> > + select VMCORE_INFO
> > select CRASH_RESERVE
> > select CRASH_DUMP
> > help
> > diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
> > index 9b142b9d5187..733f210ffda1 100644
> > --- a/arch/powerpc/kernel/setup-common.c
> > +++ b/arch/powerpc/kernel/setup-common.c
> > @@ -109,7 +109,7 @@ int ppc_do_canonicalize_irqs;
> > EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
> > #endif
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> > /* This keeps a track of which one is the crashing cpu. */
> > int crashing_cpu = -1;
> > #endif
> > diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
> > index bb7657115f1d..c9a9b759cc92 100644
> > --- a/arch/powerpc/platforms/powernv/opal-core.c
> > +++ b/arch/powerpc/platforms/powernv/opal-core.c
> > @@ -16,7 +16,7 @@
> > #include <linux/kobject.h>
> > #include <linux/sysfs.h>
> > #include <linux/slab.h>
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > #include <linux/of.h>
> > #include <asm/page.h>
> > diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> > index c92c623b311e..63a36539ea1a 100644
> > --- a/arch/riscv/kernel/Makefile
> > +++ b/arch/riscv/kernel/Makefile
> > @@ -91,7 +91,7 @@ obj-$(CONFIG_KGDB) += kgdb.o
> > obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o
> > obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o
> > obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
> > -obj-$(CONFIG_CRASH_CORE) += crash_core.o
> > +obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
> > obj-$(CONFIG_JUMP_LABEL) += jump_label.o
> > diff --git a/arch/riscv/kernel/crash_core.c b/arch/riscv/kernel/vmcore_info.c
> > similarity index 96%
> > rename from arch/riscv/kernel/crash_core.c
> > rename to arch/riscv/kernel/vmcore_info.c
> > index 8706736fd4e2..e8ad57a60a2f 100644
> > --- a/arch/riscv/kernel/crash_core.c
> > +++ b/arch/riscv/kernel/vmcore_info.c
> > @@ -1,6 +1,6 @@
> > // SPDX-License-Identifier: GPL-2.0-only
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > #include <linux/pagemap.h>
> > void arch_crash_save_vmcoreinfo(void)
> > diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> > index 0000325ab98f..913d4022131e 100644
> > --- a/arch/x86/kernel/Makefile
> > +++ b/arch/x86/kernel/Makefile
> > @@ -98,7 +98,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
> > obj-$(CONFIG_X86_TSC) += trace_clock.o
> > obj-$(CONFIG_TRACING) += trace.o
> > obj-$(CONFIG_RETHOOK) += rethook.o
> > -obj-$(CONFIG_CRASH_CORE) += crash_core_$(BITS).o
> > +obj-$(CONFIG_VMCORE_INFO) += vmcore_info_$(BITS).o
> > obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o
> > obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o
> > obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o
> > diff --git a/arch/x86/kernel/crash_core_32.c b/arch/x86/kernel/vmcore_info_32.c
> > similarity index 90%
> > rename from arch/x86/kernel/crash_core_32.c
> > rename to arch/x86/kernel/vmcore_info_32.c
> > index 8a89c109e20a..5995a749288a 100644
> > --- a/arch/x86/kernel/crash_core_32.c
> > +++ b/arch/x86/kernel/vmcore_info_32.c
> > @@ -1,6 +1,6 @@
> > // SPDX-License-Identifier: GPL-2.0-only
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > #include <linux/pgtable.h>
> > #include <asm/setup.h>
> > diff --git a/arch/x86/kernel/crash_core_64.c b/arch/x86/kernel/vmcore_info_64.c
> > similarity index 94%
> > rename from arch/x86/kernel/crash_core_64.c
> > rename to arch/x86/kernel/vmcore_info_64.c
> > index 7d255f882afe..0dec7d868754 100644
> > --- a/arch/x86/kernel/crash_core_64.c
> > +++ b/arch/x86/kernel/vmcore_info_64.c
> > @@ -1,6 +1,6 @@
> > // SPDX-License-Identifier: GPL-2.0-only
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > #include <linux/pgtable.h>
> > #include <asm/setup.h>
> > diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> > index 03da9a4354f8..5f43dfa22f79 100644
> > --- a/drivers/firmware/qemu_fw_cfg.c
> > +++ b/drivers/firmware/qemu_fw_cfg.c
> > @@ -37,7 +37,7 @@
> > #include <uapi/linux/qemu_fw_cfg.h>
> > #include <linux/delay.h>
> > #include <linux/crash_dump.h>
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > MODULE_AUTHOR("Gabriel L. Somlo <[email protected]>");
> > MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> > @@ -67,7 +67,7 @@ static void fw_cfg_sel_endianness(u16 key)
> > iowrite16(key, fw_cfg_reg_ctrl);
> > }
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> > static inline bool fw_cfg_dma_enabled(void)
> > {
> > return (fw_cfg_rev & FW_CFG_VERSION_DMA) && fw_cfg_reg_dma;
> > @@ -156,7 +156,7 @@ static ssize_t fw_cfg_read_blob(u16 key,
> > return count;
> > }
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> > /* write chunk of given fw_cfg blob (caller responsible for sanity-check) */
> > static ssize_t fw_cfg_write_blob(u16 key,
> > void *buf, loff_t pos, size_t count)
> > @@ -195,7 +195,7 @@ static ssize_t fw_cfg_write_blob(u16 key,
> > return ret;
> > }
> > -#endif /* CONFIG_CRASH_CORE */
> > +#endif /* CONFIG_VMCORE_INFO */
> > /* clean up fw_cfg device i/o */
> > static void fw_cfg_io_cleanup(void)
> > @@ -319,7 +319,7 @@ struct fw_cfg_sysfs_entry {
> > struct list_head list;
> > };
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> > static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
> > {
> > static struct fw_cfg_vmcoreinfo *data;
> > @@ -343,7 +343,7 @@ static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
> > kfree(data);
> > return ret;
> > }
> > -#endif /* CONFIG_CRASH_CORE */
> > +#endif /* CONFIG_VMCORE_INFO */
> > /* get fw_cfg_sysfs_entry from kobject member */
> > static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj)
> > @@ -583,7 +583,7 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)
> > int err;
> > struct fw_cfg_sysfs_entry *entry;
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> > if (fw_cfg_dma_enabled() &&
> > strcmp(f->name, FW_CFG_VMCOREINFO_FILENAME) == 0 &&
> > !is_kdump_kernel()) {
> > diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
> > index 32b1116ae137..d80a1431ef7b 100644
> > --- a/fs/proc/Kconfig
> > +++ b/fs/proc/Kconfig
> > @@ -32,7 +32,7 @@ config PROC_FS
> > config PROC_KCORE
> > bool "/proc/kcore support" if !ARM
> > depends on PROC_FS && MMU
> > - select CRASH_CORE
> > + select VMCORE_INFO
> > help
> > Provides a virtual ELF core file of the live kernel. This can
> > be read with gdb and other ELF tools. No modifications can be
> > diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
> > index 6422e569b080..8e08a9a1b7ed 100644
> > --- a/fs/proc/kcore.c
> > +++ b/fs/proc/kcore.c
> > @@ -10,7 +10,7 @@
> > * Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <[email protected]>
> > */
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > #include <linux/mm.h>
> > #include <linux/proc_fs.h>
> > #include <linux/kcore.h>
> > diff --git a/include/linux/buildid.h b/include/linux/buildid.h
> > index 8a582d242f06..20aa3c2d89f7 100644
> > --- a/include/linux/buildid.h
> > +++ b/include/linux/buildid.h
> > @@ -11,7 +11,7 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
> > __u32 *size);
> > int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size);
> > -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
> > +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
> > extern unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX];
> > void init_vmlinux_build_id(void);
> > #else
> > diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
> > index 1fde49246fa6..7f19f62018ef 100644
> > --- a/include/linux/crash_core.h
> > +++ b/include/linux/crash_core.h
> > @@ -6,79 +6,6 @@
> > #include <linux/elfcore.h>
> > #include <linux/elf.h>
> > -#define CRASH_CORE_NOTE_NAME "CORE"
> > -#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
> > -#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
> > -#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
> > -
> > -/*
> > - * The per-cpu notes area is a list of notes terminated by a "NULL"
> > - * note header. For kdump, the code in vmcore.c runs in the context
> > - * of the second kernel to combine them into one note.
> > - */
> > -#define CRASH_CORE_NOTE_BYTES ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
> > - CRASH_CORE_NOTE_NAME_BYTES + \
> > - CRASH_CORE_NOTE_DESC_BYTES)
> > -
> > -#define VMCOREINFO_BYTES PAGE_SIZE
> > -#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
> > -#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
> > -#define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
> > - VMCOREINFO_NOTE_NAME_BYTES + \
> > - VMCOREINFO_BYTES)
> > -
> > -typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
> > -/* Per cpu memory for storing cpu states in case of system crash. */
> > -extern note_buf_t __percpu *crash_notes;
> > -
> > -void crash_update_vmcoreinfo_safecopy(void *ptr);
> > -void crash_save_vmcoreinfo(void);
> > -void arch_crash_save_vmcoreinfo(void);
> > -__printf(1, 2)
> > -void vmcoreinfo_append_str(const char *fmt, ...);
> > -phys_addr_t paddr_vmcoreinfo_note(void);
> > -
> > -#define VMCOREINFO_OSRELEASE(value) \
> > - vmcoreinfo_append_str("OSRELEASE=%s\n", value)
> > -#define VMCOREINFO_BUILD_ID() \
> > - ({ \
> > - static_assert(sizeof(vmlinux_build_id) == 20); \
> > - vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
> > - })
> > -
> > -#define VMCOREINFO_PAGESIZE(value) \
> > - vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
> > -#define VMCOREINFO_SYMBOL(name) \
> > - vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
> > -#define VMCOREINFO_SYMBOL_ARRAY(name) \
> > - vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
> > -#define VMCOREINFO_SIZE(name) \
> > - vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> > - (unsigned long)sizeof(name))
> > -#define VMCOREINFO_STRUCT_SIZE(name) \
> > - vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> > - (unsigned long)sizeof(struct name))
> > -#define VMCOREINFO_OFFSET(name, field) \
> > - vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> > - (unsigned long)offsetof(struct name, field))
> > -#define VMCOREINFO_TYPE_OFFSET(name, field) \
> > - vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> > - (unsigned long)offsetof(name, field))
> > -#define VMCOREINFO_LENGTH(name, value) \
> > - vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
> > -#define VMCOREINFO_NUMBER(name) \
> > - vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
> > -#define VMCOREINFO_CONFIG(name) \
> > - vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
> > -
> > -extern unsigned char *vmcoreinfo_data;
> > -extern size_t vmcoreinfo_size;
> > -extern u32 *vmcoreinfo_note;
> > -
> > -Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> > - void *data, size_t data_len);
> > -void final_note(Elf_Word *buf);
> > -
> > /* Alignment required for elf header segment */
> > #define ELF_CORE_HEADER_ALIGN 4096
> > diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> > index 6d79bfb52e5b..9c7bb8b56ed6 100644
> > --- a/include/linux/kexec.h
> > +++ b/include/linux/kexec.h
> > @@ -16,6 +16,7 @@
> > #if !defined(__ASSEMBLY__)
> > #include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > #include <linux/crash_reserve.h>
> > #include <asm/io.h>
> > #include <linux/range.h>
> > diff --git a/include/linux/vmcore_info.h b/include/linux/vmcore_info.h
> > new file mode 100644
> > index 000000000000..e1dec1a6a749
> > --- /dev/null
> > +++ b/include/linux/vmcore_info.h
> > @@ -0,0 +1,81 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef LINUX_VMCORE_INFO_H
> > +#define LINUX_VMCORE_INFO_H
> > +
> > +#include <linux/linkage.h>
> > +#include <linux/elfcore.h>
> > +#include <linux/elf.h>
> > +
> > +#define CRASH_CORE_NOTE_NAME "CORE"
> > +#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
> > +#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
> > +#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
> > +
> > +/*
> > + * The per-cpu notes area is a list of notes terminated by a "NULL"
> > + * note header. For kdump, the code in vmcore.c runs in the context
> > + * of the second kernel to combine them into one note.
> > + */
> > +#define CRASH_CORE_NOTE_BYTES ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
> > + CRASH_CORE_NOTE_NAME_BYTES + \
> > + CRASH_CORE_NOTE_DESC_BYTES)
> > +
> > +#define VMCOREINFO_BYTES PAGE_SIZE
> > +#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
> > +#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
> > +#define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
> > + VMCOREINFO_NOTE_NAME_BYTES + \
> > + VMCOREINFO_BYTES)
> > +
> > +typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
> > +/* Per cpu memory for storing cpu states in case of system crash. */
> > +extern note_buf_t __percpu *crash_notes;
> > +
> > +void crash_update_vmcoreinfo_safecopy(void *ptr);
> > +void crash_save_vmcoreinfo(void);
> > +void arch_crash_save_vmcoreinfo(void);
> > +__printf(1, 2)
> > +void vmcoreinfo_append_str(const char *fmt, ...);
> > +phys_addr_t paddr_vmcoreinfo_note(void);
> > +
> > +#define VMCOREINFO_OSRELEASE(value) \
> > + vmcoreinfo_append_str("OSRELEASE=%s\n", value)
> > +#define VMCOREINFO_BUILD_ID() \
> > + ({ \
> > + static_assert(sizeof(vmlinux_build_id) == 20); \
> > + vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
> > + })
> > +
> > +#define VMCOREINFO_PAGESIZE(value) \
> > + vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
> > +#define VMCOREINFO_SYMBOL(name) \
> > + vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
> > +#define VMCOREINFO_SYMBOL_ARRAY(name) \
> > + vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
> > +#define VMCOREINFO_SIZE(name) \
> > + vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> > + (unsigned long)sizeof(name))
> > +#define VMCOREINFO_STRUCT_SIZE(name) \
> > + vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> > + (unsigned long)sizeof(struct name))
> > +#define VMCOREINFO_OFFSET(name, field) \
> > + vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> > + (unsigned long)offsetof(struct name, field))
> > +#define VMCOREINFO_TYPE_OFFSET(name, field) \
> > + vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> > + (unsigned long)offsetof(name, field))
> > +#define VMCOREINFO_LENGTH(name, value) \
> > + vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
> > +#define VMCOREINFO_NUMBER(name) \
> > + vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
> > +#define VMCOREINFO_CONFIG(name) \
> > + vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
> > +
> > +extern unsigned char *vmcoreinfo_data;
> > +extern size_t vmcoreinfo_size;
> > +extern u32 *vmcoreinfo_note;
> > +
> > +Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> > + void *data, size_t data_len);
> > +void final_note(Elf_Word *buf);
> > +#endif /* LINUX_VMCORE_INFO_H */
> > diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> > index 8b7be71edd85..8faf27043432 100644
> > --- a/kernel/Kconfig.kexec
> > +++ b/kernel/Kconfig.kexec
> > @@ -5,11 +5,11 @@ menu "Kexec and crash features"
> > config CRASH_RESERVE
> > bool
> > -config CRASH_CORE
> > +config VMCORE_INFO
> > bool
> > config KEXEC_CORE
> > - select CRASH_CORE
> > + select VMCORE_INFO
> > select CRASH_RESERVE
> > bool
> > diff --git a/kernel/Makefile b/kernel/Makefile
> > index 05fa88b3ab74..649272a1d6b9 100644
> > --- a/kernel/Makefile
> > +++ b/kernel/Makefile
> > @@ -68,9 +68,9 @@ obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
> > obj-$(CONFIG_KALLSYMS) += kallsyms.o
> > obj-$(CONFIG_KALLSYMS_SELFTEST) += kallsyms_selftest.o
> > obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
> > -obj-$(CONFIG_CRASH_CORE) += crash_core.o
> > +obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
> > obj-$(CONFIG_CRASH_RESERVE) += crash_reserve.o
> > -obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
> > +obj-$(CONFIG_KEXEC_CORE) += kexec_core.o crash_core.o
> > obj-$(CONFIG_KEXEC) += kexec.o
> > obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
> > obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o
> > diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> > index 055859c62f19..2f4df1fe6f7a 100644
> > --- a/kernel/crash_core.c
> > +++ b/kernel/crash_core.c
> > @@ -26,14 +26,6 @@
> > /* Per cpu memory for storing cpu states in case of system crash. */
> > note_buf_t __percpu *crash_notes;
> > -/* vmcoreinfo stuff */
> > -unsigned char *vmcoreinfo_data;
> > -size_t vmcoreinfo_size;
> > -u32 *vmcoreinfo_note;
> > -
> > -/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
> > -static unsigned char *vmcoreinfo_data_safecopy;
> > -
> > int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
> > void **addr, unsigned long *sz)
> > {
> > @@ -195,206 +187,6 @@ int crash_exclude_mem_range(struct crash_mem *mem,
> > return 0;
> > }
> > -Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> > - void *data, size_t data_len)
> > -{
> > - struct elf_note *note = (struct elf_note *)buf;
> > -
> > - note->n_namesz = strlen(name) + 1;
> > - note->n_descsz = data_len;
> > - note->n_type = type;
> > - buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> > - memcpy(buf, name, note->n_namesz);
> > - buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
> > - memcpy(buf, data, data_len);
> > - buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
> > -
> > - return buf;
> > -}
> > -
> > -void final_note(Elf_Word *buf)
> > -{
> > - memset(buf, 0, sizeof(struct elf_note));
> > -}
> > -
> > -static void update_vmcoreinfo_note(void)
> > -{
> > - u32 *buf = vmcoreinfo_note;
> > -
> > - if (!vmcoreinfo_size)
> > - return;
> > - buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> > - vmcoreinfo_size);
> > - final_note(buf);
> > -}
> > -
> > -void crash_update_vmcoreinfo_safecopy(void *ptr)
> > -{
> > - if (ptr)
> > - memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
> > -
> > - vmcoreinfo_data_safecopy = ptr;
> > -}
> > -
> > -void crash_save_vmcoreinfo(void)
> > -{
> > - if (!vmcoreinfo_note)
> > - return;
> > -
> > - /* Use the safe copy to generate vmcoreinfo note if have */
> > - if (vmcoreinfo_data_safecopy)
> > - vmcoreinfo_data = vmcoreinfo_data_safecopy;
> > -
> > - vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
> > - update_vmcoreinfo_note();
> > -}
> > -
> > -void vmcoreinfo_append_str(const char *fmt, ...)
> > -{
> > - va_list args;
> > - char buf[0x50];
> > - size_t r;
> > -
> > - va_start(args, fmt);
> > - r = vscnprintf(buf, sizeof(buf), fmt, args);
> > - va_end(args);
> > -
> > - r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
> > -
> > - memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
> > -
> > - vmcoreinfo_size += r;
> > -
> > - WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
> > - "vmcoreinfo data exceeds allocated size, truncating");
> > -}
> > -
> > -/*
> > - * provide an empty default implementation here -- architecture
> > - * code may override this
> > - */
> > -void __weak arch_crash_save_vmcoreinfo(void)
> > -{}
> > -
> > -phys_addr_t __weak paddr_vmcoreinfo_note(void)
> > -{
> > - return __pa(vmcoreinfo_note);
> > -}
> > -EXPORT_SYMBOL(paddr_vmcoreinfo_note);
> > -
> > -static int __init crash_save_vmcoreinfo_init(void)
> > -{
> > - vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
> > - if (!vmcoreinfo_data) {
> > - pr_warn("Memory allocation for vmcoreinfo_data failed\n");
> > - return -ENOMEM;
> > - }
> > -
> > - vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
> > - GFP_KERNEL | __GFP_ZERO);
> > - if (!vmcoreinfo_note) {
> > - free_page((unsigned long)vmcoreinfo_data);
> > - vmcoreinfo_data = NULL;
> > - pr_warn("Memory allocation for vmcoreinfo_note failed\n");
> > - return -ENOMEM;
> > - }
> > -
> > - VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
> > - VMCOREINFO_BUILD_ID();
> > - VMCOREINFO_PAGESIZE(PAGE_SIZE);
> > -
> > - VMCOREINFO_SYMBOL(init_uts_ns);
> > - VMCOREINFO_OFFSET(uts_namespace, name);
> > - VMCOREINFO_SYMBOL(node_online_map);
> > -#ifdef CONFIG_MMU
> > - VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
> > -#endif
> > - VMCOREINFO_SYMBOL(_stext);
> > - VMCOREINFO_SYMBOL(vmap_area_list);
> > -
> > -#ifndef CONFIG_NUMA
> > - VMCOREINFO_SYMBOL(mem_map);
> > - VMCOREINFO_SYMBOL(contig_page_data);
> > -#endif
> > -#ifdef CONFIG_SPARSEMEM
> > - VMCOREINFO_SYMBOL_ARRAY(mem_section);
> > - VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
> > - VMCOREINFO_STRUCT_SIZE(mem_section);
> > - VMCOREINFO_OFFSET(mem_section, section_mem_map);
> > - VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
> > - VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
> > -#endif
> > - VMCOREINFO_STRUCT_SIZE(page);
> > - VMCOREINFO_STRUCT_SIZE(pglist_data);
> > - VMCOREINFO_STRUCT_SIZE(zone);
> > - VMCOREINFO_STRUCT_SIZE(free_area);
> > - VMCOREINFO_STRUCT_SIZE(list_head);
> > - VMCOREINFO_SIZE(nodemask_t);
> > - VMCOREINFO_OFFSET(page, flags);
> > - VMCOREINFO_OFFSET(page, _refcount);
> > - VMCOREINFO_OFFSET(page, mapping);
> > - VMCOREINFO_OFFSET(page, lru);
> > - VMCOREINFO_OFFSET(page, _mapcount);
> > - VMCOREINFO_OFFSET(page, private);
> > - VMCOREINFO_OFFSET(page, compound_head);
> > - VMCOREINFO_OFFSET(pglist_data, node_zones);
> > - VMCOREINFO_OFFSET(pglist_data, nr_zones);
> > -#ifdef CONFIG_FLATMEM
> > - VMCOREINFO_OFFSET(pglist_data, node_mem_map);
> > -#endif
> > - VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
> > - VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
> > - VMCOREINFO_OFFSET(pglist_data, node_id);
> > - VMCOREINFO_OFFSET(zone, free_area);
> > - VMCOREINFO_OFFSET(zone, vm_stat);
> > - VMCOREINFO_OFFSET(zone, spanned_pages);
> > - VMCOREINFO_OFFSET(free_area, free_list);
> > - VMCOREINFO_OFFSET(list_head, next);
> > - VMCOREINFO_OFFSET(list_head, prev);
> > - VMCOREINFO_OFFSET(vmap_area, va_start);
> > - VMCOREINFO_OFFSET(vmap_area, list);
> > - VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
> > - log_buf_vmcoreinfo_setup();
> > - VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
> > - VMCOREINFO_NUMBER(NR_FREE_PAGES);
> > - VMCOREINFO_NUMBER(PG_lru);
> > - VMCOREINFO_NUMBER(PG_private);
> > - VMCOREINFO_NUMBER(PG_swapcache);
> > - VMCOREINFO_NUMBER(PG_swapbacked);
> > - VMCOREINFO_NUMBER(PG_slab);
> > -#ifdef CONFIG_MEMORY_FAILURE
> > - VMCOREINFO_NUMBER(PG_hwpoison);
> > -#endif
> > - VMCOREINFO_NUMBER(PG_head_mask);
> > -#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
> > - VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> > -#ifdef CONFIG_HUGETLB_PAGE
> > - VMCOREINFO_NUMBER(PG_hugetlb);
> > -#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
> > - VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
> > -#endif
> > -
> > -#ifdef CONFIG_KALLSYMS
> > - VMCOREINFO_SYMBOL(kallsyms_names);
> > - VMCOREINFO_SYMBOL(kallsyms_num_syms);
> > - VMCOREINFO_SYMBOL(kallsyms_token_table);
> > - VMCOREINFO_SYMBOL(kallsyms_token_index);
> > -#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
> > - VMCOREINFO_SYMBOL(kallsyms_offsets);
> > - VMCOREINFO_SYMBOL(kallsyms_relative_base);
> > -#else
> > - VMCOREINFO_SYMBOL(kallsyms_addresses);
> > -#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
> > -#endif /* CONFIG_KALLSYMS */
> > -
> > - arch_crash_save_vmcoreinfo();
> > - update_vmcoreinfo_note();
> > -
> > - return 0;
> > -}
> > -
> > -subsys_initcall(crash_save_vmcoreinfo_init);
> > -
> > static int __init crash_notes_memory_init(void)
> > {
> > /* Allocate memory for saving cpu registers. */
> > diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
> > index 1d4bc493b2f4..11526fc42bc2 100644
> > --- a/kernel/ksysfs.c
> > +++ b/kernel/ksysfs.c
> > @@ -154,7 +154,7 @@ KERNEL_ATTR_RW(kexec_crash_size);
> > #endif /* CONFIG_KEXEC_CORE */
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> > static ssize_t vmcoreinfo_show(struct kobject *kobj,
> > struct kobj_attribute *attr, char *buf)
> > @@ -177,7 +177,7 @@ KERNEL_ATTR_RO(crash_elfcorehdr_size);
> > #endif
> > -#endif /* CONFIG_CRASH_CORE */
> > +#endif /* CONFIG_VMCORE_INFO */
> > /* whether file capabilities are enabled */
> > static ssize_t fscaps_show(struct kobject *kobj,
> > @@ -265,7 +265,7 @@ static struct attribute * kernel_attrs[] = {
> > &kexec_crash_loaded_attr.attr,
> > &kexec_crash_size_attr.attr,
> > #endif
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> > &vmcoreinfo_attr.attr,
> > #ifdef CONFIG_CRASH_HOTPLUG
> > &crash_elfcorehdr_size_attr.attr,
> > diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> > index f2444b581e16..7d74b000b43a 100644
> > --- a/kernel/printk/printk.c
> > +++ b/kernel/printk/printk.c
> > @@ -34,7 +34,7 @@
> > #include <linux/security.h>
> > #include <linux/memblock.h>
> > #include <linux/syscalls.h>
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> > #include <linux/ratelimit.h>
> > #include <linux/kmsg_dump.h>
> > #include <linux/syslog.h>
> > @@ -951,7 +951,7 @@ const struct file_operations kmsg_fops = {
> > .release = devkmsg_release,
> > };
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> > /*
> > * This appends the listed symbols to /proc/vmcore
> > *
> > diff --git a/kernel/vmcore_info.c b/kernel/vmcore_info.c
> > new file mode 100644
> > index 000000000000..84f3663530c8
> > --- /dev/null
> > +++ b/kernel/vmcore_info.c
> > @@ -0,0 +1,233 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * crash.c - kernel crash support code.
> > + * Copyright (C) 2002-2004 Eric Biederman <[email protected]>
> > + */
> > +
> > +#include <linux/buildid.h>
> > +#include <linux/init.h>
> > +#include <linux/utsname.h>
> > +#include <linux/vmalloc.h>
> > +#include <linux/sizes.h>
> > +#include <linux/kexec.h>
> > +#include <linux/memory.h>
> > +#include <linux/cpuhotplug.h>
> > +#include <linux/memblock.h>
> > +#include <linux/kexec.h>
> > +#include <linux/kmemleak.h>
> > +
> > +#include <asm/page.h>
> > +#include <asm/sections.h>
> > +
> > +#include <crypto/sha1.h>
> > +
> > +#include "kallsyms_internal.h"
> > +#include "kexec_internal.h"
> > +
> > +/* vmcoreinfo stuff */
> > +unsigned char *vmcoreinfo_data;
> > +size_t vmcoreinfo_size;
> > +u32 *vmcoreinfo_note;
> > +
> > +/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
> > +static unsigned char *vmcoreinfo_data_safecopy;
> > +
> > +Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> > + void *data, size_t data_len)
> > +{
> > + struct elf_note *note = (struct elf_note *)buf;
> > +
> > + note->n_namesz = strlen(name) + 1;
> > + note->n_descsz = data_len;
> > + note->n_type = type;
> > + buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> > + memcpy(buf, name, note->n_namesz);
> > + buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
> > + memcpy(buf, data, data_len);
> > + buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
> > +
> > + return buf;
> > +}
> > +
> > +void final_note(Elf_Word *buf)
> > +{
> > + memset(buf, 0, sizeof(struct elf_note));
> > +}
> > +
> > +static void update_vmcoreinfo_note(void)
> > +{
> > + u32 *buf = vmcoreinfo_note;
> > +
> > + if (!vmcoreinfo_size)
> > + return;
> > + buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> > + vmcoreinfo_size);
> > + final_note(buf);
> > +}
> > +
> > +void crash_update_vmcoreinfo_safecopy(void *ptr)
> > +{
> > + if (ptr)
> > + memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
> > +
> > + vmcoreinfo_data_safecopy = ptr;
> > +}
> > +
> > +void crash_save_vmcoreinfo(void)
> > +{
> > + if (!vmcoreinfo_note)
> > + return;
> > +
> > + /* Use the safe copy to generate vmcoreinfo note if have */
> > + if (vmcoreinfo_data_safecopy)
> > + vmcoreinfo_data = vmcoreinfo_data_safecopy;
> > +
> > + vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
> > + update_vmcoreinfo_note();
> > +}
> > +
> > +void vmcoreinfo_append_str(const char *fmt, ...)
> > +{
> > + va_list args;
> > + char buf[0x50];
> > + size_t r;
> > +
> > + va_start(args, fmt);
> > + r = vscnprintf(buf, sizeof(buf), fmt, args);
> > + va_end(args);
> > +
> > + r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
> > +
> > + memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
> > +
> > + vmcoreinfo_size += r;
> > +
> > + WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
> > + "vmcoreinfo data exceeds allocated size, truncating");
> > +}
> > +
> > +/*
> > + * provide an empty default implementation here -- architecture
> > + * code may override this
> > + */
> > +void __weak arch_crash_save_vmcoreinfo(void)
> > +{}
> > +
> > +phys_addr_t __weak paddr_vmcoreinfo_note(void)
> > +{
> > + return __pa(vmcoreinfo_note);
> > +}
> > +EXPORT_SYMBOL(paddr_vmcoreinfo_note);
> > +
> > +static int __init crash_save_vmcoreinfo_init(void)
> > +{
> > + vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
> > + if (!vmcoreinfo_data) {
> > + pr_warn("Memory allocation for vmcoreinfo_data failed\n");
> > + return -ENOMEM;
> > + }
> > +
> > + vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
> > + GFP_KERNEL | __GFP_ZERO);
> > + if (!vmcoreinfo_note) {
> > + free_page((unsigned long)vmcoreinfo_data);
> > + vmcoreinfo_data = NULL;
> > + pr_warn("Memory allocation for vmcoreinfo_note failed\n");
> > + return -ENOMEM;
> > + }
> > +
> > + VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
> > + VMCOREINFO_BUILD_ID();
> > + VMCOREINFO_PAGESIZE(PAGE_SIZE);
> > +
> > + VMCOREINFO_SYMBOL(init_uts_ns);
> > + VMCOREINFO_OFFSET(uts_namespace, name);
> > + VMCOREINFO_SYMBOL(node_online_map);
> > +#ifdef CONFIG_MMU
> > + VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
> > +#endif
> > + VMCOREINFO_SYMBOL(_stext);
> > + VMCOREINFO_SYMBOL(vmap_area_list);
> > +
> > +#ifndef CONFIG_NUMA
> > + VMCOREINFO_SYMBOL(mem_map);
> > + VMCOREINFO_SYMBOL(contig_page_data);
> > +#endif
> > +#ifdef CONFIG_SPARSEMEM
> > + VMCOREINFO_SYMBOL_ARRAY(mem_section);
> > + VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
> > + VMCOREINFO_STRUCT_SIZE(mem_section);
> > + VMCOREINFO_OFFSET(mem_section, section_mem_map);
> > + VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
> > + VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
> > +#endif
> > + VMCOREINFO_STRUCT_SIZE(page);
> > + VMCOREINFO_STRUCT_SIZE(pglist_data);
> > + VMCOREINFO_STRUCT_SIZE(zone);
> > + VMCOREINFO_STRUCT_SIZE(free_area);
> > + VMCOREINFO_STRUCT_SIZE(list_head);
> > + VMCOREINFO_SIZE(nodemask_t);
> > + VMCOREINFO_OFFSET(page, flags);
> > + VMCOREINFO_OFFSET(page, _refcount);
> > + VMCOREINFO_OFFSET(page, mapping);
> > + VMCOREINFO_OFFSET(page, lru);
> > + VMCOREINFO_OFFSET(page, _mapcount);
> > + VMCOREINFO_OFFSET(page, private);
> > + VMCOREINFO_OFFSET(page, compound_head);
> > + VMCOREINFO_OFFSET(pglist_data, node_zones);
> > + VMCOREINFO_OFFSET(pglist_data, nr_zones);
> > +#ifdef CONFIG_FLATMEM
> > + VMCOREINFO_OFFSET(pglist_data, node_mem_map);
> > +#endif
> > + VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
> > + VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
> > + VMCOREINFO_OFFSET(pglist_data, node_id);
> > + VMCOREINFO_OFFSET(zone, free_area);
> > + VMCOREINFO_OFFSET(zone, vm_stat);
> > + VMCOREINFO_OFFSET(zone, spanned_pages);
> > + VMCOREINFO_OFFSET(free_area, free_list);
> > + VMCOREINFO_OFFSET(list_head, next);
> > + VMCOREINFO_OFFSET(list_head, prev);
> > + VMCOREINFO_OFFSET(vmap_area, va_start);
> > + VMCOREINFO_OFFSET(vmap_area, list);
> > + VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
> > + log_buf_vmcoreinfo_setup();
> > + VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
> > + VMCOREINFO_NUMBER(NR_FREE_PAGES);
> > + VMCOREINFO_NUMBER(PG_lru);
> > + VMCOREINFO_NUMBER(PG_private);
> > + VMCOREINFO_NUMBER(PG_swapcache);
> > + VMCOREINFO_NUMBER(PG_swapbacked);
> > + VMCOREINFO_NUMBER(PG_slab);
> > +#ifdef CONFIG_MEMORY_FAILURE
> > + VMCOREINFO_NUMBER(PG_hwpoison);
> > +#endif
> > + VMCOREINFO_NUMBER(PG_head_mask);
> > +#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
> > + VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> > +#ifdef CONFIG_HUGETLB_PAGE
> > + VMCOREINFO_NUMBER(PG_hugetlb);
> > +#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
> > + VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
> > +#endif
> > +
> > +#ifdef CONFIG_KALLSYMS
> > + VMCOREINFO_SYMBOL(kallsyms_names);
> > + VMCOREINFO_SYMBOL(kallsyms_num_syms);
> > + VMCOREINFO_SYMBOL(kallsyms_token_table);
> > + VMCOREINFO_SYMBOL(kallsyms_token_index);
> > +#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
> > + VMCOREINFO_SYMBOL(kallsyms_offsets);
> > + VMCOREINFO_SYMBOL(kallsyms_relative_base);
> > +#else
> > + VMCOREINFO_SYMBOL(kallsyms_addresses);
> > +#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
> > +#endif /* CONFIG_KALLSYMS */
> > +
> > + arch_crash_save_vmcoreinfo();
> > + update_vmcoreinfo_note();
> > +
> > + return 0;
> > +}
> > +
> > +subsys_initcall(crash_save_vmcoreinfo_init);
> > diff --git a/lib/buildid.c b/lib/buildid.c
> > index e3a7acdeef0e..3e6868c86b45 100644
> > --- a/lib/buildid.c
> > +++ b/lib/buildid.c
> > @@ -174,7 +174,7 @@ int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size)
> > return parse_build_id_buf(build_id, NULL, buf, buf_size);
> > }
> > -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
> > +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
> > unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX] __ro_after_init;
> > /**
>


2024-02-22 21:29:43

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

On Thu, 22 Feb 2024 10:47:29 +0530 Hari Bathini <[email protected]> wrote:

>
>
> On 22/02/24 2:27 am, Andrew Morton wrote:
> > On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <[email protected]> wrote:
> >
> >> On 04/02/24 8:56 am, Baoquan He wrote:
> >>>>> Hope Hari and Pingfan can help have a look, see if
> >>>>> it's doable. Now, I make it either have both kexec and crash enabled, or
> >>>>> disable both of them altogether.
> >>>>
> >>>> Sure. I will take a closer look...
> >>> Thanks a lot. Please feel free to post patches to make that, or I can do
> >>> it with your support or suggestion.
> >>
> >> Tested your changes and on top of these changes, came up with the below
> >> changes to get it working for powerpc:
> >>
> >>
> >> https://lore.kernel.org/all/[email protected]/
> >
> > So can we take it that you're OK with Baoquan's series as-is?
>
> Hi Andrew,
>
> If you mean
>
> v3 (https://lore.kernel.org/all/[email protected]/)
> +
> follow-up from Baoquan
> (https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv/)
>
> Yes.
>

Can I add your Acked-by: and/or Tested-by: to the patches in this series?

2024-02-23 05:42:24

by Hari Bathini

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items



On 23/02/24 2:59 am, Andrew Morton wrote:
> On Thu, 22 Feb 2024 10:47:29 +0530 Hari Bathini <[email protected]> wrote:
>
>>
>>
>> On 22/02/24 2:27 am, Andrew Morton wrote:
>>> On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <[email protected]> wrote:
>>>
>>>> On 04/02/24 8:56 am, Baoquan He wrote:
>>>>>>> Hope Hari and Pingfan can help have a look, see if
>>>>>>> it's doable. Now, I make it either have both kexec and crash enabled, or
>>>>>>> disable both of them altogether.
>>>>>>
>>>>>> Sure. I will take a closer look...
>>>>> Thanks a lot. Please feel free to post patches to make that, or I can do
>>>>> it with your support or suggestion.
>>>>
>>>> Tested your changes and on top of these changes, came up with the below
>>>> changes to get it working for powerpc:
>>>>
>>>>
>>>> https://lore.kernel.org/all/[email protected]/
>>>
>>> So can we take it that you're OK with Baoquan's series as-is?
>>
>> Hi Andrew,
>>
>> If you mean
>>
>> v3 (https://lore.kernel.org/all/[email protected]/)
>> +
>> follow-up from Baoquan
>> (https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv/)
>>
>> Yes.
>>
>
> Can I add your Acked-by: and/or Tested-by: to the patches in this series?

Sure, Andrew.

Acked-by: Hari Bathini <[email protected]>

for..

Patches 1-5 & 8 in:

https://lore.kernel.org/all/[email protected]/

and this follow-up patch:

https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv/

Thanks
Hari