Kexec Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] kexec,mm/cma: do not run the next kernel from a fixed-base CMA area
@ 2026-10-14 14:57 Radhey Shyam Pandey
  2026-10-14 14:57 ` [RFC PATCH 1/2] kexec: do not place the next kernel in a fixed-address " Radhey Shyam Pandey
  2026-10-14 14:57 ` [RFC PATCH 2/2] mm/cma: reject CMA areas that overlap the kernel image Radhey Shyam Pandey
  0 siblings, 2 replies; 5+ messages in thread
From: Radhey Shyam Pandey @ 2026-10-14 14:57 UTC (permalink / raw)
  To: akpm, david, ljs, liam, vbabka, rppt, surenb, mhocko, baoquan.he,
	pasha.tatashin, pratyush, graf
  Cc: linux-mm, linux-kernel, kexec, Radhey Shyam Pandey

Since commit 07d24902977e ("kexec: enable CMA based contiguous
allocation"), kexec_locate_mem_hole() tries kexec_alloc_contig() before
the memblock hole search. On success the CMA address becomes the final
destination of the next kernel rather than a staging buffer, so the
image is run in place instead of being copied during the hot phase.

That is unsafe when the default CMA area has a fixed base. CMA
allocation state is purely runtime: the outgoing kernel marks the pages
busy in its own bitmap, but that bitmap is not carried across kexec.
The incoming kernel builds its CMA areas afresh from the same device
tree, which describes the pool's extent - the one thing both kernels
agree on exactly - and has no way to learn that part of the pool holds
the image it is executing from. cma_activate_area() hands the area to
init_cma_reserved_pageblock(), which clears PageReserved on every page
and frees them into MIGRATE_CMA, overriding the memblock_reserve() of
[_text, _end) the architecture installed.

On a VEK385 (arm64, three device-tree CMA pools, 14 GiB total) this
reproduces within ~300ms of /sbin/init starting, as a copy-on-write
fault writing to the read-only linear alias of .text after kernel text
had been handed out as a movable page:

  Unable to handle kernel write to read-only memory at virtual address ffff00084030c000
  Call trace:
   copy_page+0x48/0xc4 (P)
   copy_user_highpage+0x14/0x30
   __handle_mm_fault+0x318/0x1340

Patch 1 is the fix. It records whether an area was placed at an address
CMA chose or one dictated from outside, and refuses the latter for the
kexec payload, leaving kexec_locate_mem_hole() to fall back to the
memblock hole search as it did before CMA placement existed. Areas
placed by __cma_declare_contiguous_nid() without a fixed base are still
used, because the next kernel repeats that search against its own
memblock state and so cannot land on the same extent. "cma=nn" keeps
working and "cma=nn@ss" does not, which is the intended distinction.

Patch 2 adds a check in cma_init_reserved_mem() so that a caller passing
a base overlapping the kernel image is refused rather than silently
corrupting it. It is hardening rather than the fix, and deliberately
carries no Fixes: tag - see the open question below.

Open question for patch 2
=========================
Returning an error is not sufficient on its own for a device-tree pool.
fdt_init_reserved_mem_node() responds to an error from a non-nomap
region by calling memblock_phys_free() on the whole range, which drops
the kernel image's own reservation along with it, so the pages are still
released - as plain free memory instead of MIGRATE_CMA. powerpc's
fadump_cma_init() is the one caller that keeps its reservation on
failure and is therefore fully protected.

Should of_reserved_mem avoid freeing a region whose node_init failed, or
should cma_init_reserved_mem() signal this case differently? I have left
patch 2 as a diagnostic and a second line of defence behind patch 1
rather than guess at the right answer. Patch 1 stands on its own and
does not depend on how patch 2 is resolved.

Testing
=======
With patch 1 applied, kexec_file_load() on the VEK385 declines the
default pool (4 GiB at 0x800000000) and places the Image through the
memblock search at 0x9c00000 size 0x1de0000. The kernel that boots from
it reports its image as [0x09c00000-0x0b9e0000] and 14680064K
cma-reserved, i.e. all three pools present and none of them overlapping
the running kernel. Both segments report being copied rather than run in
place. Without patch 1, the payload is placed inside the default pool
and the trace above follows.


Radhey Shyam Pandey (2):
  kexec: do not place the next kernel in a fixed-address CMA area
  mm/cma: reject CMA areas that overlap the kernel image

 include/linux/cma.h | 10 ++++++++++
 kernel/kexec_file.c | 12 ++++++++++++
 mm/cma.c            | 39 +++++++++++++++++++++++++++++++++++++++
 mm/cma.h            |  2 ++
 4 files changed, 63 insertions(+)


base-commit: 1fffefb00cc0b0da1f2ae24e3d33364530ea6515
-- 
2.43.0



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-14 15:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-14 14:57 [RFC PATCH 0/2] kexec,mm/cma: do not run the next kernel from a fixed-base CMA area Radhey Shyam Pandey
2026-10-14 14:57 ` [RFC PATCH 1/2] kexec: do not place the next kernel in a fixed-address " Radhey Shyam Pandey
2026-10-14 15:07   ` sashiko-bot
2026-10-14 14:57 ` [RFC PATCH 2/2] mm/cma: reject CMA areas that overlap the kernel image Radhey Shyam Pandey
2026-10-14 15:09   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox