powerpc/kexec: split CONFIG_KEXEC_FILE and CONFIG_CRASH_DUMP
CONFIG_KEXEC_FILE does not have to select CONFIG_CRASH_DUMP. Move some code under CONFIG_CRASH_DUMP to support CONFIG_KEXEC_FILE and !CONFIG_CRASH_DUMP case. Signed-off-by: Hari Bathini <hbathini@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20240226103010.589537-3-hbathini@linux.ibm.com
This commit is contained in:
parent
56a34d799b
commit
33f2cc0a2e
|
@ -47,7 +47,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
|
|||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (image->type == KEXEC_TYPE_CRASH) {
|
||||
if (IS_ENABLED(CONFIG_CRASH_DUMP) && image->type == KEXEC_TYPE_CRASH) {
|
||||
/* min & max buffer values for kdump case */
|
||||
kbuf.buf_min = pbuf.buf_min = crashk_res.start;
|
||||
kbuf.buf_max = pbuf.buf_max =
|
||||
|
@ -70,7 +70,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
|
|||
kexec_dprintk("Loaded purgatory at 0x%lx\n", pbuf.mem);
|
||||
|
||||
/* Load additional segments needed for panic kernel */
|
||||
if (image->type == KEXEC_TYPE_CRASH) {
|
||||
if (IS_ENABLED(CONFIG_CRASH_DUMP) && image->type == KEXEC_TYPE_CRASH) {
|
||||
ret = load_crashdump_segments_ppc64(image, &kbuf);
|
||||
if (ret) {
|
||||
pr_err("Failed to load kdump kernel segments\n");
|
||||
|
|
|
@ -96,119 +96,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_usable_memory_ranges - Get usable memory ranges. This list includes
|
||||
* regions like crashkernel, opal/rtas & tce-table,
|
||||
* that kdump kernel could use.
|
||||
* @mem_ranges: Range list to add the memory ranges to.
|
||||
*
|
||||
* Returns 0 on success, negative errno on error.
|
||||
*/
|
||||
static int get_usable_memory_ranges(struct crash_mem **mem_ranges)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Early boot failure observed on guests when low memory (first memory
|
||||
* block?) is not added to usable memory. So, add [0, crashk_res.end]
|
||||
* instead of [crashk_res.start, crashk_res.end] to workaround it.
|
||||
* Also, crashed kernel's memory must be added to reserve map to
|
||||
* avoid kdump kernel from using it.
|
||||
*/
|
||||
ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1);
|
||||
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;
|
||||
|
||||
ret = add_tce_mem_ranges(mem_ranges);
|
||||
out:
|
||||
if (ret)
|
||||
pr_err("Failed to setup usable memory ranges\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
phys_addr_t base, end;
|
||||
struct crash_mem *tmem;
|
||||
u64 i;
|
||||
int ret;
|
||||
|
||||
for_each_mem_range(i, &base, &end) {
|
||||
u64 size = end - base;
|
||||
|
||||
/* 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;
|
||||
|
||||
/*
|
||||
* FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
|
||||
* regions are exported to save their context at the time of
|
||||
* crash, they should actually be backed up just like the
|
||||
* first 64K bytes of memory.
|
||||
*/
|
||||
ret = add_rtas_mem_range(mem_ranges);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = add_opal_mem_range(mem_ranges);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_reserved_memory_ranges - Get reserve memory ranges. This list includes
|
||||
* memory regions that should be added to the
|
||||
|
@ -434,6 +321,120 @@ static int locate_mem_hole_bottom_up_ppc64(struct kexec_buf *kbuf,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
/**
|
||||
* get_usable_memory_ranges - Get usable memory ranges. This list includes
|
||||
* regions like crashkernel, opal/rtas & tce-table,
|
||||
* that kdump kernel could use.
|
||||
* @mem_ranges: Range list to add the memory ranges to.
|
||||
*
|
||||
* Returns 0 on success, negative errno on error.
|
||||
*/
|
||||
static int get_usable_memory_ranges(struct crash_mem **mem_ranges)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Early boot failure observed on guests when low memory (first memory
|
||||
* block?) is not added to usable memory. So, add [0, crashk_res.end]
|
||||
* instead of [crashk_res.start, crashk_res.end] to workaround it.
|
||||
* Also, crashed kernel's memory must be added to reserve map to
|
||||
* avoid kdump kernel from using it.
|
||||
*/
|
||||
ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1);
|
||||
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;
|
||||
|
||||
ret = add_tce_mem_ranges(mem_ranges);
|
||||
out:
|
||||
if (ret)
|
||||
pr_err("Failed to setup usable memory ranges\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
phys_addr_t base, end;
|
||||
struct crash_mem *tmem;
|
||||
u64 i;
|
||||
int ret;
|
||||
|
||||
for_each_mem_range(i, &base, &end) {
|
||||
u64 size = end - base;
|
||||
|
||||
/* 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;
|
||||
|
||||
/*
|
||||
* FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
|
||||
* regions are exported to save their context at the time of
|
||||
* crash, they should actually be backed up just like the
|
||||
* first 64K bytes of memory.
|
||||
*/
|
||||
ret = add_rtas_mem_range(mem_ranges);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = add_opal_mem_range(mem_ranges);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* check_realloc_usable_mem - Reallocate buffer if it can't accommodate entries
|
||||
* @um_info: Usable memory buffer and ranges info.
|
||||
|
@ -863,6 +864,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* setup_purgatory_ppc64 - initialize PPC64 specific purgatory's global
|
||||
|
@ -972,26 +974,14 @@ static unsigned int cpu_node_size(void)
|
|||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* kexec_extra_fdt_size_ppc64 - Return the estimated additional size needed to
|
||||
* setup FDT for kexec/kdump kernel.
|
||||
* @image: kexec image being loaded.
|
||||
*
|
||||
* Returns the estimated extra size needed for kexec/kdump kernel FDT.
|
||||
*/
|
||||
unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
|
||||
static unsigned int kdump_extra_fdt_size_ppc64(struct kimage *image)
|
||||
{
|
||||
unsigned int cpu_nodes, extra_size = 0;
|
||||
struct device_node *dn;
|
||||
u64 usm_entries;
|
||||
|
||||
// Budget some space for the password blob. There's already extra space
|
||||
// for the key name
|
||||
if (plpks_is_available())
|
||||
extra_size += (unsigned int)plpks_get_passwordlen();
|
||||
|
||||
if (image->type != KEXEC_TYPE_CRASH)
|
||||
return extra_size;
|
||||
if (!IS_ENABLED(CONFIG_CRASH_DUMP) || image->type != KEXEC_TYPE_CRASH)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* For kdump kernel, account for linux,usable-memory and
|
||||
|
@ -1019,6 +1009,25 @@ unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
|
|||
return extra_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* kexec_extra_fdt_size_ppc64 - Return the estimated additional size needed to
|
||||
* setup FDT for kexec/kdump kernel.
|
||||
* @image: kexec image being loaded.
|
||||
*
|
||||
* Returns the estimated extra size needed for kexec/kdump kernel FDT.
|
||||
*/
|
||||
unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
|
||||
{
|
||||
unsigned int extra_size = 0;
|
||||
|
||||
// Budget some space for the password blob. There's already extra space
|
||||
// for the key name
|
||||
if (plpks_is_available())
|
||||
extra_size += (unsigned int)plpks_get_passwordlen();
|
||||
|
||||
return extra_size + kdump_extra_fdt_size_ppc64(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* add_node_props - Reads node properties from device node structure and add
|
||||
* them to fdt.
|
||||
|
@ -1171,6 +1180,7 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
|
|||
struct crash_mem *umem = NULL, *rmem = NULL;
|
||||
int i, nr_ranges, ret;
|
||||
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
/*
|
||||
* Restrict memory usage for kdump kernel by setting up
|
||||
* usable memory ranges and memory reserve map.
|
||||
|
@ -1207,6 +1217,7 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
|
|||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update cpus nodes information to account hotplug CPUs. */
|
||||
ret = update_cpus_node(fdt);
|
||||
|
@ -1278,7 +1289,7 @@ int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf)
|
|||
buf_min = kbuf->buf_min;
|
||||
buf_max = kbuf->buf_max;
|
||||
/* Segments for kdump kernel should be within crashkernel region */
|
||||
if (kbuf->image->type == KEXEC_TYPE_CRASH) {
|
||||
if (IS_ENABLED(CONFIG_CRASH_DUMP) && kbuf->image->type == KEXEC_TYPE_CRASH) {
|
||||
buf_min = (buf_min < crashk_res.start ?
|
||||
crashk_res.start : buf_min);
|
||||
buf_max = (buf_max > crashk_res.end ?
|
||||
|
|
Loading…
Reference in New Issue