linux/kernel/liveupdate
Michal Clapinski 797fe91e50 kho: align kho_scratch to MAX_ORDER_NR_PAGES pages
While booting with KHO, the following crash was observed:

BUG: unable to handle page fault for address: ff19164fffff8328
RIP: 0010:__free_one_page+0x1a1/0x6b0
Call Trace:
 <TASK>
 [<ffffffff913208bf>] free_one_page+0xaf/0x240
 [<ffffffff93973288>] deferred_free_pages+0xa8/0xd0
 [<ffffffff93971b4f>] deferred_init_memmap_chunk+0x10f/0x1b0
 [<ffffffff9396e265>] padata_mt_helper+0x65/0xa0
 [<ffffffff90fac402>] process_scheduled_works+0x202/0x410
 [<ffffffff90fae739>] worker_thread+0x1f9/0x2d0
 [<ffffffff90fb62fd>] kthread+0x27d/0x2f0
 [<ffffffff90fae540>] ? __pfx_worker_thread+0x10/0x10
 [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
 [<ffffffff90efdc55>] ret_from_fork+0x145/0x280
 [<ffffffff90fb6080>] ? __pfx_kthread+0x10/0x10
 [<ffffffff90e2e46a>] ret_from_fork_asm+0x1a/0x30
 </TASK>

deferred_init_memmap_chunk() interleaves initialization of struct pages
with freeing them. This works fine without KHO because free regions
will never be buddy neighbors. However, with KHO, free memory will be split
into (free && scratch) and (free && !scratch), that can be buddy neighbors.

KHO scratch is aligned to CMA_MIN_ALIGNMENT_PAGES pages but buddy looks
at the neighborhood of MAX_ORDER_NR_PAGES pages. These values are
configurable but CMA_MIN_ALIGNMENT_PAGES is always less or equal to
MAX_ORDER_NR_PAGES. In the crashing configuration they were set as
follows:

	CMA_MIN_ALIGNMENT_PAGES = 1 << 9
	MAX_ORDER_NR_PAGES = 1 << 10

So while freeing one chunk, buddy accessed uninitialized struct pages
from another chunk, tried to merge the blocks and crashed.

To fix this, let's just align KHO scratch to MAX_ORDER_NR_PAGES pages.

Fixes: c6073743d0 ("kho: make preserved pages compatible with deferred struct page init")
Signed-off-by: Michal Clapinski <mclapinski@google.com>
Link: https://patch.msgid.link/20260717134028.2880508-1-mclapinski@google.com
[rppt: massaged the changelog]
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
2026-07-25 15:26:30 +03:00
..
Kconfig kho: make preserved pages compatible with deferred struct page init 2026-06-01 02:31:37 +03:00
kexec_handover_debug.c
kexec_handover_debugfs.c kho: fix kho_in_debugfs_init() to handle non-FDT blobs 2026-04-18 00:10:48 -07:00
kexec_handover_internal.h kho: rename fdt parameter to blob in kho_add/remove_subtree() 2026-04-18 00:10:48 -07:00
kexec_handover.c kho: align kho_scratch to MAX_ORDER_NR_PAGES pages 2026-07-25 15:26:30 +03:00
kho_block.c kho: add support for linked-block serialization 2026-06-03 21:15:46 +03:00
luo_core.c liveupdate: defer session block allocation and physical address setting 2026-06-03 21:15:46 +03:00
luo_file.c liveupdate: Remove limit on the number of files per session 2026-06-03 21:15:46 +03:00
luo_flb.c liveupdate: centralize state management into struct luo_ser 2026-06-03 21:15:45 +03:00
luo_internal.h liveupdate: Remove limit on the number of files per session 2026-06-03 21:15:46 +03:00
luo_session.c liveupdate: fix GET_NAME ioctl argument validation 2026-07-16 09:25:30 +03:00
Makefile kho: add support for linked-block serialization 2026-06-03 21:15:46 +03:00