Linux-RISC-V Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] riscv: crash: Add crash hotplug support
@ 2026-09-08 12:51 Rui Qi
  2026-09-09 21:30 ` kernel test robot
  0 siblings, 1 reply; 2+ messages in thread
From: Rui Qi @ 2026-09-08 12:51 UTC (permalink / raw)
  To: palmer, pjw, aou, alex
  Cc: Rui Qi, Deepak Gupta, Kees Cook, Charles Mirabile, Drew Fustini,
	Martin Kaiser, open list:RISC-V ARCHITECTURE, open list

When CPUs or memory are hot-plugged on a running system, the crash
dump's elfcorehdr -- which describes the available CPUs and memory to
the capture kernel -- must be kept in sync, otherwise a crash after a
hotplug event would produce a vmcore that does not reflect the current
system topology.

Enable crash hotplug for RISC-V by selecting
ARCH_SUPPORTS_CRASH_HOTPLUG and providing the three architecture hooks
invoked through the override macros in <asm/kexec.h>:

  arch_crash_hotplug_support() reports whether an image supports the
  mechanism; arch_crash_get_elfcorehdr_size() sizes the segment for
  NR_CPUS and, with memory hotplug, CRASH_MAX_MEMORY_RANGES;
  arch_crash_handle_hotplug_event() rebuilds the elfcorehdr through the
  crash_prepare_headers() helper and writes it over the old segment.

The elfcorehdr is copied with memcpy_flushcache(), matching the x86
implementation; on RISC-V this currently expands to a plain memcpy()
and will benefit automatically once the architecture provides a
flushcache backend. The implementation otherwise follows the x86 crash
hotplug model.

Signed-off-by: Rui Qi <qirui.001@bytedance.com>
Tested-by: Rui Qi <qirui.001@bytedance.com>

---
Testing performed:

Verified that kdump was loaded before each panic, then triggered a
sysrq panic under each of the following hotplug states:

  - CPU1 offline only
  - one memory block offline only
  - two CPUs offline
  - two memory blocks offline
  - CPU and memory offline, held for 60 s before panic

Each case produced a valid vmcore that could be opened with the crash
tool. At panic time the observed state matched expectations: offline
CPUs were reflected in __cpu_online_mask, and offline memory blocks
appeared as MEM_OFFLINE. kdump worked correctly across all tested CPU
and memory hotplug offline scenarios.
---
 arch/riscv/Kconfig             |   3 +
 arch/riscv/include/asm/kexec.h |  11 ++++
 arch/riscv/kernel/Makefile     |   1 +
 arch/riscv/kernel/crash.c      | 113 +++++++++++++++++++++++++++++++++
 4 files changed, 128 insertions(+)
 create mode 100644 arch/riscv/kernel/crash.c

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index ab7ca8f57420..123a6862dc10 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -1133,6 +1133,9 @@ config ARCH_DEFAULT_CRASH_DUMP
 config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
 	def_bool CRASH_RESERVE
 
+config ARCH_SUPPORTS_CRASH_HOTPLUG
+	def_bool y
+
 config COMPAT
 	bool "Kernel support for 32-bit U-mode"
 	default 64BIT
diff --git a/arch/riscv/include/asm/kexec.h b/arch/riscv/include/asm/kexec.h
index b9ee8346cc8c..de6b9b684a57 100644
--- a/arch/riscv/include/asm/kexec.h
+++ b/arch/riscv/include/asm/kexec.h
@@ -75,4 +75,15 @@ int load_extra_segments(struct kimage *image, unsigned long kernel_start,
 			unsigned long cmdline_len);
 #endif
 
+#ifdef CONFIG_CRASH_HOTPLUG
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
+#define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
+
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
+#define arch_crash_hotplug_support arch_crash_hotplug_support
+
+unsigned int arch_crash_get_elfcorehdr_size(void);
+#define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
+#endif
+
 #endif
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index ebe1c3588177..d0a5d442110f 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_KEXEC_CORE)	+= kexec_relocate.o crash_save_regs.o machine_kexec.o
 obj-$(CONFIG_KEXEC_FILE)	+= kexec_elf.o kexec_image.o machine_kexec_file.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
+obj-$(CONFIG_CRASH_HOTPLUG)	+= crash.o
 obj-$(CONFIG_VMCORE_INFO)	+= vmcore_info.o
 
 obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
diff --git a/arch/riscv/kernel/crash.c b/arch/riscv/kernel/crash.c
new file mode 100644
index 000000000000..fe5a4b306aae
--- /dev/null
+++ b/arch/riscv/kernel/crash.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * RISC-V crash hotplug support
+ *
+ * Copyright (C) 2025 Bytedance Ltd.
+ */
+
+#include <linux/kexec.h>
+#include <linux/crash_core.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+
+#ifdef CONFIG_CRASH_HOTPLUG
+
+#undef pr_fmt
+#define pr_fmt(fmt) "crash hp: " fmt
+
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags)
+{
+#ifdef CONFIG_KEXEC_FILE
+	if (image->file_mode)
+		return 1;
+#endif
+	/*
+	 * For the kexec_load() syscall path, the user space kexec tool
+	 * needs to indicate that the elfcorehdr segment is excluded from
+	 * SHA verification by setting the appropriate flags.
+	 */
+	return (kexec_flags & KEXEC_UPDATE_ELFCOREHDR ||
+		kexec_flags & KEXEC_CRASH_HOTPLUG_SUPPORT);
+}
+
+unsigned int arch_crash_get_elfcorehdr_size(void)
+{
+	unsigned int sz;
+
+	/* kernel_map, VMCOREINFO and maximum CPUs */
+	sz = 2 + CONFIG_NR_CPUS;
+	if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
+		sz += CONFIG_CRASH_MAX_MEMORY_RANGES;
+	sz *= sizeof(Elf64_Phdr);
+	return sz;
+}
+
+/**
+ * arch_crash_handle_hotplug_event() - Handle hotplug elfcorehdr changes
+ * @image: a pointer to kexec_crash_image
+ * @arg: struct memory_notify handler for memory hotplug case and
+ *       NULL for CPU hotplug case.
+ *
+ * Prepare the new elfcorehdr and replace the existing elfcorehdr.
+ */
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
+{
+	void *elfbuf = NULL, *old_elfcorehdr;
+	unsigned long mem, memsz;
+	unsigned long elfsz = 0;
+
+	/*
+	 * As crash_prepare_elf64_headers() has already described all
+	 * possible CPUs, there is no need to update the elfcorehdr
+	 * for additional CPU changes.
+	 */
+	if ((image->file_mode || image->elfcorehdr_updated) &&
+		((image->hp_action == KEXEC_CRASH_HP_ADD_CPU) ||
+		(image->hp_action == KEXEC_CRASH_HP_REMOVE_CPU)))
+		return;
+
+	/*
+	 * Create the new elfcorehdr reflecting the changes to CPU and/or
+	 * memory resources.
+	 */
+	if (crash_prepare_headers(true, &elfbuf, &elfsz, NULL)) {
+		pr_err("unable to create new elfcorehdr");
+		goto out;
+	}
+
+	/*
+	 * Obtain address and size of the elfcorehdr segment, and
+	 * check it against the new elfcorehdr buffer.
+	 */
+	mem = image->segment[image->elfcorehdr_index].mem;
+	memsz = image->segment[image->elfcorehdr_index].memsz;
+	if (elfsz > memsz) {
+		pr_err("update elfcorehdr elfsz %lu > memsz %lu",
+			elfsz, memsz);
+		goto out;
+	}
+
+	/*
+	 * Copy new elfcorehdr over the old elfcorehdr at destination.
+	 */
+	old_elfcorehdr = kmap_local_page(pfn_to_page(mem >> PAGE_SHIFT));
+	if (!old_elfcorehdr) {
+		pr_err("mapping elfcorehdr segment failed\n");
+		goto out;
+	}
+
+	/*
+	 * Temporarily invalidate the crash image while the
+	 * elfcorehdr is updated.
+	 */
+	xchg(&kexec_crash_image, NULL);
+	memcpy_flushcache(old_elfcorehdr, elfbuf, elfsz);
+	xchg(&kexec_crash_image, image);
+	kunmap_local(old_elfcorehdr);
+	pr_debug("updated elfcorehdr\n");
+
+out:
+	vfree(elfbuf);
+}
+
+#endif /* CONFIG_CRASH_HOTPLUG */
-- 
2.20.1

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] riscv: crash: Add crash hotplug support
  2026-09-08 12:51 [PATCH] riscv: crash: Add crash hotplug support Rui Qi
@ 2026-09-09 21:30 ` kernel test robot
  0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2026-09-09 21:30 UTC (permalink / raw)
  To: Rui Qi, palmer, pjw, aou, alex
  Cc: oe-kbuild-all, Rui Qi, Deepak Gupta, Kees Cook, Charles Mirabile,
	Drew Fustini, Martin Kaiser, open list:RISC-V ARCHITECTURE,
	open list

Hi Rui,

kernel test robot noticed the following build errors:

[auto build test ERROR on kees/for-next/kspp]
[also build test ERROR on linus/master kees/for-next/pstore v7.3-rc2 next-20260909]
[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/Rui-Qi/riscv-crash-Add-crash-hotplug-support/20260908-205143
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/kspp
patch link:    https://lore.kernel.org/r/20260908125155.1777895-1-qirui.001%40bytedance.com
patch subject: [PATCH] riscv: crash: Add crash hotplug support
config: riscv-randconfig-r071-20260910 (https://download.01.org/0day-ci/archive/20260910/202609100553.E6HUYviI-lkp@intel.com/config)
compiler: clang version 21.1.8 (https://github.com/llvm/llvm-project 2078da43e25a4623cab2d0d60decddf709aaea28)
smatch: v0.5.0-9187-g5189e3fb
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260910/202609100553.E6HUYviI-lkp@intel.com/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 <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202609100553.E6HUYviI-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from kernel/crash_reserve.c:12:
   In file included from include/linux/kexec.h:38:
>> arch/riscv/include/asm/kexec.h:79:45: warning: declaration of 'struct kimage' will not be visible outside of this function [-Wvisibility]
      79 | void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
         |                                             ^
   arch/riscv/include/asm/kexec.h:82:39: warning: declaration of 'struct kimage' will not be visible outside of this function [-Wvisibility]
      82 | int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
         |                                       ^
   2 warnings generated.
--
   In file included from kernel/kexec.c:13:
   In file included from include/linux/kexec.h:38:
>> arch/riscv/include/asm/kexec.h:79:45: warning: declaration of 'struct kimage' will not be visible outside of this function [-Wvisibility]
      79 | void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
         |                                             ^
   arch/riscv/include/asm/kexec.h:82:39: warning: declaration of 'struct kimage' will not be visible outside of this function [-Wvisibility]
      82 | int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
         |                                       ^
>> kernel/kexec.c:138:61: error: incompatible pointer types passing 'struct kimage *' to parameter of type 'struct kimage *' [-Werror,-Wincompatible-pointer-types]
     138 |         if ((flags & KEXEC_ON_CRASH) && arch_crash_hotplug_support(image, flags))
         |                                                                    ^~~~~
   arch/riscv/include/asm/kexec.h:82:47: note: passing argument to parameter 'image' here
      82 | int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
         |                                               ^
   2 warnings and 1 error generated.
--
   In file included from kernel/crash_core.c:14:
   In file included from include/linux/kexec.h:38:
>> arch/riscv/include/asm/kexec.h:79:45: warning: declaration of 'struct kimage' will not be visible outside of this function [-Wvisibility]
      79 | void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
         |                                             ^
   arch/riscv/include/asm/kexec.h:82:39: warning: declaration of 'struct kimage' will not be visible outside of this function [-Wvisibility]
      82 | int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
         |                                       ^
>> kernel/crash_core.c:718:34: error: incompatible pointer types passing 'struct kimage *' to parameter of type 'struct kimage *' [-Werror,-Wincompatible-pointer-types]
     718 |         arch_crash_handle_hotplug_event(image, arg);
         |                                         ^~~~~
   arch/riscv/include/asm/kexec.h:79:53: note: passing argument to parameter 'image' here
      79 | void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
         |                                                     ^
   2 warnings and 1 error generated.
--
   In file included from arch/riscv/kernel/crash.c:8:
   In file included from include/linux/kexec.h:38:
>> arch/riscv/include/asm/kexec.h:79:45: warning: declaration of 'struct kimage' will not be visible outside of this function [-Wvisibility]
      79 | void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
         |                                             ^
   arch/riscv/include/asm/kexec.h:82:39: warning: declaration of 'struct kimage' will not be visible outside of this function [-Wvisibility]
      82 | int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
         |                                       ^
>> arch/riscv/kernel/crash.c:18:5: error: conflicting types for 'arch_crash_hotplug_support'
      18 | int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags)
         |     ^
   arch/riscv/include/asm/kexec.h:83:36: note: expanded from macro 'arch_crash_hotplug_support'
      83 | #define arch_crash_hotplug_support arch_crash_hotplug_support
         |                                    ^
   arch/riscv/include/asm/kexec.h:82:5: note: previous declaration is here
      82 | int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
         |     ^
>> arch/riscv/kernel/crash.c:53:6: error: conflicting types for 'arch_crash_handle_hotplug_event'
      53 | void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
         |      ^
   arch/riscv/include/asm/kexec.h:80:41: note: expanded from macro 'arch_crash_handle_hotplug_event'
      80 | #define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
         |                                         ^
   arch/riscv/include/asm/kexec.h:79:6: note: previous declaration is here
      79 | void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
         |      ^
   2 warnings and 2 errors generated.


vim +/arch_crash_hotplug_support +18 arch/riscv/kernel/crash.c

    17	
  > 18	int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags)
    19	{
    20	#ifdef CONFIG_KEXEC_FILE
    21		if (image->file_mode)
    22			return 1;
    23	#endif
    24		/*
    25		 * For the kexec_load() syscall path, the user space kexec tool
    26		 * needs to indicate that the elfcorehdr segment is excluded from
    27		 * SHA verification by setting the appropriate flags.
    28		 */
    29		return (kexec_flags & KEXEC_UPDATE_ELFCOREHDR ||
    30			kexec_flags & KEXEC_CRASH_HOTPLUG_SUPPORT);
    31	}
    32	
    33	unsigned int arch_crash_get_elfcorehdr_size(void)
    34	{
    35		unsigned int sz;
    36	
    37		/* kernel_map, VMCOREINFO and maximum CPUs */
    38		sz = 2 + CONFIG_NR_CPUS;
    39		if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
    40			sz += CONFIG_CRASH_MAX_MEMORY_RANGES;
    41		sz *= sizeof(Elf64_Phdr);
    42		return sz;
    43	}
    44	
    45	/**
    46	 * arch_crash_handle_hotplug_event() - Handle hotplug elfcorehdr changes
    47	 * @image: a pointer to kexec_crash_image
    48	 * @arg: struct memory_notify handler for memory hotplug case and
    49	 *       NULL for CPU hotplug case.
    50	 *
    51	 * Prepare the new elfcorehdr and replace the existing elfcorehdr.
    52	 */
  > 53	void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
    54	{
    55		void *elfbuf = NULL, *old_elfcorehdr;
    56		unsigned long mem, memsz;
    57		unsigned long elfsz = 0;
    58	
    59		/*
    60		 * As crash_prepare_elf64_headers() has already described all
    61		 * possible CPUs, there is no need to update the elfcorehdr
    62		 * for additional CPU changes.
    63		 */
    64		if ((image->file_mode || image->elfcorehdr_updated) &&
    65			((image->hp_action == KEXEC_CRASH_HP_ADD_CPU) ||
    66			(image->hp_action == KEXEC_CRASH_HP_REMOVE_CPU)))
    67			return;
    68	
    69		/*
    70		 * Create the new elfcorehdr reflecting the changes to CPU and/or
    71		 * memory resources.
    72		 */
    73		if (crash_prepare_headers(true, &elfbuf, &elfsz, NULL)) {
    74			pr_err("unable to create new elfcorehdr");
    75			goto out;
    76		}
    77	
    78		/*
    79		 * Obtain address and size of the elfcorehdr segment, and
    80		 * check it against the new elfcorehdr buffer.
    81		 */
    82		mem = image->segment[image->elfcorehdr_index].mem;
    83		memsz = image->segment[image->elfcorehdr_index].memsz;
    84		if (elfsz > memsz) {
    85			pr_err("update elfcorehdr elfsz %lu > memsz %lu",
    86				elfsz, memsz);
    87			goto out;
    88		}
    89	
    90		/*
    91		 * Copy new elfcorehdr over the old elfcorehdr at destination.
    92		 */
    93		old_elfcorehdr = kmap_local_page(pfn_to_page(mem >> PAGE_SHIFT));
    94		if (!old_elfcorehdr) {
    95			pr_err("mapping elfcorehdr segment failed\n");
    96			goto out;
    97		}
    98	
    99		/*
   100		 * Temporarily invalidate the crash image while the
   101		 * elfcorehdr is updated.
   102		 */
   103		xchg(&kexec_crash_image, NULL);
   104		memcpy_flushcache(old_elfcorehdr, elfbuf, elfsz);
   105		xchg(&kexec_crash_image, image);
   106		kunmap_local(old_elfcorehdr);
   107		pr_debug("updated elfcorehdr\n");
   108	
   109	out:
   110		vfree(elfbuf);
   111	}
   112	

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

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-09 21:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-08 12:51 [PATCH] riscv: crash: Add crash hotplug support Rui Qi
2026-09-09 21:30 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox