/* Loads additional segments in case of a panic kernel is being loaded. * One segment for backup region, another segment for storing elf headers * for crash memory image. */ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, unsigned long UNUSED(max_addr), unsigned long UNUSED(min_base)) { void *tmp; unsigned long sz, elfcorehdr; int nr_ranges, align = 1024; struct memory_range *mem_range; crash_create_elf_headers_func crash_create = crash_create_elf32_headers; struct crash_elf_info *elf_info = &elf_info32; unsigned long start_offset = 0x80000000UL; #ifdef __mips64 if (arch_options.core_header_type == CORE_TYPE_ELF64) { elf_info = &elf_info64; crash_create = crash_create_elf64_headers; start_offset = 0xffffffff80000000UL; } #endif if (get_kernel_paddr(elf_info)) return -1; if (get_kernel_vaddr_and_size(elf_info, start_offset)) return -1; if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) return -1; info->backup_src_start = BACKUP_SRC_START; info->backup_src_size = BACKUP_SRC_SIZE; /* Create a backup region segment to store backup data*/ sz = (BACKUP_SRC_SIZE + align - 1) & ~(align - 1); tmp = xmalloc(sz); memset(tmp, 0, sz); info->backup_start = add_buffer(info, tmp, sz, sz, align, crash_reserved_mem.start, crash_reserved_mem.end, -1); if (crash_create(info, elf_info, crash_memory_range, nr_ranges, &tmp, &sz, ELF_CORE_HEADER_ALIGN) < 0) return -1; elfcorehdr = add_buffer(info, tmp, sz, sz, align, crash_reserved_mem.start, crash_reserved_mem.end, -1); /* * backup segment is after elfcorehdr, so use elfcorehdr as top of * kernel's available memory */ cmdline_add_mem(mod_cmdline, crash_reserved_mem.start, elfcorehdr - crash_reserved_mem.start); cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr); cmdline_add_savemaxmem(mod_cmdline, saved_max_mem); dbgprintf("CRASH MEMORY RANGES:\n"); dbgprintf("%016Lx-%016Lx\n", crash_reserved_mem.start, crash_reserved_mem.end); return 0; }
/** * load_crashdump_segments() - loads additional segments needed for kdump * @info: kexec info structure * @mod_cmdline: kernel command line * * This function loads additional segments which are needed for the dump capture * kernel. It also updates kernel command line passed in @mod_cmdline to have * right parameters for the dump capture kernel. * * Return %0 in case of success and %-1 in case of error. */ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline) { unsigned long elfcorehdr; unsigned long bufsz; void *buf; int err; /* * First fetch all the memory (RAM) ranges that we are going to pass to * the crashdump kernel during panic. */ err = crash_get_memory_ranges(); if (err) return err; /* * Now that we have memory regions sorted, we can use first memory * region as PHYS_OFFSET. */ phys_offset = crash_memory_ranges[0].start; dbgprintf("phys_offset: %#lx\n", phys_offset); err = crash_create_elf32_headers(info, &elf_info, crash_memory_ranges, crash_memory_nr_ranges, &buf, &bufsz, ELF_CORE_HEADER_ALIGN); if (err) return err; /* * We allocate ELF core header from the end of the memory area reserved * for the crashkernel. We align the header to SECTION_SIZE (which is * 1MB) so that available memory passed in kernel command line will be * aligned to 1MB. This is because kernel create_mapping() wants memory * regions to be aligned to SECTION_SIZE. */ elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 1 << 20, crash_reserved_mem.start, crash_reserved_mem.end, -1, 0); dbgprintf("elfcorehdr: %#lx\n", elfcorehdr); cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr); /* * Add 'mem=size' parameter to dump capture kernel command line. This * prevents the dump capture kernel from using any other memory regions * which belong to the primary kernel. */ cmdline_add_mem(mod_cmdline, elfcorehdr - crash_reserved_mem.start); dump_memory_ranges(); dbgprintf("kernel command line: \"%s\"\n", mod_cmdline); return 0; }