mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v3 0/2] x86/crash: fix kexec_file_load(2) -EINVAL on machines with many possible CPUs
@ 2026-08-26  7:35 Ionut Nechita (Wind River)
  2026-08-26  7:35 ` [PATCH v3 1/2] x86/crash: reserve elfcorehdr for CONFIG_NR_CPUS, not CONFIG_NR_CPUS_DEFAULT Ionut Nechita (Wind River)
  2026-08-26  7:35 ` [PATCH v3 2/2] crash: update stale NR_CPUS_DEFAULT references in elfcorehdr sizing docs Ionut Nechita (Wind River)
  0 siblings, 2 replies; 4+ messages in thread
From: Ionut Nechita (Wind River) @ 2026-08-26  7:35 UTC (permalink / raw)
  To: x86, kexec
  Cc: tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
	pasha.tatashin, pratyush, ruirui.yang, eric.devolder, hbathini,
	sourabhjain, ruanjinjie, include, linux-kernel

From: Ionut Nechita <ionut.nechita@windriver.com>

Hi,

On x86 with CONFIG_CRASH_HOTPLUG=y and CONFIG_MEMORY_HOTPLUG=n, the
crash elfcorehdr segment is reserved for

    nr_mem_ranges + 2 + CONFIG_NR_CPUS_DEFAULT

program headers, while the header that crash_prepare_elf64_headers()
actually builds carries

    nr_mem_ranges + 2 + num_possible_cpus()

of them.  num_possible_cpus() is bounded by CONFIG_NR_CPUS, not by
CONFIG_NR_CPUS_DEFAULT, so on configs that raise CONFIG_NR_CPUS above
the arch default without MAXSMP the header outgrows its reservation once
the excess exceeds the page padding, and kexec_file_load(2) is rejected
by sanity_check_segment_list() with -EINVAL.

Patch 1 reserves the elfcorehdr for CONFIG_NR_CPUS, the compile-time
upper bound of num_possible_cpus(), so the reservation always covers the
header that is actually generated.  It also fixes the same shortfall in
arch_crash_get_elfcorehdr_size(), which feeds
/sys/kernel/crash_elfcorehdr_size and therefore the kexec_load(2) path.

Patch 2 is a documentation-only follow-up requested during v1 review: it
updates the two remaining places that still name NR_CPUS_DEFAULT when
describing the elfcorehdr sizing (the comment above
crash_handle_hotplug_event() and the CRASH_MAX_MEMORY_RANGES help text).

Based on linux-next (next-20260825, base-commit a8406e6c0b79b).

Verified on a single-socket Xeon 6776P running a PREEMPT_RT kernel with:

    # CONFIG_MAXSMP is not set
    # CONFIG_MEMORY_HOTPLUG is not set
    CONFIG_NR_CPUS_RANGE_BEGIN=2
    CONFIG_NR_CPUS_RANGE_END=512
    CONFIG_NR_CPUS_DEFAULT=64
    CONFIG_NR_CPUS=256
    CONFIG_CRASH_MAX_MEMORY_RANGES=8192

- 144 possible CPUs: excess is (144 - 64) * 56 = 4480 bytes, more than
  the 4096 bytes of page padding, so 'kexec -p -s' fails with
  "kexec_file_load failed: Invalid argument"
- 72 possible CPUs (reduced via firmware): excess is (72 - 64) * 56 =
  448 bytes, still absorbed by the page rounding, and the load succeeds

Changes since v2:
- No code changes.  The diff is byte-identical to v2; only the patch 1/2
  changelog and the collected tags differ.
- Patch 1/2: corrected the claim that kexec_load(2) is "unaffected".
  As Sourabh Jain pointed out, with crash hotplug enabled kexec-tools
  sizes the elfcorehdr segment from /sys/kernel/crash_elfcorehdr_size in
  load_crashdump_segments(), i.e. from arch_crash_get_elfcorehdr_size(),
  which uses the same CONFIG_NR_CPUS_DEFAULT; add_segment_phys_virt()
  then clamps bufsz to memsz.  So that path does not fail the load, it
  silently truncates the elfcorehdr, which shows up later as a bad dump.
  Switching arch_crash_get_elfcorehdr_size() to CONFIG_NR_CPUS - which
  this patch already did - fixes that path as well.  The changelog now
  says so instead of claiming immunity.
- Patch 1/2: picked up Reviewed-by from Sourabh Jain and Acked-by from
  Baoquan He.
- Patch 2/2: picked up Reviewed-by from Bradley Morgan.
- Both patches: added an Assisted-by: LLM trailer, per
  Documentation/process/coding-assistants.rst.  An LLM was used for the
  root cause analysis and the changelog wording; the bug itself was
  found and reproduced on real hardware, the fix was reviewed by me, and
  the Signed-off-by is mine.  This should have been present in v1 and
  v2, and was not - my oversight.
- Rebased from next-20260824 onto next-20260825.

The two further issues Sourabh raised on the v2 thread - the
add_segment_phys_virt() bufsz truncation in kexec-tools, and having
crash_load_segments() skip the kbuf.memsz update when the prepared
buffer is already larger than the statically computed size - are
deliberately left out of this series and are worth handling separately,
as he suggested.

On the num_possible_cpus() alternative raised by Jinjie in v1: it would
give a tighter reservation and powerpc's arch_crash_get_elfcorehdr_size()
already does exactly that.  I kept CONFIG_NR_CPUS here because it is the
minimal, easy-to-backport fix - it just swaps the wrong compile-time
constant for the correct compile-time upper bound.  I am happy to respin
with num_possible_cpus() if maintainers prefer that.

v1: https://lore.kernel.org/lkml/20260812170433.533845-1-ionut.nechita@windriver.com/
v2: https://lore.kernel.org/lkml/20260825075043.42041-1-ionut.nechita@windriver.com/

Ionut Nechita (2):
  x86/crash: reserve elfcorehdr for CONFIG_NR_CPUS, not
    CONFIG_NR_CPUS_DEFAULT
  crash: update stale NR_CPUS_DEFAULT references in elfcorehdr sizing
    docs

 arch/x86/kernel/crash.c | 6 +++---
 kernel/Kconfig.kexec    | 2 +-
 kernel/crash_core.c     | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)


base-commit: a8406e6c0b793ce0788019683837c40855b55995
--
2.55.0


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

end of thread, other threads:[~2026-08-26 13:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-26  7:35 [PATCH v3 0/2] x86/crash: fix kexec_file_load(2) -EINVAL on machines with many possible CPUs Ionut Nechita (Wind River)
2026-08-26  7:35 ` [PATCH v3 1/2] x86/crash: reserve elfcorehdr for CONFIG_NR_CPUS, not CONFIG_NR_CPUS_DEFAULT Ionut Nechita (Wind River)
2026-08-26 13:33   ` Dave Hansen
2026-08-26  7:35 ` [PATCH v3 2/2] crash: update stale NR_CPUS_DEFAULT references in elfcorehdr sizing docs Ionut Nechita (Wind River)

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

all inboxes | Powered by JetHome®