This routine provides a means to tune the size of the elfcorehdr buffer segment, taking into account the --hotplug and --elfcorehdrsz options. The possibilities are: no --elfcorehdrsz w/ --elfcorehdrsz no --hotplug just-large-enough user-specified w/ --hotplug maximum-size user-specified Where just-large-enough is the min_size parameter, computed based upon the existing CPUs and memory regions in the system. Where maximum-size is computed based upon the maximum number of CPUs and memory regions possible in the system. Signed-off-by: Eric DeVolder <eric.devolder@xxxxxxxxxx> --- include/elf.h | 2 ++ kexec/crashdump.c | 33 +++++++++++++++++++++++++++++++++ kexec/crashdump.h | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/include/elf.h b/include/elf.h index 1c8d2cc..2c5884d 100644 --- a/include/elf.h +++ b/include/elf.h @@ -163,6 +163,8 @@ typedef struct #define EI_PAD 9 /* Byte index of padding bytes */ +#define PN_XNUM 0xffff /* Maximum number of headers in e_phnum */ + /* Legal values for e_type (object file type). */ #define ET_NONE 0 /* No file type */ diff --git a/kexec/crashdump.c b/kexec/crashdump.c index 0b363c5..4210c53 100644 --- a/kexec/crashdump.c +++ b/kexec/crashdump.c @@ -53,6 +53,9 @@ #undef EHDR #undef FUNC +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + unsigned long crash_architecture(struct crash_elf_info *elf_info) { if (xen_present()) @@ -157,3 +160,33 @@ int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len) { return get_vmcoreinfo("/sys/kernel/vmcoreinfo", addr, len); } + +unsigned long get_elfcorehdrsz(struct crash_elf_info *elf_info, + unsigned long min_size, + unsigned long nr_memory_ranges) +{ + /* Size elfcorehdr appropriately */ + unsigned long sz = min_size; + + if (elfcorehdrsz) { + /* Utilize option value */ + sz = elfcorehdrsz; + } else { + /* Compute maximum for hotplug */ + if (do_hotplug) { + long int nr_cpus = get_nr_cpus(); + sz = nr_cpus + nr_memory_ranges; + sz = MIN(sz, PN_XNUM); + if (elf_info->class == ELFCLASS32) { + sz *= sizeof(Elf32_Phdr); + sz += sizeof(Elf32_Ehdr); + } else { + sz *= sizeof(Elf64_Phdr); + sz += sizeof(Elf64_Ehdr); + } + } + /* else default is min_size */ + } + sz = MAX(min_size, sz); + return sz; +} diff --git a/kexec/crashdump.h b/kexec/crashdump.h index 28d3278..e4cedce 100644 --- a/kexec/crashdump.h +++ b/kexec/crashdump.h @@ -53,6 +53,10 @@ int crash_create_elf64_headers(struct kexec_info *info, unsigned long crash_architecture(struct crash_elf_info *elf_info); +unsigned long get_elfcorehdrsz(struct crash_elf_info *elf_info, + unsigned long min_size, + unsigned long nr_memory_ranges); + unsigned long phys_to_virt(struct crash_elf_info *elf_info, unsigned long long paddr); -- 2.31.1 _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec