The Kconfig is refactored to consolidate KEXEC and CRASH options from various arch/<arch>/Kconfig files into new file kernel/Kconfig.kexec. The Kconfig.kexec is now a submenu titled "Kexec and crash features" located under "General Setup". The following options are impacted: - KEXEC - KEXEC_FILE - KEXEC_SIG - KEXEC_SIG_FORCE - KEXEC_IMAGE_VERIFY_SIG - KEXEC_BZIMAGE_VERIFY_SIG - KEXEC_JUMP - CRASH_DUMP Over time, these options have been copied between Kconfig files and are very similar to one another, but with slight differences. The following architectures are impacted by the refactor (because of use of one or more KEXEC/CRASH options): - arm - arm64 - ia64 - loongarch - m68k - mips - parisc - powerpc - riscv - s390 - sh - x86 More information: In the patch series "crash: Kernel handling of CPU and memory hot un/plug" https://lore.kernel.org/lkml/20230503224145.7405-1-eric.devolder@xxxxxxxxxx/ the new kernel feature introduces the config option CRASH_HOTPLUG. In reviewing, Thomas Gleixner requested that the new config option not be placed in x86 Kconfig. Rather the option needs a generic/common home. To Thomas' point, the KEXEC and CRASH options have largely been duplicated in the various arch/<arch>/Kconfig files, with minor differences. This kind of proliferation is to be avoid/stopped. https://lore.kernel.org/lkml/875y91yv63.ffs@tglx/ To that end, I have refactored the arch Kconfigs so as to consolidate the various KEXEC and CRASH options. Generally speaking, this work has the following themes: - KEXEC and CRASH options are moved into new file kernel/Kconfig.kexec - These items from arch/Kconfig: CRASH_CORE KEXEC_CORE KEXEC_ELF HAVE_IMA_KEXEC - These items from arch/x86/Kconfig form the common options: KEXEC KEXEC_FILE KEXEC_SIG KEXEC_SIG_FORCE KEXEC_BZIMAGE_VERIFY_SIG KEXEC_JUMP CRASH_DUMP - These items from arch/arm64/Kconfig form the common options: KEXEC_IMAGE_VERIFY_SIG - The crash hotplug series appends CRASH_HOTPLUG to Kconfig.kexec - The Kconfig.kexec is now a submenu titled "Kexec and crash features" and is now listed in "General Setup" submenu from init/Kconfig. - To control the common options, each has a new ARCH_SUPPORTS_<option> option. These gateway options determine whether the common options options are valid for the architecture. - To account for the slight differences in the original architecture coding of the common options, each now has a corresponding ARCH_SELECTS_<option> which are used to elicit the same side effects as the original arch/<arch>/Kconfig files for KEXEC and CRASH options. An example, 'make menuconfig' illustrating the submenu: > General setup > Kexec and crash features [*] Enable kexec system call [*] Enable kexec file based system call [*] Verify kernel signature during kexec_file_load() syscall [ ] Require a valid signature in kexec_file_load() syscall [ ] Enable bzImage signature verification support [*] kexec jump [*] kernel crash dumps [*] Update the crash elfcorehdr on system configuration changes In the process of consolidating the common options, I encountered slight differences in the coding of these options in several of the architectures. As a result, I settled on the following solution: - Each of the common options has a 'depends on ARCH_SUPPORTS_<option>' statement. For example, the KEXEC_FILE option has a 'depends on ARCH_SUPPORTS_KEXEC_FILE' statement. This approach is needed on all common options so as to prevent options from appearing for architectures which previously did not allow/enable them. For example, arm supports KEXEC but not KEXEC_FILE. The arch/arm/Kconfig does not provide ARCH_SUPPORTS_KEXEC_FILE and so KEXEC_FILE and related options are not available to arm. - The boolean ARCH_SUPPORTS_<option> in effect allows the arch to determine when the feature is allowed. Archs which don't have the feature simply do not provide the corresponding ARCH_SUPPORTS_<option>. For each arch, where there previously were KEXEC and/or CRASH options, these have been replaced with the corresponding boolean ARCH_SUPPORTS_<option>, and an appropriate def_bool statement. For example, if the arch supports KEXEC_FILE, then the ARCH_SUPPORTS_KEXEC_FILE simply has a 'def_bool y'. This permits the KEXEC_FILE option to be available. If the arch has a 'depends on' statement in its original coding of the option, then that expression becomes part of the def_bool expression. For example, arm64 had: config KEXEC depends on PM_SLEEP_SMP and in this solution, this converts to: config ARCH_SUPPORTS_KEXEC def_bool PM_SLEEP_SMP - In order to account for the architecture differences in the coding for the common options, the ARCH_SELECTS_<option> in the arch/<arch>/Kconfig is used. This option has a 'depends on <option>' statement to couple it to the main option, and from there can insert the differences from the common option and the arch original coding of that option. For example, a few archs enable CRYPTO and CRYTPO_SHA256 for KEXEC_FILE. These require a ARCH_SELECTS_KEXEC_FILE and 'select CRYPTO' and 'select CRYPTO_SHA256' statements. Illustrating the option relationships: For each of the common KEXEC and CRASH options: ARCH_SUPPORTS_<option> <- <option> <- ARCH_SELECTS_<option> <option> # in Kconfig.kexec ARCH_SUPPORTS_<option> # in arch/<arch>/Kconfig, as needed ARCH_SELECTS_<option> # in arch/<arch>/Kconfig, as needed For example, KEXEC: ARCH_SUPPORTS_KEXEC <- KEXEC <- ARCH_SELECTS_KEXEC KEXEC # in Kconfig.kexec ARCH_SUPPORTS_KEXEC # in arch/<arch>/Kconfig, as needed ARCH_SELECTS_KEXEC # in arch/<arch>/Kconfig, as needed To summarize, the ARCH_SUPPORTS_<option> permits the <option> to be enabled, and the ARCH_SELECTS_<option> handles side effects (ie. select statements). Examples: A few examples to show the new strategy in action: ===== x86 (minus the help section) ===== Original: config KEXEC bool "kexec system call" select KEXEC_CORE config KEXEC_FILE bool "kexec file based system call" select KEXEC_CORE select HAVE_IMA_KEXEC if IMA depends on X86_64 depends on CRYPTO=y depends on CRYPTO_SHA256=y config ARCH_HAS_KEXEC_PURGATORY def_bool KEXEC_FILE config KEXEC_SIG bool "Verify kernel signature during kexec_file_load() syscall" depends on KEXEC_FILE config KEXEC_SIG_FORCE bool "Require a valid signature in kexec_file_load() syscall" depends on KEXEC_SIG config KEXEC_BZIMAGE_VERIFY_SIG bool "Enable bzImage signature verification support" depends on KEXEC_SIG depends on SIGNED_PE_FILE_VERIFICATION select SYSTEM_TRUSTED_KEYRING config CRASH_DUMP bool "kernel crash dumps" depends on X86_64 || (X86_32 && HIGHMEM) config KEXEC_JUMP bool "kexec jump" depends on KEXEC && HIBERNATION help becomes... New: config ARCH_SUPPORTS_KEXEC def_bool y config ARCH_SUPPORTS_KEXEC_FILE def_bool X86_64 && CRYPTO && CRYPTO_SHA256 config ARCH_SELECTS_KEXEC_FILE def_bool y depends on KEXEC_FILE select HAVE_IMA_KEXEC if IMA config ARCH_SUPPORTS_KEXEC_PURGATORY def_bool KEXEC_FILE config ARCH_SUPPORTS_KEXEC_SIG def_bool y config ARCH_SUPPORTS_KEXEC_SIG_FORCE def_bool y config ARCH_SUPPORTS_KEXEC_BZIMAGE_VERIFY_SIG def_bool y config ARCH_SUPPORTS_KEXEC_JUMP def_bool y config ARCH_SUPPORTS_CRASH_DUMP def_bool X86_64 || (X86_32 && HIGHMEM) ===== powerpc (minus the help section) ===== Original: config KEXEC bool "kexec system call" depends on PPC_BOOK3S || PPC_E500 || (44x && !SMP) select KEXEC_CORE config KEXEC_FILE bool "kexec file based system call" select KEXEC_CORE select HAVE_IMA_KEXEC if IMA select KEXEC_ELF depends on PPC64 depends on CRYPTO=y depends on CRYPTO_SHA256=y config ARCH_HAS_KEXEC_PURGATORY def_bool KEXEC_FILE config CRASH_DUMP bool "Build a dump capture kernel" depends on PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP) select RELOCATABLE if PPC64 || 44x || PPC_85xx becomes... New: config ARCH_SUPPORTS_KEXEC def_bool PPC_BOOK3S || PPC_E500 || (44x && !SMP) config ARCH_SUPPORTS_KEXEC_FILE def_bool PPC64 && CRYPTO=y && CRYPTO_SHA256=y config ARCH_SUPPORTS_KEXEC_PURGATORY def_bool KEXEC_FILE config ARCH_SELECTS_KEXEC_FILE def_bool y depends on KEXEC_FILE select KEXEC_ELF select HAVE_IMA_KEXEC if IMA config ARCH_SUPPORTS_CRASH_DUMP def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP) config ARCH_SELECTS_CRASH_DUMP def_bool y depends on CRASH_DUMP select RELOCATABLE if PPC64 || 44x || PPC_85xx Testing Approach and Results There are 388 config files in the arch/<arch>/configs directories. For each of these config files, a .config is generated both before and after this Kconfig series, and checked for equivalence. This approach allows for a rather rapid check of all architectures and a wide variety of configs wrt/ KEXEC and CRASH, and avoids requiring compiling for all architectures and running kernels and run-time testing. For each config file, the olddefconfig, allnoconfig and allyesconfig targets are utilized. In testing the randconfig has revealed problems as well, but is not used in the before and after equivalence check since one can not generate the "same" .config for before and after, even if using the same KCONFIG_SEED since the option list is different. As such, the following script steps compare the before and after of 'make olddefconfig'. The new symbols introduced by this series are filtered out, but otherwise the config files are PASS only if they were equivalent, and FAIL otherwise. The script performs the test by doing the following: # Obtain the "golden" .config output for given config file # Reset test sandbox git checkout master git branch -D test_Kconfig git checkout -B test_Kconfig master make distclean # Write out updated config cp -f <config file> .config make ARCH=<arch> olddefconfig # Track each item in .config, LHSB is "golden" scoreboard .config # Obtain the "changed" .config output for given config file # Reset test sandbox make distclean # Apply this Kconfig series git am <this Kconfig series> # Write out updated config cp -f <config file> .config make ARCH=<arch> olddefconfig # Track each item in .config, RHSB is "changed" scoreboard .config # Determine test result # Filter-out new symbols introduced by this series # Filter-out symbol=n which not in either scoreboard # Compare LHSB "golden" and RHSB "changed" scoreboards and issue PASS/FAIL The script was instrumental during the refactoring of Kconfig as it continually revealed problems. The end result being that the solution presented in this series passes all configs as checked by the script, with the following exceptions: - arch/ia64/configs/zx1_config with olddefconfig This config file has: # CONFIG_KEXEC is not set CONFIG_CRASH_DUMP=y and this refactor now couples KEXEC to CRASH_DUMP, so it is not possible to enable CRASH_DUMP without KEXEC. - arch/sh/configs/* with allyesconfig The arch/sh/Kconfig codes CRASH_DUMP as dependent upon BROKEN_ON_MMU (which clearly is not meant to be set). This symbol is not provided but with the allyesconfig it is set to yes which enables CRASH_DUMP. But KEXEC is coded as dependent upon MMU, and is set to no in arch/sh/mm/Kconfig, so KEXEC is not enabled. This refactor now couples KEXEC to CRASH_DUMP, so it is not possible to enable CRASH_DUMP without KEXEC. While the above exceptions are not equivalent to their original, the config file produced is valid (and in fact better wrt/ CRASH_DUMP handling). Regards, eric --- v6: 12jul2023 - More cycles with randconfig has revealed problems relating to MODULE_SIG_FORMAT/SYSTEM_DATA_VERIFICATION on s390. This version solves the problem by placing MODULE_SIG_FORMAT on the ARCH_SUPPORTS_KEXEC_SIG def_bool statement, similar to original. - Added patch to rename ARCH_HAS_KEXEC_PURGATORY to ARCH_SUPPORTS_KEXEC_PURGATORY to follow convention agreed upon since v2. - Re-run regressions locally including failing randconfig config files reported. v5: 6jul2023 https://lore.kernel.org/lkml/20230706222027.189117-1-eric.devolder@xxxxxxxxxx/ - Filled out all common options with a 'depends on ARCH_SUPPORTS_ <option>' and provided it in the needed archs. Result of testing with allnoconfig and allyesconfig. - Added 'depends on ARCH_SUPPORTS_KEXEC' to CRASH_DUMP, per Arnd Bergmann. - Investigated fails revealed by Andrew Morton's machinery, and spot tested with this solution. v4: 5jul2023 https://lore.kernel.org/lkml/20230705142004.3605799-1-eric.devolder@xxxxxxxxxx/ - Corrected conversion issue with riscv, per Conor Dooley. - Andrew Mortons's akpm test machinery found a problem with config files generated by randconfig. The problem existed prior to this series and manifests because most arch/<arch>/Kconfig CRASH_DUMP does not have any dependencies on KEXEC. As a result, randconfig produces a config file enabling CRASH_DUMP but not KEXEC, which leads to compile/link-time problems. Andrew requested closing this hole. To that end 'select KEXEC' has been added to CRASH_DUMP. This behavior pre-existed for arm arm64 ia64 loongarch mips powerpc riscv sh and x86. - Applied Acked-by's from: s390: Alexander Gordeev <agordeev@xxxxxxxxxxxxx> v3: 26jun2023 https://lore.kernel.org/lkml/20230626161332.183214-1-eric.devolder@xxxxxxxxxx/ - Rebased onto 6.4.0 - Reworded s390 commit message to clarify MODULE_SIG_FORMAT, per Alexander Gordeev - Applied Acked-by's from: m68k: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> mips: Thomas Bogendoerfer <tsbogend@xxxxxxxxxxxxxxxx> sh: John Paul Adrian Glaubitz <glaubitz@xxxxxxxxxxxxxxxxxxx> v2: 19jun2023 https://lore.kernel.org/lkml/20230619145801.1064716-1-eric.devolder@xxxxxxxxxx/ - The ARCH_HAS_ and ARCH_SUPPORTS_ combination was found to be too similar/confusing. Renamed these two new options as such: ARCH_HAS_<option> ---> ARCH_SUPPORTS_<option> ARCH_SUPPORTS_<option> ---> ARCH_SELECTS_<option> Per Kees Cook, Michael Ellerman NOTE: ARCH_HAS_KEXEC_PURGATORY was left as-is, as that is what it is prior to this series. Updated this cover letter to reflect the same. - Some minor cleaning up of the help sections, per Zhen Lei and Alexander Gordeev. - Removed the MODULE_SIG_FORMAT dependency from KEXEC_SIG in kernel/Kconfig.kexec. Only s390 had it prior to this series. See also commit message in "s390/kexec: refactor for kernel/Kconfig.kexec" - Added to Kconfig.kexec the KEXEC_IMAGE_VERIFY_SIG from arm64, per Zhen Lei. - Fixed the powerpc ARCH_SUPPORTS_KEXEC_FILE conversion, per Michael Ellerman. v1: 12jun2023 https://lore.kernel.org/lkml/20230612172805.681179-1-eric.devolder@xxxxxxxxxx/ - Initial - Based on 6.4.0-rc6 --- Eric DeVolder (14): kexec: consolidate kexec and crash options into kernel/Kconfig.kexec x86/kexec: refactor for kernel/Kconfig.kexec arm/kexec: refactor for kernel/Kconfig.kexec ia64/kexec: refactor for kernel/Kconfig.kexec arm64/kexec: refactor for kernel/Kconfig.kexec loongarch/kexec: refactor for kernel/Kconfig.kexec m68k/kexec: refactor for kernel/Kconfig.kexec mips/kexec: refactor for kernel/Kconfig.kexec parisc/kexec: refactor for kernel/Kconfig.kexec powerpc/kexec: refactor for kernel/Kconfig.kexec riscv/kexec: refactor for kernel/Kconfig.kexec s390/kexec: refactor for kernel/Kconfig.kexec sh/kexec: refactor for kernel/Kconfig.kexec kexec: rename ARCH_HAS_KEXEC_PURGATORY arch/Kconfig | 13 ---- arch/arm/Kconfig | 29 ++------- arch/arm64/Kconfig | 64 +++++-------------- arch/ia64/Kconfig | 28 ++------ arch/loongarch/Kconfig | 26 ++------ arch/m68k/Kconfig | 19 +----- arch/mips/Kconfig | 32 ++-------- arch/parisc/Kconfig | 34 ++++------ arch/powerpc/Kconfig | 57 ++++++----------- arch/riscv/Kbuild | 2 +- arch/riscv/Kconfig | 46 ++++---------- arch/riscv/kernel/elf_kexec.c | 4 +- arch/s390/Kbuild | 2 +- arch/s390/Kconfig | 69 +++++++------------- arch/sh/Kconfig | 46 +++----------- arch/x86/Kconfig | 92 ++++++--------------------- init/Kconfig | 2 + kernel/Kconfig.kexec | 116 ++++++++++++++++++++++++++++++++++ kernel/kexec_file.c | 6 +- 19 files changed, 257 insertions(+), 430 deletions(-) create mode 100644 kernel/Kconfig.kexec -- 2.31.1