From: Stanislav Kinsburskii <stanislav.kinsburskii@xxxxxxxxx> Retrieve the pmpool bitmap from metadata in the fdt passed over kexec, bypassing the need for reinitialization. This ensures the seamless transfer of the pmpool state across kexec. Signed-off-by: Stanislav Kinsburskii <skinsburskii@xxxxxxxxxxxxxxxxxxx> --- mm/pmpool.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/mm/pmpool.c b/mm/pmpool.c index f2173db782d6..6c1a28fd3493 100644 --- a/mm/pmpool.c +++ b/mm/pmpool.c @@ -9,6 +9,7 @@ #include <linux/libfdt.h> #include <linux/memblock.h> #include <linux/mm.h> +#include <linux/of.h> #include <linux/pmpool.h> #include "cma.h" @@ -49,11 +50,56 @@ static void pmpool_fixup_cma(struct cma *cma) pr_info("CMA bitmap moved to %#llx\n", virt_to_phys(cma->bitmap)); } +static int pmpool_fdt_restore(struct cma *cma) +{ + struct device_node *dn; + u64 val; + + dn = of_find_compatible_node(NULL, NULL, "pmpool"); + if (!dn) + return -ENOENT; + + if (of_property_read_u64(dn, "base", &val)) { + pr_err("invalid fdt: no base\n"); + return -EINVAL; + } + if (val != PFN_PHYS(cma->base_pfn)) { + pr_err("fdt base doesn't match: %#llx != %#llx\n", + val, PFN_PHYS(cma->base_pfn)); + return -EINVAL; + } + + if (of_property_read_u64(dn, "size", &val)) { + pr_err("invalid fdt: no size\n"); + return -EINVAL; + } + if (val != (cma->count << PAGE_SHIFT)) { + pr_err("fdt size doesn't match: %#llx != %#lx\n", + val, cma->count << PAGE_SHIFT); + return -EINVAL; + } + + if (of_property_read_u64(dn, "bitmap", &val)) { + pr_err("invalid fdt: no bitmap\n"); + return -EINVAL; + } + + pr_info("CMA bitmap restored to %#llx\n", val); + + bitmap_free(cma->bitmap); + cma->bitmap = phys_to_virt(val); + + return 0; +} + static int __init default_pmpool_fixup_cma(void) { if (!default_pmpool) return 0; + if (!pmpool_fdt_restore(default_pmpool->cma)) + return 0; + pmpool_fixup_cma(default_pmpool->cma); return 0; } _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec