On 08/26/22 at 01:36pm, Eric DeVolder wrote: > At the outcome of this patch set, the crash_prepare_elf64_headers() > is utilized on both the kexec_file_load and kexec_load paths. As > such, need to move this function out of kexec_file.c and into a > common location crash_core.c. > > No functionality change. > > Signed-off-by: Eric DeVolder <eric.devol...@oracle.com>
LGTM, Baoquan He <b...@redhat.com> > --- > kernel/crash_core.c | 100 ++++++++++++++++++++++++++++++++++++++++++++ > kernel/kexec_file.c | 99 ------------------------------------------- > 2 files changed, 100 insertions(+), 99 deletions(-) > > diff --git a/kernel/crash_core.c b/kernel/crash_core.c > index 07b26df453a9..8c8c82386e8d 100644 > --- a/kernel/crash_core.c > +++ b/kernel/crash_core.c > @@ -10,6 +10,7 @@ > #include <linux/utsname.h> > #include <linux/vmalloc.h> > #include <linux/sizes.h> > +#include <linux/kexec.h> > > #include <asm/page.h> > #include <asm/sections.h> > @@ -314,6 +315,105 @@ static int __init parse_crashkernel_dummy(char *arg) > } > early_param("crashkernel", parse_crashkernel_dummy); > > +int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, > + void **addr, unsigned long *sz) > +{ > + Elf64_Ehdr *ehdr; > + Elf64_Phdr *phdr; > + unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; > + unsigned char *buf; > + unsigned int cpu, i; > + unsigned long long notes_addr; > + unsigned long mstart, mend; > + > + /* extra phdr for vmcoreinfo ELF note */ > + nr_phdr = nr_cpus + 1; > + nr_phdr += mem->nr_ranges; > + > + /* > + * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping > + * area (for example, ffffffff80000000 - ffffffffa0000000 on x86_64). > + * I think this is required by tools like gdb. So same physical > + * memory will be mapped in two ELF headers. One will contain kernel > + * text virtual addresses and other will have __va(physical) addresses. > + */ > + > + nr_phdr++; > + elf_sz = sizeof(Elf64_Ehdr) + nr_phdr * sizeof(Elf64_Phdr); > + elf_sz = ALIGN(elf_sz, ELF_CORE_HEADER_ALIGN); > + > + buf = vzalloc(elf_sz); > + if (!buf) > + return -ENOMEM; > + > + ehdr = (Elf64_Ehdr *)buf; > + phdr = (Elf64_Phdr *)(ehdr + 1); > + memcpy(ehdr->e_ident, ELFMAG, SELFMAG); > + ehdr->e_ident[EI_CLASS] = ELFCLASS64; > + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; > + ehdr->e_ident[EI_VERSION] = EV_CURRENT; > + ehdr->e_ident[EI_OSABI] = ELF_OSABI; > + memset(ehdr->e_ident + EI_PAD, 0, EI_NIDENT - EI_PAD); > + ehdr->e_type = ET_CORE; > + ehdr->e_machine = ELF_ARCH; > + ehdr->e_version = EV_CURRENT; > + ehdr->e_phoff = sizeof(Elf64_Ehdr); > + ehdr->e_ehsize = sizeof(Elf64_Ehdr); > + ehdr->e_phentsize = sizeof(Elf64_Phdr); > + > + /* Prepare one phdr of type PT_NOTE for each present CPU */ > + for_each_present_cpu(cpu) { > + phdr->p_type = PT_NOTE; > + notes_addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu)); > + phdr->p_offset = phdr->p_paddr = notes_addr; > + phdr->p_filesz = phdr->p_memsz = sizeof(note_buf_t); > + (ehdr->e_phnum)++; > + phdr++; > + } > + > + /* Prepare one PT_NOTE header for vmcoreinfo */ > + phdr->p_type = PT_NOTE; > + phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note(); > + phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE; > + (ehdr->e_phnum)++; > + phdr++; > + > + /* Prepare PT_LOAD type program header for kernel text region */ > + if (need_kernel_map) { > + phdr->p_type = PT_LOAD; > + phdr->p_flags = PF_R|PF_W|PF_X; > + phdr->p_vaddr = (unsigned long) _text; > + phdr->p_filesz = phdr->p_memsz = _end - _text; > + phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); > + ehdr->e_phnum++; > + phdr++; > + } > + > + /* Go through all the ranges in mem->ranges[] and prepare phdr */ > + for (i = 0; i < mem->nr_ranges; i++) { > + mstart = mem->ranges[i].start; > + mend = mem->ranges[i].end; > + > + phdr->p_type = PT_LOAD; > + phdr->p_flags = PF_R|PF_W|PF_X; > + phdr->p_offset = mstart; > + > + phdr->p_paddr = mstart; > + phdr->p_vaddr = (unsigned long) __va(mstart); > + phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; > + phdr->p_align = 0; > + ehdr->e_phnum++; > + pr_debug("Crash PT_LOAD ELF header. phdr=%p vaddr=0x%llx, > paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", > + phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, > + ehdr->e_phnum, phdr->p_offset); > + phdr++; > + } > + > + *addr = buf; > + *sz = elf_sz; > + return 0; > +} > + > Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type, > void *data, size_t data_len) > { > diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c > index 1d546dc97c50..8017eeb43036 100644 > --- a/kernel/kexec_file.c > +++ b/kernel/kexec_file.c > @@ -1217,102 +1217,3 @@ int crash_exclude_mem_range(struct crash_mem *mem, > mem->nr_ranges++; > return 0; > } > - > -int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, > - void **addr, unsigned long *sz) > -{ > - Elf64_Ehdr *ehdr; > - Elf64_Phdr *phdr; > - unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; > - unsigned char *buf; > - unsigned int cpu, i; > - unsigned long long notes_addr; > - unsigned long mstart, mend; > - > - /* extra phdr for vmcoreinfo ELF note */ > - nr_phdr = nr_cpus + 1; > - nr_phdr += mem->nr_ranges; > - > - /* > - * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping > - * area (for example, ffffffff80000000 - ffffffffa0000000 on x86_64). > - * I think this is required by tools like gdb. So same physical > - * memory will be mapped in two ELF headers. One will contain kernel > - * text virtual addresses and other will have __va(physical) addresses. > - */ > - > - nr_phdr++; > - elf_sz = sizeof(Elf64_Ehdr) + nr_phdr * sizeof(Elf64_Phdr); > - elf_sz = ALIGN(elf_sz, ELF_CORE_HEADER_ALIGN); > - > - buf = vzalloc(elf_sz); > - if (!buf) > - return -ENOMEM; > - > - ehdr = (Elf64_Ehdr *)buf; > - phdr = (Elf64_Phdr *)(ehdr + 1); > - memcpy(ehdr->e_ident, ELFMAG, SELFMAG); > - ehdr->e_ident[EI_CLASS] = ELFCLASS64; > - ehdr->e_ident[EI_DATA] = ELFDATA2LSB; > - ehdr->e_ident[EI_VERSION] = EV_CURRENT; > - ehdr->e_ident[EI_OSABI] = ELF_OSABI; > - memset(ehdr->e_ident + EI_PAD, 0, EI_NIDENT - EI_PAD); > - ehdr->e_type = ET_CORE; > - ehdr->e_machine = ELF_ARCH; > - ehdr->e_version = EV_CURRENT; > - ehdr->e_phoff = sizeof(Elf64_Ehdr); > - ehdr->e_ehsize = sizeof(Elf64_Ehdr); > - ehdr->e_phentsize = sizeof(Elf64_Phdr); > - > - /* Prepare one phdr of type PT_NOTE for each present CPU */ > - for_each_present_cpu(cpu) { > - phdr->p_type = PT_NOTE; > - notes_addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu)); > - phdr->p_offset = phdr->p_paddr = notes_addr; > - phdr->p_filesz = phdr->p_memsz = sizeof(note_buf_t); > - (ehdr->e_phnum)++; > - phdr++; > - } > - > - /* Prepare one PT_NOTE header for vmcoreinfo */ > - phdr->p_type = PT_NOTE; > - phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note(); > - phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE; > - (ehdr->e_phnum)++; > - phdr++; > - > - /* Prepare PT_LOAD type program header for kernel text region */ > - if (need_kernel_map) { > - phdr->p_type = PT_LOAD; > - phdr->p_flags = PF_R|PF_W|PF_X; > - phdr->p_vaddr = (unsigned long) _text; > - phdr->p_filesz = phdr->p_memsz = _end - _text; > - phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); > - ehdr->e_phnum++; > - phdr++; > - } > - > - /* Go through all the ranges in mem->ranges[] and prepare phdr */ > - for (i = 0; i < mem->nr_ranges; i++) { > - mstart = mem->ranges[i].start; > - mend = mem->ranges[i].end; > - > - phdr->p_type = PT_LOAD; > - phdr->p_flags = PF_R|PF_W|PF_X; > - phdr->p_offset = mstart; > - > - phdr->p_paddr = mstart; > - phdr->p_vaddr = (unsigned long) __va(mstart); > - phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; > - phdr->p_align = 0; > - ehdr->e_phnum++; > - pr_debug("Crash PT_LOAD ELF header. phdr=%p vaddr=0x%llx, > paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", > - phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, > - ehdr->e_phnum, phdr->p_offset); > - phdr++; > - } > - > - *addr = buf; > - *sz = elf_sz; > - return 0; > -} > -- > 2.31.1 > _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec