diff options
| author | Jinjie Ruan <ruanjinjie@huawei.com> | 2026-11-09 12:13:24 +0800 |
|---|---|---|
| committer | Catalin Marinas <catalin.marinas@arm.com> | 2026-11-12 19:38:26 +0000 |
| commit | 18f2d01bfce99a885511c451cba95234eea190bc (patch) | |
| tree | 1f4896db7ee7d2b6658857db2e7eebdf3b401615 | |
| parent | be777145858218f591b4d9d19f3d40d3ecea9de3 (diff) | |
| download | linux-18f2d01bfce99a885511c451cba95234eea190bc.tar.gz linux-18f2d01bfce99a885511c451cba95234eea190bc.zip | |
arm64: kexec_file: Do not use CMA for images with a non-zero text_offset
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@huawei.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/20260921090450.807575-2-ruanjinjie@huawei.com/
Link: https://lore.kernel.org/all/20260921090450.807575-3-ruanjinjie@huawei.com/
Link: https://lore.kernel.org/all/au4JOjnQlx2aSpiE@arm.com/
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
| -rw-r--r-- | arch/arm64/kernel/kexec_image.c | 7 |
1 files changed, 7 insertions, 0 deletions
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 */ |
