Hari Bathini <hbath...@linux.ibm.com> writes:

>  /**
> + * get_crash_memory_ranges - Get crash memory ranges. This list includes
> + *                           first/crashing kernel's memory regions that
> + *                           would be exported via an elfcore.
> + * @mem_ranges:              Range list to add the memory ranges to.
> + *
> + * Returns 0 on success, negative errno on error.
> + */
> +static int get_crash_memory_ranges(struct crash_mem **mem_ranges)
> +{
> +     struct memblock_region *reg;
> +     struct crash_mem *tmem;
> +     int ret;
> +
> +     for_each_memblock(memory, reg) {
> +             u64 base, size;
> +
> +             base = (u64)reg->base;
> +             size = (u64)reg->size;
> +
> +             /* Skip backup memory region, which needs a separate entry */
> +             if (base == BACKUP_SRC_START) {
> +                     if (size > BACKUP_SRC_SIZE) {
> +                             base = BACKUP_SRC_END + 1;
> +                             size -= BACKUP_SRC_SIZE;
> +                     } else
> +                             continue;
> +             }
> +
> +             ret = add_mem_range(mem_ranges, base, size);
> +             if (ret)
> +                     goto out;
> +
> +             /* Try merging adjacent ranges before reallocation attempt */
> +             if ((*mem_ranges)->nr_ranges == (*mem_ranges)->max_nr_ranges)
> +                     sort_memory_ranges(*mem_ranges, true);
> +     }
> +
> +     /* Reallocate memory ranges if there is no space to split ranges */
> +     tmem = *mem_ranges;
> +     if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) {
> +             tmem = realloc_mem_ranges(mem_ranges);
> +             if (!tmem)
> +                     goto out;
> +     }
> +
> +     /* Exclude crashkernel region */
> +     ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end);
> +     if (ret)
> +             goto out;
> +
> +     ret = add_rtas_mem_range(mem_ranges);
> +     if (ret)
> +             goto out;
> +
> +     ret = add_opal_mem_range(mem_ranges);
> +     if (ret)
> +             goto out;

Maybe I'm confused, but don't you add the RTAS and OPAL regions as
usable memory for the crashkernel? In that case they shouldn't show up
in the core file.

> +
> +     /* create a separate program header for the backup region */
> +     ret = add_mem_range(mem_ranges, BACKUP_SRC_START, BACKUP_SRC_SIZE);
> +     if (ret)
> +             goto out;
> +
> +     sort_memory_ranges(*mem_ranges, false);
> +out:
> +     if (ret)
> +             pr_err("Failed to setup crash memory ranges\n");
> +     return ret;
> +}

<snip>

> +/**
> + * prepare_elf_headers - Prepare headers for the elfcore to be exported as
> + *                       /proc/vmcore by the kdump kernel.
> + * @image:               Kexec image.
> + * @cmem:                Crash memory ranges to be exported via elfcore.
> + * @addr:                Vmalloc'd memory allocated by 
> crash_prepare_elf64_headers
> + *                       to prepare the elf headers.
> + * @sz:                  Size of the vmalloc'd memory allocated.
> + *
> + * Returns 0 on success, negative errno on error.
> + */
> +static int prepare_elf_headers(struct kimage *image, struct crash_mem *cmem,
> +                            void **addr, unsigned long *sz)
> +{
> +     int ret;
> +
> +     ret = crash_prepare_elf64_headers(cmem, false, addr, sz);
> +
> +     /* Fix the offset for backup region in the ELF header */
> +     if (!ret)
> +             update_backup_region_phdr(image, *addr);
> +
> +     return ret;
> +}

The code above can be inlined into its caller, I don't see a need to
have a separate function.

> +
> +/**
> + * load_elfcorehdr_segment - Setup crash memory ranges and initialize 
> elfcorehdr
> + *                           segment needed to load kdump kernel.
> + * @image:                   Kexec image.
> + * @kbuf:                    Buffer contents and memory parameters.
> + *
> + * Returns 0 on success, negative errno on error.
> + */
> +static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf 
> *kbuf)
> +{
> +     struct crash_mem *cmem = NULL;
> +     unsigned long headers_sz;
> +     void *headers = NULL;
> +     int ret;
> +
> +     ret = get_crash_memory_ranges(&cmem);
> +     if (ret)
> +             goto out;
> +
> +     /* Setup elfcorehdr segment */
> +     ret = prepare_elf_headers(image, cmem, &headers, &headers_sz);
> +     if (ret) {
> +             pr_err("Failed to prepare elf headers for the core\n");
> +             goto out;
> +     }
> +
> +     kbuf->buffer = headers;
> +     kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
> +     kbuf->bufsz = kbuf->memsz = headers_sz;
> +     kbuf->top_down = false;
> +
> +     ret = kexec_add_buffer(kbuf);
> +     if (ret) {
> +             vfree(headers);
> +             goto out;
> +     }
> +
> +     image->arch.elfcorehdr_addr = kbuf->mem;
> +     image->arch.elf_headers_sz = headers_sz;
> +     image->arch.elf_headers = headers;
> +out:
> +     kfree(cmem);
> +     return ret;
> +}

--
Thiago Jung Bauermann
IBM Linux Technology Center

Reply via email to