[PATCH 1/3] kexec_load: Use new kexec flag for hotplug support

Aditya Gupta adityag at linux.ibm.com
Wed May 29 23:23:22 PDT 2024


Hello sourabh,


On 29/05/24 18:43, Sourabh Jain wrote:
> Hello Aditya,
>
>
> On 28/05/24 17:03, Aditya Gupta wrote:
>>
>>> 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.
>
> No they shouldn't until they have CRASH_HTOPLUG support in the kernel.
>
>
>>
>>> 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 ?
>
> Skipping elfcorehdr for architectures that don't support CRASH_HOTPLUG 
> is, I think, incorrect.
> Therefore, I believe the proposed approach in this patch, which asks 
> the architecture which
> segments to exclude, is better.
>
Got it, makes sense to me. Thanks for the explanation sourabh.


- Aditya Gupta




More information about the kexec mailing list