[PATCH 2/2] powerpc/fadump: consider reserved ranges while reserving memory
Mahesh J Salgaonkar
mahesh at linux.ibm.com
Mon Apr 20 15:20:08 AEST 2020
On 2020-03-11 01:57:10 Wed, Hari Bathini wrote:
> Commit 0962e8004e97 ("powerpc/prom: Scan reserved-ranges node for
> memory reservations") enabled support to parse reserved-ranges DT
> node and reserve kernel memory falling in these ranges for F/W
> purposes. Memory reserved for FADump should not overlap with these
> ranges as it could corrupt memory meant for F/W or crash'ed kernel
> memory to be exported as vmcore.
>
> But since commit 579ca1a27675 ("powerpc/fadump: make use of memblock's
> bottom up allocation mode"), memblock_find_in_range() is being used to
> find the appropriate area to reserve memory for FADump, which can't
> account for reserved-ranges as these ranges are reserved only after
> FADump memory reservation.
>
> With reserved-ranges now being populated during early boot, look out
> for these memory ranges while reserving memory for FADump. Without
> this change, MPIPL on PowerNV systems aborts with hostboot failure,
> when memory reserved for FADump is less than 4096MB.
>
> Fixes: 579ca1a27675 ("powerpc/fadump: make use of memblock's bottom up allocation mode")
> Cc: stable at vger.kernel.org # v5.4+
> Signed-off-by: Hari Bathini <hbathini at linux.ibm.com>
> ---
> arch/powerpc/kernel/fadump.c | 76 ++++++++++++++++++++++++++++++++++++------
> 1 file changed, 66 insertions(+), 10 deletions(-)
>
> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
> index 7fcf4a8f..ab83be9 100644
> --- a/arch/powerpc/kernel/fadump.c
> +++ b/arch/powerpc/kernel/fadump.c
> @@ -443,10 +443,70 @@ static int __init fadump_get_boot_mem_regions(void)
> return ret;
> }
>
> +/*
> + * Returns true, if the given range overlaps with reserved memory ranges
> + * starting at idx. Also, updates idx to index of overlapping memory range
> + * with the given memory range.
> + * False, otherwise.
> + */
> +static bool overlaps_reserved_ranges(u64 base, u64 end, int *idx)
> +{
> + bool ret = false;
> + int i;
> +
> + for (i = *idx; i < reserved_mrange_info.mem_range_cnt; i++) {
> + u64 rbase = reserved_mrange_info.mem_ranges[i].base;
> + u64 rend = rbase + reserved_mrange_info.mem_ranges[i].size;
> +
> + if (end <= rbase)
> + break;
> +
> + if ((end > rbase) && (base < rend)) {
> + *idx = i;
> + ret = true;
> + break;
> + }
> + }
> +
> + return ret;
> +}
> +
> +/*
> + * Locate a suitable memory area to reserve memory for FADump. While at it,
> + * lookup reserved-ranges & avoid overlap with them, as they are used by F/W.
> + */
> +static u64 __init fadump_locate_reserve_mem(u64 base, u64 size)
> +{
> + struct fadump_memory_range *mrngs;
> + phys_addr_t mstart, mend;
> + int idx = 0;
> + u64 i;
> +
> + mrngs = reserved_mrange_info.mem_ranges;
> + for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE,
> + &mstart, &mend, NULL) {
> + pr_debug("%llu) mstart: %llx, mend: %llx, base: %llx\n",
> + i, mstart, mend, base);
> +
> + if (mstart > base)
> + base = PAGE_ALIGN(mstart);
> +
> + while ((mend > base) && ((mend - base) >= size)) {
> + if (!overlaps_reserved_ranges(base, base + size, &idx))
> + goto out;
> +
> + base = mrngs[idx].base + mrngs[idx].size;
> + base = PAGE_ALIGN(base);
What happens when all the memory ranges found to be overlaped with
reserved ranges ? Shoudn't this function return NULL ? Looks like in
that case this function returns the last set base address which is
either still overlaped or not big enough in size.
Rest looks good to me.
Thanks,
-Mahesh.
> + }
> + }
> +
> +out:
> + return base;
> +}
> +
More information about the Linuxppc-dev
mailing list