[PATCH] kho: try to allocate contiguous memory for kexec segments
Michal Clapinski
mclapinski at google.com
Mon Jun 1 12:30:14 PDT 2026
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 <mclapinski at google.com>
---
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
More information about the kexec
mailing list