This allows us to skip relocations (and maybe checksum calculation in the future).
kho_scratch is marked as MIGRATE_CMA but isn't actually given to the CMA, so it should only contain movable allocations, therefore this should always succeed. Signed-off-by: Michal Clapinski <[email protected]> --- kernel/kexec_core.c | 6 +++++- kernel/liveupdate/kexec_handover.c | 21 +++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index dc770b9a6d05..cba3ce985aa9 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -43,6 +43,7 @@ #include <linux/kmsg_dump.h> #include <linux/dma-map-ops.h> #include <linux/sysfs.h> +#include <linux/kexec_handover.h> #include <asm/page.h> #include <asm/sections.h> @@ -566,7 +567,10 @@ static void kimage_free_cma(struct kimage *image) continue; arch_kexec_pre_free_pages(page_address(cma), nr_pages); - dma_release_from_contiguous(NULL, cma, nr_pages); + if (kho_is_enabled()) + free_contig_range(page_to_pfn(cma), nr_pages); + else + dma_release_from_contiguous(NULL, cma, nr_pages); image->segment_cma[i] = NULL; } diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c index 4834a809985a..289fd5948fd2 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -1770,15 +1770,28 @@ static int kho_walk_scratch(struct kexec_buf *kbuf, return ret; } +static void kho_try_alloc_contig(struct kexec_buf *kbuf) +{ + unsigned long start_pfn = PFN_DOWN(kbuf->mem); + unsigned long nr_pages = kbuf->memsz >> PAGE_SHIFT; + + if (alloc_contig_range(start_pfn, start_pfn + nr_pages, + ACR_FLAGS_CMA, GFP_KERNEL)) + return; + + kbuf->cma = pfn_to_page(start_pfn); + arch_kexec_post_alloc_pages(page_address(kbuf->cma), nr_pages, 0); +} + int kho_locate_mem_hole(struct kexec_buf *kbuf, int (*func)(struct resource *, void *)) { - int ret; - if (!kho_enable || kbuf->image->type == KEXEC_TYPE_CRASH) return 1; - ret = kho_walk_scratch(kbuf, func); + if (!kho_walk_scratch(kbuf, func)) + return -EADDRNOTAVAIL; - return ret == 1 ? 0 : -EADDRNOTAVAIL; + kho_try_alloc_contig(kbuf); + return 0; } -- 2.54.0.929.g9b7fa37559-goog
