Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crash: add a new kexec flag for hotplug support

Commit a72bbec70da2 ("crash: hotplug support for kexec_load()")
introduced a new kexec flag, `KEXEC_UPDATE_ELFCOREHDR`. Kexec tool uses
this flag to indicate to the kernel that it is safe to modify the
elfcorehdr of the kdump image loaded using the kexec_load system call.

However, it is possible that architectures may need to update kexec
segments other then elfcorehdr. For example, FDT (Flatten Device Tree)
on PowerPC. Introducing a new kexec flag for every new kexec segment
may not be a good solution. Hence, a generic kexec flag bit,
`KEXEC_CRASH_HOTPLUG_SUPPORT`, is introduced to share the CPU/Memory
hotplug support intent between the kexec tool and the kernel for the
kexec_load system call.

Now we have two kexec flags that enables crash hotplug support for
kexec_load system call. First is KEXEC_UPDATE_ELFCOREHDR (only used in
x86), and second is KEXEC_CRASH_HOTPLUG_SUPPORT (for all architectures).

To simplify the process of finding and reporting the crash hotplug
support the following changes are introduced.

1. Define arch specific function to process the kexec flags and
determine crash hotplug support

2. Rename the @update_elfcorehdr member of struct kimage to
@hotplug_support and populate it for both kexec_load and
kexec_file_load syscalls, because architecture can update more than
one kexec segment

3. Let generic function crash_check_hotplug_support report hotplug
support for loaded kdump image based on value of @hotplug_support

To bring the x86 crash hotplug support in line with the above points,
the following changes have been made:

- Introduce the arch_crash_hotplug_support function to process kexec
flags and determine crash hotplug support

- Remove the arch_crash_hotplug_[cpu|memory]_support functions

Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Acked-by: Baoquan He <bhe@redhat.com>
Acked-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20240326055413.186534-3-sourabhjain@linux.ibm.com

authored by

Sourabh Jain and committed by
Michael Ellerman
79365026 11800571

+48 -44
+2 -9
arch/x86/include/asm/kexec.h
··· 210 210 void arch_crash_handle_hotplug_event(struct kimage *image, void *arg); 211 211 #define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event 212 212 213 - #ifdef CONFIG_HOTPLUG_CPU 214 - int arch_crash_hotplug_cpu_support(void); 215 - #define crash_hotplug_cpu_support arch_crash_hotplug_cpu_support 216 - #endif 217 - 218 - #ifdef CONFIG_MEMORY_HOTPLUG 219 - int arch_crash_hotplug_memory_support(void); 220 - #define crash_hotplug_memory_support arch_crash_hotplug_memory_support 221 - #endif 213 + int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags); 214 + #define arch_crash_hotplug_support arch_crash_hotplug_support 222 215 223 216 unsigned int arch_crash_get_elfcorehdr_size(void); 224 217 #define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
+17 -11
arch/x86/kernel/crash.c
··· 402 402 #undef pr_fmt 403 403 #define pr_fmt(fmt) "crash hp: " fmt 404 404 405 - /* These functions provide the value for the sysfs crash_hotplug nodes */ 406 - #ifdef CONFIG_HOTPLUG_CPU 407 - int arch_crash_hotplug_cpu_support(void) 405 + int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags) 408 406 { 409 - return crash_check_update_elfcorehdr(); 410 - } 411 - #endif 412 407 413 - #ifdef CONFIG_MEMORY_HOTPLUG 414 - int arch_crash_hotplug_memory_support(void) 415 - { 416 - return crash_check_update_elfcorehdr(); 417 - } 408 + #ifdef CONFIG_KEXEC_FILE 409 + if (image->file_mode) 410 + return 1; 418 411 #endif 412 + /* 413 + * Initially, crash hotplug support for kexec_load was added 414 + * with the KEXEC_UPDATE_ELFCOREHDR flag. Later, this 415 + * functionality was expanded to accommodate multiple kexec 416 + * segment updates, leading to the introduction of the 417 + * KEXEC_CRASH_HOTPLUG_SUPPORT kexec flag bit. Consequently, 418 + * when the kexec tool sends either of these flags, it indicates 419 + * that the required kexec segment (elfcorehdr) is excluded from 420 + * the SHA calculation. 421 + */ 422 + return (kexec_flags & KEXEC_UPDATE_ELFCOREHDR || 423 + kexec_flags & KEXEC_CRASH_HOTPLUG_SUPPORT); 424 + } 419 425 420 426 unsigned int arch_crash_get_elfcorehdr_size(void) 421 427 {
+1 -1
drivers/base/cpu.c
··· 306 306 struct device_attribute *attr, 307 307 char *buf) 308 308 { 309 - return sysfs_emit(buf, "%d\n", crash_hotplug_cpu_support()); 309 + return sysfs_emit(buf, "%d\n", crash_check_hotplug_support()); 310 310 } 311 311 static DEVICE_ATTR_ADMIN_RO(crash_hotplug); 312 312 #endif
+1 -1
drivers/base/memory.c
··· 535 535 static ssize_t crash_hotplug_show(struct device *dev, 536 536 struct device_attribute *attr, char *buf) 537 537 { 538 - return sysfs_emit(buf, "%d\n", crash_hotplug_memory_support()); 538 + return sysfs_emit(buf, "%d\n", crash_check_hotplug_support()); 539 539 } 540 540 static DEVICE_ATTR_RO(crash_hotplug); 541 541 #endif
+6 -7
include/linux/crash_core.h
··· 40 40 static inline void arch_crash_handle_hotplug_event(struct kimage *image, void *arg) { } 41 41 #endif 42 42 43 - int crash_check_update_elfcorehdr(void); 43 + int crash_check_hotplug_support(void); 44 44 45 - #ifndef crash_hotplug_cpu_support 46 - static inline int crash_hotplug_cpu_support(void) { return 0; } 47 - #endif 48 - 49 - #ifndef crash_hotplug_memory_support 50 - static inline int crash_hotplug_memory_support(void) { return 0; } 45 + #ifndef arch_crash_hotplug_support 46 + static inline int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags) 47 + { 48 + return 0; 49 + } 51 50 #endif 52 51 53 52 #ifndef crash_get_elfcorehdr_size
+7 -4
include/linux/kexec.h
··· 319 319 /* If set, we are using file mode kexec syscall */ 320 320 unsigned int file_mode:1; 321 321 #ifdef CONFIG_CRASH_HOTPLUG 322 - /* If set, allow changes to elfcorehdr of kexec_load'd image */ 323 - unsigned int update_elfcorehdr:1; 322 + /* If set, it is safe to update kexec segments that are 323 + * excluded from SHA calculation. 324 + */ 325 + unsigned int hotplug_support:1; 324 326 #endif 325 327 326 328 #ifdef ARCH_HAS_KIMAGE_ARCH ··· 393 391 394 392 /* List of defined/legal kexec flags */ 395 393 #ifndef CONFIG_KEXEC_JUMP 396 - #define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_UPDATE_ELFCOREHDR) 394 + #define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_UPDATE_ELFCOREHDR | KEXEC_CRASH_HOTPLUG_SUPPORT) 397 395 #else 398 - #define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT | KEXEC_UPDATE_ELFCOREHDR) 396 + #define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT | KEXEC_UPDATE_ELFCOREHDR | \ 397 + KEXEC_CRASH_HOTPLUG_SUPPORT) 399 398 #endif 400 399 401 400 /* List of defined/legal kexec file flags */
+1
include/uapi/linux/kexec.h
··· 13 13 #define KEXEC_ON_CRASH 0x00000001 14 14 #define KEXEC_PRESERVE_CONTEXT 0x00000002 15 15 #define KEXEC_UPDATE_ELFCOREHDR 0x00000004 16 + #define KEXEC_CRASH_HOTPLUG_SUPPORT 0x00000008 16 17 #define KEXEC_ARCH_MASK 0xffff0000 17 18 18 19 /*
+6 -9
kernel/crash_core.c
··· 493 493 494 494 /* 495 495 * This routine utilized when the crash_hotplug sysfs node is read. 496 - * It reflects the kernel's ability/permission to update the crash 497 - * elfcorehdr directly. 496 + * It reflects the kernel's ability/permission to update the kdump 497 + * image directly. 498 498 */ 499 - int crash_check_update_elfcorehdr(void) 499 + int crash_check_hotplug_support(void) 500 500 { 501 501 int rc = 0; 502 502 ··· 508 508 return 0; 509 509 } 510 510 if (kexec_crash_image) { 511 - if (kexec_crash_image->file_mode) 512 - rc = 1; 513 - else 514 - rc = kexec_crash_image->update_elfcorehdr; 511 + rc = kexec_crash_image->hotplug_support; 515 512 } 516 513 /* Release lock now that update complete */ 517 514 kexec_unlock(); ··· 549 552 550 553 image = kexec_crash_image; 551 554 552 - /* Check that updating elfcorehdr is permitted */ 553 - if (!(image->file_mode || image->update_elfcorehdr)) 555 + /* Check that kexec segments update is permitted */ 556 + if (!image->hotplug_support) 554 557 goto out; 555 558 556 559 if (hp_action == KEXEC_CRASH_HP_ADD_CPU ||
+2 -2
kernel/kexec.c
··· 135 135 image->preserve_context = 1; 136 136 137 137 #ifdef CONFIG_CRASH_HOTPLUG 138 - if (flags & KEXEC_UPDATE_ELFCOREHDR) 139 - image->update_elfcorehdr = 1; 138 + if ((flags & KEXEC_ON_CRASH) && arch_crash_hotplug_support(image, flags)) 139 + image->hotplug_support = 1; 140 140 #endif 141 141 142 142 ret = machine_kexec_prepare(image);
+5
kernel/kexec_file.c
··· 376 376 if (ret) 377 377 goto out; 378 378 379 + #ifdef CONFIG_CRASH_HOTPLUG 380 + if ((flags & KEXEC_FILE_ON_CRASH) && arch_crash_hotplug_support(image, flags)) 381 + image->hotplug_support = 1; 382 + #endif 383 + 379 384 ret = machine_kexec_prepare(image); 380 385 if (ret) 381 386 goto out;