Skip to content

Commit 2377c92

Browse files
hbathinimpe
authored andcommitted
powerpc/kexec_file: fix FDT size estimation for kdump kernel
On systems with large amount of memory, loading kdump kernel through kexec_file_load syscall may fail with the below error: "Failed to update fdt with linux,drconf-usable-memory property" This happens because the size estimation for kdump kernel's FDT does not account for the additional space needed to setup usable memory properties. Fix it by accounting for the space needed to include linux,usable-memory & linux,drconf-usable-memory properties while estimating kdump kernel's FDT size. Fixes: 6ecd016 ("powerpc/kexec_file: Add appropriate regions for memory reserve map") Cc: [email protected] # v5.9+ Signed-off-by: Hari Bathini <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/161243826811.119001.14083048209224609814.stgit@hbathini
1 parent 2ac02e5 commit 2377c92

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

arch/powerpc/include/asm/kexec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
136136
int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
137137
const void *fdt, unsigned long kernel_load_addr,
138138
unsigned long fdt_load_addr);
139+
unsigned int kexec_fdt_totalsize_ppc64(struct kimage *image);
139140
int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
140141
unsigned long initrd_load_addr,
141142
unsigned long initrd_len, const char *cmdline);

arch/powerpc/kexec/elf_64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
102102
pr_debug("Loaded initrd at 0x%lx\n", initrd_load_addr);
103103
}
104104

105-
fdt_size = fdt_totalsize(initial_boot_params) * 2;
105+
fdt_size = kexec_fdt_totalsize_ppc64(image);
106106
fdt = kmalloc(fdt_size, GFP_KERNEL);
107107
if (!fdt) {
108108
pr_err("Not enough memory for the device tree.\n");

arch/powerpc/kexec/file_load_64.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/memblock.h>
2222
#include <linux/slab.h>
2323
#include <linux/vmalloc.h>
24+
#include <asm/setup.h>
2425
#include <asm/drmem.h>
2526
#include <asm/kexec_ranges.h>
2627
#include <asm/crashdump-ppc64.h>
@@ -925,6 +926,40 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
925926
return ret;
926927
}
927928

929+
/**
930+
* kexec_fdt_totalsize_ppc64 - Return the estimated size needed to setup FDT
931+
* for kexec/kdump kernel.
932+
* @image: kexec image being loaded.
933+
*
934+
* Returns the estimated size needed for kexec/kdump kernel FDT.
935+
*/
936+
unsigned int kexec_fdt_totalsize_ppc64(struct kimage *image)
937+
{
938+
unsigned int fdt_size;
939+
u64 usm_entries;
940+
941+
/*
942+
* The below estimate more than accounts for a typical kexec case where
943+
* the additional space is to accommodate things like kexec cmdline,
944+
* chosen node with properties for initrd start & end addresses and
945+
* a property to indicate kexec boot..
946+
*/
947+
fdt_size = fdt_totalsize(initial_boot_params) + (2 * COMMAND_LINE_SIZE);
948+
if (image->type != KEXEC_TYPE_CRASH)
949+
return fdt_size;
950+
951+
/*
952+
* For kdump kernel, also account for linux,usable-memory and
953+
* linux,drconf-usable-memory properties. Get an approximate on the
954+
* number of usable memory entries and use for FDT size estimation.
955+
*/
956+
usm_entries = ((memblock_end_of_DRAM() / drmem_lmb_size()) +
957+
(2 * (resource_size(&crashk_res) / drmem_lmb_size())));
958+
fdt_size += (unsigned int)(usm_entries * sizeof(u64));
959+
960+
return fdt_size;
961+
}
962+
928963
/**
929964
* setup_new_fdt_ppc64 - Update the flattend device-tree of the kernel
930965
* being loaded.

0 commit comments

Comments
 (0)