diff options
-rw-r--r-- | arch/powerpc/include/asm/fadump-internal.h | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/fadump.c | 16 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-fadump.c | 30 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-fadump.h | 7 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/rtas-fadump.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/rtas-fadump.h | 9 |
6 files changed, 64 insertions, 15 deletions
diff --git a/arch/powerpc/include/asm/fadump-internal.h b/arch/powerpc/include/asm/fadump-internal.h index 6c2868d38bd3..a669aaa7c610 100644 --- a/arch/powerpc/include/asm/fadump-internal.h +++ b/arch/powerpc/include/asm/fadump-internal.h @@ -19,16 +19,6 @@ #define RMA_START 0x0 #define RMA_END (ppc64_rma_size) -/* - * On some Power systems where RMO is 128MB, it still requires minimum of - * 256MB for kernel to boot successfully. When kdump infrastructure is - * configured to save vmcore over network, we run into OOM issue while - * loading modules related to network setup. Hence we need additional 64M - * of memory to avoid OOM issue. - */ -#define MIN_BOOT_MEM (((RMA_END < (0x1UL << 28)) ? (0x1UL << 28) : RMA_END) \ - + (0x1UL << 26)) - /* The upper limit percentage for user specified boot memory size (25%) */ #define MAX_BOOT_MEM_RATIO 4 @@ -128,6 +118,7 @@ struct fadump_ops { u64 (*fadump_init_mem_struct)(struct fw_dump *fadump_conf); u64 (*fadump_get_metadata_size)(void); int (*fadump_setup_metadata)(struct fw_dump *fadump_conf); + u64 (*fadump_get_bootmem_min)(void); int (*fadump_register)(struct fw_dump *fadump_conf); int (*fadump_unregister)(struct fw_dump *fadump_conf); int (*fadump_invalidate)(struct fw_dump *fadump_conf); diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 645d9d4d9332..bd49b1f200bf 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -240,10 +240,10 @@ static void fadump_show_config(void) * that is required for a kernel to boot successfully. * */ -static inline unsigned long fadump_calculate_reserve_size(void) +static inline u64 fadump_calculate_reserve_size(void) { + u64 base, size, bootmem_min; int ret; - unsigned long long base, size; if (fw_dump.reserve_bootvar) pr_warn("'fadump_reserve_mem=' parameter is deprecated in favor of 'crashkernel=' parameter.\n"); @@ -293,7 +293,8 @@ static inline unsigned long fadump_calculate_reserve_size(void) if (memory_limit && size > memory_limit) size = memory_limit; - return (size > MIN_BOOT_MEM ? size : MIN_BOOT_MEM); + bootmem_min = fw_dump.ops->fadump_get_bootmem_min(); + return (size > bootmem_min ? size : bootmem_min); } /* @@ -323,8 +324,8 @@ static unsigned long get_fadump_area_size(void) int __init fadump_reserve_mem(void) { + u64 base, size, mem_boundary, bootmem_min, align = PAGE_SIZE; bool is_memblock_bottom_up = memblock_bottom_up(); - u64 base, size, mem_boundary, align = PAGE_SIZE; int ret = 1; if (!fw_dump.fadump_enabled) @@ -350,6 +351,13 @@ int __init fadump_reserve_mem(void) ALIGN(fw_dump.boot_memory_size, align); } #endif + + bootmem_min = fw_dump.ops->fadump_get_bootmem_min(); + if (fw_dump.boot_memory_size < bootmem_min) { + pr_err("Can't enable fadump with boot memory size (0x%lx) less than 0x%llx\n", + fw_dump.boot_memory_size, bootmem_min); + goto error_out; + } } /* diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c index a89d3a0cccae..006648e4d5e6 100644 --- a/arch/powerpc/platforms/powernv/opal-fadump.c +++ b/arch/powerpc/platforms/powernv/opal-fadump.c @@ -9,6 +9,7 @@ #include <linux/string.h> #include <linux/seq_file.h> +#include <linux/of.h> #include <linux/of_fdt.h> #include <linux/libfdt.h> #include <linux/mm.h> @@ -262,6 +263,11 @@ static int opal_fadump_setup_metadata(struct fw_dump *fadump_conf) return err; } +static u64 opal_fadump_get_bootmem_min(void) +{ + return OPAL_FADUMP_MIN_BOOT_MEM; +} + static int opal_fadump_register(struct fw_dump *fadump_conf) { s64 rc = OPAL_PARAMETER; @@ -606,6 +612,7 @@ static struct fadump_ops opal_fadump_ops = { .fadump_init_mem_struct = opal_fadump_init_mem_struct, .fadump_get_metadata_size = opal_fadump_get_metadata_size, .fadump_setup_metadata = opal_fadump_setup_metadata, + .fadump_get_bootmem_min = opal_fadump_get_bootmem_min, .fadump_register = opal_fadump_register, .fadump_unregister = opal_fadump_unregister, .fadump_invalidate = opal_fadump_invalidate, @@ -620,9 +627,9 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) const __be32 *prop; unsigned long dn; u64 addr = 0; + int i, len; s64 ret; - /* * Check if Firmware-Assisted Dump is supported. if yes, check * if dump has been initiated on last reboot. @@ -638,6 +645,27 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) return; } + prop = of_get_flat_dt_prop(dn, "fw-load-area", &len); + if (prop) { + /* + * Each f/w load area is an (address,size) pair, + * 2 cells each, totalling 4 cells per range. + */ + for (i = 0; i < len / (sizeof(*prop) * 4); i++) { + u64 base, end; + + base = of_read_number(prop + (i * 4) + 0, 2); + end = base; + end += of_read_number(prop + (i * 4) + 2, 2); + if (end > OPAL_FADUMP_MIN_BOOT_MEM) { + pr_err("F/W load area: 0x%llx-0x%llx\n", + base, end); + pr_err("F/W version not supported!\n"); + return; + } + } + } + fadump_conf->ops = &opal_fadump_ops; fadump_conf->fadump_supported = 1; diff --git a/arch/powerpc/platforms/powernv/opal-fadump.h b/arch/powerpc/platforms/powernv/opal-fadump.h index d0e17d6a2b5c..e630cb0f108f 100644 --- a/arch/powerpc/platforms/powernv/opal-fadump.h +++ b/arch/powerpc/platforms/powernv/opal-fadump.h @@ -11,6 +11,13 @@ #include <asm/reg.h> /* + * With kernel & initrd loaded at 512MB (with 256MB size), enforce a minimum + * boot memory size of 768MB to ensure f/w loading kernel and initrd doesn't + * mess with crash'ed kernel's memory during MPIPL. + */ +#define OPAL_FADUMP_MIN_BOOT_MEM (0x30000000UL) + +/* * OPAL FADump metadata structure format version * * OPAL FADump kernel metadata structure stores kernel metadata needed to diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c b/arch/powerpc/platforms/pseries/rtas-fadump.c index bf1e8fc549b5..1d8f2871fa34 100644 --- a/arch/powerpc/platforms/pseries/rtas-fadump.c +++ b/arch/powerpc/platforms/pseries/rtas-fadump.c @@ -116,6 +116,11 @@ static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf) return addr; } +static u64 rtas_fadump_get_bootmem_min(void) +{ + return RTAS_FADUMP_MIN_BOOT_MEM; +} + static int rtas_fadump_register(struct fw_dump *fadump_conf) { unsigned int wait_time; @@ -467,6 +472,7 @@ static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh, static struct fadump_ops rtas_fadump_ops = { .fadump_init_mem_struct = rtas_fadump_init_mem_struct, + .fadump_get_bootmem_min = rtas_fadump_get_bootmem_min, .fadump_register = rtas_fadump_register, .fadump_unregister = rtas_fadump_unregister, .fadump_invalidate = rtas_fadump_invalidate, diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.h b/arch/powerpc/platforms/pseries/rtas-fadump.h index 531f3f3e42b3..6602ff69e10d 100644 --- a/arch/powerpc/platforms/pseries/rtas-fadump.h +++ b/arch/powerpc/platforms/pseries/rtas-fadump.h @@ -9,6 +9,15 @@ #ifndef _PSERIES_RTAS_FADUMP_H #define _PSERIES_RTAS_FADUMP_H +/* + * On some Power systems where RMO is 128MB, it still requires minimum of + * 256MB for kernel to boot successfully. When kdump infrastructure is + * configured to save vmcore over network, we run into OOM issue while + * loading modules related to network setup. Hence we need additional 64M + * of memory to avoid OOM issue. + */ +#define RTAS_FADUMP_MIN_BOOT_MEM ((0x1UL << 28) + (0x1UL << 26)) + /* Firmware provided dump sections */ #define RTAS_FADUMP_CPU_STATE_DATA 0x0001 #define RTAS_FADUMP_HPTE_REGION 0x0002 |