Hello sourabh, On Wed, May 22, 2024 at 06:43:51PM GMT, Sourabh Jain wrote: > Kernel commit 79365026f869 (crash: add a new kexec flag for hotplug > support) has introduced a new kexec flag to generalize hotplug support. > The newly introduced kexec flags for hotplug allow architectures to > exclude all the required kexec segments from SHA calculation so that > the kernel can update them on hotplug events. This was not possible > earlier with the KEXEC_UPDATE_ELFCOREHDR kexec flags since it was added > only for the elfcorehdr segment. > > To enable architectures to control the list of kexec segments to exclude > when hotplug support is enabled, add a new architecture-specific > function named arch_do_exclude_segment. During the SHA calculation, this > function gets called to let the architecture decide whether a specific > kexec segment should be considered for SHA calculation or not. > > Given that the KEXEC_UPDATE_ELFCOREHDR is no longer required and was > colliding with the KEXEC_LIVE_UPDATE update flag, it is removed. > > Cc: Aditya Gupta <adityag@xxxxxxxxxxxxx> > Cc: Baoquan He <bhe@xxxxxxxxxx> > Cc: Coiby Xu <coxu@xxxxxxxxxx> > Cc: Hari Bathini <hbathini@xxxxxxxxxxxxx> > Cc: Mahesh Salgaonkar <mahesh@xxxxxxxxxxxxx> > Signed-off-by: Sourabh Jain <sourabhjain@xxxxxxxxxxxxx> > --- > kexec/arch/arm/kexec-arm.c | 5 +++++ > kexec/arch/arm64/kexec-arm64.c | 4 ++++ > kexec/arch/cris/kexec-cris.c | 4 ++++ > kexec/arch/hppa/kexec-hppa.c | 5 +++++ > kexec/arch/i386/kexec-x86.c | 8 ++++++++ > kexec/arch/ia64/kexec-ia64.c | 4 ++++ > kexec/arch/loongarch/kexec-loongarch.c | 5 +++++ > kexec/arch/m68k/kexec-m68k.c | 5 +++++ > kexec/arch/mips/kexec-mips.c | 4 ++++ > kexec/arch/ppc/kexec-ppc.c | 4 ++++ > kexec/arch/ppc64/kexec-ppc64.c | 5 +++++ > kexec/arch/s390/kexec-s390.c | 5 +++++ > kexec/arch/sh/kexec-sh.c | 5 +++++ > kexec/arch/x86_64/kexec-x86_64.c | 5 +++++ > kexec/kexec-syscall.h | 2 +- > kexec/kexec.c | 14 ++++++++------ > kexec/kexec.h | 2 ++ > 17 files changed, 79 insertions(+), 7 deletions(-) > > diff --git a/kexec/arch/arm/kexec-arm.c b/kexec/arch/arm/kexec-arm.c > index 49f35b1..34531f9 100644 > --- a/kexec/arch/arm/kexec-arm.c > +++ b/kexec/arch/arm/kexec-arm.c > @@ -148,3 +148,8 @@ int have_sysfs_fdt(void) > { > return !access(SYSFS_FDT, F_OK); > } > + > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c > index 4a67b0d..9d052b0 100644 > --- a/kexec/arch/arm64/kexec-arm64.c > +++ b/kexec/arch/arm64/kexec-arm64.c > @@ -1363,3 +1363,7 @@ void arch_reuse_initrd(void) > void arch_update_purgatory(struct kexec_info *UNUSED(info)) > { > } > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/cris/kexec-cris.c b/kexec/arch/cris/kexec-cris.c > index 3b69709..7f09121 100644 > --- a/kexec/arch/cris/kexec-cris.c > +++ b/kexec/arch/cris/kexec-cris.c > @@ -109,3 +109,7 @@ unsigned long add_buffer(struct kexec_info *info, const void *buf, > buf_min, buf_max, buf_end, 1); > } > > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/hppa/kexec-hppa.c b/kexec/arch/hppa/kexec-hppa.c > index 77c9739..a64dc3d 100644 > --- a/kexec/arch/hppa/kexec-hppa.c > +++ b/kexec/arch/hppa/kexec-hppa.c > @@ -146,3 +146,8 @@ unsigned long virt_to_phys(unsigned long addr) > { > return addr - phys_offset; > } > + > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/i386/kexec-x86.c b/kexec/arch/i386/kexec-x86.c > index 444cb69..b4947a0 100644 > --- a/kexec/arch/i386/kexec-x86.c > +++ b/kexec/arch/i386/kexec-x86.c > @@ -208,3 +208,11 @@ void arch_update_purgatory(struct kexec_info *info) > elf_rel_set_symbol(&info->rhdr, "panic_kernel", > &panic_kernel, sizeof(panic_kernel)); > } > + > +int arch_do_exclude_segment(struct kexec_segment *seg_ptr, struct kexec_info *info) > +{ > + if (info->elfcorehdr == (unsigned long) seg_ptr->mem) > + return 1; > + > + return 0; > +} > diff --git a/kexec/arch/ia64/kexec-ia64.c b/kexec/arch/ia64/kexec-ia64.c > index 418d997..8d9c1f3 100644 > --- a/kexec/arch/ia64/kexec-ia64.c > +++ b/kexec/arch/ia64/kexec-ia64.c > @@ -245,3 +245,7 @@ void arch_update_purgatory(struct kexec_info *UNUSED(info)) > { > } > > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/loongarch/kexec-loongarch.c b/kexec/arch/loongarch/kexec-loongarch.c > index 32a42d2..9a50ff6 100644 > --- a/kexec/arch/loongarch/kexec-loongarch.c > +++ b/kexec/arch/loongarch/kexec-loongarch.c > @@ -378,3 +378,8 @@ unsigned long add_buffer(struct kexec_info *info, const void *buf, > return add_buffer_phys_virt(info, buf, bufsz, memsz, buf_align, > buf_min, buf_max, buf_end, 1); > } > + > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/m68k/kexec-m68k.c b/kexec/arch/m68k/kexec-m68k.c > index cb54927..0c7dbaf 100644 > --- a/kexec/arch/m68k/kexec-m68k.c > +++ b/kexec/arch/m68k/kexec-m68k.c > @@ -108,3 +108,8 @@ void add_segment(struct kexec_info *info, const void *buf, size_t bufsz, > { > add_segment_phys_virt(info, buf, bufsz, base, memsz, 1); > } > + > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/mips/kexec-mips.c b/kexec/arch/mips/kexec-mips.c > index d8cbea8..94224ee 100644 > --- a/kexec/arch/mips/kexec-mips.c > +++ b/kexec/arch/mips/kexec-mips.c > @@ -189,3 +189,7 @@ unsigned long add_buffer(struct kexec_info *info, const void *buf, > buf_min, buf_max, buf_end, 1); > } > > +int arch_do_exclude_segment(const void *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c > index 03bec36..c8af870 100644 > --- a/kexec/arch/ppc/kexec-ppc.c > +++ b/kexec/arch/ppc/kexec-ppc.c > @@ -966,3 +966,7 @@ void arch_update_purgatory(struct kexec_info *UNUSED(info)) > { > } > > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c > index bd5274c..fb27b6b 100644 > --- a/kexec/arch/ppc64/kexec-ppc64.c > +++ b/kexec/arch/ppc64/kexec-ppc64.c > @@ -967,3 +967,8 @@ int arch_compat_trampoline(struct kexec_info *UNUSED(info)) > void arch_update_purgatory(struct kexec_info *UNUSED(info)) > { > } > + > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/s390/kexec-s390.c b/kexec/arch/s390/kexec-s390.c > index 33ba6b9..0561ee7 100644 > --- a/kexec/arch/s390/kexec-s390.c > +++ b/kexec/arch/s390/kexec-s390.c > @@ -267,3 +267,8 @@ int get_crash_kernel_load_range(uint64_t *start, uint64_t *end) > { > return parse_iomem_single("Crash kernel\n", start, end); > } > + > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/sh/kexec-sh.c b/kexec/arch/sh/kexec-sh.c > index ce341c8..f84c40c 100644 > --- a/kexec/arch/sh/kexec-sh.c > +++ b/kexec/arch/sh/kexec-sh.c > @@ -257,3 +257,8 @@ unsigned long add_buffer(struct kexec_info *info, const void *buf, > return add_buffer_phys_virt(info, buf, bufsz, memsz, buf_align, > buf_min, buf_max, buf_end, 1); > } > + > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} > diff --git a/kexec/arch/x86_64/kexec-x86_64.c b/kexec/arch/x86_64/kexec-x86_64.c > index ffd84f0..42af90a 100644 > --- a/kexec/arch/x86_64/kexec-x86_64.c > +++ b/kexec/arch/x86_64/kexec-x86_64.c > @@ -188,3 +188,8 @@ void arch_update_purgatory(struct kexec_info *info) > elf_rel_set_symbol(&info->rhdr, "panic_kernel", > &panic_kernel, sizeof(panic_kernel)); > } > + > +int arch_do_exclude_segment(struct kexec_segment *UNUSED(seg_ptr), struct kexec_info *UNUSED(info)) > +{ > + return 0; > +} Should all arch_do_exclude_segment return 1 for elfcorehdr ? Please refer my below comment. > diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h > index 73e5254..4675c46 100644 > --- a/kexec/kexec-syscall.h > +++ b/kexec/kexec-syscall.h > @@ -112,7 +112,7 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd, > > #define KEXEC_ON_CRASH 0x00000001 > #define KEXEC_PRESERVE_CONTEXT 0x00000002 > -#define KEXEC_UPDATE_ELFCOREHDR 0x00000004 > +#define KEXEC_CRASH_HOTPLUG_SUPPORT 0x00000008 > #define KEXEC_ARCH_MASK 0xffff0000 > > /* Flags for kexec file based system call */ > diff --git a/kexec/kexec.c b/kexec/kexec.c > index 222f79e..034cea6 100644 > --- a/kexec/kexec.c > +++ b/kexec/kexec.c > @@ -701,10 +701,13 @@ static void update_purgatory(struct kexec_info *info) > continue; > } > > - /* Don't include elfcorehdr in the checksum, if hotplug > - * support enabled. > + /* > + * Let architecture decide which segments to exclude from checksum > + * if hotplug support is enabled. > */ > - if (do_hotplug && (info->segment[i].mem == (void *)info->elfcorehdr)) { > + if (do_hotplug && arch_do_exclude_segment(&info->segment[i], info)) { > + dbgprintf("Skipping segment mem: 0x%lx from SHA calculation\n", > + (unsigned long)info->segment[i].mem); > continue; > } Current behaviour seems to skip elfcorehdr segment in all architectures. But now as all architectures are returning 0 in arch_do_exclude_segment, will elfcorehdr still be skipped ? Rest all looks good to me. Thanks, Aditya Gupta > > @@ -1651,7 +1654,6 @@ int main(int argc, char *argv[]) > die("--load-live-update can only be used with xen\n"); > } > > - /* NOTE: Xen KEXEC_LIVE_UPDATE and KEXEC_UPDATE_ELFCOREHDR collide */ > if (do_hotplug) { > const char *ces = "/sys/kernel/crash_elfcorehdr_size"; > char *buf, *endptr = NULL; > @@ -1665,8 +1667,8 @@ int main(int argc, char *argv[]) > if (!elfcorehdrsz || (endptr && *endptr != '\0')) > die("Path %s does not exist, the kernel needs CONFIG_CRASH_HOTPLUG\n", ces); > dbgprintf("ELFCOREHDR_SIZE %lu\n", elfcorehdrsz); > - /* Indicate to the kernel it is ok to modify the elfcorehdr */ > - kexec_flags |= KEXEC_UPDATE_ELFCOREHDR; > + /* Indicate to the kernel it is ok to modify the relevant kexec segments */ > + kexec_flags |= KEXEC_CRASH_HOTPLUG_SUPPORT; > } > > fileind = optind; > diff --git a/kexec/kexec.h b/kexec/kexec.h > index 1004aff..2d758c9 100644 > --- a/kexec/kexec.h > +++ b/kexec/kexec.h > @@ -307,6 +307,8 @@ extern int do_hotplug; > #define BOOTLOADER_VERSION PACKAGE_VERSION > > void arch_usage(void); > +/* Return non-zero if segment needs to be excluded from SHA calculation, else 0. */ > +int arch_do_exclude_segment(struct kexec_segment *seg_ptr, struct kexec_info *info); > int arch_process_options(int argc, char **argv); > int arch_compat_trampoline(struct kexec_info *info); > void arch_update_purgatory(struct kexec_info *info); > -- > 2.44.0 > _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec