[PATCH v9] arm64: kexec_file: Do not use CMA for images with a non-zero text_offset
From: Jinjie Ruan
Date: Sun Nov 08 2026 - 23:13:56 EST
From: Jinjie Ruan <ruanjinjie@xxxxxxxxxx>
image_load() adds text_offset to kernel_segment->mem and subtracts it
from kernel_segment->memsz. For CMA backed segments this breaks the
load path: the payload is copied to page_address(cma), which is the CMA
base, while image->start is set to the adjusted address, so kexec jumps
into the middle of the kernel. kimage_map_segment() has the same
mismatch when a segment has been moved.
The adjusted memsz also breaks the release path: the CMA pages are
freed using segment->memsz >> PAGE_SHIFT, which is fewer than were
allocated, leaking the tail of the allocation.
Both problems are specific to CMA segments, which are accessed through
page_address(cma) and ignore segment->mem. The normal load path uses
segment->mem, so the text_offset adjustment stays consistent there.
Keep honoring text_offset, but load such images from regular memory by
setting image->no_cma: they lose the CMA contiguous allocation, but
keep working.
Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <ruanjinjie@xxxxxxxxxx>
Cc: Catalin Marinas <catalin.marinas@xxxxxxx>
Cc: Will Deacon <will@xxxxxxxxxx>
Cc: Mike Rapoport <rppt@xxxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Link: https://lore.kernel.org/all/20260921090450.807575-2-ruanjinjie@xxxxxxxxxx/
Link: https://lore.kernel.org/all/20260921090450.807575-3-ruanjinjie@xxxxxxxxxx/
Link: https://lore.kernel.org/all/au4JOjnQlx2aSpiE@xxxxxxx/
---
v8 -> v9:
- Fix with no_cma as Catalin suggested.
- Link to v8: https://lore.kernel.org/all/20261105125442.2282987-1-ruanjinjie@xxxxxxxxxx/
v7 -> v8:
- Split out from the patch set.
- Link to v7: https://lore.kernel.org/all/20261026075201.699550-1-ruanjinjie@xxxxxxxxxx/
---
arch/arm64/kernel/kexec_image.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
index 78b1f956d8d7..f4ad22447259 100644
--- a/arch/arm64/kernel/kexec_image.c
+++ b/arch/arm64/kernel/kexec_image.c
@@ -81,6 +81,13 @@ static void *image_load(struct kimage *image,
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
kbuf.memsz = le64_to_cpu(h->image_size);
text_offset = le64_to_cpu(h->text_offset);
+ /*
+ * A CMA segment is loaded and mapped through page_address(cma), which
+ * is the CMA base and cannot represent the text_offset adjustment
+ * below. Load images with a non-zero text_offset from normal memory.
+ */
+ if (text_offset)
+ image->no_cma = true;
kbuf.buf_align = MIN_KIMG_ALIGN;
/* Adjust kernel segment with TEXT_OFFSET */
--
2.43.0