AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/09/24 05:43 flow patch-triage
2m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "KMSANReasoning": "",
  "NeedsKMSAN": false,
  "Reasoning": "This patch is purely a nomenclature and symbol refactoring that renames Kexec HandOver (KHO) \"scratch\" regions to \"bootmem\" (and MEMBLOCK_KHO_SCRATCH to MEMBLOCK_KHO_NOPRSRV) across documentation, comments, variable/function/type identifiers, debugfs entries, and kernel parameters. It introduces no logic modifications, no restructuring of data structures or algorithm flows, no altered assertions, and does not change any compiled executable C logic or runtime control flow. Therefore, it does not warrant fuzzing.",
  "WorthFuzzing": false
}

1/1 2026/09/24 05:43 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 475e71ae9dc7be020eff31dacf7864dd14387c59\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Thu Sep 24 05:43:46 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt\nindex 68647ff4bdd24..8a42a924f133f 100644\n--- a/Documentation/admin-guide/kernel-parameters.txt\n+++ b/Documentation/admin-guide/kernel-parameters.txt\n@@ -3031,11 +3031,12 @@ Kernel parameters\n \t\t\t\"0\" | \"off\" | \"n\" - kexec handover is disabled\n \t\t\t\"1\" | \"on\" | \"y\" - kexec handover is enabled\n \n-\tkho_scratch=\t[KEXEC,EARLY]\n+\tkho_bootmem=\t[KEXEC,EARLY]\n \t\t\tFormat: ll[KMG],mm[KMG],nn[KMG] | nn%\n-\t\t\tDefines the size of the KHO scratch region. The KHO\n-\t\t\tscratch regions are physically contiguous memory\n-\t\t\tranges that can only be used for non-kernel\n+\n+\t\t\tDefines the size of the KHO boot memory region. The\n+\t\t\tKHO boot memory regions are physically contiguous\n+\t\t\tmemory ranges that can only be used for non-kernel\n \t\t\tallocations. That way, even when memory is heavily\n \t\t\tfragmented with handed over memory, the kexeced\n \t\t\tkernel will always have enough contiguous ranges to\n@@ -3044,10 +3045,10 @@ Kernel parameters\n \t\t\tIt is possible to specify the exact amount of\n \t\t\tmemory in the form of \"ll[KMG],mm[KMG],nn[KMG]\"\n \t\t\twhere the first parameter defines the size of a low\n-\t\t\tmemory scratch area, the second parameter defines\n-\t\t\tthe size of a global scratch area and the third\n+\t\t\tmemory bootmem area, the second parameter defines\n+\t\t\tthe size of a global bootmem area and the third\n \t\t\tparameter defines the size of additional per-node\n-\t\t\tscratch areas.  The form \"nn%\" defines scale factor\n+\t\t\tbootmem areas.  The form \"nn%\" defines scale factor\n \t\t\t(in percents) of memory that was used during boot.\n \n \tkmac=\t\t[MIPS] Korina ethernet MAC address.\ndiff --git a/Documentation/admin-guide/mm/kho.rst b/Documentation/admin-guide/mm/kho.rst\nindex 3e3912eeb2e67..902d171a780af 100644\n--- a/Documentation/admin-guide/mm/kho.rst\n+++ b/Documentation/admin-guide/mm/kho.rst\n@@ -20,10 +20,10 @@ need to enable if you would like to preserve their respective state across\n kexec.\n \n To use KHO, please boot the kernel with the ``kho=on`` command line\n-parameter. You may use ``kho_scratch`` parameter to define size of the\n-scratch regions. For example ``kho_scratch=16M,512M,256M`` will reserve a\n-16 MiB low memory scratch area, a 512 MiB global scratch region, and 256 MiB\n-per NUMA node scratch regions on boot.\n+parameter. You may use ``kho_bootmem`` parameter to define size of the\n+boot memory regions. For example ``kho_bootmem=16M,512M,256M`` will reserve a\n+16 MiB low memory bootmem area, a 512 MiB global bootmem region, and 256 MiB\n+per NUMA node bootmem regions on boot.\n \n Perform a KHO kexec\n ===================\n@@ -96,15 +96,15 @@ stabilized.\n     current KHO state in this file. Kexec user space tooling can use this\n     as input file for the KHO payload image.\n \n-``/sys/kernel/debug/kho/out/scratch_len``\n-    Lengths of KHO scratch regions, which are physically contiguous\n+``/sys/kernel/debug/kho/out/bootmem_len``\n+    Lengths of KHO bootmem regions, which are physically contiguous\n     memory regions that will always stay available for future kexec\n     allocations. Kexec user space tools can use this file to determine\n     where it should place its payload images.\n \n-``/sys/kernel/debug/kho/out/scratch_phys``\n-    Physical locations of KHO scratch regions. Kexec user space tools\n-    can use this file in conjunction to scratch_len to determine where\n+``/sys/kernel/debug/kho/out/bootmem_phys``\n+    Physical locations of KHO bootmem regions. Kexec user space tools\n+    can use this file in conjunction to bootmem_len to determine where\n     it should place its payload images.\n \n ``/sys/kernel/debug/kho/out/sub_fdts/``\ndiff --git a/Documentation/core-api/kho/index.rst b/Documentation/core-api/kho/index.rst\nindex 320914a42178e..e78a2bbe2be1d 100644\n--- a/Documentation/core-api/kho/index.rst\n+++ b/Documentation/core-api/kho/index.rst\n@@ -13,8 +13,8 @@ Kexec HandOver (KHO) is a mechanism that allows Linux to preserve memory\n regions, which could contain serialized system states, across kexec.\n \n KHO uses :ref:`flattened device tree (FDT) \u003ckho_fdt\u003e` to pass information about\n-the preserved state from pre-exec kernel to post-kexec kernel and :ref:`scratch\n-memory regions \u003ckho_scratch\u003e` to ensure integrity of the preserved memory.\n+the preserved state from pre-exec kernel to post-kexec kernel and :ref:`boot\n+memory regions \u003ckho_bootmem\u003e` to ensure integrity of the preserved memory.\n \n .. _kho_fdt:\n \n@@ -40,31 +40,31 @@ and post-kexec kernels. This ABI is defined by header files in\n \n    abi.rst\n \n-.. _kho_scratch:\n+.. _kho_bootmem:\n \n-Scratch Regions\n-===============\n+Boot Memory Regions\n+===================\n \n To boot into kexec, we need to have a physically contiguous memory range that\n contains no handed over memory. Kexec then places the target kernel and initrd\n into that region. The new kernel exclusively uses this region for memory\n allocations before during boot up to the initialization of the page allocator.\n \n-We guarantee that we always have such regions through the scratch regions: On\n-first boot KHO allocates several physically contiguous memory regions. Since\n+We guarantee that we always have such regions through the boot memory regions:\n+On first boot KHO allocates several physically contiguous memory regions. Since\n after kexec these regions will be used by early memory allocations, there is a\n-scratch region per NUMA node plus a scratch region to satisfy allocations\n-requests that do not require particular NUMA node assignment.\n-By default, size of the scratch region is calculated based on amount of memory\n-allocated during boot. The ``kho_scratch`` kernel command line option may be\n-used to explicitly define size of the scratch regions.\n-The scratch regions are declared as CMA when page allocator is initialized so\n-that their memory can be used during system lifetime. CMA gives us the\n-guarantee that no handover pages land in that region, because handover pages\n-must be at a static physical memory location and CMA enforces that only\n-movable pages can be located inside.\n-\n-After KHO kexec, we ignore the ``kho_scratch`` kernel command line option and\n+boot memory region per NUMA node plus a boot memory region to satisfy\n+allocations requests that do not require particular NUMA node assignment. By\n+default, size of the boot memory region is calculated based on amount of memory\n+allocated during boot. The ``kho_bootmem`` kernel command line option may be\n+used to explicitly define size of the boot memory regions. The boot memory\n+regions are declared as CMA when page allocator is initialized so that their\n+memory can be used during system lifetime. CMA gives us the guarantee that no\n+handover pages land in that region, because handover pages must be at a static\n+physical memory location and CMA enforces that only movable pages can be located\n+inside.\n+\n+After KHO kexec, we ignore the ``kho_bootmem`` kernel command line option and\n instead reuse the exact same region that was originally allocated. This allows\n us to recursively execute any amount of KHO kexecs. Because we used this region\n for boot memory allocations and as target memory for kexec blobs, some parts\ndiff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c\nindex 22267a83e064a..290153818d0f3 100644\n--- a/arch/x86/boot/compressed/kaslr.c\n+++ b/arch/x86/boot/compressed/kaslr.c\n@@ -764,12 +764,12 @@ static void process_e820_entries(unsigned long minimum,\n }\n \n /*\n- * If KHO is active, only process its scratch areas to ensure we are not\n+ * If KHO is active, only process its bootmem areas to ensure we are not\n  * stepping onto preserved memory.\n  */\n static bool process_kho_entries(unsigned long minimum, unsigned long image_size)\n {\n-\tstruct kho_scratch *kho_scratch;\n+\tstruct kho_bootmem *kho_bootmem;\n \tstruct setup_data *ptr;\n \tstruct kho_data *kho;\n \tint i, nr_areas = 0;\n@@ -781,8 +781,8 @@ static bool process_kho_entries(unsigned long minimum, unsigned long image_size)\n \twhile (ptr) {\n \t\tif (ptr-\u003etype == SETUP_KEXEC_KHO) {\n \t\t\tkho = (struct kho_data *)(unsigned long)ptr-\u003edata;\n-\t\t\tkho_scratch = (void *)(unsigned long)kho-\u003escratch_addr;\n-\t\t\tnr_areas = kho-\u003escratch_size / sizeof(*kho_scratch);\n+\t\t\tkho_bootmem = (void *)(unsigned long)kho-\u003ebootmem_addr;\n+\t\t\tnr_areas = kho-\u003ebootmem_size / sizeof(*kho_bootmem);\n \t\t\tbreak;\n \t\t}\n \n@@ -793,7 +793,7 @@ static bool process_kho_entries(unsigned long minimum, unsigned long image_size)\n \t\treturn false;\n \n \tfor (i = 0; i \u003c nr_areas; i++) {\n-\t\tstruct kho_scratch *area = \u0026kho_scratch[i];\n+\t\tstruct kho_bootmem *area = \u0026kho_bootmem[i];\n \t\tstruct mem_vector region = {\n \t\t\t.start = area-\u003eaddr,\n \t\t\t.size = area-\u003esize,\n@@ -822,7 +822,7 @@ static unsigned long find_random_phys_addr(unsigned long minimum,\n \t}\n \n \t/*\n-\t * During kexec handover only process KHO scratch areas that are known\n+\t * During kexec handover only process KHO bootmem areas that are known\n \t * not to contain any data that must be preserved.\n \t */\n \tif (!process_kho_entries(minimum, image_size) \u0026\u0026\ndiff --git a/arch/x86/include/uapi/asm/setup_data.h b/arch/x86/include/uapi/asm/setup_data.h\nindex 2671c4e1b3a0b..61090db5065c4 100644\n--- a/arch/x86/include/uapi/asm/setup_data.h\n+++ b/arch/x86/include/uapi/asm/setup_data.h\n@@ -85,8 +85,8 @@ struct ima_setup_data {\n struct kho_data {\n \t__u64 fdt_addr;\n \t__u64 fdt_size;\n-\t__u64 scratch_addr;\n-\t__u64 scratch_size;\n+\t__u64 bootmem_addr;\n+\t__u64 bootmem_size;\n } __attribute__((packed));\n \n #endif /* __ASSEMBLER__ */\ndiff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c\nindex eb72537bc0b19..0967b485f38b9 100644\n--- a/arch/x86/kernel/e820.c\n+++ b/arch/x86/kernel/e820.c\n@@ -1352,18 +1352,17 @@ __init void e820__memblock_setup(void)\n \t * below 1M (aka ISA_END_ADDRESS) up until direct map is completely set\n \t * up in init_mem_mapping().\n \t *\n-\t * KHO kernels are special and use only scratch memory for memblock\n+\t * KHO kernels are special and use only NOPRSRV memory for memblock\n \t * allocations, but memory below 1M is ignored by kernel after early\n-\t * boot and cannot be naturally marked as scratch.\n+\t * boot and cannot be naturally marked as NOPRSRV.\n \t *\n \t * To allow allocation of the real-mode trampoline and a few (if any)\n \t * other very early allocations from below 1M forcibly mark the memory\n-\t * below 1M as scratch.\n+\t * below 1M as NOPRSRV.\n \t *\n-\t * After real mode trampoline is allocated, we clear that scratch\n-\t * marking.\n+\t * After real mode trampoline is allocated, we clear that marking.\n \t */\n-\tmemblock_mark_kho_scratch(0, SZ_1M);\n+\tmemblock_mark_kho_noprsrv(0, SZ_1M);\n \n \t/*\n \t * 32-bit systems are limited to 4BG of memory even with HIGHMEM and\ndiff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c\nindex 7e980ea49d8d6..3aa77006adab2 100644\n--- a/arch/x86/kernel/kexec-bzimage64.c\n+++ b/arch/x86/kernel/kexec-bzimage64.c\n@@ -285,14 +285,14 @@ static void setup_kho(const struct kimage *image, struct boot_params *params,\n \tsd-\u003elen = sizeof(struct kho_data);\n \n \t/* Only add if we have all KHO images in place */\n-\tif (!image-\u003ekho.fdt || !image-\u003ekho.scratch)\n+\tif (!image-\u003ekho.fdt || !image-\u003ekho.bootmem)\n \t\treturn;\n \n \t/* Add setup data */\n \tkho-\u003efdt_addr = image-\u003ekho.fdt;\n \tkho-\u003efdt_size = PAGE_SIZE;\n-\tkho-\u003escratch_addr = image-\u003ekho.scratch-\u003emem;\n-\tkho-\u003escratch_size = image-\u003ekho.scratch-\u003ebufsz;\n+\tkho-\u003ebootmem_addr = image-\u003ekho.bootmem-\u003emem;\n+\tkho-\u003ebootmem_size = image-\u003ekho.bootmem-\u003ebufsz;\n \tsd-\u003enext = params-\u003ehdr.setup_data;\n \tparams-\u003ehdr.setup_data = params_load_addr + setup_data_offset;\n }\ndiff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c\nindex cda6adb9f69c4..19fc8e1714e64 100644\n--- a/arch/x86/kernel/setup.c\n+++ b/arch/x86/kernel/setup.c\n@@ -472,7 +472,7 @@ static void __init add_kho(u64 phys_addr, u32 data_len)\n \t\treturn;\n \t}\n \n-\tkho_populate(kho-\u003efdt_addr, kho-\u003efdt_size, kho-\u003escratch_addr, kho-\u003escratch_size);\n+\tkho_populate(kho-\u003efdt_addr, kho-\u003efdt_size, kho-\u003ebootmem_addr, kho-\u003ebootmem_size);\n \n \tearly_memunmap(kho, size);\n }\ndiff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c\nindex 694d80a5c68e1..65110b2ee1a1d 100644\n--- a/arch/x86/realmode/init.c\n+++ b/arch/x86/realmode/init.c\n@@ -66,7 +66,7 @@ void __init reserve_real_mode(void)\n \t */\n \tmemblock_reserve(0, SZ_1M);\n \n-\tmemblock_clear_kho_scratch(0, SZ_1M);\n+\tmemblock_clear_kho_noprsrv(0, SZ_1M);\n }\n \n static void __init sme_sev_setup_real_mode(struct trampoline_header *th)\ndiff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c\nindex 6103b1a082d24..9f09b0d2daa0b 100644\n--- a/drivers/firmware/efi/efi-init.c\n+++ b/drivers/firmware/efi/efi-init.c\n@@ -165,10 +165,10 @@ static __init void reserve_regions(void)\n \t\tpr_info(\"Processing EFI memory map:\\n\");\n \n \t/*\n-\t * Discard memblocks discovered so far except for KHO scratch\n+\t * Discard memblocks discovered so far except for KHO bootmem\n \t * regions. Most memblocks at this point originate from memory nodes\n \t * in the DT and UEFI uses its own memory map instead. However, if\n-\t * KHO is enabled, scratch regions, which are good known memory\n+\t * KHO is enabled, bootmem regions, which are good known memory\n \t * must be preserved.\n \t */\n \tmemblock_dump_all();\n@@ -178,7 +178,7 @@ static __init void reserve_regions(void)\n \n \t\t/* Remove all non-KHO regions */\n \t\tfor_each_mem_region(r) {\n-\t\t\tif (!memblock_is_kho_scratch(r)) {\n+\t\t\tif (!memblock_is_kho_noprsrv(r)) {\n \t\t\t\tmemblock_remove(r-\u003ebase, r-\u003esize);\n \t\t\t\tr--;\n \t\t\t}\ndiff --git a/drivers/of/fdt.c b/drivers/of/fdt.c\nindex a64afc3ded3d4..ecc9231026224 100644\n--- a/drivers/of/fdt.c\n+++ b/drivers/of/fdt.c\n@@ -929,7 +929,7 @@ void __init early_init_dt_check_for_usable_mem_range(void)\n static void __init early_init_dt_check_kho(void)\n {\n \tunsigned long node = chosen_node_offset;\n-\tu64 fdt_start, fdt_size, scratch_start, scratch_size;\n+\tu64 fdt_start, fdt_size, bootmem_start, bootmem_size;\n \n \tif (!IS_ENABLED(CONFIG_KEXEC_HANDOVER) || (long)node \u003c 0)\n \t\treturn;\n@@ -938,11 +938,11 @@ static void __init early_init_dt_check_kho(void)\n \t\t\t\t      \u0026fdt_start, \u0026fdt_size))\n \t\treturn;\n \n-\tif (!of_flat_dt_get_addr_size(node, \"linux,kho-scratch\",\n-\t\t\t\t      \u0026scratch_start, \u0026scratch_size))\n+\tif (!of_flat_dt_get_addr_size(node, \"linux,kho-bootmem\",\n+\t\t\t\t      \u0026bootmem_start, \u0026bootmem_size))\n \t\treturn;\n \n-\tkho_populate(fdt_start, fdt_size, scratch_start, scratch_size);\n+\tkho_populate(fdt_start, fdt_size, bootmem_start, bootmem_size);\n }\n \n #ifdef CONFIG_SERIAL_EARLYCON\ndiff --git a/drivers/of/kexec.c b/drivers/of/kexec.c\nindex 029903b986cbd..bb4e0d9bfd384 100644\n--- a/drivers/of/kexec.c\n+++ b/drivers/of/kexec.c\n@@ -261,23 +261,23 @@ static int kho_add_chosen(const struct kimage *image, void *fdt, int chosen_node\n #ifdef CONFIG_KEXEC_HANDOVER\n \tphys_addr_t fdt_mem = 0;\n \tphys_addr_t fdt_len = 0;\n-\tphys_addr_t scratch_mem = 0;\n-\tphys_addr_t scratch_len = 0;\n+\tphys_addr_t bootmem_arr = 0;\n+\tphys_addr_t bootmem_len = 0;\n \n \tret = fdt_delprop(fdt, chosen_node, \"linux,kho-fdt\");\n \tif (ret \u0026\u0026 ret != -FDT_ERR_NOTFOUND)\n \t\treturn ret;\n-\tret = fdt_delprop(fdt, chosen_node, \"linux,kho-scratch\");\n+\tret = fdt_delprop(fdt, chosen_node, \"linux,kho-bootmem\");\n \tif (ret \u0026\u0026 ret != -FDT_ERR_NOTFOUND)\n \t\treturn ret;\n \n-\tif (!image-\u003ekho.fdt || !image-\u003ekho.scratch)\n+\tif (!image-\u003ekho.fdt || !image-\u003ekho.bootmem)\n \t\treturn 0;\n \n \tfdt_mem = image-\u003ekho.fdt;\n \tfdt_len = PAGE_SIZE;\n-\tscratch_mem = image-\u003ekho.scratch-\u003emem;\n-\tscratch_len = image-\u003ekho.scratch-\u003ebufsz;\n+\tbootmem_arr = image-\u003ekho.bootmem-\u003emem;\n+\tbootmem_len = image-\u003ekho.bootmem-\u003ebufsz;\n \n \tpr_debug(\"Adding kho metadata to DT\");\n \n@@ -285,8 +285,8 @@ static int kho_add_chosen(const struct kimage *image, void *fdt, int chosen_node\n \t\t\t\t       fdt_mem, fdt_len);\n \tif (ret)\n \t\treturn ret;\n-\tret = fdt_appendprop_addrrange(fdt, 0, chosen_node, \"linux,kho-scratch\",\n-\t\t\t\t       scratch_mem, scratch_len);\n+\tret = fdt_appendprop_addrrange(fdt, 0, chosen_node, \"linux,kho-bootmem\",\n+\t\t\t\t       bootmem_arr, bootmem_len);\n \n #endif /* CONFIG_KEXEC_HANDOVER */\n \treturn ret;\ndiff --git a/include/asm-generic/kexec_handover.h b/include/asm-generic/kexec_handover.h\nindex 50839fb5ee8ed..cf73d9b34c3c9 100644\n--- a/include/asm-generic/kexec_handover.h\n+++ b/include/asm-generic/kexec_handover.h\n@@ -4,7 +4,7 @@\n \n #include \u003clinux/types.h\u003e\n \n-struct kho_scratch {\n+struct kho_bootmem {\n \tphys_addr_t addr;\n \tphys_addr_t size;\n };\ndiff --git a/include/linux/kexec.h b/include/linux/kexec.h\nindex e5f1cfc11fefb..f970ca2c8ce95 100644\n--- a/include/linux/kexec.h\n+++ b/include/linux/kexec.h\n@@ -403,7 +403,7 @@ struct kimage {\n #endif\n \n \tstruct {\n-\t\tstruct kexec_segment *scratch;\n+\t\tstruct kexec_segment *bootmem;\n \t\tphys_addr_t fdt;\n \t} kho;\n \ndiff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h\nindex 46de86dc343e9..ef2b188c8ed09 100644\n--- a/include/linux/kexec_handover.h\n+++ b/include/linux/kexec_handover.h\n@@ -36,15 +36,15 @@ int kho_retrieve_subtree(const char *name, phys_addr_t *phys, size_t *size);\n void kho_memory_init(void);\n void kho_memory_init_early(void);\n \n-void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys,\n-\t\t  u64 scratch_len);\n+void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t bootmem_phys,\n+\t\t  u64 bootmem_len);\n \n-bool kho_scratch_overlap(phys_addr_t phys, size_t size);\n+bool kho_bootmem_overlap(phys_addr_t phys, size_t size);\n \n-static inline enum migratetype kho_scratch_migratetype(unsigned long pfn,\n+static inline enum migratetype kho_bootmem_migratetype(unsigned long pfn,\n \t\t\t\t\t\t       enum migratetype mt)\n {\n-\tif (kho_scratch_overlap(PFN_PHYS(pfn), pageblock_nr_pages \u003c\u003c PAGE_SHIFT))\n+\tif (kho_bootmem_overlap(PFN_PHYS(pfn), pageblock_nr_pages \u003c\u003c PAGE_SHIFT))\n \t\treturn MIGRATE_CMA;\n \treturn mt;\n }\n@@ -123,16 +123,16 @@ static inline void kho_memory_init(void) { }\n static inline void kho_memory_init_early(void) { }\n \n static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len,\n-\t\t\t\tphys_addr_t scratch_phys, u64 scratch_len)\n+\t\t\t\tphys_addr_t bootmem_phys, u64 bootmem_len)\n {\n }\n \n-static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size)\n+static inline bool kho_bootmem_overlap(phys_addr_t phys, size_t size)\n {\n \treturn false;\n }\n \n-static inline enum migratetype kho_scratch_migratetype(unsigned long pfn,\n+static inline enum migratetype kho_bootmem_migratetype(unsigned long pfn,\n \t\t\t\t\t\t       enum migratetype mt)\n {\n \treturn mt;\ndiff --git a/include/linux/memblock.h b/include/linux/memblock.h\nindex d62db9e776cf9..aaa11a589843c 100644\n--- a/include/linux/memblock.h\n+++ b/include/linux/memblock.h\n@@ -46,11 +46,11 @@ extern unsigned long long max_possible_pfn;\n  * @MEMBLOCK_RSRV_KERN: memory region that is reserved for kernel use,\n  * either explictitly with memblock_reserve_kern() or via memblock\n  * allocation APIs. All memblock allocations set this flag.\n- * @MEMBLOCK_KHO_SCRATCH: memory region that kexec can pass to the next\n- * kernel in handover mode. During early boot, we do not know about all\n- * memory reservations yet, so we get scratch memory from the previous\n- * kernel that we know is good to use. It is the only memory that\n- * allocations may happen from in this phase.\n+ * @MEMBLOCK_KHO_NOPRSRV: memory region with no preservation from kexec\n+ * handover. During early boot, we do not know about all memory preservations\n+ * yet, so we get memory with no preservations from the previous kernel that we\n+ * know is good to use. It is the only memory that allocations may happen from\n+ * in this phase.\n  * @MEMBLOCK_RSRV_HUGETLB: memory is reserved for hugetlb pages\n  */\n enum memblock_flags {\n@@ -61,7 +61,7 @@ enum memblock_flags {\n \tMEMBLOCK_DRIVER_MANAGED = 0x8,\t/* always detected via a driver */\n \tMEMBLOCK_RSRV_NOINIT\t= 0x10,\t/* don't initialize struct pages */\n \tMEMBLOCK_RSRV_KERN\t= 0x20,\t/* memory reserved for kernel use */\n-\tMEMBLOCK_KHO_SCRATCH\t= 0x40,\t/* scratch memory for kexec handover */\n+\tMEMBLOCK_KHO_NOPRSRV\t= 0x40,\t/* memory with no KHO preservations */\n \tMEMBLOCK_RSRV_HUGETLB\t= 0x80, /* memory reserved for hugetlb pages */\n };\n \n@@ -158,8 +158,8 @@ int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);\n int memblock_clear_nomap(phys_addr_t base, phys_addr_t size);\n int memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t size);\n int memblock_reserved_mark_kern(phys_addr_t base, phys_addr_t size);\n-int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size);\n-int memblock_clear_kho_scratch(phys_addr_t base, phys_addr_t size);\n+int memblock_mark_kho_noprsrv(phys_addr_t base, phys_addr_t size);\n+int memblock_clear_kho_noprsrv(phys_addr_t base, phys_addr_t size);\n \n void memblock_free(void *ptr, size_t size);\n void reset_all_zones_managed_pages(void);\n@@ -301,9 +301,9 @@ static inline bool memblock_is_driver_managed(struct memblock_region *m)\n \treturn m-\u003eflags \u0026 MEMBLOCK_DRIVER_MANAGED;\n }\n \n-static inline bool memblock_is_kho_scratch(struct memblock_region *m)\n+static inline bool memblock_is_kho_noprsrv(struct memblock_region *m)\n {\n-\treturn m-\u003eflags \u0026 MEMBLOCK_KHO_SCRATCH;\n+\treturn m-\u003eflags \u0026 MEMBLOCK_KHO_NOPRSRV;\n }\n \n int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn,\n@@ -614,12 +614,12 @@ static inline void early_memtest(phys_addr_t start, phys_addr_t end) { }\n static inline void memtest_report_meminfo(struct seq_file *m) { }\n #endif\n \n-#ifdef CONFIG_MEMBLOCK_KHO_SCRATCH\n-void memblock_set_kho_scratch_only(void);\n-void memblock_clear_kho_scratch_only(void);\n+#ifdef CONFIG_KEXEC_HANDOVER\n+void memblock_set_kho_noprsrv_only(void);\n+void memblock_clear_kho_noprsrv_only(void);\n #else\n-static inline void memblock_set_kho_scratch_only(void) { }\n-static inline void memblock_clear_kho_scratch_only(void) { }\n+static inline void memblock_set_kho_noprsrv_only(void) { }\n+static inline void memblock_clear_kho_noprsrv_only(void) { }\n #endif\n \n #endif /* _LINUX_MEMBLOCK_H */\ndiff --git a/kernel/kexec_file.c b/kernel/kexec_file.c\nindex a8455481f6394..b668ce8d68eed 100644\n--- a/kernel/kexec_file.c\n+++ b/kernel/kexec_file.c\n@@ -742,8 +742,8 @@ int kexec_locate_mem_hole(struct kexec_buf *kbuf)\n \t\treturn 0;\n \n \t/*\n-\t * If KHO is active, only use KHO scratch memory. All other memory\n-\t * could potentially be handed over.\n+\t * If KHO is active, only use KHO bootmem. All other memory could\n+\t * potentially be handed over.\n \t */\n \tret = kho_locate_mem_hole(kbuf, locate_mem_hole_callback);\n \tif (ret \u003c= 0)\ndiff --git a/kernel/liveupdate/Kconfig b/kernel/liveupdate/Kconfig\nindex c13af38ba23ab..f50daee8eff07 100644\n--- a/kernel/liveupdate/Kconfig\n+++ b/kernel/liveupdate/Kconfig\n@@ -5,7 +5,6 @@ menu \"Live Update and Kexec HandOver\"\n config KEXEC_HANDOVER\n \tbool \"kexec handover\"\n \tdepends on ARCH_SUPPORTS_KEXEC_HANDOVER \u0026\u0026 ARCH_SUPPORTS_KEXEC_FILE\n-\tselect MEMBLOCK_KHO_SCRATCH\n \tselect KEXEC_FILE\n \tselect LIBFDT\n \tselect CMA\ndiff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c\nindex 3c87c2a3d6f09..7018e25e4eda1 100644\n--- a/kernel/liveupdate/kexec_handover.c\n+++ b/kernel/liveupdate/kexec_handover.c\n@@ -43,12 +43,12 @@\n /*\n  * This is the minimal alignment required by deferred struct page init.\n  * deferred_init_memmap_chunk frees memory to the buddy allocator, which looks\n- * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them.\n- * If KHO scratch is not aligned to that value, buddy can access uninitialized\n- * struct pages, which can cause a crash.\n+ * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them. If KHO bootmem\n+ * is not aligned to that value, buddy can access uninitialized struct pages,\n+ * which can cause a crash.\n  */\n-#define SCRATCH_ALIGNMENT_BYTES (PAGE_SIZE * MAX_ORDER_NR_PAGES)\n-static_assert(SCRATCH_ALIGNMENT_BYTES \u003e= CMA_MIN_ALIGNMENT_BYTES);\n+#define BOOTMEM_ALIGNMENT_BYTES (PAGE_SIZE * MAX_ORDER_NR_PAGES)\n+static_assert(BOOTMEM_ALIGNMENT_BYTES \u003e= CMA_MIN_ALIGNMENT_BYTES);\n \n /* The magic token for preserved pages */\n #define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */\n@@ -98,7 +98,7 @@ static struct kho_out kho_out = {\n \n struct kho_in {\n \tphys_addr_t fdt_phys;\n-\tphys_addr_t scratch_phys;\n+\tphys_addr_t bootmem_phys;\n \tchar previous_release[__NEW_UTS_LEN + 1];\n \tu32 kexec_count;\n \tstruct kho_debugfs dbg;\n@@ -658,34 +658,34 @@ static void __init *kho_get_mem_map(const void *fdt)\n \n /*\n  * With KHO enabled, memory can become fragmented because KHO regions may\n- * be anywhere in physical address space. The scratch regions give us a\n+ * be anywhere in physical address space. The bootmem regions give us a\n  * safe zones that we will never see KHO allocations from. This is where we\n- * can later safely load our new kexec images into and then use the scratch\n+ * can later safely load our new kexec images into and then use the bootmem\n  * area for early allocations that happen before page allocator is\n  * initialized.\n  */\n-struct kho_scratch *kho_scratch;\n-unsigned int kho_scratch_cnt;\n+struct kho_bootmem *kho_bootmem;\n+unsigned int kho_bootmem_cnt;\n \n /*\n- * The scratch areas are scaled by default as percent of memory allocated from\n+ * The bootmem areas are scaled by default as percent of memory allocated from\n  * memblock. A user can override the scale with command line parameter:\n  *\n- * kho_scratch=N%\n+ * kho_bootmem=N%\n  *\n  * It is also possible to explicitly define size for a lowmem, a global and\n- * per-node scratch areas:\n+ * per-node bootmem areas:\n  *\n- * kho_scratch=l[KMG],n[KMG],m[KMG]\n+ * kho_bootmem=l[KMG],n[KMG],m[KMG]\n  *\n  * The explicit size definition takes precedence over scale definition.\n  */\n-static unsigned int scratch_scale __initdata = 200;\n-static phys_addr_t scratch_size_global __initdata;\n-static phys_addr_t scratch_size_pernode __initdata;\n-static phys_addr_t scratch_size_lowmem __initdata;\n+static unsigned int bootmem_scale __initdata = 200;\n+static phys_addr_t bootmem_size_global __initdata;\n+static phys_addr_t bootmem_size_pernode __initdata;\n+static phys_addr_t bootmem_size_lowmem __initdata;\n \n-static int __init kho_parse_scratch_size(char *p)\n+static int __init kho_parse_bootmem_size(char *p)\n {\n \tsize_t len;\n \tunsigned long sizes[3];\n@@ -709,9 +709,9 @@ static int __init kho_parse_scratch_size(char *p)\n \t\t\treturn -EINVAL;\n \n \t\tmemcpy(s_scale, p, len - 1);\n-\t\tret = kstrtouint(s_scale, 10, \u0026scratch_scale);\n+\t\tret = kstrtouint(s_scale, 10, \u0026bootmem_scale);\n \t\tif (!ret)\n-\t\t\tpr_notice(\"scratch scale is %d%%\\n\", scratch_scale);\n+\t\t\tpr_notice(\"bootmem scale is %d%%\\n\", bootmem_scale);\n \t\treturn ret;\n \t}\n \n@@ -739,81 +739,81 @@ static int __init kho_parse_scratch_size(char *p)\n \tif (*p)\n \t\treturn -EINVAL;\n \n-\tscratch_size_lowmem = sizes[0];\n-\tscratch_size_global = sizes[1];\n-\tscratch_size_pernode = sizes[2];\n-\tscratch_scale = 0;\n+\tbootmem_size_lowmem = sizes[0];\n+\tbootmem_size_global = sizes[1];\n+\tbootmem_size_pernode = sizes[2];\n+\tbootmem_scale = 0;\n \n-\tpr_notice(\"scratch areas: lowmem: %lluMiB global: %lluMiB pernode: %lldMiB\\n\",\n-\t\t  (u64)(scratch_size_lowmem \u003e\u003e 20),\n-\t\t  (u64)(scratch_size_global \u003e\u003e 20),\n-\t\t  (u64)(scratch_size_pernode \u003e\u003e 20));\n+\tpr_notice(\"bootmem areas: lowmem: %lluMiB global: %lluMiB pernode: %lldMiB\\n\",\n+\t\t  (u64)(bootmem_size_lowmem \u003e\u003e 20),\n+\t\t  (u64)(bootmem_size_global \u003e\u003e 20),\n+\t\t  (u64)(bootmem_size_pernode \u003e\u003e 20));\n \n \treturn 0;\n }\n-early_param(\"kho_scratch\", kho_parse_scratch_size);\n+early_param(\"kho_bootmem\", kho_parse_bootmem_size);\n \n-static void __init scratch_size_update(void)\n+static void __init bootmem_size_update(void)\n {\n \t/*\n \t * If fixed sizes are not provided via command line, calculate them now.\n \t * Remove HugeTLB allocations from it because they never get allocated\n-\t * from scratch.\n+\t * from bootmem.\n \t */\n-\tif (scratch_scale) {\n+\tif (bootmem_scale) {\n \t\tphys_addr_t size;\n \n \t\tsize = memblock_reserved_kern_size(ARCH_LOW_ADDRESS_LIMIT,\n \t\t\t\t\t\t   NUMA_NO_NODE);\n \t\tsize -= memblock_reserved_hugetlb_size(ARCH_LOW_ADDRESS_LIMIT,\n \t\t\t\t\t\t       NUMA_NO_NODE);\n-\t\tsize = size * scratch_scale / 100;\n-\t\tscratch_size_lowmem = size;\n+\t\tsize = size * bootmem_scale / 100;\n+\t\tbootmem_size_lowmem = size;\n \n \t\tsize = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,\n \t\t\t\t\t\t   NUMA_NO_NODE);\n \t\tsize -= memblock_reserved_hugetlb_size(MEMBLOCK_ALLOC_ANYWHERE,\n \t\t\t\t\t\t       NUMA_NO_NODE);\n-\t\tsize = size * scratch_scale / 100 - scratch_size_lowmem;\n-\t\tscratch_size_global = size;\n+\t\tsize = size * bootmem_scale / 100 - bootmem_size_lowmem;\n+\t\tbootmem_size_global = size;\n \t}\n \n \t/*\n-\t * Scratch areas are released as MIGRATE_CMA. Round them up to the right\n+\t * bootmem areas are released as MIGRATE_CMA. Round them up to the right\n \t * size.\n \t */\n-\tscratch_size_lowmem = round_up(scratch_size_lowmem, SCRATCH_ALIGNMENT_BYTES);\n-\tscratch_size_global = round_up(scratch_size_global, SCRATCH_ALIGNMENT_BYTES);\n+\tbootmem_size_lowmem = round_up(bootmem_size_lowmem, BOOTMEM_ALIGNMENT_BYTES);\n+\tbootmem_size_global = round_up(bootmem_size_global, BOOTMEM_ALIGNMENT_BYTES);\n }\n \n-static phys_addr_t __init scratch_size_node(int nid)\n+static phys_addr_t __init bootmem_size_node(int nid)\n {\n \tphys_addr_t size;\n \n-\tif (scratch_scale) {\n+\tif (bootmem_scale) {\n \t\tsize = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,\n \t\t\t\t\t\t   nid);\n \t\t/* Do not count HugeTLB pages. */\n \t\tsize -= memblock_reserved_hugetlb_size(MEMBLOCK_ALLOC_ANYWHERE,\n \t\t\t\t\t\t       nid);\n-\t\tsize = size * scratch_scale / 100;\n+\t\tsize = size * bootmem_scale / 100;\n \t} else {\n-\t\tsize = scratch_size_pernode;\n+\t\tsize = bootmem_size_pernode;\n \t}\n \n-\treturn round_up(size, SCRATCH_ALIGNMENT_BYTES);\n+\treturn round_up(size, BOOTMEM_ALIGNMENT_BYTES);\n }\n \n-bool kho_scratch_overlap(phys_addr_t phys, size_t size)\n+bool kho_bootmem_overlap(phys_addr_t phys, size_t size)\n {\n-\tphys_addr_t scratch_start, scratch_end;\n+\tphys_addr_t bootmem_start, bootmem_end;\n \tunsigned int i;\n \n-\tfor (i = 0; i \u003c kho_scratch_cnt; i++) {\n-\t\tscratch_start = kho_scratch[i].addr;\n-\t\tscratch_end = kho_scratch[i].addr + kho_scratch[i].size;\n+\tfor (i = 0; i \u003c kho_bootmem_cnt; i++) {\n+\t\tbootmem_start = kho_bootmem[i].addr;\n+\t\tbootmem_end = kho_bootmem[i].addr + kho_bootmem[i].size;\n \n-\t\tif (phys \u003c scratch_end \u0026\u0026 (phys + size) \u003e scratch_start)\n+\t\tif (phys \u003c bootmem_end \u0026\u0026 (phys + size) \u003e bootmem_start)\n \t\t\treturn true;\n \t}\n \n@@ -821,7 +821,7 @@ bool kho_scratch_overlap(phys_addr_t phys, size_t size)\n }\n \n /**\n- * kho_reserve_scratch - Reserve a contiguous chunk of memory for kexec\n+ * kho_reserve_bootmem - Reserve a contiguous chunk of memory for kexec\n  *\n  * With KHO we can preserve arbitrary pages in the system. To ensure we still\n  * have a large contiguous region of memory when we search the physical address\n@@ -829,7 +829,7 @@ bool kho_scratch_overlap(phys_addr_t phys, size_t size)\n  * active. This CMA region will only be used for movable pages which are not a\n  * problem for us during KHO because we can just move them somewhere else.\n  */\n-static void __init kho_reserve_scratch(void)\n+static void __init kho_reserve_bootmem(void)\n {\n \tphys_addr_t addr, size;\n \tint nid, i = 0;\n@@ -837,73 +837,73 @@ static void __init kho_reserve_scratch(void)\n \tif (!kho_enable)\n \t\treturn;\n \n-\tscratch_size_update();\n+\tbootmem_size_update();\n \n \t/* FIXME: deal with node hot-plug/remove */\n-\tkho_scratch_cnt = nodes_weight(node_states[N_MEMORY]) + 2;\n-\tsize = kho_scratch_cnt * sizeof(*kho_scratch);\n-\tkho_scratch = memblock_alloc(size, PAGE_SIZE);\n-\tif (!kho_scratch) {\n-\t\tpr_err(\"Failed to reserve scratch array\\n\");\n+\tkho_bootmem_cnt = nodes_weight(node_states[N_MEMORY]) + 2;\n+\tsize = kho_bootmem_cnt * sizeof(*kho_bootmem);\n+\tkho_bootmem = memblock_alloc(size, PAGE_SIZE);\n+\tif (!kho_bootmem) {\n+\t\tpr_err(\"Failed to reserve bootmem array\\n\");\n \t\tgoto err_disable_kho;\n \t}\n \n \t/*\n-\t * reserve scratch area in low memory for lowmem allocations in the\n+\t * reserve bootmem area in low memory for lowmem allocations in the\n \t * next kernel\n \t */\n-\tsize = scratch_size_lowmem;\n-\taddr = memblock_phys_alloc_range(size, SCRATCH_ALIGNMENT_BYTES, 0,\n+\tsize = bootmem_size_lowmem;\n+\taddr = memblock_phys_alloc_range(size, BOOTMEM_ALIGNMENT_BYTES, 0,\n \t\t\t\t\t ARCH_LOW_ADDRESS_LIMIT);\n \tif (!addr) {\n-\t\tpr_err(\"Failed to reserve lowmem scratch buffer\\n\");\n-\t\tgoto err_free_scratch_desc;\n+\t\tpr_err(\"Failed to reserve lowmem bootmem\\n\");\n+\t\tgoto err_free_bootmem_desc;\n \t}\n \n-\tkho_scratch[i].addr = addr;\n-\tkho_scratch[i].size = size;\n+\tkho_bootmem[i].addr = addr;\n+\tkho_bootmem[i].size = size;\n \ti++;\n \n \t/* reserve large contiguous area for allocations without nid */\n-\tsize = scratch_size_global;\n-\taddr = memblock_phys_alloc(size, SCRATCH_ALIGNMENT_BYTES);\n+\tsize = bootmem_size_global;\n+\taddr = memblock_phys_alloc(size, BOOTMEM_ALIGNMENT_BYTES);\n \tif (!addr) {\n-\t\tpr_err(\"Failed to reserve global scratch buffer\\n\");\n-\t\tgoto err_free_scratch_areas;\n+\t\tpr_err(\"Failed to reserve global bootmem\\n\");\n+\t\tgoto err_free_bootmem_areas;\n \t}\n \n-\tkho_scratch[i].addr = addr;\n-\tkho_scratch[i].size = size;\n+\tkho_bootmem[i].addr = addr;\n+\tkho_bootmem[i].size = size;\n \ti++;\n \n \t/*\n \t * Loop over nodes that have both memory and are online. Skip\n-\t * memoryless nodes, as we can not allocate scratch areas there.\n+\t * memoryless nodes, as we can not allocate bootmem areas there.\n \t */\n \tfor_each_node_state(nid, N_MEMORY) {\n-\t\tsize = scratch_size_node(nid);\n-\t\taddr = memblock_alloc_range_nid(size, SCRATCH_ALIGNMENT_BYTES,\n+\t\tsize = bootmem_size_node(nid);\n+\t\taddr = memblock_alloc_range_nid(size, BOOTMEM_ALIGNMENT_BYTES,\n \t\t\t\t\t\t0, MEMBLOCK_ALLOC_ACCESSIBLE,\n \t\t\t\t\t\tnid, true);\n \t\tif (!addr) {\n-\t\t\tpr_err(\"Failed to reserve nid %d scratch buffer\\n\", nid);\n-\t\t\tgoto err_free_scratch_areas;\n+\t\t\tpr_err(\"Failed to reserve nid %d bootmem\\n\", nid);\n+\t\t\tgoto err_free_bootmem_areas;\n \t\t}\n \n-\t\tkho_scratch[i].addr = addr;\n-\t\tkho_scratch[i].size = size;\n+\t\tkho_bootmem[i].addr = addr;\n+\t\tkho_bootmem[i].size = size;\n \t\ti++;\n \t}\n \n \treturn;\n \n-err_free_scratch_areas:\n+err_free_bootmem_areas:\n \tfor (i--; i \u003e= 0; i--)\n-\t\tmemblock_phys_free(kho_scratch[i].addr, kho_scratch[i].size);\n-err_free_scratch_desc:\n-\tmemblock_free(kho_scratch, kho_scratch_cnt * sizeof(*kho_scratch));\n+\t\tmemblock_phys_free(kho_bootmem[i].addr, kho_bootmem[i].size);\n+err_free_bootmem_desc:\n+\tmemblock_free(kho_bootmem, kho_bootmem_cnt * sizeof(*kho_bootmem));\n err_disable_kho:\n-\tpr_warn(\"Failed to reserve scratch area, disabling kexec handover\\n\");\n+\tpr_warn(\"Failed to reserve bootmem, disabling kexec handover\\n\");\n \tkho_enable = false;\n }\n \n@@ -913,11 +913,11 @@ static void __init kho_reserve_scratch(void)\n  * on smaller systems. The algorithm itself doesn't depend on the actual value,\n  * so it can be changed to a different heuristic later if needed.\n  */\n-#define KHO_SCRATCH_EXT_BLKSIZE\t\tSZ_1G\n-#define KHO_SCRATCH_EXT_BLKSHIFT\tconst_ilog2(KHO_SCRATCH_EXT_BLKSIZE)\n+#define KHO_DISCOVER_BLKSIZE\t\tSZ_1G\n+#define KHO_DISCOVER_BLKSHIFT\tconst_ilog2(KHO_DISCOVER_BLKSIZE)\n \n /* Called for the KHO preserved memory radix tree. */\n-static int __init kho_ext_walk_leaf(unsigned long key, void *data)\n+static int __init kho_discover_walk_leaf(unsigned long key, void *data)\n {\n \tstruct kho_radix_tree *busy_blocks = data;\n \tphys_addr_t start, end;\n@@ -932,54 +932,57 @@ static int __init kho_ext_walk_leaf(unsigned long key, void *data)\n \tend = start + (1UL \u003c\u003c (order + PAGE_SHIFT));\n \n \twhile (start \u003c end) {\n-\t\terr = kho_radix_add_key(busy_blocks, start \u003e\u003e KHO_SCRATCH_EXT_BLKSHIFT);\n+\t\terr = kho_radix_add_key(busy_blocks, start \u003e\u003e KHO_DISCOVER_BLKSHIFT);\n \t\tif (err)\n \t\t\treturn err;\n \n-\t\tstart += (1UL \u003c\u003c KHO_SCRATCH_EXT_BLKSHIFT);\n+\t\tstart += (1UL \u003c\u003c KHO_DISCOVER_BLKSHIFT);\n \t}\n \n \treturn 0;\n }\n \n /* Called for the KHO preserved memory radix tree. */\n-static int __init kho_ext_walk_node(phys_addr_t phys, void *data)\n+static int __init kho_discover_walk_node(phys_addr_t phys, void *data)\n {\n \tstruct kho_radix_tree *busy_blocks = data;\n \n-\treturn kho_radix_add_key(busy_blocks, phys \u003e\u003e KHO_SCRATCH_EXT_BLKSHIFT);\n+\treturn kho_radix_add_key(busy_blocks, phys \u003e\u003e KHO_DISCOVER_BLKSHIFT);\n }\n \n /* Called for the busy block radix tree. */\n-static int __init kho_ext_mark_scratch(unsigned long key, void *data)\n+static int __init kho_discover_mark_noprsrv(unsigned long key, void *data)\n {\n \tphys_addr_t *prev_end = data;\n-\tphys_addr_t start = key \u003c\u003c KHO_SCRATCH_EXT_BLKSHIFT;\n+\tphys_addr_t start = key \u003c\u003c KHO_DISCOVER_BLKSHIFT;\n \tint err;\n \n \tif (start \u003e *prev_end) {\n-\t\terr = memblock_mark_kho_scratch(*prev_end, start - *prev_end);\n+\t\terr = memblock_mark_kho_noprsrv(*prev_end, start - *prev_end);\n \t\tif (err)\n \t\t\treturn err;\n \t}\n \n-\t*prev_end = start + (1UL \u003c\u003c KHO_SCRATCH_EXT_BLKSHIFT);\n+\t*prev_end = start + (1UL \u003c\u003c KHO_DISCOVER_BLKSHIFT);\n \treturn 0;\n }\n \n /*\n- * kho_extend_scratch - Extend the scratch regions\n+ * kho_discover_noprsrv - Discover memory with no preservations\n+ *\n+ * Discovers memory ranges with no preserved memory and marks it as NOPRSRV.\n+ * This lets memblock allocate memory from areas outside KHO bootmem.\n  *\n  * The KHO preserved memory radix tree mixes both physical address and order\n  * into a single key. This makes it hard to look for free ranges directly. This\n  * function first walks the radix tree and digests it down into another radix\n- * tree, whose keys identify blocks of size KHO_SCRATCH_EXT_BLKSIZE which\n- * contain preserved memory.\n+ * tree, whose keys identify blocks of size KHO_DISCOVER_BLKSIZE which contain\n+ * preserved memory.\n  *\n  * Then it walks the digested radix tree and marks everything that doesn't have\n- * preserved memory as scratch.\n+ * preserved memory as NOPRSRV.\n  *\n- * NOTE: This function allocates memory so it should be called when scratch has\n+ * NOTE: This function allocates memory so it should be called when bootmem has\n  * available space.\n  *\n  * NOTE: The pages of the KHO preserved memory radix tree tables are not marked\n@@ -988,18 +991,18 @@ static int __init kho_ext_mark_scratch(unsigned long key, void *data)\n  * them to be \"preserved memory\" and marks their blocks as busy.\n  *\n  * NOTE: efi_init()::reserve_regions() removes all regions except\n- * MEMBLOCK_KHO_SCRATCH. This function adds such regions but they are not KHO\n- * scratch memory, so they should not be removed. This function should always be\n+ * MEMBLOCK_KHO_NOPRSRV. This function adds such regions but they are not KHO\n+ * boot memory, so they should not be removed. This function should always be\n  * called after reserve_regions().\n  */\n-static void __init kho_extend_scratch(void)\n+static void __init kho_discover_noprsrv(void)\n {\n \tconst struct kho_radix_walk_cb kho_cb = {\n-\t\t.leaf = kho_ext_walk_leaf,\n-\t\t.node = kho_ext_walk_node,\n+\t\t.leaf = kho_discover_walk_leaf,\n+\t\t.node = kho_discover_walk_node,\n \t};\n \tconst struct kho_radix_walk_cb ext_cb = {\n-\t\t.leaf = kho_ext_mark_scratch,\n+\t\t.leaf = kho_discover_mark_noprsrv,\n \t};\n \tstatic struct lock_class_key busy_radix_class;\n \tstruct kho_radix_tree busy_blocks;\n@@ -1024,21 +1027,21 @@ static void __init kho_extend_scratch(void)\n \tif (err)\n \t\tgoto out;\n \n-\t/* Walk the busy blocks and mark everything between keys as scratch. */\n+\t/* Walk the busy blocks and mark everything between keys as noprsrv. */\n \terr = kho_radix_walk_tree(\u0026busy_blocks, \u0026ext_cb, \u0026prev_end);\n \tif (err)\n \t\tgoto out;\n \n \t/* Mark everything from last busy block to end of DRAM. */\n \tif (prev_end \u003c memblock_end_of_DRAM())\n-\t\terr = memblock_mark_kho_scratch(prev_end, memblock_end_of_DRAM() - prev_end);\n+\t\terr = memblock_mark_kho_noprsrv(prev_end, memblock_end_of_DRAM() - prev_end);\n \n \t/* fallthrough */\n out:\n \tkho_radix_destroy_tree(\u0026busy_blocks);\n print:\n \tif (err)\n-\t\tpr_err(\"Failed to extend scratch: %pe\\n\", ERR_PTR(err));\n+\t\tpr_err(\"Failed to discover extra allocatable memory: %pe\\n\", ERR_PTR(err));\n }\n \n /**\n@@ -1152,7 +1155,7 @@ int kho_preserve_folio(struct folio *folio)\n \tconst unsigned int order = folio_order(folio);\n \n \tif (IS_ENABLED(CONFIG_KEXEC_HANDOVER_DEBUG) \u0026\u0026\n-\t    WARN_ON(kho_scratch_overlap(pfn \u003c\u003c PAGE_SHIFT, PAGE_SIZE \u003c\u003c order)))\n+\t    WARN_ON(kho_bootmem_overlap(pfn \u003c\u003c PAGE_SHIFT, PAGE_SIZE \u003c\u003c order)))\n \t\treturn -EINVAL;\n \n \treturn kho_radix_add_key(tree, kho_encode_radix_key(PFN_PHYS(pfn),\n@@ -1230,7 +1233,7 @@ int kho_preserve_pages(struct page *page, unsigned long nr_pages)\n \tint err = 0;\n \n \tif (IS_ENABLED(CONFIG_KEXEC_HANDOVER_DEBUG) \u0026\u0026\n-\t    WARN_ON(kho_scratch_overlap(start_pfn \u003c\u003c PAGE_SHIFT,\n+\t    WARN_ON(kho_bootmem_overlap(start_pfn \u003c\u003c PAGE_SHIFT,\n \t\t\t\t\tnr_pages \u003c\u003c PAGE_SHIFT))) {\n \t\treturn -EINVAL;\n \t}\n@@ -1827,7 +1830,7 @@ static __init int kho_init(void)\n \n \terr = kho_radix_init_tree(tree, NULL);\n \tif (err)\n-\t\tgoto err_free_scratch;\n+\t\tgoto err_free_bootmem;\n \n \tkho_out.fdt = kho_alloc_preserve(PAGE_SIZE);\n \tif (IS_ERR(kho_out.fdt)) {\n@@ -1856,9 +1859,9 @@ static __init int kho_init(void)\n \t\treturn 0;\n \t}\n \n-\tfor (int i = 0; i \u003c kho_scratch_cnt; i++) {\n-\t\tunsigned long base_pfn = PHYS_PFN(kho_scratch[i].addr);\n-\t\tunsigned long count = kho_scratch[i].size \u003e\u003e PAGE_SHIFT;\n+\tfor (int i = 0; i \u003c kho_bootmem_cnt; i++) {\n+\t\tunsigned long base_pfn = PHYS_PFN(kho_bootmem[i].addr);\n+\t\tunsigned long count = kho_bootmem[i].size \u003e\u003e PAGE_SHIFT;\n \t\tunsigned long pfn;\n \n \t\t/*\n@@ -1866,10 +1869,10 @@ static __init int kho_init(void)\n \t\t * corresponding PRESENT bit in the kernel page table.\n \t\t * Subsequent kmemleak scans of these pages cause the\n \t\t * non-PRESENT page faults.\n-\t\t * Mark scratch areas with kmemleak_ignore_phys() to exclude\n+\t\t * Mark bootmem areas with kmemleak_ignore_phys() to exclude\n \t\t * them from kmemleak scanning.\n \t\t */\n-\t\tkmemleak_ignore_phys(kho_scratch[i].addr);\n+\t\tkmemleak_ignore_phys(kho_bootmem[i].addr);\n \t\tfor (pfn = base_pfn; pfn \u003c base_pfn + count;\n \t\t     pfn += pageblock_nr_pages)\n \t\t\tinit_cma_reserved_pageblock(pfn_to_page(pfn));\n@@ -1885,11 +1888,11 @@ static __init int kho_init(void)\n \tkho_unpreserve_free(kho_out.fdt);\n err_free_kho_radix_tree:\n \tkho_radix_destroy_tree(tree);\n-err_free_scratch:\n+err_free_bootmem:\n \tkho_out.fdt = NULL;\n-\tfor (int i = 0; i \u003c kho_scratch_cnt; i++) {\n-\t\tvoid *start = __va(kho_scratch[i].addr);\n-\t\tvoid *end = start + kho_scratch[i].size;\n+\tfor (int i = 0; i \u003c kho_bootmem_cnt; i++) {\n+\t\tvoid *start = __va(kho_bootmem[i].addr);\n+\t\tvoid *end = start + kho_bootmem[i].size;\n \n \t\tfree_reserved_area(start, end, -1, \"\");\n \t}\n@@ -1908,7 +1911,7 @@ void __init kho_memory_init_early(void)\n \n \t/*\n \t * kho_get_mem_map() should always succeed. If it fails, kho_populate()\n-\t * catches that and never sets kho_in.scratch_phys, which stops memory\n+\t * catches that and never sets kho_in.bootmem_phys, which stops memory\n \t * retrieval.\n \t */\n \tmem_map = kho_get_mem_map(fdt);\n@@ -1916,26 +1919,25 @@ void __init kho_memory_init_early(void)\n \t\tgoto err;\n \n \t/*\n-\t * kho_scratch_overlap() needs kho_scratch to be initialized. It\n-\t * is used by free_area_init() on KHO boots, so initialize it\n-\t * early.\n+\t * kho_bootmem_overlap() needs kho_bootmem to be initialized. It is used\n+\t * by free_area_init() on KHO boots, so initialize it early.\n \t */\n-\tkho_scratch = phys_to_virt(kho_in.scratch_phys);\n+\tkho_bootmem = phys_to_virt(kho_in.bootmem_phys);\n \n \tif (kho_radix_init_tree(\u0026kho_in.radix_tree, mem_map))\n \t\tgoto err;\n \n-\tkho_extend_scratch();\n+\tkho_discover_noprsrv();\n \n \treturn;\n \n err:\n \t/*\n \t * Failed to initialize preserved memory radix tree. Clear FDT\n-\t * and scratch so KHO users don't treat it as a KHO boot.\n+\t * and bootmem so KHO users don't treat it as a KHO boot.\n \t */\n \tkho_in.fdt_phys = 0;\n-\tkho_in.scratch_phys = 0;\n+\tkho_in.bootmem_phys = 0;\n }\n \n void __init kho_memory_init(void)\n@@ -1946,17 +1948,17 @@ void __init kho_memory_init(void)\n \t\treturn;\n \t}\n \n-\tif (kho_in.scratch_phys)\n+\tif (kho_in.bootmem_phys)\n \t\tkho_mem_retrieve();\n \telse\n-\t\tkho_reserve_scratch();\n+\t\tkho_reserve_bootmem();\n }\n \n void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len,\n-\t\t\t phys_addr_t scratch_phys, u64 scratch_len)\n+\t\t\t phys_addr_t bootmem_phys, u64 bootmem_len)\n {\n-\tunsigned int scratch_cnt = scratch_len / sizeof(*kho_scratch);\n-\tstruct kho_scratch *scratch = NULL;\n+\tunsigned int bootmem_cnt = bootmem_len / sizeof(*kho_bootmem);\n+\tstruct kho_bootmem *bootmem = NULL;\n \tphys_addr_t mem_map_phys;\n \tvoid *fdt = NULL;\n \tbool populated = false;\n@@ -1985,52 +1987,52 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len,\n \tif (!mem_map_phys)\n \t\tgoto unmap_fdt;\n \n-\tscratch = early_memremap(scratch_phys, scratch_len);\n-\tif (!scratch) {\n-\t\tpr_warn(\"setup: failed to memremap scratch (phys=0x%llx, len=%lld)\\n\",\n-\t\t\tscratch_phys, scratch_len);\n+\tbootmem = early_memremap(bootmem_phys, bootmem_len);\n+\tif (!bootmem) {\n+\t\tpr_warn(\"setup: failed to memremap bootmem (phys=0x%llx, len=%lld)\\n\",\n+\t\t\tbootmem_phys, bootmem_len);\n \t\tgoto unmap_fdt;\n \t}\n \n \t/*\n-\t * We pass a safe contiguous blocks of memory to use for early boot\n-\t * purporses from the previous kernel so that we can resize the\n-\t * memblock array as needed.\n+\t * We pass a safe contiguous blocks of memory with no preservations to\n+\t * use for early boot purporses from the previous kernel so that we can\n+\t * resize the memblock array as needed.\n \t */\n-\tfor (int i = 0; i \u003c scratch_cnt; i++) {\n-\t\tstruct kho_scratch *area = \u0026scratch[i];\n+\tfor (int i = 0; i \u003c bootmem_cnt; i++) {\n+\t\tstruct kho_bootmem *area = \u0026bootmem[i];\n \t\tu64 size = area-\u003esize;\n \n \t\tmemblock_add(area-\u003eaddr, size);\n-\t\terr = memblock_mark_kho_scratch(area-\u003eaddr, size);\n+\t\terr = memblock_mark_kho_noprsrv(area-\u003eaddr, size);\n \t\tif (err) {\n-\t\t\tpr_warn(\"failed to mark the scratch region 0x%pa+0x%pa: %pe\",\n+\t\t\tpr_warn(\"failed to mark the bootmem region 0x%pa+0x%pa: %pe\",\n \t\t\t\t\u0026area-\u003eaddr, \u0026size, ERR_PTR(err));\n-\t\t\tgoto unmap_scratch;\n+\t\t\tgoto unmap_bootmem;\n \t\t}\n-\t\tpr_debug(\"Marked 0x%pa+0x%pa as scratch\", \u0026area-\u003eaddr, \u0026size);\n+\t\tpr_debug(\"Marked 0x%pa+0x%pa as bootmem\", \u0026area-\u003eaddr, \u0026size);\n \t}\n \n-\tmemblock_reserve(scratch_phys, scratch_len);\n+\tmemblock_reserve(bootmem_phys, bootmem_len);\n \n \t/*\n-\t * Now that we have a viable region of scratch memory, let's tell\n+\t * Now that we have a viable region of boot memory, let's tell\n \t * the memblocks allocator to only use that for any allocations.\n \t * That way we ensure that nothing scribbles over in use data while\n \t * we initialize the page tables which we will need to ingest all\n \t * memory reservations from the previous kernel.\n \t */\n-\tmemblock_set_kho_scratch_only();\n+\tmemblock_set_kho_noprsrv_only();\n \n \tkho_in.fdt_phys = fdt_phys;\n-\tkho_in.scratch_phys = scratch_phys;\n-\tkho_scratch_cnt = scratch_cnt;\n+\tkho_in.bootmem_phys = bootmem_phys;\n+\tkho_bootmem_cnt = bootmem_cnt;\n \n \tpopulated = true;\n \tpr_info(\"found kexec handover data.\\n\");\n \n-unmap_scratch:\n-\tearly_memunmap(scratch, scratch_len);\n+unmap_bootmem:\n+\tearly_memunmap(bootmem, bootmem_len);\n unmap_fdt:\n \tearly_memunmap(fdt, fdt_len);\n report:\n@@ -2042,47 +2044,47 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len,\n \n int kho_fill_kimage(struct kimage *image)\n {\n-\tssize_t scratch_size;\n+\tssize_t bootmem_size;\n \tint err = 0;\n-\tstruct kexec_buf scratch;\n+\tstruct kexec_buf bootmem;\n \n \tif (!kho_enable || image-\u003etype == KEXEC_TYPE_CRASH)\n \t\treturn 0;\n \n \timage-\u003ekho.fdt = virt_to_phys(kho_out.fdt);\n \n-\tscratch_size = sizeof(*kho_scratch) * kho_scratch_cnt;\n-\tscratch = (struct kexec_buf){\n+\tbootmem_size = sizeof(*kho_bootmem) * kho_bootmem_cnt;\n+\tbootmem = (struct kexec_buf){\n \t\t.image = image,\n-\t\t.buffer = kho_scratch,\n-\t\t.bufsz = scratch_size,\n+\t\t.buffer = kho_bootmem,\n+\t\t.bufsz = bootmem_size,\n \t\t.mem = KEXEC_BUF_MEM_UNKNOWN,\n-\t\t.memsz = scratch_size,\n+\t\t.memsz = bootmem_size,\n \t\t.buf_align = SZ_64K, /* Makes it easier to map */\n \t\t.buf_max = ULONG_MAX,\n \t\t.top_down = true,\n \t};\n-\terr = kexec_add_buffer(\u0026scratch);\n+\terr = kexec_add_buffer(\u0026bootmem);\n \tif (err)\n \t\treturn err;\n-\timage-\u003ekho.scratch = \u0026image-\u003esegment[image-\u003enr_segments - 1];\n+\timage-\u003ekho.bootmem = \u0026image-\u003esegment[image-\u003enr_segments - 1];\n \n \treturn 0;\n }\n \n-static int kho_walk_scratch(struct kexec_buf *kbuf,\n+static int kho_walk_bootmem(struct kexec_buf *kbuf,\n \t\t\t    int (*func)(struct resource *, void *))\n {\n \tint ret = 0;\n \tint i;\n \n-\tfor (i = 0; i \u003c kho_scratch_cnt; i++) {\n+\tfor (i = 0; i \u003c kho_bootmem_cnt; i++) {\n \t\tstruct resource res = {\n-\t\t\t.start = kho_scratch[i].addr,\n-\t\t\t.end = kho_scratch[i].addr + kho_scratch[i].size - 1,\n+\t\t\t.start = kho_bootmem[i].addr,\n+\t\t\t.end = kho_bootmem[i].addr + kho_bootmem[i].size - 1,\n \t\t};\n \n-\t\t/* Try to fit the kimage into our KHO scratch region */\n+\t\t/* Try to fit the kimage into our KHO bootmem region */\n \t\tret = func(\u0026res, kbuf);\n \t\tif (ret)\n \t\t\tbreak;\n@@ -2099,7 +2101,7 @@ int kho_locate_mem_hole(struct kexec_buf *kbuf,\n \tif (!kho_enable || kbuf-\u003eimage-\u003etype == KEXEC_TYPE_CRASH)\n \t\treturn 1;\n \n-\tret = kho_walk_scratch(kbuf, func);\n+\tret = kho_walk_bootmem(kbuf, func);\n \n \treturn ret == 1 ? 0 : -EADDRNOTAVAIL;\n }\ndiff --git a/kernel/liveupdate/kexec_handover_debugfs.c b/kernel/liveupdate/kexec_handover_debugfs.c\nindex 257ee8a52be66..7d74477da0b79 100644\n--- a/kernel/liveupdate/kexec_handover_debugfs.c\n+++ b/kernel/liveupdate/kexec_handover_debugfs.c\n@@ -77,23 +77,23 @@ void kho_debugfs_blob_remove(struct kho_debugfs *dbg, void *blob)\n \t}\n }\n \n-static int scratch_phys_show(struct seq_file *m, void *v)\n+static int bootmem_phys_show(struct seq_file *m, void *v)\n {\n-\tfor (int i = 0; i \u003c kho_scratch_cnt; i++)\n-\t\tseq_printf(m, \"0x%llx\\n\", kho_scratch[i].addr);\n+\tfor (int i = 0; i \u003c kho_bootmem_cnt; i++)\n+\t\tseq_printf(m, \"0x%llx\\n\", kho_bootmem[i].addr);\n \n \treturn 0;\n }\n-DEFINE_SHOW_ATTRIBUTE(scratch_phys);\n+DEFINE_SHOW_ATTRIBUTE(bootmem_phys);\n \n-static int scratch_len_show(struct seq_file *m, void *v)\n+static int bootmem_len_show(struct seq_file *m, void *v)\n {\n-\tfor (int i = 0; i \u003c kho_scratch_cnt; i++)\n-\t\tseq_printf(m, \"0x%llx\\n\", kho_scratch[i].size);\n+\tfor (int i = 0; i \u003c kho_bootmem_cnt; i++)\n+\t\tseq_printf(m, \"0x%llx\\n\", kho_bootmem[i].size);\n \n \treturn 0;\n }\n-DEFINE_SHOW_ATTRIBUTE(scratch_len);\n+DEFINE_SHOW_ATTRIBUTE(bootmem_len);\n \n __init void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt)\n {\n@@ -186,13 +186,13 @@ __init int kho_out_debugfs_init(struct kho_debugfs *dbg)\n \tif (IS_ERR(sub_fdt_dir))\n \t\tgoto err_rmdir;\n \n-\tf = debugfs_create_file(\"scratch_phys\", 0400, dir, NULL,\n-\t\t\t\t\u0026scratch_phys_fops);\n+\tf = debugfs_create_file(\"bootmem_phys\", 0400, dir, NULL,\n+\t\t\t\t\u0026bootmem_phys_fops);\n \tif (IS_ERR(f))\n \t\tgoto err_rmdir;\n \n-\tf = debugfs_create_file(\"scratch_len\", 0400, dir, NULL,\n-\t\t\t\t\u0026scratch_len_fops);\n+\tf = debugfs_create_file(\"bootmem_len\", 0400, dir, NULL,\n+\t\t\t\t\u0026bootmem_len_fops);\n \tif (IS_ERR(f))\n \t\tgoto err_rmdir;\n \ndiff --git a/kernel/liveupdate/kexec_handover_internal.h b/kernel/liveupdate/kexec_handover_internal.h\nindex 805d2a76c3881..e9685e1ef6d78 100644\n--- a/kernel/liveupdate/kexec_handover_internal.h\n+++ b/kernel/liveupdate/kexec_handover_internal.h\n@@ -19,8 +19,8 @@ struct kho_debugfs {\n struct kho_debugfs {};\n #endif\n \n-extern struct kho_scratch *kho_scratch;\n-extern unsigned int kho_scratch_cnt;\n+extern struct kho_bootmem *kho_bootmem;\n+extern unsigned int kho_bootmem_cnt;\n \n #ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS\n int kho_debugfs_init(void);\ndiff --git a/mm/Kconfig b/mm/Kconfig\nindex 604c58199acbf..631a410eaee98 100644\n--- a/mm/Kconfig\n+++ b/mm/Kconfig\n@@ -483,10 +483,6 @@ config HAVE_GUP_FAST\n \tdepends on MMU\n \tbool\n \n-# Enable memblock support for scratch memory which is needed for kexec handover\n-config MEMBLOCK_KHO_SCRATCH\n-\tbool\n-\n # Don't discard allocated memory used to track \"memory\" and \"reserved\" memblocks\n # after early boot, so it can still be used to test for validity of memory.\n # Also, memblocks are updated with memory hot(un)plug.\ndiff --git a/mm/memblock.c b/mm/memblock.c\nindex 9ce86349a29fa..f5aaa38cfa313 100644\n--- a/mm/memblock.c\n+++ b/mm/memblock.c\n@@ -113,11 +113,11 @@ unsigned long min_low_pfn;\n unsigned long max_pfn;\n unsigned long long max_possible_pfn;\n \n-#ifdef CONFIG_MEMBLOCK_KHO_SCRATCH\n-/* When set to true, only allocate from MEMBLOCK_KHO_SCRATCH ranges */\n-static bool kho_scratch_only;\n+#ifdef CONFIG_KEXEC_HANDOVER\n+/* When set to true, only allocate from MEMBLOCK_KHO_NOPRSRV ranges */\n+static bool kho_noprsrv_only;\n #else\n-#define kho_scratch_only false\n+#define kho_noprsrv_only false\n #endif\n \n static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_MEMORY_REGIONS] __initdata_memblock;\n@@ -179,9 +179,9 @@ bool __init_memblock memblock_has_mirror(void)\n \n static enum memblock_flags __init_memblock choose_memblock_flags(void)\n {\n-\t/* skip non-scratch memory for kho early boot allocations */\n-\tif (kho_scratch_only)\n-\t\treturn MEMBLOCK_KHO_SCRATCH;\n+\t/* only use KHO_NOPRSRV memory for kho early boot allocations */\n+\tif (kho_noprsrv_only)\n+\t\treturn MEMBLOCK_KHO_NOPRSRV;\n \n \treturn system_has_some_mirror ? MEMBLOCK_MIRROR : MEMBLOCK_NONE;\n }\n@@ -1175,33 +1175,33 @@ int __init_memblock memblock_reserved_mark_kern(phys_addr_t base, phys_addr_t si\n }\n \n /**\n- * memblock_mark_kho_scratch - Mark a memory region as MEMBLOCK_KHO_SCRATCH.\n+ * memblock_mark_kho_noprsrv - Mark a memory region as MEMBLOCK_KHO_NOPRSRV.\n  * @base: the base phys addr of the region\n  * @size: the size of the region\n  *\n- * Only memory regions marked with %MEMBLOCK_KHO_SCRATCH will be considered\n+ * Only memory regions marked with %MEMBLOCK_KHO_NOPRSRV will be considered\n  * for allocations during early boot with kexec handover.\n  *\n  * Return: 0 on success, -errno on failure.\n  */\n-__init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)\n+__init int memblock_mark_kho_noprsrv(phys_addr_t base, phys_addr_t size)\n {\n \treturn memblock_setclr_flag(\u0026memblock.memory, base, size, 1,\n-\t\t\t\t    MEMBLOCK_KHO_SCRATCH);\n+\t\t\t\t    MEMBLOCK_KHO_NOPRSRV);\n }\n \n /**\n- * memblock_clear_kho_scratch - Clear MEMBLOCK_KHO_SCRATCH flag for a\n+ * memblock_clear_kho_noprsrv - Clear MEMBLOCK_KHO_NOPRSRV flag for a\n  * specified region.\n  * @base: the base phys addr of the region\n  * @size: the size of the region\n  *\n  * Return: 0 on success, -errno on failure.\n  */\n-__init int memblock_clear_kho_scratch(phys_addr_t base, phys_addr_t size)\n+__init int memblock_clear_kho_noprsrv(phys_addr_t base, phys_addr_t size)\n {\n \treturn memblock_setclr_flag(\u0026memblock.memory, base, size, 0,\n-\t\t\t\t    MEMBLOCK_KHO_SCRATCH);\n+\t\t\t\t    MEMBLOCK_KHO_NOPRSRV);\n }\n \n static bool should_skip_region(struct memblock_type *type,\n@@ -1237,9 +1237,9 @@ static bool should_skip_region(struct memblock_type *type,\n \n \t/*\n \t * In early alloc during kexec handover, we can only consider\n-\t * MEMBLOCK_KHO_SCRATCH regions for the allocations\n+\t * MEMBLOCK_KHO_NOPRSRV regions for the allocations\n \t */\n-\tif ((flags \u0026 MEMBLOCK_KHO_SCRATCH) \u0026\u0026 !memblock_is_kho_scratch(m))\n+\tif ((flags \u0026 MEMBLOCK_KHO_NOPRSRV) \u0026\u0026 !memblock_is_kho_noprsrv(m))\n \t\treturn true;\n \n \treturn false;\n@@ -1794,7 +1794,7 @@ void * __init memblock_alloc_hugetlb(phys_addr_t size, int nid, bool exact_nid)\n \tif (numa_valid_node(nid) \u0026\u0026 !exact_nid) {\n \t\tnid = NUMA_NO_NODE;\n \t\t/*\n-\t\t * If a previous candidate overlapped with KHO scratch, it would\n+\t\t * If a previous candidate overlapped with KHO bootmem, it would\n \t\t * update start or end. Now that the search is opening to all\n \t\t * nodes, reset them.\n \t\t */\n@@ -1810,12 +1810,12 @@ void * __init memblock_alloc_hugetlb(phys_addr_t size, int nid, bool exact_nid)\n found:\n \t/*\n \t * HugeTLB pages can be preserved with KHO and no preserved memory can\n-\t * be in scratch. So retry if found address overlaps with scratch.\n+\t * be in bootmem. So retry if found address overlaps with bootmem.\n \t *\n-\t * Scratch areas are normally not very large, so this shouldn't take too\n+\t * Bootmem areas are normally not very large, so this shouldn't take too\n \t * many retries.\n \t */\n-\tif (kho_scratch_overlap(addr, size)) {\n+\tif (kho_bootmem_overlap(addr, size)) {\n \t\tif (memblock_bottom_up())\n \t\t\tstart = addr + size;\n \t\telse\n@@ -2498,7 +2498,7 @@ void __init memblock_free_all(void)\n \tfree_unused_memmap();\n \treset_all_zones_managed_pages();\n \n-\tmemblock_clear_kho_scratch_only();\n+\tmemblock_clear_kho_noprsrv_only();\n \tpages = free_low_memory_core_early();\n \ttotalram_pages_add(pages);\n }\n@@ -2596,15 +2596,15 @@ int reserve_mem_release_by_name(const char *name)\n \treturn 1;\n }\n \n-#ifdef CONFIG_MEMBLOCK_KHO_SCRATCH\n-__init void memblock_set_kho_scratch_only(void)\n+#ifdef CONFIG_KEXEC_HANDOVER\n+__init void memblock_set_kho_noprsrv_only(void)\n {\n-\tkho_scratch_only = true;\n+\tkho_noprsrv_only = true;\n }\n \n-__init void memblock_clear_kho_scratch_only(void)\n+__init void memblock_clear_kho_noprsrv_only(void)\n {\n-\tkho_scratch_only = false;\n+\tkho_noprsrv_only = false;\n }\n #endif\n \n@@ -2860,7 +2860,7 @@ static int __init reserve_mem(char *p)\n \tif (reserve_mem_kho_revive(name, size, align))\n \t\treturn 1;\n \n-\t/* TODO: Allocation must be outside of scratch region */\n+\t/* TODO: Allocation must be outside of KHO_NOPRSRV region */\n \tstart = memblock_phys_alloc(size, align);\n \tif (!start) {\n \t\tpr_err(\"reserve_mem: memblock allocation failed\\n\");\n@@ -2885,7 +2885,7 @@ static const char * const flagname[] = {\n \t[ilog2(MEMBLOCK_DRIVER_MANAGED)] = \"DRV_MNG\",\n \t[ilog2(MEMBLOCK_RSRV_NOINIT)] = \"RSV_NIT\",\n \t[ilog2(MEMBLOCK_RSRV_KERN)] = \"RSV_KERN\",\n-\t[ilog2(MEMBLOCK_KHO_SCRATCH)] = \"KHO_SCRATCH\",\n+\t[ilog2(MEMBLOCK_KHO_NOPRSRV)] = \"KHO_NOPRSRV\",\n };\n \n static int memblock_debug_show(struct seq_file *m, void *private)\ndiff --git a/mm/memfd_luo.c b/mm/memfd_luo.c\nindex 59de210bee5f9..6b68220275ebe 100644\n--- a/mm/memfd_luo.c\n+++ b/mm/memfd_luo.c\n@@ -121,8 +121,7 @@ static int memfd_luo_preserve_folios(struct file *file,\n \t/*\n \t * Pin the folios so they don't move around behind our back. This also\n \t * ensures none of the folios are in CMA -- which ensures they don't\n-\t * fall in KHO scratch memory. It also moves swapped out folios back to\n-\t * memory.\n+\t * fall in KHO bootmem. It also moves swapped out folios back to memory.\n \t *\n \t * A side effect of doing this is that it allocates a folio for all\n \t * indices in the file. This might waste memory on sparse memfds. If\ndiff --git a/mm/mm_init.c b/mm/mm_init.c\nindex 1533aebafb688..24a53d5f0893d 100644\n--- a/mm/mm_init.c\n+++ b/mm/mm_init.c\n@@ -684,7 +684,7 @@ static __meminit void pageblock_migratetype_init_range(unsigned long pfn,\n \tconst unsigned long end = pfn + nr_pages;\n \n \tfor (pfn = pageblock_align(pfn); pfn \u003c end; pfn += pageblock_nr_pages) {\n-\t\tenum migratetype mt = kho_scratch_migratetype(pfn, migratetype);\n+\t\tenum migratetype mt = kho_bootmem_migratetype(pfn, migratetype);\n \n \t\tinit_pageblock_migratetype(pfn_to_page(pfn), mt, false);\n \t\tif (!atomic \u0026\u0026 IS_ALIGNED(pfn, PAGES_PER_SECTION))\n@@ -767,7 +767,7 @@ static void __meminit __init_deferred_page(unsigned long pfn, int nid)\n \n \tif (pageblock_aligned(pfn)) {\n \t\tenum migratetype mt =\n-\t\t\tkho_scratch_migratetype(pfn, MIGRATE_MOVABLE);\n+\t\t\tkho_bootmem_migratetype(pfn, MIGRATE_MOVABLE);\n \t\tinit_pageblock_migratetype(pfn_to_page(pfn), mt, false);\n \t}\n }\n@@ -903,7 +903,7 @@ void __meminit memmap_init_range(unsigned long size, int nid, unsigned long zone\n \t\t * over the place during system boot.\n \t\t */\n \t\tif (pageblock_aligned(pfn)) {\n-\t\t\tenum migratetype mt = kho_scratch_migratetype(pfn, migratetype);\n+\t\t\tenum migratetype mt = kho_bootmem_migratetype(pfn, migratetype);\n \n \t\t\tinit_pageblock_migratetype(page, mt, isolate_pageblock);\n \t\t\tcond_resched();\ndiff --git a/tools/testing/memblock/internal.h b/tools/testing/memblock/internal.h\nindex f1974e0090139..ba4d1c02fde5d 100644\n--- a/tools/testing/memblock/internal.h\n+++ b/tools/testing/memblock/internal.h\n@@ -46,7 +46,7 @@ static inline bool __is_kernel(unsigned long addr)\n \n #define __SetPageReserved(p)\t((void)(p))\n \n-static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size)\n+static inline bool kho_bootmem_overlap(phys_addr_t phys, size_t size)\n {\n \treturn false;\n }\n"
}

2/1 2026/09/24 05:43 agent patch-evaluator
2m Model:
core

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "This patch is purely a nomenclature and symbol refactoring that renames Kexec HandOver (KHO) \"scratch\" regions to \"bootmem\" (and MEMBLOCK_KHO_SCRATCH to MEMBLOCK_KHO_NOPRSRV) across documentation, comments, variable/function/type identifiers, debugfs entries, and kernel parameters. It introduces no logic modifications, no restructuring of data structures or algorithm flows, no altered assertions, and does not change any compiled executable C logic or runtime control flow. Therefore, it does not warrant fuzzing.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.

================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.

- REACHABILITY IS THE PRIMARY GATE:
  Fuzzing can only discover bugs in code that can actually execute in standard virtualized
  environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
  If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
  regardless of whether it adds assertions or complex logic.

- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
  Patch authors routinely label changes as "cleanups", "refactorings", or state
  "No functional change intended". Do NOT take these claims at face value.
  Code refactorings that rearrange logic, introduce helper functions, or alter state management
  in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
  If reachable executable code is modified or refactored, it MUST be fuzzed.

- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
  When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
  BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
  Even if the author believes the invariant always holds, fuzzing is essential to verify whether
  an unusual sequence of operations can violate it.

================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:

- Non-kernel and non-executable changes:
  * Modifications to Documentation/, comments, or spelling fixes.
  * User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
    that do not affect the compiled kernel image (vmlinux) or kernel modules.
  * Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
    that do not alter control flow or data structures.
  * Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
  * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
    ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
  * Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
    physical PCI hot-unplug or manual sysfs driver unbinding.
  * Code paths exclusive to architectures other than the target architecture.

================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
  * Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
    BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
  * Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
  * Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
  * Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).

================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:

- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
  Do NOT list generic, ubiquitous functions called by almost every program in the corpus
  (including, but not limited to: general memory allocators and deallocators, page fault
  and trap handlers, or core synchronization primitives; this is not an exhaustive list).
  Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
  which severely dilutes fuzzing effort away from the actual changes.

- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
  List functions that specifically implement the logic being added or altered, or direct API entrypoints
  for the subsystem feature under review.

- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
  Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
  distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
  If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
  functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).

================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit 475e71ae9dc7be020eff31dacf7864dd14387c59
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Sep 24 05:43:46 2026 +0000

    syz-cluster: applied patch under review

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 68647ff4bdd24..8a42a924f133f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3031,11 +3031,12 @@ Kernel parameters
 			"0" | "off" | "n" - kexec handover is disabled
 			"1" | "on" | "y" - kexec handover is enabled
 
-	kho_scratch=	[KEXEC,EARLY]
+	kho_bootmem=	[KEXEC,EARLY]
 			Format: ll[KMG],mm[KMG],nn[KMG] | nn%
-			Defines the size of the KHO scratch region. The KHO
-			scratch regions are physically contiguous memory
-			ranges that can only be used for non-kernel
+
+			Defines the size of the KHO boot memory region. The
+			KHO boot memory regions are physically contiguous
+			memory ranges that can only be used for non-kernel
 			allocations. That way, even when memory is heavily
 			fragmented with handed over memory, the kexeced
 			kernel will always have enough contiguous ranges to
@@ -3044,10 +3045,10 @@ Kernel parameters
 			It is possible to specify the exact amount of
 			memory in the form of "ll[KMG],mm[KMG],nn[KMG]"
 			where the first parameter defines the size of a low
-			memory scratch area, the second parameter defines
-			the size of a global scratch area and the third
+			memory bootmem area, the second parameter defines
+			the size of a global bootmem area and the third
 			parameter defines the size of additional per-node
-			scratch areas.  The form "nn%" defines scale factor
+			bootmem areas.  The form "nn%" defines scale factor
 			(in percents) of memory that was used during boot.
 
 	kmac=		[MIPS] Korina ethernet MAC address.
diff --git a/Documentation/admin-guide/mm/kho.rst b/Documentation/admin-guide/mm/kho.rst
index 3e3912eeb2e67..902d171a780af 100644
--- a/Documentation/admin-guide/mm/kho.rst
+++ b/Documentation/admin-guide/mm/kho.rst
@@ -20,10 +20,10 @@ need to enable if you would like to preserve their respective state across
 kexec.
 
 To use KHO, please boot the kernel with the ``kho=on`` command line
-parameter. You may use ``kho_scratch`` parameter to define size of the
-scratch regions. For example ``kho_scratch=16M,512M,256M`` will reserve a
-16 MiB low memory scratch area, a 512 MiB global scratch region, and 256 MiB
-per NUMA node scratch regions on boot.
+parameter. You may use ``kho_bootmem`` parameter to define size of the
+boot memory regions. For example ``kho_bootmem=16M,512M,256M`` will reserve a
+16 MiB low memory bootmem area, a 512 MiB global bootmem region, and 256 MiB
+per NUMA node bootmem regions on boot.
 
 Perform a KHO kexec
 ===================
@@ -96,15 +96,15 @@ stabilized.
     current KHO state in this file. Kexec user space tooling can use this
     as input file for the KHO payload image.
 
-``/sys/kernel/debug/kho/out/scratch_len``
-    Lengths of KHO scratch regions, which are physically contiguous
+``/sys/kernel/debug/kho/out/bootmem_len``
+    Lengths of KHO bootmem regions, which are physically contiguous
     memory regions that will always stay available for future kexec
     allocations. Kexec user space tools can use this file to determine
     where it should place its payload images.
 
-``/sys/kernel/debug/kho/out/scratch_phys``
-    Physical locations of KHO scratch regions. Kexec user space tools
-    can use this file in conjunction to scratch_len to determine where
+``/sys/kernel/debug/kho/out/bootmem_phys``
+    Physical locations of KHO bootmem regions. Kexec user space tools
+    can use this file in conjunction to bootmem_len to determine where
     it should place its payload images.
 
 ``/sys/kernel/debug/kho/out/sub_fdts/``
diff --git a/Documentation/core-api/kho/index.rst b/Documentation/core-api/kho/index.rst
index 320914a42178e..e78a2bbe2be1d 100644
--- a/Documentation/core-api/kho/index.rst
+++ b/Documentation/core-api/kho/index.rst
@@ -13,8 +13,8 @@ Kexec HandOver (KHO) is a mechanism that allows Linux to preserve memory
 regions, which could contain serialized system states, across kexec.
 
 KHO uses :ref:`flattened device tree (FDT) <kho_fdt>` to pass information about
-the preserved state from pre-exec kernel to post-kexec kernel and :ref:`scratch
-memory regions <kho_scratch>` to ensure integrity of the preserved memory.
+the preserved state from pre-exec kernel to post-kexec kernel and :ref:`boot
+memory regions <kho_bootmem>` to ensure integrity of the preserved memory.
 
 .. _kho_fdt:
 
@@ -40,31 +40,31 @@ and post-kexec kernels. This ABI is defined by header files in
 
    abi.rst
 
-.. _kho_scratch:
+.. _kho_bootmem:
 
-Scratch Regions
-===============
+Boot Memory Regions
+===================
 
 To boot into kexec, we need to have a physically contiguous memory range that
 contains no handed over memory. Kexec then places the target kernel and initrd
 into that region. The new kernel exclusively uses this region for memory
 allocations before during boot up to the initialization of the page allocator.
 
-We guarantee that we always have such regions through the scratch regions: On
-first boot KHO allocates several physically contiguous memory regions. Since
+We guarantee that we always have such regions through the boot memory regions:
+On first boot KHO allocates several physically contiguous memory regions. Since
 after kexec these regions will be used by early memory allocations, there is a
-scratch region per NUMA node plus a scratch region to satisfy allocations
-requests that do not require particular NUMA node assignment.
-By default, size of the scratch region is calculated based on amount of memory
-allocated during boot. The ``kho_scratch`` kernel command line option may be
-used to explicitly define size of the scratch regions.
-The scratch regions are declared as CMA when page allocator is initialized so
-that their memory can be used during system lifetime. CMA gives us the
-guarantee that no handover pages land in that region, because handover pages
-must be at a static physical memory location and CMA enforces that only
-movable pages can be located inside.
-
-After KHO kexec, we ignore the ``kho_scratch`` kernel command line option and
+boot memory region per NUMA node plus a boot memory region to satisfy
+allocations requests that do not require particular NUMA node assignment. By
+default, size of the boot memory region is calculated based on amount of memory
+allocated during boot. The ``kho_bootmem`` kernel command line option may be
+used to explicitly define size of the boot memory regions. The boot memory
+regions are declared as CMA when page allocator is initialized so that their
+memory can be used during system lifetime. CMA gives us the guarantee that no
+handover pages land in that region, because handover pages must be at a static
+physical memory location and CMA enforces that only movable pages can be located
+inside.
+
+After KHO kexec, we ignore the ``kho_bootmem`` kernel command line option and
 instead reuse the exact same region that was originally allocated. This allows
 us to recursively execute any amount of KHO kexecs. Because we used this region
 for boot memory allocations and as target memory for kexec blobs, some parts
diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 22267a83e064a..290153818d0f3 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -764,12 +764,12 @@ static void process_e820_entries(unsigned long minimum,
 }
 
 /*
- * If KHO is active, only process its scratch areas to ensure we are not
+ * If KHO is active, only process its bootmem areas to ensure we are not
  * stepping onto preserved memory.
  */
 static bool process_kho_entries(unsigned long minimum, unsigned long image_size)
 {
-	struct kho_scratch *kho_scratch;
+	struct kho_bootmem *kho_bootmem;
 	struct setup_data *ptr;
 	struct kho_data *kho;
 	int i, nr_areas = 0;
@@ -781,8 +781,8 @@ static bool process_kho_entries(unsigned long minimum, unsigned long image_size)
 	while (ptr) {
 		if (ptr->type == SETUP_KEXEC_KHO) {
 			kho = (struct kho_data *)(unsigned long)ptr->data;
-			kho_scratch = (void *)(unsigned long)kho->scratch_addr;
-			nr_areas = kho->scratch_size / sizeof(*kho_scratch);
+			kho_bootmem = (void *)(unsigned long)kho->bootmem_addr;
+			nr_areas = kho->bootmem_size / sizeof(*kho_bootmem);
 			break;
 		}
 
@@ -793,7 +793,7 @@ static bool process_kho_entries(unsigned long minimum, unsigned long image_size)
 		return false;
 
 	for (i = 0; i < nr_areas; i++) {
-		struct kho_scratch *area = &kho_scratch[i];
+		struct kho_bootmem *area = &kho_bootmem[i];
 		struct mem_vector region = {
 			.start = area->addr,
 			.size = area->size,
@@ -822,7 +822,7 @@ static unsigned long find_random_phys_addr(unsigned long minimum,
 	}
 
 	/*
-	 * During kexec handover only process KHO scratch areas that are known
+	 * During kexec handover only process KHO bootmem areas that are known
 	 * not to contain any data that must be preserved.
 	 */
 	if (!process_kho_entries(minimum, image_size) &&
diff --git a/arch/x86/include/uapi/asm/setup_data.h b/arch/x86/include/uapi/asm/setup_data.h
index 2671c4e1b3a0b..61090db5065c4 100644
--- a/arch/x86/include/uapi/asm/setup_data.h
+++ b/arch/x86/include/uapi/asm/setup_data.h
@@ -85,8 +85,8 @@ struct ima_setup_data {
 struct kho_data {
 	__u64 fdt_addr;
 	__u64 fdt_size;
-	__u64 scratch_addr;
-	__u64 scratch_size;
+	__u64 bootmem_addr;
+	__u64 bootmem_size;
 } __attribute__((packed));
 
 #endif /* __ASSEMBLER__ */
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index eb72537bc0b19..0967b485f38b9 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1352,18 +1352,17 @@ __init void e820__memblock_setup(void)
 	 * below 1M (aka ISA_END_ADDRESS) up until direct map is completely set
 	 * up in init_mem_mapping().
 	 *
-	 * KHO kernels are special and use only scratch memory for memblock
+	 * KHO kernels are special and use only NOPRSRV memory for memblock
 	 * allocations, but memory below 1M is ignored by kernel after early
-	 * boot and cannot be naturally marked as scratch.
+	 * boot and cannot be naturally marked as NOPRSRV.
 	 *
 	 * To allow allocation of the real-mode trampoline and a few (if any)
 	 * other very early allocations from below 1M forcibly mark the memory
-	 * below 1M as scratch.
+	 * below 1M as NOPRSRV.
 	 *
-	 * After real mode trampoline is allocated, we clear that scratch
-	 * marking.
+	 * After real mode trampoline is allocated, we clear that marking.
 	 */
-	memblock_mark_kho_scratch(0, SZ_1M);
+	memblock_mark_kho_noprsrv(0, SZ_1M);
 
 	/*
 	 * 32-bit systems are limited to 4BG of memory even with HIGHMEM and
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 7e980ea49d8d6..3aa77006adab2 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -285,14 +285,14 @@ static void setup_kho(const struct kimage *image, struct boot_params *params,
 	sd->len = sizeof(struct kho_data);
 
 	/* Only add if we have all KHO images in place */
-	if (!image->kho.fdt || !image->kho.scratch)
+	if (!image->kho.fdt || !image->kho.bootmem)
 		return;
 
 	/* Add setup data */
 	kho->fdt_addr = image->kho.fdt;
 	kho->fdt_size = PAGE_SIZE;
-	kho->scratch_addr = image->kho.scratch->mem;
-	kho->scratch_size = image->kho.scratch->bufsz;
+	kho->bootmem_addr = image->kho.bootmem->mem;
+	kho->bootmem_size = image->kho.bootmem->bufsz;
 	sd->next = params->hdr.setup_data;
 	params->hdr.setup_data = params_load_addr + setup_data_offset;
 }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cda6adb9f69c4..19fc8e1714e64 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -472,7 +472,7 @@ static void __init add_kho(u64 phys_addr, u32 data_len)
 		return;
 	}
 
-	kho_populate(kho->fdt_addr, kho->fdt_size, kho->scratch_addr, kho->scratch_size);
+	kho_populate(kho->fdt_addr, kho->fdt_size, kho->bootmem_addr, kho->bootmem_size);
 
 	early_memunmap(kho, size);
 }
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 694d80a5c68e1..65110b2ee1a1d 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -66,7 +66,7 @@ void __init reserve_real_mode(void)
 	 */
 	memblock_reserve(0, SZ_1M);
 
-	memblock_clear_kho_scratch(0, SZ_1M);
+	memblock_clear_kho_noprsrv(0, SZ_1M);
 }
 
 static void __init sme_sev_setup_real_mode(struct trampoline_header *th)
diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index 6103b1a082d24..9f09b0d2daa0b 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -165,10 +165,10 @@ static __init void reserve_regions(void)
 		pr_info("Processing EFI memory map:\n");
 
 	/*
-	 * Discard memblocks discovered so far except for KHO scratch
+	 * Discard memblocks discovered so far except for KHO bootmem
 	 * regions. Most memblocks at this point originate from memory nodes
 	 * in the DT and UEFI uses its own memory map instead. However, if
-	 * KHO is enabled, scratch regions, which are good known memory
+	 * KHO is enabled, bootmem regions, which are good known memory
 	 * must be preserved.
 	 */
 	memblock_dump_all();
@@ -178,7 +178,7 @@ static __init void reserve_regions(void)
 
 		/* Remove all non-KHO regions */
 		for_each_mem_region(r) {
-			if (!memblock_is_kho_scratch(r)) {
+			if (!memblock_is_kho_noprsrv(r)) {
 				memblock_remove(r->base, r->size);
 				r--;
 			}
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index a64afc3ded3d4..ecc9231026224 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -929,7 +929,7 @@ void __init early_init_dt_check_for_usable_mem_range(void)
 static void __init early_init_dt_check_kho(void)
 {
 	unsigned long node = chosen_node_offset;
-	u64 fdt_start, fdt_size, scratch_start, scratch_size;
+	u64 fdt_start, fdt_size, bootmem_start, bootmem_size;
 
 	if (!IS_ENABLED(CONFIG_KEXEC_HANDOVER) || (long)node < 0)
 		return;
@@ -938,11 +938,11 @@ static void __init early_init_dt_check_kho(void)
 				      &fdt_start, &fdt_size))
 		return;
 
-	if (!of_flat_dt_get_addr_size(node, "linux,kho-scratch",
-				      &scratch_start, &scratch_size))
+	if (!of_flat_dt_get_addr_size(node, "linux,kho-bootmem",
+				      &bootmem_start, &bootmem_size))
 		return;
 
-	kho_populate(fdt_start, fdt_size, scratch_start, scratch_size);
+	kho_populate(fdt_start, fdt_size, bootmem_start, bootmem_size);
 }
 
 #ifdef CONFIG_SERIAL_EARLYCON
diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
index 029903b986cbd..bb4e0d9bfd384 100644
--- a/drivers/of/kexec.c
+++ b/drivers/of/kexec.c
@@ -261,23 +261,23 @@ static int kho_add_chosen(const struct kimage *image, void *fdt, int chosen_node
 #ifdef CONFIG_KEXEC_HANDOVER
 	phys_addr_t fdt_mem = 0;
 	phys_addr_t fdt_len = 0;
-	phys_addr_t scratch_mem = 0;
-	phys_addr_t scratch_len = 0;
+	phys_addr_t bootmem_arr = 0;
+	phys_addr_t bootmem_len = 0;
 
 	ret = fdt_delprop(fdt, chosen_node, "linux,kho-fdt");
 	if (ret && ret != -FDT_ERR_NOTFOUND)
 		return ret;
-	ret = fdt_delprop(fdt, chosen_node, "linux,kho-scratch");
+	ret = fdt_delprop(fdt, chosen_node, "linux,kho-bootmem");
 	if (ret && ret != -FDT_ERR_NOTFOUND)
 		return ret;
 
-	if (!image->kho.fdt || !image->kho.scratch)
+	if (!image->kho.fdt || !image->kho.bootmem)
 		return 0;
 
 	fdt_mem = image->kho.fdt;
 	fdt_len = PAGE_SIZE;
-	scratch_mem = image->kho.scratch->mem;
-	scratch_len = image->kho.scratch->bufsz;
+	bootmem_arr = image->kho.bootmem->mem;
+	bootmem_len = image->kho.bootmem->bufsz;
 
 	pr_debug("Adding kho metadata to DT");
 
@@ -285,8 +285,8 @@ static int kho_add_chosen(const struct kimage *image, void *fdt, int chosen_node
 				       fdt_mem, fdt_len);
 	if (ret)
 		return ret;
-	ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, "linux,kho-scratch",
-				       scratch_mem, scratch_len);
+	ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, "linux,kho-bootmem",
+				       bootmem_arr, bootmem_len);
 
 #endif /* CONFIG_KEXEC_HANDOVER */
 	return ret;
diff --git a/include/asm-generic/kexec_handover.h b/include/asm-generic/kexec_handover.h
index 50839fb5ee8ed..cf73d9b34c3c9 100644
--- a/include/asm-generic/kexec_handover.h
+++ b/include/asm-generic/kexec_handover.h
@@ -4,7 +4,7 @@
 
 #include <linux/types.h>
 
-struct kho_scratch {
+struct kho_bootmem {
 	phys_addr_t addr;
 	phys_addr_t size;
 };
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index e5f1cfc11fefb..f970ca2c8ce95 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -403,7 +403,7 @@ struct kimage {
 #endif
 
 	struct {
-		struct kexec_segment *scratch;
+		struct kexec_segment *bootmem;
 		phys_addr_t fdt;
 	} kho;
 
diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h
index 46de86dc343e9..ef2b188c8ed09 100644
--- a/include/linux/kexec_handover.h
+++ b/include/linux/kexec_handover.h
@@ -36,15 +36,15 @@ int kho_retrieve_subtree(const char *name, phys_addr_t *phys, size_t *size);
 void kho_memory_init(void);
 void kho_memory_init_early(void);
 
-void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys,
-		  u64 scratch_len);
+void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t bootmem_phys,
+		  u64 bootmem_len);
 
-bool kho_scratch_overlap(phys_addr_t phys, size_t size);
+bool kho_bootmem_overlap(phys_addr_t phys, size_t size);
 
-static inline enum migratetype kho_scratch_migratetype(unsigned long pfn,
+static inline enum migratetype kho_bootmem_migratetype(unsigned long pfn,
 						       enum migratetype mt)
 {
-	if (kho_scratch_overlap(PFN_PHYS(pfn), pageblock_nr_pages << PAGE_SHIFT))
+	if (kho_bootmem_overlap(PFN_PHYS(pfn), pageblock_nr_pages << PAGE_SHIFT))
 		return MIGRATE_CMA;
 	return mt;
 }
@@ -123,16 +123,16 @@ static inline void kho_memory_init(void) { }
 static inline void kho_memory_init_early(void) { }
 
 static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len,
-				phys_addr_t scratch_phys, u64 scratch_len)
+				phys_addr_t bootmem_phys, u64 bootmem_len)
 {
 }
 
-static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size)
+static inline bool kho_bootmem_overlap(phys_addr_t phys, size_t size)
 {
 	return false;
 }
 
-static inline enum migratetype kho_scratch_migratetype(unsigned long pfn,
+static inline enum migratetype kho_bootmem_migratetype(unsigned long pfn,
 						       enum migratetype mt)
 {
 	return mt;
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index d62db9e776cf9..aaa11a589843c 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -46,11 +46,11 @@ extern unsigned long long max_possible_pfn;
  * @MEMBLOCK_RSRV_KERN: memory region that is reserved for kernel use,
  * either explictitly with memblock_reserve_kern() or via memblock
  * allocation APIs. All memblock allocations set this flag.
- * @MEMBLOCK_KHO_SCRATCH: memory region that kexec can pass to the next
- * kernel in handover mode. During early boot, we do not know about all
- * memory reservations yet, so we get scratch memory from the previous
- * kernel that we know is good to use. It is the only memory that
- * allocations may happen from in this phase.
+ * @MEMBLOCK_KHO_NOPRSRV: memory region with no preservation from kexec
+ * handover. During early boot, we do not know about all memory preservations
+ * yet, so we get memory with no preservations from the previous kernel that we
+ * know is good to use. It is the only memory that allocations may happen from
+ * in this phase.
  * @MEMBLOCK_RSRV_HUGETLB: memory is reserved for hugetlb pages
  */
 enum memblock_flags {
@@ -61,7 +61,7 @@ enum memblock_flags {
 	MEMBLOCK_DRIVER_MANAGED = 0x8,	/* always detected via a driver */
 	MEMBLOCK_RSRV_NOINIT	= 0x10,	/* don't initialize struct pages */
 	MEMBLOCK_RSRV_KERN	= 0x20,	/* memory reserved for kernel use */
-	MEMBLOCK_KHO_SCRATCH	= 0x40,	/* scratch memory for kexec handover */
+	MEMBLOCK_KHO_NOPRSRV	= 0x40,	/* memory with no KHO preservations */
 	MEMBLOCK_RSRV_HUGETLB	= 0x80, /* memory reserved for hugetlb pages */
 };
 
@@ -158,8 +158,8 @@ int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
 int memblock_clear_nomap(phys_addr_t base, phys_addr_t size);
 int memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t size);
 int memblock_reserved_mark_kern(phys_addr_t base, phys_addr_t size);
-int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size);
-int memblock_clear_kho_scratch(phys_addr_t base, phys_addr_t size);
+int memblock_mark_kho_noprsrv(phys_addr_t base, phys_addr_t size);
+int memblock_clear_kho_noprsrv(phys_addr_t base, phys_addr_t size);
 
 void memblock_free(void *ptr, size_t size);
 void reset_all_zones_managed_pages(void);
@@ -301,9 +301,9 @@ static inline bool memblock_is_driver_managed(struct memblock_region *m)
 	return m->flags & MEMBLOCK_DRIVER_MANAGED;
 }
 
-static inline bool memblock_is_kho_scratch(struct memblock_region *m)
+static inline bool memblock_is_kho_noprsrv(struct memblock_region *m)
 {
-	return m->flags & MEMBLOCK_KHO_SCRATCH;
+	return m->flags & MEMBLOCK_KHO_NOPRSRV;
 }
 
 int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn,
@@ -614,12 +614,12 @@ static inline void early_memtest(phys_addr_t start, phys_addr_t end) { }
 static inline void memtest_report_meminfo(struct seq_file *m) { }
 #endif
 
-#ifdef CONFIG_MEMBLOCK_KHO_SCRATCH
-void memblock_set_kho_scratch_only(void);
-void memblock_clear_kho_scratch_only(void);
+#ifdef CONFIG_KEXEC_HANDOVER
+void memblock_set_kho_noprsrv_only(void);
+void memblock_clear_kho_noprsrv_only(void);
 #else
-static inline void memblock_set_kho_scratch_only(void) { }
-static inline void memblock_clear_kho_scratch_only(void) { }
+static inline void memblock_set_kho_noprsrv_only(void) { }
+static inline void memblock_clear_kho_noprsrv_only(void) { }
 #endif
 
 #endif /* _LINUX_MEMBLOCK_H */
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index a8455481f6394..b668ce8d68eed 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -742,8 +742,8 @@ int kexec_locate_mem_hole(struct kexec_buf *kbuf)
 		return 0;
 
 	/*
-	 * If KHO is active, only use KHO scratch memory. All other memory
-	 * could potentially be handed over.
+	 * If KHO is active, only use KHO bootmem. All other memory could
+	 * potentially be handed over.
 	 */
 	ret = kho_locate_mem_hole(kbuf, locate_mem_hole_callback);
 	if (ret <= 0)
diff --git a/kernel/liveupdate/Kconfig b/kernel/liveupdate/Kconfig
index c13af38ba23ab..f50daee8eff07 100644
--- a/kernel/liveupdate/Kconfig
+++ b/kernel/liveupdate/Kconfig
@@ -5,7 +5,6 @@ menu "Live Update and Kexec HandOver"
 config KEXEC_HANDOVER
 	bool "kexec handover"
 	depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE
-	select MEMBLOCK_KHO_SCRATCH
 	select KEXEC_FILE
 	select LIBFDT
 	select CMA
diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 3c87c2a3d6f09..7018e25e4eda1 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -43,12 +43,12 @@
 /*
  * This is the minimal alignment required by deferred struct page init.
  * deferred_init_memmap_chunk frees memory to the buddy allocator, which looks
- * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them.
- * If KHO scratch is not aligned to that value, buddy can access uninitialized
- * struct pages, which can cause a crash.
+ * at the neighboring pages (up to MAX_PAGE_ORDER) to merge them. If KHO bootmem
+ * is not aligned to that value, buddy can access uninitialized struct pages,
+ * which can cause a crash.
  */
-#define SCRATCH_ALIGNMENT_BYTES (PAGE_SIZE * MAX_ORDER_NR_PAGES)
-static_assert(SCRATCH_ALIGNMENT_BYTES >= CMA_MIN_ALIGNMENT_BYTES);
+#define BOOTMEM_ALIGNMENT_BYTES (PAGE_SIZE * MAX_ORDER_NR_PAGES)
+static_assert(BOOTMEM_ALIGNMENT_BYTES >= CMA_MIN_ALIGNMENT_BYTES);
 
 /* The magic token for preserved pages */
 #define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */
@@ -98,7 +98,7 @@ static struct kho_out kho_out = {
 
 struct kho_in {
 	phys_addr_t fdt_phys;
-	phys_addr_t scratch_phys;
+	phys_addr_t bootmem_phys;
 	char previous_release[__NEW_UTS_LEN + 1];
 	u32 kexec_count;
 	struct kho_debugfs dbg;
@@ -658,34 +658,34 @@ static void __init *kho_get_mem_map(const void *fdt)
 
 /*
  * With KHO enabled, memory can become fragmented because KHO regions may
- * be anywhere in physical address space. The scratch regions give us a
+ * be anywhere in physical address space. The bootmem regions give us a
  * safe zones that we will never see KHO allocations from. This is where we
- * can later safely load our new kexec images into and then use the scratch
+ * can later safely load our new kexec images into and then use the bootmem
  * area for early allocations that happen before page allocator is
  * initialized.
  */
-struct kho_scratch *kho_scratch;
-unsigned int kho_scratch_cnt;
+struct kho_bootmem *kho_bootmem;
+unsigned int kho_bootmem_cnt;
 
 /*
- * The scratch areas are scaled by default as percent of memory allocated from
+ * The bootmem areas are scaled by default as percent of memory allocated from
  * memblock. A user can override the scale with command line parameter:
  *
- * kho_scratch=N%
+ * kho_bootmem=N%
  *
  * It is also possible to explicitly define size for a lowmem, a global and
- * per-node scratch areas:
+ * per-node bootmem areas:
  *
- * kho_scratch=l[KMG],n[KMG],m[KMG]
+ * kho_bootmem=l[KMG],n[KMG],m[KMG]
  *
  * The explicit size definition takes precedence over scale definition.
  */
-static unsigned int scratch_scale __initdata = 200;
-static phys_addr_t scratch_size_global __initdata;
-static phys_addr_t scratch_size_pernode __initdata;
-static phys_addr_t scratch_size_lowmem __initdata;
+static unsigned int bootmem_scale __initdata = 200;
+static phys_addr_t bootmem_size_global __initdata;
+static phys_addr_t bootmem_size_pernode __initdata;
+static phys_addr_t bootmem_size_lowmem __initdata;
 
-static int __init kho_parse_scratch_size(char *p)
+static int __init kho_parse_bootmem_size(char *p)
 {
 	size_t len;
 	unsigned long sizes[3];
@@ -709,9 +709,9 @@ static int __init kho_parse_scratch_size(char *p)
 			return -EINVAL;
 
 		memcpy(s_scale, p, len - 1);
-		ret = kstrtouint(s_scale, 10, &scratch_scale);
+		ret = kstrtouint(s_scale, 10, &bootmem_scale);
 		if (!ret)
-			pr_notice("scratch scale is %d%%\n", scratch_scale);
+			pr_notice("bootmem scale is %d%%\n", bootmem_scale);
 		return ret;
 	}
 
@@ -739,81 +739,81 @@ static int __init kho_parse_scratch_size(char *p)
 	if (*p)
 		return -EINVAL;
 
-	scratch_size_lowmem = sizes[0];
-	scratch_size_global = sizes[1];
-	scratch_size_pernode = sizes[2];
-	scratch_scale = 0;
+	bootmem_size_lowmem = sizes[0];
+	bootmem_size_global = sizes[1];
+	bootmem_size_pernode = sizes[2];
+	bootmem_scale = 0;
 
-	pr_notice("scratch areas: lowmem: %lluMiB global: %lluMiB pernode: %lldMiB\n",
-		  (u64)(scratch_size_lowmem >> 20),
-		  (u64)(scratch_size_global >> 20),
-		  (u64)(scratch_size_pernode >> 20));
+	pr_notice("bootmem areas: lowmem: %lluMiB global: %lluMiB pernode: %lldMiB\n",
+		  (u64)(bootmem_size_lowmem >> 20),
+		  (u64)(bootmem_size_global >> 20),
+		  (u64)(bootmem_size_pernode >> 20));
 
 	return 0;
 }
-early_param("kho_scratch", kho_parse_scratch_size);
+early_param("kho_bootmem", kho_parse_bootmem_size);
 
-static void __init scratch_size_update(void)
+static void __init bootmem_size_update(void)
 {
 	/*
 	 * If fixed sizes are not provided via command line, calculate them now.
 	 * Remove HugeTLB allocations from it because they never get allocated
-	 * from scratch.
+	 * from bootmem.
 	 */
-	if (scratch_scale) {
+	if (bootmem_scale) {
 		phys_addr_t size;
 
 		size = memblock_reserved_kern_size(ARCH_LOW_ADDRESS_LIMIT,
 						   NUMA_NO_NODE);
 		size -= memblock_reserved_hugetlb_size(ARCH_LOW_ADDRESS_LIMIT,
 						       NUMA_NO_NODE);
-		size = size * scratch_scale / 100;
-		scratch_size_lowmem = size;
+		size = size * bootmem_scale / 100;
+		bootmem_size_lowmem = size;
 
 		size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,
 						   NUMA_NO_NODE);
 		size -= memblock_reserved_hugetlb_size(MEMBLOCK_ALLOC_ANYWHERE,
 						       NUMA_NO_NODE);
-		size = size * scratch_scale / 100 - scratch_size_lowmem;
-		scratch_size_global = size;
+		size = size * bootmem_scale / 100 - bootmem_size_lowmem;
+		bootmem_size_global = size;
 	}
 
 	/*
-	 * Scratch areas are released as MIGRATE_CMA. Round them up to the right
+	 * bootmem areas are released as MIGRATE_CMA. Round them up to the right
 	 * size.
 	 */
-	scratch_size_lowmem = round_up(scratch_size_lowmem, SCRATCH_ALIGNMENT_BYTES);
-	scratch_size_global = round_up(scratch_size_global, SCRATCH_ALIGNMENT_BYTES);
+	bootmem_size_lowmem = round_up(bootmem_size_lowmem, BOOTMEM_ALIGNMENT_BYTES);
+	bootmem_size_global = round_up(bootmem_size_global, BOOTMEM_ALIGNMENT_BYTES);
 }
 
-static phys_addr_t __init scratch_size_node(int nid)
+static phys_addr_t __init bootmem_size_node(int nid)
 {
 	phys_addr_t size;
 
-	if (scratch_scale) {
+	if (bootmem_scale) {
 		size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,
 						   nid);
 		/* Do not count HugeTLB pages. */
 		size -= memblock_reserved_hugetlb_size(MEMBLOCK_ALLOC_ANYWHERE,
 						       nid);
-		size = size * scratch_scale / 100;
+		size = size * bootmem_scale / 100;
 	} else {
-		size = scratch_size_pernode;
+		size = bootmem_size_pernode;
 	}
 
-	return round_up(size, SCRATCH_ALIGNMENT_BYTES);
+	return round_up(size, BOOTMEM_ALIGNMENT_BYTES);
 }
 
-bool kho_scratch_overlap(phys_addr_t phys, size_t size)
+bool kho_bootmem_overlap(phys_addr_t phys, size_t size)
 {
-	phys_addr_t scratch_start, scratch_end;
+	phys_addr_t bootmem_start, bootmem_end;
 	unsigned int i;
 
-	for (i = 0; i < kho_scratch_cnt; i++) {
-		scratch_start = kho_scratch[i].addr;
-		scratch_end = kho_scratch[i].addr + kho_scratch[i].size;
+	for (i = 0; i < kho_bootmem_cnt; i++) {
+		bootmem_start = kho_bootmem[i].addr;
+		bootmem_end = kho_bootmem[i].addr + kho_bootmem[i].size;
 
-		if (phys < scratch_end && (phys + size) > scratch_start)
+		if (phys < bootmem_end && (phys + size) > bootmem_start)
 			return true;
 	}
 
@@ -821,7 +821,7 @@ bool kho_scratch_overlap(phys_addr_t phys, size_t size)
 }
 
 /**
- * kho_reserve_scratch - Reserve a contiguous chunk of memory for kexec
+ * kho_reserve_bootmem - Reserve a contiguous chunk of memory for kexec
  *
  * With KHO we can preserve arbitrary pages in the system. To ensure we still
  * have a large contiguous region of memory when we search the physical address
@@ -829,7 +829,7 @@ bool kho_scratch_overlap(phys_addr_t phys, size_t size)
  * active. This CMA region will only be used for movable pages which are not a
  * problem for us during KHO because we can just move them somewhere else.
  */
-static void __init kho_reserve_scratch(void)
+static void __init kho_reserve_bootmem(void)
 {
 	phys_addr_t addr, size;
 	int nid, i = 0;
@@ -837,73 +837,73 @@ static void __init kho_reserve_scratch(void)
 	if (!kho_enable)
 		return;
 
-	scratch_size_update();
+	bootmem_size_update();
 
 	/* FIXME: deal with node hot-plug/remove */
-	kho_scratch_cnt = nodes_weight(node_states[N_MEMORY]) + 2;
-	size = kho_scratch_cnt * sizeof(*kho_scratch);
-	kho_scratch = memblock_alloc(size, PAGE_SIZE);
-	if (!kho_scratch) {
-		pr_err("Failed to reserve scratch array\n");
+	kho_bootmem_cnt = nodes_weight(node_states[N_MEMORY]) + 2;
+	size = kho_bootmem_cnt * sizeof(*kho_bootmem);
+	kho_bootmem = memblock_alloc(size, PAGE_SIZE);
+	if (!kho_bootmem) {
+		pr_err("Failed to reserve bootmem array\n");
 		goto err_disable_kho;
 	}
 
 	/*
-	 * reserve scratch area in low memory for lowmem allocations in the
+	 * reserve bootmem area in low memory for lowmem allocations in the
 	 * next kernel
 	 */
-	size = scratch_size_lowmem;
-	addr = memblock_phys_alloc_range(size, SCRATCH_ALIGNMENT_BYTES, 0,
+	size = bootmem_size_lowmem;
+	addr = memblock_phys_alloc_range(size, BOOTMEM_ALIGNMENT_BYTES, 0,
 					 ARCH_LOW_ADDRESS_LIMIT);
 	if (!addr) {
-		pr_err("Failed to reserve lowmem scratch buffer\n");
-		goto err_free_scratch_desc;
+		pr_err("Failed to reserve lowmem bootmem\n");
+		goto err_free_bootmem_desc;
 	}
 
-	kho_scratch[i].addr = addr;
-	kho_scratch[i].size = size;
+	kho_bootmem[i].addr = addr;
+	kho_bootmem[i].size = size;
 	i++;
 
 	/* reserve large contiguous area for allocations without nid */
-	size = scratch_size_global;
-	addr = memblock_phys_alloc(size, SCRATCH_ALIGNMENT_BYTES);
+	size = bootmem_size_global;
+	addr = memblock_phys_alloc(size, BOOTMEM_ALIGNMENT_BYTES);
 	if (!addr) {
-		pr_err("Failed to reserve global scratch buffer\n");
-		goto err_free_scratch_areas;
+		pr_err("Failed to reserve global bootmem\n");
+		goto err_free_bootmem_areas;
 	}
 
-	kho_scratch[i].addr = addr;
-	kho_scratch[i].size = size;
+	kho_bootmem[i].addr = addr;
+	kho_bootmem[i].size = size;
 	i++;
 
 	/*
 	 * Loop over nodes that have both memory and are online. Skip
-	 * memoryless nodes, as we can not allocate scratch areas there.
+	 * memoryless nodes, as we can not allocate bootmem areas there.
 	 */
 	for_each_node_state(nid, N_MEMORY) {
-		size = scratch_size_node(nid);
-		addr = memblock_alloc_range_nid(size, SCRATCH_ALIGNMENT_BYTES,
+		size = bootmem_size_node(nid);
+		addr = memblock_alloc_range_nid(size, BOOTMEM_ALIGNMENT_BYTES,
 						0, MEMBLOCK_ALLOC_ACCESSIBLE,
 						nid, true);
 		if (!addr) {
-			pr_err("Failed to reserve nid %d scratch buffer\n", nid);
-			goto err_free_scratch_areas;
+			pr_err("Failed to reserve nid %d bootmem\n", nid);
+			goto err_free_bootmem_areas;
 		}
 
-		kho_scratch[i].addr = addr;
-		kho_scratch[i].size = size;
+		kho_bootmem[i].addr = addr;
+		kho_bootmem[i].size = size;
 		i++;
 	}
 
 	return;
 
-err_free_scratch_areas:
+err_free_bootmem_areas:
 	for (i--; i >= 0; i--)
-		memblock_phys_free(kho_scratch[i].addr, kho_scratch[i].size);
-err_free_scratch_desc:
-	memblock_free(kho_scratch, kho_scratch_cnt * sizeof(*kho_scratch));
+		memblock_phys_free(kho_bootmem[i].addr, kho_bootmem[i].size);
+err_free_bootmem_desc:
+	memblock_free(kho_bootmem, kho_bootmem_cnt * sizeof(*kho_bootmem));
 err_disable_kho:
-	pr_warn("Failed to reserve scratch area, disabling kexec handover\n");
+	pr_warn("Failed to reserve bootmem, disabling kexec handover\n");
 	kho_enable = false;
 }
 
@@ -913,11 +913,11 @@ static void __init kho_reserve_scratch(void)
  * on smaller systems. The algorithm itself doesn't depend on the actual value,
  * so it can be changed to a different heuristic later if needed.
  */
-#define KHO_SCRATCH_EXT_BLKSIZE		SZ_1G
-#define KHO_SCRATCH_EXT_BLKSHIFT	const_ilog2(KHO_SCRATCH_EXT_BLKSIZE)
+#define KHO_DISCOVER_BLKSIZE		SZ_1G
+#define KHO_DISCOVER_BLKSHIFT	const_ilog2(KHO_DISCOVER_BLKSIZE)
 
 /* Called for the KHO preserved memory radix tree. */
-static int __init kho_ext_walk_leaf(unsigned long key, void *data)
+static int __init kho_discover_walk_leaf(unsigned long key, void *data)
 {
 	struct kho_radix_tree *busy_blocks = data;
 	phys_addr_t start, end;
@@ -932,54 +932,57 @@ static int __init kho_ext_walk_leaf(unsigned long key, void *data)
 	end = start + (1UL << (order + PAGE_SHIFT));
 
 	while (start < end) {
-		err = kho_radix_add_key(busy_blocks, start >> KHO_SCRATCH_EXT_BLKSHIFT);
+		err = kho_radix_add_key(busy_blocks, start >> KHO_DISCOVER_BLKSHIFT);
 		if (err)
 			return err;
 
-		start += (1UL << KHO_SCRATCH_EXT_BLKSHIFT);
+		start += (1UL << KHO_DISCOVER_BLKSHIFT);
 	}
 
 	return 0;
 }
 
 /* Called for the KHO preserved memory radix tree. */
-static int __init kho_ext_walk_node(phys_addr_t phys, void *data)
+static int __init kho_discover_walk_node(phys_addr_t phys, void *data)
 {
 	struct kho_radix_tree *busy_blocks = data;
 
-	return kho_radix_add_key(busy_blocks, phys >> KHO_SCRATCH_EXT_BLKSHIFT);
+	return kho_radix_add_key(busy_blocks, phys >> KHO_DISCOVER_BLKSHIFT);
 }
 
 /* Called for the busy block radix tree. */
-static int __init kho_ext_mark_scratch(unsigned long key, void *data)
+static int __init kho_discover_mark_noprsrv(unsigned long key, void *data)
 {
 	phys_addr_t *prev_end = data;
-	phys_addr_t start = key << KHO_SCRATCH_EXT_BLKSHIFT;
+	phys_addr_t start = key << KHO_DISCOVER_BLKSHIFT;
 	int err;
 
 	if (start > *prev_end) {
-		err = memblock_mark_kho_scratch(*prev_end, start - *prev_end);
+		err = memblock_mark_kho_noprsrv(*prev_end, start - *prev_end);
 		if (err)
 			return err;
 	}
 
-	*prev_end = start + (1UL << KHO_SCRATCH_EXT_BLKSHIFT);
+	*prev_end = start + (1UL << KHO_DISCOVER_BLKSHIFT);
 	return 0;
 }
 
 /*
- * kho_extend_scratch - Extend the scratch regions
+ * kho_discover_noprsrv - Discover memory with no preservations
+ *
+ * Discovers memory ranges with no preserved memory and marks it as NOPRSRV.
+ * This lets memblock allocate memory from areas outside KHO bootmem.
  *
  * The KHO preserved memory radix tree mixes both physical address and order
  * into a single key. This makes it hard to look for free ranges directly. This
  * function first walks the radix tree and digests it down into another radix
- * tree, whose keys identify blocks of size KHO_SCRATCH_EXT_BLKSIZE which
- * contain preserved memory.
+ * tree, whose keys identify blocks of size KHO_DISCOVER_BLKSIZE which contain
+ * preserved memory.
  *
  * Then it walks the digested radix tree and marks everything that doesn't have
- * preserved memory as scratch.
+ * preserved memory as NOPRSRV.
  *
- * NOTE: This function allocates memory so it should be called when scratch has
+ * NOTE: This function allocates memory so it should be called when bootmem has
  * available space.
  *
  * NOTE: The pages of the KHO preserved memory radix tree tables are not marked
@@ -988,18 +991,18 @@ static int __init kho_ext_mark_scratch(unsigned long key, void *data)
  * them to be "preserved memory" and marks their blocks as busy.
  *
  * NOTE: efi_init()::reserve_regions() removes all regions except
- * MEMBLOCK_KHO_SCRATCH. This function adds such regions but they are not KHO
- * scratch memory, so they should not be removed. This function should always be
+ * MEMBLOCK_KHO_NOPRSRV. This function adds such regions but they are not KHO
+ * boot memory, so they should not be removed. This function should always be
  * called after reserve_regions().
  */
-static void __init kho_extend_scratch(void)
+static void __init kho_discover_noprsrv(void)
 {
 	const struct kho_radix_walk_cb kho_cb = {
-		.leaf = kho_ext_walk_leaf,
-		.node = kho_ext_walk_node,
+		.leaf = kho_discover_walk_leaf,
+		.node = kho_discover_walk_node,
 	};
 	const struct kho_radix_walk_cb ext_cb = {
-		.leaf = kho_ext_mark_scratch,
+		.leaf = kho_discover_mark_noprsrv,
 	};
 	static struct lock_class_key busy_radix_class;
 	struct kho_radix_tree busy_blocks;
@@ -1024,21 +1027,21 @@ static void __init kho_extend_scratch(void)
 	if (err)
 		goto out;
 
-	/* Walk the busy blocks and mark everything between keys as scratch. */
+	/* Walk the busy blocks and mark everything between keys as noprsrv. */
 	err = kho_radix_walk_tree(&busy_blocks, &ext_cb, &prev_end);
 	if (err)
 		goto out;
 
 	/* Mark everything from last busy block to end of DRAM. */
 	if (prev_end < memblock_end_of_DRAM())
-		err = memblock_mark_kho_scratch(prev_end, memblock_end_of_DRAM() - prev_end);
+		err = memblock_mark_kho_noprsrv(prev_end, memblock_end_of_DRAM() - prev_end);
 
 	/* fallthrough */
 out:
 	kho_radix_destroy_tree(&busy_blocks);
 print:
 	if (err)
-		pr_err("Failed to extend scratch: %pe\n", ERR_PTR(err));
+		pr_err("Failed to discover extra allocatable memory: %pe\n", ERR_PTR(err));
 }
 
 /**
@@ -1152,7 +1155,7 @@ int kho_preserve_folio(struct folio *folio)
 	const unsigned int order = folio_order(folio);
 
 	if (IS_ENABLED(CONFIG_KEXEC_HANDOVER_DEBUG) &&
-	    WARN_ON(kho_scratch_overlap(pfn << PAGE_SHIFT, PAGE_SIZE << order)))
+	    WARN_ON(kho_bootmem_overlap(pfn << PAGE_SHIFT, PAGE_SIZE << order)))
 		return -EINVAL;
 
 	return kho_radix_add_key(tree, kho_encode_radix_key(PFN_PHYS(pfn),
@@ -1230,7 +1233,7 @@ int kho_preserve_pages(struct page *page, unsigned long nr_pages)
 	int err = 0;
 
 	if (IS_ENABLED(CONFIG_KEXEC_HANDOVER_DEBUG) &&
-	    WARN_ON(kho_scratch_overlap(start_pfn << PAGE_SHIFT,
+	    WARN_ON(kho_bootmem_overlap(start_pfn << PAGE_SHIFT,
 					nr_pages << PAGE_SHIFT))) {
 		return -EINVAL;
 	}
@@ -1827,7 +1830,7 @@ static __init int kho_init(void)
 
 	err = kho_radix_init_tree(tree, NULL);
 	if (err)
-		goto err_free_scratch;
+		goto err_free_bootmem;
 
 	kho_out.fdt = kho_alloc_preserve(PAGE_SIZE);
 	if (IS_ERR(kho_out.fdt)) {
@@ -1856,9 +1859,9 @@ static __init int kho_init(void)
 		return 0;
 	}
 
-	for (int i = 0; i < kho_scratch_cnt; i++) {
-		unsigned long base_pfn = PHYS_PFN(kho_scratch[i].addr);
-		unsigned long count = kho_scratch[i].size >> PAGE_SHIFT;
+	for (int i = 0; i < kho_bootmem_cnt; i++) {
+		unsigned long base_pfn = PHYS_PFN(kho_bootmem[i].addr);
+		unsigned long count = kho_bootmem[i].size >> PAGE_SHIFT;
 		unsigned long pfn;
 
 		/*
@@ -1866,10 +1869,10 @@ static __init int kho_init(void)
 		 * corresponding PRESENT bit in the kernel page table.
 		 * Subsequent kmemleak scans of these pages cause the
 		 * non-PRESENT page faults.
-		 * Mark scratch areas with kmemleak_ignore_phys() to exclude
+		 * Mark bootmem areas with kmemleak_ignore_phys() to exclude
 		 * them from kmemleak scanning.
 		 */
-		kmemleak_ignore_phys(kho_scratch[i].addr);
+		kmemleak_ignore_phys(kho_bootmem[i].addr);
 		for (pfn = base_pfn; pfn < base_pfn + count;
 		     pfn += pageblock_nr_pages)
 			init_cma_reserved_pageblock(pfn_to_page(pfn));
@@ -1885,11 +1888,11 @@ static __init int kho_init(void)
 	kho_unpreserve_free(kho_out.fdt);
 err_free_kho_radix_tree:
 	kho_radix_destroy_tree(tree);
-err_free_scratch:
+err_free_bootmem:
 	kho_out.fdt = NULL;
-	for (int i = 0; i < kho_scratch_cnt; i++) {
-		void *start = __va(kho_scratch[i].addr);
-		void *end = start + kho_scratch[i].size;
+	for (int i = 0; i < kho_bootmem_cnt; i++) {
+		void *start = __va(kho_bootmem[i].addr);
+		void *end = start + kho_bootmem[i].size;
 
 		free_reserved_area(start, end, -1, "");
 	}
@@ -1908,7 +1911,7 @@ void __init kho_memory_init_early(void)
 
 	/*
 	 * kho_get_mem_map() should always succeed. If it fails, kho_populate()
-	 * catches that and never sets kho_in.scratch_phys, which stops memory
+	 * catches that and never sets kho_in.bootmem_phys, which stops memory
 	 * retrieval.
 	 */
 	mem_map = kho_get_mem_map(fdt);
@@ -1916,26 +1919,25 @@ void __init kho_memory_init_early(void)
 		goto err;
 
 	/*
-	 * kho_scratch_overlap() needs kho_scratch to be initialized. It
-	 * is used by free_area_init() on KHO boots, so initialize it
-	 * early.
+	 * kho_bootmem_overlap() needs kho_bootmem to be initialized. It is used
+	 * by free_area_init() on KHO boots, so initialize it early.
 	 */
-	kho_scratch = phys_to_virt(kho_in.scratch_phys);
+	kho_bootmem = phys_to_virt(kho_in.bootmem_phys);
 
 	if (kho_radix_init_tree(&kho_in.radix_tree, mem_map))
 		goto err;
 
-	kho_extend_scratch();
+	kho_discover_noprsrv();
 
 	return;
 
 err:
 	/*
 	 * Failed to initialize preserved memory radix tree. Clear FDT
-	 * and scratch so KHO users don't treat it as a KHO boot.
+	 * and bootmem so KHO users don't treat it as a KHO boot.
 	 */
 	kho_in.fdt_phys = 0;
-	kho_in.scratch_phys = 0;
+	kho_in.bootmem_phys = 0;
 }
 
 void __init kho_memory_init(void)
@@ -1946,17 +1948,17 @@ void __init kho_memory_init(void)
 		return;
 	}
 
-	if (kho_in.scratch_phys)
+	if (kho_in.bootmem_phys)
 		kho_mem_retrieve();
 	else
-		kho_reserve_scratch();
+		kho_reserve_bootmem();
 }
 
 void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len,
-			 phys_addr_t scratch_phys, u64 scratch_len)
+			 phys_addr_t bootmem_phys, u64 bootmem_len)
 {
-	unsigned int scratch_cnt = scratch_len / sizeof(*kho_scratch);
-	struct kho_scratch *scratch = NULL;
+	unsigned int bootmem_cnt = bootmem_len / sizeof(*kho_bootmem);
+	struct kho_bootmem *bootmem = NULL;
 	phys_addr_t mem_map_phys;
 	void *fdt = NULL;
 	bool populated = false;
@@ -1985,52 +1987,52 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len,
 	if (!mem_map_phys)
 		goto unmap_fdt;
 
-	scratch = early_memremap(scratch_phys, scratch_len);
-	if (!scratch) {
-		pr_warn("setup: failed to memremap scratch (phys=0x%llx, len=%lld)\n",
-			scratch_phys, scratch_len);
+	bootmem = early_memremap(bootmem_phys, bootmem_len);
+	if (!bootmem) {
+		pr_warn("setup: failed to memremap bootmem (phys=0x%llx, len=%lld)\n",
+			bootmem_phys, bootmem_len);
 		goto unmap_fdt;
 	}
 
 	/*
-	 * We pass a safe contiguous blocks of memory to use for early boot
-	 * purporses from the previous kernel so that we can resize the
-	 * memblock array as needed.
+	 * We pass a safe contiguous blocks of memory with no preservations to
+	 * use for early boot purporses from the previous kernel so that we can
+	 * resize the memblock array as needed.
 	 */
-	for (int i = 0; i < scratch_cnt; i++) {
-		struct kho_scratch *area = &scratch[i];
+	for (int i = 0; i < bootmem_cnt; i++) {
+		struct kho_bootmem *area = &bootmem[i];
 		u64 size = area->size;
 
 		memblock_add(area->addr, size);
-		err = memblock_mark_kho_scratch(area->addr, size);
+		err = memblock_mark_kho_noprsrv(area->addr, size);
 		if (err) {
-			pr_warn("failed to mark the scratch region 0x%pa+0x%pa: %pe",
+			pr_warn("failed to mark the bootmem region 0x%pa+0x%pa: %pe",
 				&area->addr, &size, ERR_PTR(err));
-			goto unmap_scratch;
+			goto unmap_bootmem;
 		}
-		pr_debug("Marked 0x%pa+0x%pa as scratch", &area->addr, &size);
+		pr_debug("Marked 0x%pa+0x%pa as bootmem", &area->addr, &size);
 	}
 
-	memblock_reserve(scratch_phys, scratch_len);
+	memblock_reserve(bootmem_phys, bootmem_len);
 
 	/*
-	 * Now that we have a viable region of scratch memory, let's tell
+	 * Now that we have a viable region of boot memory, let's tell
 	 * the memblocks allocator to only use that for any allocations.
 	 * That way we ensure that nothing scribbles over in use data while
 	 * we initialize the page tables which we will need to ingest all
 	 * memory reservations from the previous kernel.
 	 */
-	memblock_set_kho_scratch_only();
+	memblock_set_kho_noprsrv_only();
 
 	kho_in.fdt_phys = fdt_phys;
-	kho_in.scratch_phys = scratch_phys;
-	kho_scratch_cnt = scratch_cnt;
+	kho_in.bootmem_phys = bootmem_phys;
+	kho_bootmem_cnt = bootmem_cnt;
 
 	populated = true;
 	pr_info("found kexec handover data.\n");
 
-unmap_scratch:
-	early_memunmap(scratch, scratch_len);
+unmap_bootmem:
+	early_memunmap(bootmem, bootmem_len);
 unmap_fdt:
 	early_memunmap(fdt, fdt_len);
 report:
@@ -2042,47 +2044,47 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len,
 
 int kho_fill_kimage(struct kimage *image)
 {
-	ssize_t scratch_size;
+	ssize_t bootmem_size;
 	int err = 0;
-	struct kexec_buf scratch;
+	struct kexec_buf bootmem;
 
 	if (!kho_enable || image->type == KEXEC_TYPE_CRASH)
 		return 0;
 
 	image->kho.fdt = virt_to_phys(kho_out.fdt);
 
-	scratch_size = sizeof(*kho_scratch) * kho_scratch_cnt;
-	scratch = (struct kexec_buf){
+	bootmem_size = sizeof(*kho_bootmem) * kho_bootmem_cnt;
+	bootmem = (struct kexec_buf){
 		.image = image,
-		.buffer = kho_scratch,
-		.bufsz = scratch_size,
+		.buffer = kho_bootmem,
+		.bufsz = bootmem_size,
 		.mem = KEXEC_BUF_MEM_UNKNOWN,
-		.memsz = scratch_size,
+		.memsz = bootmem_size,
 		.buf_align = SZ_64K, /* Makes it easier to map */
 		.buf_max = ULONG_MAX,
 		.top_down = true,
 	};
-	err = kexec_add_buffer(&scratch);
+	err = kexec_add_buffer(&bootmem);
 	if (err)
 		return err;
-	image->kho.scratch = &image->segment[image->nr_segments - 1];
+	image->kho.bootmem = &image->segment[image->nr_segments - 1];
 
 	return 0;
 }
 
-static int kho_walk_scratch(struct kexec_buf *kbuf,
+static int kho_walk_bootmem(struct kexec_buf *kbuf,
 			    int (*func)(struct resource *, void *))
 {
 	int ret = 0;
 	int i;
 
-	for (i = 0; i < kho_scratch_cnt; i++) {
+	for (i = 0; i < kho_bootmem_cnt; i++) {
 		struct resource res = {
-			.start = kho_scratch[i].addr,
-			.end = kho_scratch[i].addr + kho_scratch[i].size - 1,
+			.start = kho_bootmem[i].addr,
+			.end = kho_bootmem[i].addr + kho_bootmem[i].size - 1,
 		};
 
-		/* Try to fit the kimage into our KHO scratch region */
+		/* Try to fit the kimage into our KHO bootmem region */
 		ret = func(&res, kbuf);
 		if (ret)
 			break;
@@ -2099,7 +2101,7 @@ int kho_locate_mem_hole(struct kexec_buf *kbuf,
 	if (!kho_enable || kbuf->image->type == KEXEC_TYPE_CRASH)
 		return 1;
 
-	ret = kho_walk_scratch(kbuf, func);
+	ret = kho_walk_bootmem(kbuf, func);
 
 	return ret == 1 ? 0 : -EADDRNOTAVAIL;
 }
diff --git a/kernel/liveupdate/kexec_handover_debugfs.c b/kernel/liveupdate/kexec_handover_debugfs.c
index 257ee8a52be66..7d74477da0b79 100644
--- a/kernel/liveupdate/kexec_handover_debugfs.c
+++ b/kernel/liveupdate/kexec_handover_debugfs.c
@@ -77,23 +77,23 @@ void kho_debugfs_blob_remove(struct kho_debugfs *dbg, void *blob)
 	}
 }
 
-static int scratch_phys_show(struct seq_file *m, void *v)
+static int bootmem_phys_show(struct seq_file *m, void *v)
 {
-	for (int i = 0; i < kho_scratch_cnt; i++)
-		seq_printf(m, "0x%llx\n", kho_scratch[i].addr);
+	for (int i = 0; i < kho_bootmem_cnt; i++)
+		seq_printf(m, "0x%llx\n", kho_bootmem[i].addr);
 
 	return 0;
 }
-DEFINE_SHOW_ATTRIBUTE(scratch_phys);
+DEFINE_SHOW_ATTRIBUTE(bootmem_phys);
 
-static int scratch_len_show(struct seq_file *m, void *v)
+static int bootmem_len_show(struct seq_file *m, void *v)
 {
-	for (int i = 0; i < kho_scratch_cnt; i++)
-		seq_printf(m, "0x%llx\n", kho_scratch[i].size);
+	for (int i = 0; i < kho_bootmem_cnt; i++)
+		seq_printf(m, "0x%llx\n", kho_bootmem[i].size);
 
 	return 0;
 }
-DEFINE_SHOW_ATTRIBUTE(scratch_len);
+DEFINE_SHOW_ATTRIBUTE(bootmem_len);
 
 __init void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt)
 {
@@ -186,13 +186,13 @@ __init int kho_out_debugfs_init(struct kho_debugfs *dbg)
 	if (IS_ERR(sub_fdt_dir))
 		goto err_rmdir;
 
-	f = debugfs_create_file("scratch_phys", 0400, dir, NULL,
-				&scratch_phys_fops);
+	f = debugfs_create_file("bootmem_phys", 0400, dir, NULL,
+				&bootmem_phys_fops);
 	if (IS_ERR(f))
 		goto err_rmdir;
 
-	f = debugfs_create_file("scratch_len", 0400, dir, NULL,
-				&scratch_len_fops);
+	f = debugfs_create_file("bootmem_len", 0400, dir, NULL,
+				&bootmem_len_fops);
 	if (IS_ERR(f))
 		goto err_rmdir;
 
diff --git a/kernel/liveupdate/kexec_handover_internal.h b/kernel/liveupdate/kexec_handover_internal.h
index 805d2a76c3881..e9685e1ef6d78 100644
--- a/kernel/liveupdate/kexec_handover_internal.h
+++ b/kernel/liveupdate/kexec_handover_internal.h
@@ -19,8 +19,8 @@ struct kho_debugfs {
 struct kho_debugfs {};
 #endif
 
-extern struct kho_scratch *kho_scratch;
-extern unsigned int kho_scratch_cnt;
+extern struct kho_bootmem *kho_bootmem;
+extern unsigned int kho_bootmem_cnt;
 
 #ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS
 int kho_debugfs_init(void);
diff --git a/mm/Kconfig b/mm/Kconfig
index 604c58199acbf..631a410eaee98 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -483,10 +483,6 @@ config HAVE_GUP_FAST
 	depends on MMU
 	bool
 
-# Enable memblock support for scratch memory which is needed for kexec handover
-config MEMBLOCK_KHO_SCRATCH
-	bool
-
 # Don't discard allocated memory used to track "memory" and "reserved" memblocks
 # after early boot, so it can still be used to test for validity of memory.
 # Also, memblocks are updated with memory hot(un)plug.
diff --git a/mm/memblock.c b/mm/memblock.c
index 9ce86349a29fa..f5aaa38cfa313 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -113,11 +113,11 @@ unsigned long min_low_pfn;
 unsigned long max_pfn;
 unsigned long long max_possible_pfn;
 
-#ifdef CONFIG_MEMBLOCK_KHO_SCRATCH
-/* When set to true, only allocate from MEMBLOCK_KHO_SCRATCH ranges */
-static bool kho_scratch_only;
+#ifdef CONFIG_KEXEC_HANDOVER
+/* When set to true, only allocate from MEMBLOCK_KHO_NOPRSRV ranges */
+static bool kho_noprsrv_only;
 #else
-#define kho_scratch_only false
+#define kho_noprsrv_only false
 #endif
 
 static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_MEMORY_REGIONS] __initdata_memblock;
@@ -179,9 +179,9 @@ bool __init_memblock memblock_has_mirror(void)
 
 static enum memblock_flags __init_memblock choose_memblock_flags(void)
 {
-	/* skip non-scratch memory for kho early boot allocations */
-	if (kho_scratch_only)
-		return MEMBLOCK_KHO_SCRATCH;
+	/* only use KHO_NOPRSRV memory for kho early boot allocations */
+	if (kho_noprsrv_only)
+		return MEMBLOCK_KHO_NOPRSRV;
 
 	return system_has_some_mirror ? MEMBLOCK_MIRROR : MEMBLOCK_NONE;
 }
@@ -1175,33 +1175,33 @@ int __init_memblock memblock_reserved_mark_kern(phys_addr_t base, phys_addr_t si
 }
 
 /**
- * memblock_mark_kho_scratch - Mark a memory region as MEMBLOCK_KHO_SCRATCH.
+ * memblock_mark_kho_noprsrv - Mark a memory region as MEMBLOCK_KHO_NOPRSRV.
  * @base: the base phys addr of the region
  * @size: the size of the region
  *
- * Only memory regions marked with %MEMBLOCK_KHO_SCRATCH will be considered
+ * Only memory regions marked with %MEMBLOCK_KHO_NOPRSRV will be considered
  * for allocations during early boot with kexec handover.
  *
  * Return: 0 on success, -errno on failure.
  */
-__init int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size)
+__init int memblock_mark_kho_noprsrv(phys_addr_t base, phys_addr_t size)
 {
 	return memblock_setclr_flag(&memblock.memory, base, size, 1,
-				    MEMBLOCK_KHO_SCRATCH);
+				    MEMBLOCK_KHO_NOPRSRV);
 }
 
 /**
- * memblock_clear_kho_scratch - Clear MEMBLOCK_KHO_SCRATCH flag for a
+ * memblock_clear_kho_noprsrv - Clear MEMBLOCK_KHO_NOPRSRV flag for a
  * specified region.
  * @base: the base phys addr of the region
  * @size: the size of the region
  *
  * Return: 0 on success, -errno on failure.
  */
-__init int memblock_clear_kho_scratch(phys_addr_t base, phys_addr_t size)
+__init int memblock_clear_kho_noprsrv(phys_addr_t base, phys_addr_t size)
 {
 	return memblock_setclr_flag(&memblock.memory, base, size, 0,
-				    MEMBLOCK_KHO_SCRATCH);
+				    MEMBLOCK_KHO_NOPRSRV);
 }
 
 static bool should_skip_region(struct memblock_type *type,
@@ -1237,9 +1237,9 @@ static bool should_skip_region(struct memblock_type *type,
 
 	/*
 	 * In early alloc during kexec handover, we can only consider
-	 * MEMBLOCK_KHO_SCRATCH regions for the allocations
+	 * MEMBLOCK_KHO_NOPRSRV regions for the allocations
 	 */
-	if ((flags & MEMBLOCK_KHO_SCRATCH) && !memblock_is_kho_scratch(m))
+	if ((flags & MEMBLOCK_KHO_NOPRSRV) && !memblock_is_kho_noprsrv(m))
 		return true;
 
 	return false;
@@ -1794,7 +1794,7 @@ void * __init memblock_alloc_hugetlb(phys_addr_t size, int nid, bool exact_nid)
 	if (numa_valid_node(nid) && !exact_nid) {
 		nid = NUMA_NO_NODE;
 		/*
-		 * If a previous candidate overlapped with KHO scratch, it would
+		 * If a previous candidate overlapped with KHO bootmem, it would
 		 * update start or end. Now that the search is opening to all
 		 * nodes, reset them.
 		 */
@@ -1810,12 +1810,12 @@ void * __init memblock_alloc_hugetlb(phys_addr_t size, int nid, bool exact_nid)
 found:
 	/*
 	 * HugeTLB pages can be preserved with KHO and no preserved memory can
-	 * be in scratch. So retry if found address overlaps with scratch.
+	 * be in bootmem. So retry if found address overlaps with bootmem.
 	 *
-	 * Scratch areas are normally not very large, so this shouldn't take too
+	 * Bootmem areas are normally not very large, so this shouldn't take too
 	 * many retries.
 	 */
-	if (kho_scratch_overlap(addr, size)) {
+	if (kho_bootmem_overlap(addr, size)) {
 		if (memblock_bottom_up())
 			start = addr + size;
 		else
@@ -2498,7 +2498,7 @@ void __init memblock_free_all(void)
 	free_unused_memmap();
 	reset_all_zones_managed_pages();
 
-	memblock_clear_kho_scratch_only();
+	memblock_clear_kho_noprsrv_only();
 	pages = free_low_memory_core_early();
 	totalram_pages_add(pages);
 }
@@ -2596,15 +2596,15 @@ int reserve_mem_release_by_name(const char *name)
 	return 1;
 }
 
-#ifdef CONFIG_MEMBLOCK_KHO_SCRATCH
-__init void memblock_set_kho_scratch_only(void)
+#ifdef CONFIG_KEXEC_HANDOVER
+__init void memblock_set_kho_noprsrv_only(void)
 {
-	kho_scratch_only = true;
+	kho_noprsrv_only = true;
 }
 
-__init void memblock_clear_kho_scratch_only(void)
+__init void memblock_clear_kho_noprsrv_only(void)
 {
-	kho_scratch_only = false;
+	kho_noprsrv_only = false;
 }
 #endif
 
@@ -2860,7 +2860,7 @@ static int __init reserve_mem(char *p)
 	if (reserve_mem_kho_revive(name, size, align))
 		return 1;
 
-	/* TODO: Allocation must be outside of scratch region */
+	/* TODO: Allocation must be outside of KHO_NOPRSRV region */
 	start = memblock_phys_alloc(size, align);
 	if (!start) {
 		pr_err("reserve_mem: memblock allocation failed\n");
@@ -2885,7 +2885,7 @@ static const char * const flagname[] = {
 	[ilog2(MEMBLOCK_DRIVER_MANAGED)] = "DRV_MNG",
 	[ilog2(MEMBLOCK_RSRV_NOINIT)] = "RSV_NIT",
 	[ilog2(MEMBLOCK_RSRV_KERN)] = "RSV_KERN",
-	[ilog2(MEMBLOCK_KHO_SCRATCH)] = "KHO_SCRATCH",
+	[ilog2(MEMBLOCK_KHO_NOPRSRV)] = "KHO_NOPRSRV",
 };
 
 static int memblock_debug_show(struct seq_file *m, void *private)
diff --git a/mm/memfd_luo.c b/mm/memfd_luo.c
index 59de210bee5f9..6b68220275ebe 100644
--- a/mm/memfd_luo.c
+++ b/mm/memfd_luo.c
@@ -121,8 +121,7 @@ static int memfd_luo_preserve_folios(struct file *file,
 	/*
 	 * Pin the folios so they don't move around behind our back. This also
 	 * ensures none of the folios are in CMA -- which ensures they don't
-	 * fall in KHO scratch memory. It also moves swapped out folios back to
-	 * memory.
+	 * fall in KHO bootmem. It also moves swapped out folios back to memory.
 	 *
 	 * A side effect of doing this is that it allocates a folio for all
 	 * indices in the file. This might waste memory on sparse memfds. If
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 1533aebafb688..24a53d5f0893d 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -684,7 +684,7 @@ static __meminit void pageblock_migratetype_init_range(unsigned long pfn,
 	const unsigned long end = pfn + nr_pages;
 
 	for (pfn = pageblock_align(pfn); pfn < end; pfn += pageblock_nr_pages) {
-		enum migratetype mt = kho_scratch_migratetype(pfn, migratetype);
+		enum migratetype mt = kho_bootmem_migratetype(pfn, migratetype);
 
 		init_pageblock_migratetype(pfn_to_page(pfn), mt, false);
 		if (!atomic && IS_ALIGNED(pfn, PAGES_PER_SECTION))
@@ -767,7 +767,7 @@ static void __meminit __init_deferred_page(unsigned long pfn, int nid)
 
 	if (pageblock_aligned(pfn)) {
 		enum migratetype mt =
-			kho_scratch_migratetype(pfn, MIGRATE_MOVABLE);
+			kho_bootmem_migratetype(pfn, MIGRATE_MOVABLE);
 		init_pageblock_migratetype(pfn_to_page(pfn), mt, false);
 	}
 }
@@ -903,7 +903,7 @@ void __meminit memmap_init_range(unsigned long size, int nid, unsigned long zone
 		 * over the place during system boot.
 		 */
 		if (pageblock_aligned(pfn)) {
-			enum migratetype mt = kho_scratch_migratetype(pfn, migratetype);
+			enum migratetype mt = kho_bootmem_migratetype(pfn, migratetype);
 
 			init_pageblock_migratetype(page, mt, isolate_pageblock);
 			cond_resched();
diff --git a/tools/testing/memblock/internal.h b/tools/testing/memblock/internal.h
index f1974e0090139..ba4d1c02fde5d 100644
--- a/tools/testing/memblock/internal.h
+++ b/tools/testing/memblock/internal.h
@@ -46,7 +46,7 @@ static inline bool __is_kernel(unsigned long addr)
 
 #define __SetPageReserved(p)	((void)(p))
 
-static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size)
+static inline bool kho_bootmem_overlap(phys_addr_t phys, size_t size)
 {
 	return false;
 }

3/2 2026/09/24 05:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 25208
							output: 21
							thoughts: 3400
						

Thoughts:
**Analyzing the KHO Refactoring Patch**

Alright, let's break down this patch. My initial thought is that this is a straightforward rename of "KHO scratch" to "KHO bootmem," and all associated symbols and references. However, as we all know, we can't take claims of "no functional change" at face value, especially with core subsystems. It's time to dig in.

The diff itself looks extensive, touching a lot of files. We've got documentation updates in `kernel-parameters.txt`, `kho.rst`, and `index.rst`, all consistent with the renaming. Then there are changes in various architecture-specific files (`arch/x86/boot/compressed/kaslr.c`, `arch/x86/include/uapi/asm/setup_data.h`, `arch/x86/kernel/e820.c`, `arch/x86/kernel/kexec-bzimage64.c`, `arch/x86/kernel/setup.c`, `arch/x86/realmode/init.c`), which seem to be primarily identifier renames within structures and function parameters. We also see changes to drivers (`drivers/firmware/efi/efi-init.c`, `drivers/of/fdt.c`, `drivers/of/kexec.c`), again, largely renaming device tree properties and related functions. There are updates in `include` directories (`include/asm-generic/kexec_handover.h`, `include/linux/kexec.h`, `include/linux/kexec_handover.h`, `include/linux/memblock.h`) as well, with the critical rename of `MEMBLOCK_KHO_SCRATCH` to `MEMBLOCK_KHO_NOPRSRV` and related function changes.

The `kernel/kexec_file.c` comment change is also consistent with the overall theme. However, the Kconfig changes are important. We are seeing changes to the `kernel/liveupdate/Kconfig` and `mm/Kconfig` files where `CONFIG_MEMBLOCK_KHO_SCRATCH` is removed and replaced with checking for `CONFIG_KEXEC_HANDOVER`. The `kernel/liveupdate/kexec_handover.c` file has the most extensive changes, with a mix of renames and changes in the underlying structures and parameter names.

The `mm/memblock.c` and `mm/memfd_luo.c` and `mm/mm_init.c` files also show changes, further reinforcing the rename and its impact on memory management. Finally, `tools/testing/memblock/internal.h` is updated.

So, this appears to be more than just a simple find and replace. The Kconfig changes indicate a direct dependency shift from one config to another. The functions that are modified are:
`kho_discover_mark_noprsrv` vs `kho_extend_scratch`, `kho_discover_walk_leaf` vs `kho_ext_walk_leaf`, `kho_discover_walk_node` vs `kho_ext_walk_node`.
We must check if the code logic is changed during those functions.

The key questions here are whether the executable code has been refactored, whether the underlying logic, especially related to memory management and handover, has been altered, and whether any of these changes are reachable at runtime. Is the `KEXEC_HANDOVER` config easily reachable, or is it a niche use case? Understanding the implications of this configuration change is crucial. I need to know precisely what Kexec Handover does, and what is its role in the system.
We need to know the execution paths of code to see if the changes are unreachable or not.
So is `KEXEC_HANDOVER` reachable / fuzzable?
We need to determine if this is just a refactoring or if we need to assess its impact on the system, specifically with regard to potential semantic shifts in memory management or live updates. Time to pull up the source code and find out.



4/2 2026/09/24 05:44 tool grepper
0m Args:
{
  "Expression": "CONFIG_KEXEC_HANDOVER"
}

Results:
{
  "Output": "Documentation/admin-guide/mm/kho.rst=14=Prerequisites\n--\nDocumentation/admin-guide/mm/kho.rst-16-\nDocumentation/admin-guide/mm/kho.rst:17:KHO is available when the kernel is compiled with ``CONFIG_KEXEC_HANDOVER``\nDocumentation/admin-guide/mm/kho.rst-18-set to y. Every KHO producer may have its own config option that you\n--\nDocumentation/admin-guide/mm/kho.rst=87=These debugfs interfaces are available when the kernel is compiled with\nDocumentation/admin-guide/mm/kho.rst:88:``CONFIG_KEXEC_HANDOVER_DEBUGFS`` enabled.\nDocumentation/admin-guide/mm/kho.rst-89-\n--\narch/x86/boot/compressed/kaslr.c=770=static bool process_kho_entries(unsigned long minimum, unsigned long image_size)\n--\narch/x86/boot/compressed/kaslr.c-776-\narch/x86/boot/compressed/kaslr.c:777:\tif (!IS_ENABLED(CONFIG_KEXEC_HANDOVER))\narch/x86/boot/compressed/kaslr.c-778-\t\treturn false;\n--\narch/x86/kernel/kexec-bzimage64.c=274=static void setup_kho(const struct kimage *image, struct boot_params *params,\n--\narch/x86/kernel/kexec-bzimage64.c-280-\narch/x86/kernel/kexec-bzimage64.c:281:\tif (!IS_ENABLED(CONFIG_KEXEC_HANDOVER))\narch/x86/kernel/kexec-bzimage64.c-282-\t\treturn;\n--\narch/x86/kernel/kexec-bzimage64.c=301=setup_boot_parameters(struct kimage *image, struct boot_params *params,\n--\narch/x86/kernel/kexec-bzimage64.c-390-\narch/x86/kernel/kexec-bzimage64.c:391:\tif (IS_ENABLED(CONFIG_KEXEC_HANDOVER)) {\narch/x86/kernel/kexec-bzimage64.c-392-\t\t/* Setup space to store preservation metadata */\n--\narch/x86/kernel/kexec-bzimage64.c=475=static void *bzImage64_load(struct kimage *image, char *kernel,\n--\narch/x86/kernel/kexec-bzimage64.c-581-\narch/x86/kernel/kexec-bzimage64.c:582:\tif (IS_ENABLED(CONFIG_KEXEC_HANDOVER))\narch/x86/kernel/kexec-bzimage64.c-583-\t\tkbuf.bufsz += sizeof(struct setup_data) +\n--\narch/x86/kernel/setup.c=457=static void __init add_kho(u64 phys_addr, u32 data_len)\n--\narch/x86/kernel/setup.c-462-\narch/x86/kernel/setup.c:463:\tif (!IS_ENABLED(CONFIG_KEXEC_HANDOVER)) {\narch/x86/kernel/setup.c:464:\t\tpr_warn(\"Passed KHO data, but CONFIG_KEXEC_HANDOVER not set. Ignoring.\\n\");\narch/x86/kernel/setup.c-465-\t\treturn;\n--\ndrivers/of/fdt.c=929=static void __init early_init_dt_check_kho(void)\n--\ndrivers/of/fdt.c-933-\ndrivers/of/fdt.c:934:\tif (!IS_ENABLED(CONFIG_KEXEC_HANDOVER) || (long)node \u003c 0)\ndrivers/of/fdt.c-935-\t\treturn;\n--\ndrivers/of/kexec.c=258=static int kho_add_chosen(const struct kimage *image, void *fdt, int chosen_node)\n--\ndrivers/of/kexec.c-260-\tint ret = 0;\ndrivers/of/kexec.c:261:#ifdef CONFIG_KEXEC_HANDOVER\ndrivers/of/kexec.c-262-\tphys_addr_t fdt_mem = 0;\n--\ndrivers/of/kexec.c-290-\ndrivers/of/kexec.c:291:#endif /* CONFIG_KEXEC_HANDOVER */\ndrivers/of/kexec.c-292-\treturn ret;\n--\ninclude/linux/kexec_handover.h=14=struct page;\ninclude/linux/kexec_handover.h-15-\ninclude/linux/kexec_handover.h:16:#ifdef CONFIG_KEXEC_HANDOVER\ninclude/linux/kexec_handover.h-17-bool kho_is_enabled(void);\n--\ninclude/linux/kexec_handover.h=135=static inline enum migratetype kho_bootmem_migratetype(unsigned long pfn,\n--\ninclude/linux/kexec_handover.h-139-}\ninclude/linux/kexec_handover.h:140:#endif /* CONFIG_KEXEC_HANDOVER */\ninclude/linux/kexec_handover.h-141-\n--\ninclude/linux/kho_radix_tree.h=50=struct kho_radix_walk_cb {\n--\ninclude/linux/kho_radix_tree.h-54-\ninclude/linux/kho_radix_tree.h:55:#ifdef CONFIG_KEXEC_HANDOVER\ninclude/linux/kho_radix_tree.h-56-\n--\ninclude/linux/kho_radix_tree.h=62=void kho_radix_destroy_tree(struct kho_radix_tree *tree);\ninclude/linux/kho_radix_tree.h-63-\ninclude/linux/kho_radix_tree.h:64:#else  /* #ifdef CONFIG_KEXEC_HANDOVER */\ninclude/linux/kho_radix_tree.h-65-\n--\ninclude/linux/kho_radix_tree.h=86=static inline void kho_radix_destroy_tree(struct kho_radix_tree *tree) { }\ninclude/linux/kho_radix_tree.h-87-\ninclude/linux/kho_radix_tree.h:88:#endif /* #ifdef CONFIG_KEXEC_HANDOVER */\ninclude/linux/kho_radix_tree.h-89-\n--\ninclude/linux/memblock.h=614=static inline void memtest_report_meminfo(struct seq_file *m) { }\n--\ninclude/linux/memblock.h-616-\ninclude/linux/memblock.h:617:#ifdef CONFIG_KEXEC_HANDOVER\ninclude/linux/memblock.h-618-void memblock_set_kho_noprsrv_only(void);\n--\nkernel/kexec_internal.h=43=struct kexec_buf;\nkernel/kexec_internal.h-44-\nkernel/kexec_internal.h:45:#ifdef CONFIG_KEXEC_HANDOVER\nkernel/kexec_internal.h-46-int kho_locate_mem_hole(struct kexec_buf *kbuf,\n--\nkernel/kexec_internal.h=56=static inline int kho_fill_kimage(struct kimage *image) { return 0; }\nkernel/kexec_internal.h:57:#endif /* CONFIG_KEXEC_HANDOVER */\nkernel/kexec_internal.h-58-#endif /* LINUX_KEXEC_INTERNAL_H */\n--\nkernel/liveupdate/Makefile=3=luo-y :=\t\t\t\t\t\t\t\t\\\n--\nkernel/liveupdate/Makefile-9-\nkernel/liveupdate/Makefile:10:obj-$(CONFIG_KEXEC_HANDOVER)\t\t+= kexec_handover.o\nkernel/liveupdate/Makefile:11:obj-$(CONFIG_KEXEC_HANDOVER_DEBUGFS)\t+= kexec_handover_debugfs.o\nkernel/liveupdate/Makefile-12-\n--\nkernel/liveupdate/kexec_handover.c=68=static_assert(sizeof(union kho_page_info) == sizeof(((struct page *)0)-\u003eprivate));\nkernel/liveupdate/kexec_handover.c-69-\nkernel/liveupdate/kexec_handover.c:70:static bool kho_enable __ro_after_init = IS_ENABLED(CONFIG_KEXEC_HANDOVER_ENABLE_DEFAULT);\nkernel/liveupdate/kexec_handover.c-71-\n--\nkernel/liveupdate/kexec_handover.c=998=static void __init kho_discover_noprsrv(void)\n--\nkernel/liveupdate/kexec_handover.c-1058- * ``/sys/kernel/debug/kho/out/sub_fdts/@name`` when kernel is configured with\nkernel/liveupdate/kexec_handover.c:1059: * CONFIG_KEXEC_HANDOVER_DEBUGFS\nkernel/liveupdate/kexec_handover.c-1060- *\n--\nkernel/liveupdate/kexec_handover.c=1151=int kho_preserve_folio(struct folio *folio)\n--\nkernel/liveupdate/kexec_handover.c-1156-\nkernel/liveupdate/kexec_handover.c:1157:\tif (IS_ENABLED(CONFIG_KEXEC_HANDOVER_DEBUG) \u0026\u0026\nkernel/liveupdate/kexec_handover.c-1158-\t    WARN_ON(kho_bootmem_overlap(pfn \u003c\u003c PAGE_SHIFT, PAGE_SIZE \u003c\u003c order)))\n--\nkernel/liveupdate/kexec_handover.c=1226=int kho_preserve_pages(struct page *page, unsigned long nr_pages)\n--\nkernel/liveupdate/kexec_handover.c-1234-\nkernel/liveupdate/kexec_handover.c:1235:\tif (IS_ENABLED(CONFIG_KEXEC_HANDOVER_DEBUG) \u0026\u0026\nkernel/liveupdate/kexec_handover.c-1236-\t    WARN_ON(kho_bootmem_overlap(start_pfn \u003c\u003c PAGE_SHIFT,\n--\nkernel/liveupdate/kexec_handover_internal.h-8-\nkernel/liveupdate/kexec_handover_internal.h:9:#ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS\nkernel/liveupdate/kexec_handover_internal.h-10-#include \u003clinux/debugfs.h\u003e\n--\nkernel/liveupdate/kexec_handover_internal.h=23=extern unsigned int kho_bootmem_cnt;\nkernel/liveupdate/kexec_handover_internal.h-24-\nkernel/liveupdate/kexec_handover_internal.h:25:#ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS\nkernel/liveupdate/kexec_handover_internal.h-26-int kho_debugfs_init(void);\n--\nkernel/liveupdate/kexec_handover_internal.h=40=static inline void kho_debugfs_blob_remove(struct kho_debugfs *dbg,\nkernel/liveupdate/kexec_handover_internal.h-41-\t\t\t\t\t   void *blob) { }\nkernel/liveupdate/kexec_handover_internal.h:42:#endif /* CONFIG_KEXEC_HANDOVER_DEBUGFS */\nkernel/liveupdate/kexec_handover_internal.h-43-\n--\nmm/memblock.c=114=unsigned long long max_possible_pfn;\nmm/memblock.c-115-\nmm/memblock.c:116:#ifdef CONFIG_KEXEC_HANDOVER\nmm/memblock.c-117-/* When set to true, only allocate from MEMBLOCK_KHO_NOPRSRV ranges */\n--\nmm/memblock.c=2579=int reserve_mem_release_by_name(const char *name)\n--\nmm/memblock.c-2598-\nmm/memblock.c:2599:#ifdef CONFIG_KEXEC_HANDOVER\nmm/memblock.c-2600-__init void memblock_set_kho_noprsrv_only(void)\n--\nmm/memblock.c=2605=__init void memblock_clear_kho_noprsrv_only(void)\n--\nmm/memblock.c-2610-\nmm/memblock.c:2611:#ifdef CONFIG_KEXEC_HANDOVER\nmm/memblock.c-2612-\n--\nmm/memblock.c=2793=static bool __init reserve_mem_kho_revive(const char *name, phys_addr_t size,\n--\nmm/memblock.c-2797-}\nmm/memblock.c:2798:#endif /* CONFIG_KEXEC_HANDOVER */\nmm/memblock.c-2799-\n--\ntools/testing/selftests/kho/vmtest.sh=60=CONFIG_BLK_DEV_INITRD=y\ntools/testing/selftests/kho/vmtest.sh:61:CONFIG_KEXEC_HANDOVER=y\ntools/testing/selftests/kho/vmtest.sh:62:CONFIG_KEXEC_HANDOVER_DEBUG=y\ntools/testing/selftests/kho/vmtest.sh:63:CONFIG_KEXEC_HANDOVER_DEBUGFS=y\ntools/testing/selftests/kho/vmtest.sh-64-CONFIG_TEST_KEXEC_HANDOVER=y\n--\ntools/testing/selftests/liveupdate/config=3=CONFIG_KEXEC_FILE=y\ntools/testing/selftests/liveupdate/config:4:CONFIG_KEXEC_HANDOVER=y\ntools/testing/selftests/liveupdate/config:5:CONFIG_KEXEC_HANDOVER_ENABLE_DEFAULT=y\ntools/testing/selftests/liveupdate/config:6:CONFIG_KEXEC_HANDOVER_DEBUGFS=y\ntools/testing/selftests/liveupdate/config:7:CONFIG_KEXEC_HANDOVER_DEBUG=y\ntools/testing/selftests/liveupdate/config-8-CONFIG_LIVEUPDATE=y\n"
}

5/2 2026/09/24 05:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 33022
							output: 20
							thoughts: 5304
						

Thoughts:
**Initial Assessment: KEXEC_HANDOVER Identifier Renaming - A Deep Dive**

Okay, so the task at hand is to analyze this patch that seems to primarily involve renaming the `CONFIG_KEXEC_HANDOVER` (KHO) related identifiers. My initial scan has touched a variety of files: boot code, x86 kernel internals, device tree handling, Kexec infrastructure, and memory management subsystems. It appears the changes are mostly cosmetic, replacing "scratch" with "bootmem" in variables, structures, and function names. But, as an expert, I cannot simply accept "no functional change intended" at face value. I must approach this with a healthy dose of skepticism, and dig down into the details.

First, I identified the functions touched by this patch, spanning early boot code, kexec loading, device tree interaction, and core memory management. This includes modifications to key structures like `kho_data`, and calls to memory block allocation and management routines. I've noted that the patch touches boot-time code, and the `kexec_file_load` syscall path, meaning this is reachable.

Now, the methodical analysis begins. I've started examining each hunk in the patch. I've carefully scrutinized the documentation, specifically looking for changes to kernel parameters (`kho_scratch` to `kho_bootmem`), and the documentation's references to `scratch_len`, `scratch_phys` etc. This is the first key step of determining what is at risk. Then, I looked at core data structures being changed, like `struct kho_data`, which seems to be the central structure affected.

I've examined the changes to `arch/x86/boot/compressed/kaslr.c`, `arch/x86/kernel/kexec-bzimage64.c`, and other architecture-specific code, which all seem to be straightforward renamings. I noticed a renaming from `memblock_mark_kho_scratch` to `memblock_mark_kho_noprsrv` which warrants further consideration, especially since it affects memory block management.

I'm keeping a particularly close eye on `kernel/liveupdate/kexec_handover.c`, since it's at the heart of the handover functionality, and contains important constants and parameters. The change to `kho_discover_mark_noprsrv` is the key. While the constants `KHO_DISCOVER_BLKSIZE` and `KHO_DISCOVER_BLKSHIFT` have not changed.

I need to confirm if anything functional, even in subtle ways, has been changed. I am also looking at configuration changes, which are critically important here. Although `CONFIG_MEMBLOCK_KHO_SCRATCH` is removed, the dependency on `CONFIG_KEXEC_HANDOVER` has the same meaning, and `CONFIG_KEXEC_HANDOVER` is reachable! The conditions under which certain functions are compiled remain unchanged. This suggests that the code's behavior shouldn't be drastically different.

I'm checking debugfs files because changes there can indicate user-visible functionality changes, even if small. I am looking at the `kho_bootmem_overlap` function and related functions, as memory overlap is critical in Kexec. I have confirmed changes in early_param, and DT property names.

Now, I'm reviewing the triage guidelines. Does this patch change "reachable executable code"? It definitely does. This means that, despite the claims of the author, I have to assume, at first pass, that this needs more review. There is no simple way to conclude this is "non-functional".



6/2 2026/09/24 05:44 tool grepper
0m Args:
{
  "Expression": "config KEXEC_HANDOVER"
}

Results:
{
  "Output": "kernel/liveupdate/Kconfig=3=menu \"Live Update and Kexec HandOver\"\nkernel/liveupdate/Kconfig-4-\nkernel/liveupdate/Kconfig:5:config KEXEC_HANDOVER\nkernel/liveupdate/Kconfig-6-\tbool \"kexec handover\"\n--\nkernel/liveupdate/Kconfig-16-\nkernel/liveupdate/Kconfig:17:config KEXEC_HANDOVER_DEBUG\nkernel/liveupdate/Kconfig-18-\tbool \"Enable Kexec Handover debug checks\"\n--\nkernel/liveupdate/Kconfig-25-\nkernel/liveupdate/Kconfig:26:config KEXEC_HANDOVER_DEBUGFS\nkernel/liveupdate/Kconfig-27-\tbool \"kexec handover debugfs interface\"\n--\nkernel/liveupdate/Kconfig-36-\nkernel/liveupdate/Kconfig:37:config KEXEC_HANDOVER_ENABLE_DEFAULT\nkernel/liveupdate/Kconfig-38-\tbool \"Enable kexec handover by default\"\n"
}

7/2 2026/09/24 05:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 39356
							output: 24
							thoughts: 19
						

Thoughts:
Okay, here's my summary, tailored for an expert audience, as if I'm thinking these thoughts:

**Analyzing `ARCH_SUPPORTS_KEXEC_HANDOVER`**

Alright, let's dive into this `ARCH_SUPPORTS_KEXEC_HANDOVER` macro, shall we? My immediate thought is, "What architectures are *we* supporting that actually require this?" I know what the *concept* is – a critical part of a kexec implementation, handling the transition of execution from one kernel image to another, maintaining the system's state to some degree across the handover. But understanding how it applies in the context of specific hardware is key.

My focus immediately narrows to the implications of this feature. What are the specific hardware considerations that make a 'handover' necessary or beneficial? Are we talking about specific memory mappings, interrupt controllers, or other hardware features that must be handled carefully to prevent crashes or data corruption during the kernel jump? Perhaps it's dealing with specific hardware protection mechanisms. I know some architectures are more amenable to kexec than others.

I'm starting to think about the cases where we *wouldn't* need this. For example, some simple architectures may not require explicit handover steps. They're more straightforward, and a plain boot of a new kernel might be sufficient. So, the presence of this macro suggests we are targeting something more complex.

I am also considering the specific implementation. Is this macro conditionally compiled in to handle the hardware differences for kexec correctly? What are the potential performance impacts associated with supporting this feature, and do they outweigh the benefits? We need to ensure we’re not adding overhead unnecessarily, and there are probably multiple kexec methods.

In summary, this macro points to a deeper architectural nuance that needs careful consideration. Understanding how it is used and the implications of its presence or absence is a critical part of maintaining the system's robustness. Let's dig deeper and see what the code around it reveals.



8/2 2026/09/24 05:44 tool grepper
0m Args:
{
  "Expression": "ARCH_SUPPORTS_KEXEC_HANDOVER"
}

Results:
{
  "Output": "arch/arm64/Kconfig=1708=config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG\n--\narch/arm64/Kconfig-1710-\narch/arm64/Kconfig:1711:config ARCH_SUPPORTS_KEXEC_HANDOVER\narch/arm64/Kconfig-1712-\tdef_bool y\n--\narch/x86/Kconfig=1978=config ARCH_SUPPORTS_KEXEC_JUMP\n--\narch/x86/Kconfig-1980-\narch/x86/Kconfig:1981:config ARCH_SUPPORTS_KEXEC_HANDOVER\narch/x86/Kconfig-1982-\tdef_bool X86_64\n--\nkernel/liveupdate/Kconfig=5=config KEXEC_HANDOVER\nkernel/liveupdate/Kconfig-6-\tbool \"kexec handover\"\nkernel/liveupdate/Kconfig:7:\tdepends on ARCH_SUPPORTS_KEXEC_HANDOVER \u0026\u0026 ARCH_SUPPORTS_KEXEC_FILE\nkernel/liveupdate/Kconfig-8-\tselect KEXEC_FILE\n"
}

9/2 2026/09/24 05:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 40100
							output: 17
							thoughts: 4969
						

Thoughts:
**Patch Triage: KEXEC Handover Symbol Renaming**

Alright, let's break this down. We've got a patch that's essentially a massive renaming exercise related to KEXEC handover, specifically targeting x86_64 and arm64 architectures with our focus on `amd64`. My initial gut reaction is, "Just renaming? Probably not worth fuzzing, right?" But we can't take anything at face value.

First, I confirmed that `ARCH_SUPPORTS_KEXEC_HANDOVER` is enabled on the relevant architectures.

My job now is to determine if this patch warrants fuzzing, even though, superficially, it *looks* like a "no-op" renames a lot of symbols. We need to apply our expert knowledge of kernel fuzzing requirements. The instructions are very clear: unless *all* changes are *strictly* limited to a specific category, we fuzz.

Let's review the "negative criteria" for when we *don't* fuzz: modifications to documentation, comments, user-space tools, decorative logging, or build system changes. *Pure* identifier renaming *could* fall under that, but we can't be too hasty.

Section 1 of the triage instructions says, "Do NOT blindly trust "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS." Refactorings *can* introduce semantic shifts, or expose latent bugs, we need to carefully investigate. The instructions state if code is modified or refactored, it MUST be fuzzed.

First, I looked at the change log and code, checking if it rearranged logic, introduced helper functions, or altered state management. My initial observation is, "No, it's just renaming!" but we *must* be thorough.

Let's look at the changes. My focus shifted to potential changes to UAPI definitions. In `arch/x86/include/uapi/asm/setup_data.h`, `kho_scratch` (and associated metadata) is being renamed to `kho_bootmem`. This is a UAPI change, *potentially* an ABI change. This includes associated debugfs files and device tree properties. The old `CONFIG_MEMBLOCK_KHO_SCRATCH` Kconfig option is being removed and replaced by `CONFIG_KEXEC_HANDOVER`.

Next, I looked for changes in executable logic. Looking in `kernel/liveupdate/kexec_handover.c`, there are `WARN_ON` statements. The functions `kho_scratch_overlap` and `kho_bootmem_overlap` (now renamed) are identical, except for the names. The same logic is preserved in code that uses these functions.

I did a deep dive into the code: the alignment bytes, parameters, and variable references are identical and were renamed. I checked every hunk in `kernel/liveupdate/kexec_handover.c`, including the key functions related to boot memory allocation and reservation. The code looks byte-for-byte identical, apart from the renaming.

I double-checked to see if there were any logic differences in the `memblock.c` and found no changes to functionality. The changes from `scratch` to `noprsrv` are purely name changes to existing functionality, no change in value.

But WAIT! We need to be exhaustive. We need to prove this change won't affect vmlinux.

We need to re-read the rules carefully, because a pure identifier rename might *seem* like it belongs in the "Not worth Fuzzing" category. Let's make sure we do not miss anything!

I've got to check again: does renaming functions / variables / structs in C code warrant fuzzing, or is WorthFuzzing=false? "Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories". It needs to be a perfect match!

Let's check the negative categories again: the documentation, comments, decorative logging, or build system. This isn't that.
"Core Subsystems", "Refactorings and Code Cleanups", "Runtime Assertions" or "Reachable Drivers". Does this meet any of these? This isn't a *refactoring* in the code, because no logic was changed.

Most of the code touched is `__init`, meaning it only runs during boot. This is important to note:
The following functions are touched:
1. `arch/x86/boot/compressed/kaslr.c`: `process_kho_entries()`
2. `arch/x86/kernel/e820.c`: `e820__memblock_setup()`
3. `arch/x86/kernel/setup.c`: `add_kho()`
4. `arch/x8


10/2 2026/09/24 05:45 tool grepper
0m Args:
{
  "Expression": "setup_kho"
}

Results:
{
  "Output": "arch/x86/kernel/kexec-bzimage64.c=248=setup_ima_state(const struct kimage *image, struct boot_params *params,\n--\narch/x86/kernel/kexec-bzimage64.c-273-\narch/x86/kernel/kexec-bzimage64.c:274:static void setup_kho(const struct kimage *image, struct boot_params *params,\narch/x86/kernel/kexec-bzimage64.c-275-\t\t      unsigned long params_load_addr,\n--\narch/x86/kernel/kexec-bzimage64.c=301=setup_boot_parameters(struct kimage *image, struct boot_params *params,\n--\narch/x86/kernel/kexec-bzimage64.c-392-\t\t/* Setup space to store preservation metadata */\narch/x86/kernel/kexec-bzimage64.c:393:\t\tsetup_kho(image, params, params_load_addr, setup_data_offset);\narch/x86/kernel/kexec-bzimage64.c-394-\t\tsetup_data_offset += sizeof(struct setup_data) +\n"
}

11/2 2026/09/24 05:45 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 46427
							output: 18
							thoughts: 346
						

Thoughts:
**My Current Investigation into `kexec` and `liveupdate`**

Okay, so `setup_kho` is being called during `setup_boot_parameters`, which itself is part of `bzImage64_load` within the `kexec_file_load` syscall. That's a critical path to remember. Now, I need to understand what else is *not* initialized. I'm digging into how the `liveupdate` functionality works within `kexec`.

I've got the `kernel/liveupdate/kexec_handover.c` file open. I see `kho_bootmem_overlap` is called by `kho_preserve_folio`, `kho_preserve_pages`, and `kho_scratch_migratetype` (wait, there's also `kho_bootmem_migratetype`). Interesting. I should look into those callers more deeply. I need to trace back these calls.

I need to see exactly what's calling `kho_preserve_folio`, and `kho_preserve_pages`... I'm going to track down the callers. Let's see what calls `kho_fill_kimage` too, that's important. I see `kho_walk_bootmem` and `kho_locate_mem_hole` are called by `kexec_locate_mem_hole` during `kexec_file_load` – that's another important connection.

Then, there's `kernel/liveupdate/kexec_handover_debugfs.c`. I see `bootmem_phys_show` and `bootmem_len_show`, which are read callbacks for `/sys/kernel/debug/kho/out/bootmem_phys` and `/sys/kernel/debug/kho/out/bootmem_len` respectively.

And finally, I've got `mm/memblock.c` open. `should_skip_region` is called by memblock iterators. It's mostly early boot, but memblock can be queried or read via debugfs. I need to keep in mind, although early boot, that debug access may be available.

So, now my next immediate task is to figure out the callers of `kho_preserve_folio` and `kho_preserve_pages`. That's where I'll focus my efforts next.



12/2 2026/09/24 05:45 tool grepper
0m Args:
{
  "Expression": "kho_preserve_"
}

Results:
{
  "Output": "include/linux/kexec_handover.h=18=bool is_kho_boot(void);\ninclude/linux/kexec_handover.h-19-\ninclude/linux/kexec_handover.h:20:int kho_preserve_folio(struct folio *folio);\ninclude/linux/kexec_handover.h-21-void kho_unpreserve_folio(struct folio *folio);\ninclude/linux/kexec_handover.h:22:int kho_preserve_pages(struct page *page, unsigned long nr_pages);\ninclude/linux/kexec_handover.h-23-void kho_unpreserve_pages(struct page *page, unsigned long nr_pages);\ninclude/linux/kexec_handover.h:24:int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation);\ninclude/linux/kexec_handover.h-25-void kho_unpreserve_vmalloc(struct kho_vmalloc *preservation);\n--\ninclude/linux/kexec_handover.h=57=static inline bool is_kho_boot(void)\n--\ninclude/linux/kexec_handover.h-61-\ninclude/linux/kexec_handover.h:62:static inline int kho_preserve_folio(struct folio *folio)\ninclude/linux/kexec_handover.h-63-{\n--\ninclude/linux/kexec_handover.h=67=static inline void kho_unpreserve_folio(struct folio *folio) { }\ninclude/linux/kexec_handover.h-68-\ninclude/linux/kexec_handover.h:69:static inline int kho_preserve_pages(struct page *page, unsigned int nr_pages)\ninclude/linux/kexec_handover.h-70-{\n--\ninclude/linux/kexec_handover.h=74=static inline void kho_unpreserve_pages(struct page *page, unsigned int nr_pages) { }\ninclude/linux/kexec_handover.h-75-\ninclude/linux/kexec_handover.h:76:static inline int kho_preserve_vmalloc(void *ptr,\ninclude/linux/kexec_handover.h-77-\t\t\t\t       struct kho_vmalloc *preservation)\n--\nkernel/liveupdate/kexec_handover.c=557=EXPORT_SYMBOL_GPL(kho_restore_folio);\n--\nkernel/liveupdate/kexec_handover.c-564- * Restore a contiguous list of order 0 pages that was preserved with\nkernel/liveupdate/kexec_handover.c:565: * kho_preserve_pages().\nkernel/liveupdate/kexec_handover.c-566- *\n--\nkernel/liveupdate/kexec_handover.c=1140=EXPORT_SYMBOL_GPL(kho_remove_subtree);\n--\nkernel/liveupdate/kexec_handover.c-1142-/**\nkernel/liveupdate/kexec_handover.c:1143: * kho_preserve_folio - preserve a folio across kexec.\nkernel/liveupdate/kexec_handover.c-1144- * @folio: folio to preserve.\n--\nkernel/liveupdate/kexec_handover.c-1150- */\nkernel/liveupdate/kexec_handover.c:1151:int kho_preserve_folio(struct folio *folio)\nkernel/liveupdate/kexec_handover.c-1152-{\n--\nkernel/liveupdate/kexec_handover.c-1163-}\nkernel/liveupdate/kexec_handover.c:1164:EXPORT_SYMBOL_GPL(kho_preserve_folio);\nkernel/liveupdate/kexec_handover.c-1165-\n--\nkernel/liveupdate/kexec_handover.c-1170- * Instructs KHO to unpreserve a folio that was preserved by\nkernel/liveupdate/kexec_handover.c:1171: * kho_preserve_folio() before. The provided @folio (pfn and order)\nkernel/liveupdate/kexec_handover.c-1172- * must exactly match a previously preserved folio.\n--\nkernel/liveupdate/kexec_handover.c=1182=EXPORT_SYMBOL_GPL(kho_unpreserve_folio);\nkernel/liveupdate/kexec_handover.c-1183-\nkernel/liveupdate/kexec_handover.c:1184:static unsigned int __kho_preserve_pages_order(unsigned long start_pfn,\nkernel/liveupdate/kexec_handover.c-1185-\t\t\t\t\t       unsigned long end_pfn)\n--\nkernel/liveupdate/kexec_handover.c=1201=static void __kho_unpreserve(struct kho_radix_tree *tree,\n--\nkernel/liveupdate/kexec_handover.c-1206-\twhile (pfn \u003c end_pfn) {\nkernel/liveupdate/kexec_handover.c:1207:\t\torder = __kho_preserve_pages_order(pfn, end_pfn);\nkernel/liveupdate/kexec_handover.c-1208-\n--\nkernel/liveupdate/kexec_handover.c-1216-/**\nkernel/liveupdate/kexec_handover.c:1217: * kho_preserve_pages - preserve contiguous pages across kexec\nkernel/liveupdate/kexec_handover.c-1218- * @page: first page in the list.\n--\nkernel/liveupdate/kexec_handover.c-1225- */\nkernel/liveupdate/kexec_handover.c:1226:int kho_preserve_pages(struct page *page, unsigned long nr_pages)\nkernel/liveupdate/kexec_handover.c-1227-{\n--\nkernel/liveupdate/kexec_handover.c-1241-\twhile (pfn \u003c end_pfn) {\nkernel/liveupdate/kexec_handover.c:1242:\t\tunsigned int order = __kho_preserve_pages_order(pfn, end_pfn);\nkernel/liveupdate/kexec_handover.c-1243-\n--\nkernel/liveupdate/kexec_handover.c-1258-}\nkernel/liveupdate/kexec_handover.c:1259:EXPORT_SYMBOL_GPL(kho_preserve_pages);\nkernel/liveupdate/kexec_handover.c-1260-\n--\nkernel/liveupdate/kexec_handover.c-1267- * This must be called with the same @page and @nr_pages as the corresponding\nkernel/liveupdate/kexec_handover.c:1268: * kho_preserve_pages() call. Unpreserving arbitrary sub-ranges of larger\nkernel/liveupdate/kexec_handover.c-1269- * preserved blocks is not supported.\n--\nkernel/liveupdate/kexec_handover.c=1312=static struct kho_vmalloc_chunk *new_vmalloc_chunk(struct kho_vmalloc_chunk *cur)\n--\nkernel/liveupdate/kexec_handover.c-1320-\nkernel/liveupdate/kexec_handover.c:1321:\terr = kho_preserve_pages(virt_to_page(chunk), 1);\nkernel/liveupdate/kexec_handover.c-1322-\tif (err)\n--\nkernel/liveupdate/kexec_handover.c=1333=static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk,\n--\nkernel/liveupdate/kexec_handover.c-1347-/**\nkernel/liveupdate/kexec_handover.c:1348: * kho_preserve_vmalloc - preserve memory allocated with vmalloc() across kexec\nkernel/liveupdate/kexec_handover.c-1349- * @ptr: pointer to the area in vmalloc address space\n--\nkernel/liveupdate/kexec_handover.c-1361- */\nkernel/liveupdate/kexec_handover.c:1362:int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation)\nkernel/liveupdate/kexec_handover.c-1363-{\n--\nkernel/liveupdate/kexec_handover.c-1387-\nkernel/liveupdate/kexec_handover.c:1388:\t\terr = kho_preserve_pages(vm-\u003epages[i], nr_contig_pages);\nkernel/liveupdate/kexec_handover.c-1389-\t\tif (err)\n--\nkernel/liveupdate/kexec_handover.c-1412-}\nkernel/liveupdate/kexec_handover.c:1413:EXPORT_SYMBOL_GPL(kho_preserve_vmalloc);\nkernel/liveupdate/kexec_handover.c-1414-\n--\nkernel/liveupdate/kexec_handover.c-1416- * kho_unpreserve_vmalloc - unpreserve memory allocated with vmalloc()\nkernel/liveupdate/kexec_handover.c:1417: * @preservation: preservation metadata returned by kho_preserve_vmalloc()\nkernel/liveupdate/kexec_handover.c-1418- *\nkernel/liveupdate/kexec_handover.c-1419- * Instructs KHO to unpreserve the area in vmalloc address space that was\nkernel/liveupdate/kexec_handover.c:1420: * previously preserved with kho_preserve_vmalloc().\nkernel/liveupdate/kexec_handover.c-1421- */\n--\nkernel/liveupdate/kexec_handover.c=1435=EXPORT_SYMBOL_GPL(kho_unpreserve_vmalloc);\n--\nkernel/liveupdate/kexec_handover.c-1442- * Recreates an area in vmalloc address space and populates it with memory that\nkernel/liveupdate/kexec_handover.c:1443: * was preserved using kho_preserve_vmalloc().\nkernel/liveupdate/kexec_handover.c-1444- *\n--\nkernel/liveupdate/kexec_handover.c=1549=void *kho_alloc_preserve(size_t size)\n--\nkernel/liveupdate/kexec_handover.c-1564-\nkernel/liveupdate/kexec_handover.c:1565:\tret = kho_preserve_folio(folio);\nkernel/liveupdate/kexec_handover.c-1566-\tif (ret) {\n--\nlib/test_kho.c=54=static int kho_test_preserve_data(struct kho_test_state *state)\n--\nlib/test_kho.c-63-\nlib/test_kho.c:64:\terr = kho_preserve_vmalloc(folios_info, \u0026folios_info_phys);\nlib/test_kho.c-65-\tif (err)\n--\nlib/test_kho.c-75-\t\tfolios_info[i] = virt_to_phys(folio_address(folio)) | order;\nlib/test_kho.c:76:\t\terr = kho_preserve_folio(folio);\nlib/test_kho.c-77-\t\tif (err)\n--\nlib/test_kho.c=124=static int kho_test_preserve(struct kho_test_state *state)\n--\nlib/test_kho.c-133-\nlib/test_kho.c:134:\terr = kho_preserve_folio(state-\u003efdt);\nlib/test_kho.c-135-\tif (err)\n--\nmm/memblock.c=2613=static int __init reserved_mem_preserve(void)\n--\nmm/memblock.c-2622-\nmm/memblock.c:2623:\t\terr = kho_preserve_pages(page, nr_pages);\nmm/memblock.c-2624-\t\tif (err)\n--\nmm/memblock.c=2642=static int __init prepare_kho_fdt(void)\n--\nmm/memblock.c-2654-\tfdt = page_to_virt(fdt_page);\nmm/memblock.c:2655:\terr = kho_preserve_pages(fdt_page, 1);\nmm/memblock.c-2656-\tif (err)\n--\nmm/memfd_luo.c=87=static int memfd_luo_preserve_folios(struct file *file,\n--\nmm/memfd_luo.c-150-\nmm/memfd_luo.c:151:\t\terr = kho_preserve_folio(folio);\nmm/memfd_luo.c-152-\t\tif (err)\n--\nmm/memfd_luo.c-202-\nmm/memfd_luo.c:203:\terr = kho_preserve_vmalloc(folios_ser, kho_vmalloc);\nmm/memfd_luo.c-204-\tif (err)\n"
}

13/2 2026/09/24 05:45 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 50544
							output: 43
							thoughts: 6483
						

Thoughts:
**Fuzzing Decision for a Pure Renaming Patch**

Okay, so I've got this patch series in front of me, and my task is to determine if it's "WorthFuzzing." My initial reaction, given my experience, is that it's probably not. Let's delve in.

First, I see the code touches several files within `mm/memfd_luo.c` and `kernel/liveupdate/`. Key functions like `kho_preserve_folio`, `kho_preserve_pages`, `kho_locate_mem_hole`, `setup_kho`, `bootmem_phys_show`, and `bootmem_len_show` are involved. The instructions clearly state I must determine if there is a realistic chance of bugs being uncovered via fuzzing.

My primary concern, however, comes down to the instruction in Section 3, specifically under the "Negative Criteria". The instructions say that if the *only* changes are in documentation, non-executable code (scripts, samples) or logging that doesn't affect control flow, then the patch is not worth fuzzing. I have a feeling this is the case here.

So, let's look at the patch, carefully. It looks like it's primarily renaming symbols and identifiers. For example, it looks like `kho_scratch` is being renamed to `kho_bootmem`. Similarly, `MEMBLOCK_KHO_SCRATCH` is renamed to `MEMBLOCK_KHO_NOPRSRV`. It also seems to have touched debugfs entries and kernel command-line parameters. Now, I am thinking, these functions are called from `kexec_file_load`, and can be read via debugfs, so they *are* reachable.

Let's carefully check every modified function. I see that it renames variables, function names, structure fields, debugfs entries, and kernel command-line parameters. But, critically, it doesn't seem to alter any actual executable code.

Now I'm diving deep into the fuzzing guidelines. Section 2, the "Negative Criteria," is key. I'm focusing on whether this renaming constitutes a change that *must* be fuzzed.

My primary question: Does pure renaming of identifiers qualify as something that alters "compiled C logic" or "introduces logic modifications"? Clearly, it does not. The compiled machine code would be almost exactly identical. However, there are a few exceptions, like `bootmem_phys_show`, `bootmem_len_show`, and the debugfs and kernel command-line names.

So, here's the crucial analysis. I'm imagining how syzkaller would interact with this patch. Does syzkaller have debugfs support? Yes. Could syzkaller read and write these debugfs nodes? Yes, but what could syzkaller *do*? Reading from the debugfs nodes just provides information on memory regions. Are there any conditions where these simple read operations could lead to a crash or a regression? It doesn't look like. The instructions say the goal is to discover crashes, regressions, or exposed latent bugs. This change simply cannot cause that.

The patch's impact appears to be on non-executable parts (e.g., debugfs names, kernel command line parameters), string literals, and symbol tables. It's essentially a cosmetic change that, while it touches reachable code paths via debugfs, doesn't alter any core logic.

I believe this patch falls squarely under "Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints that do not alter control flow or data structures," or "Build system or Kconfig changes that do not alter compiled C logic." There's no modification of data structures or algorithm flows. No new or altered assertions. Therefore, from my experience, fuzzing this will not be fruitful. **I'd classify this as not worth fuzzing.**



14/2 2026/09/24 05:46 tool read-file
0m Args:
{
  "File": "kernel/liveupdate/kexec_handover_debugfs.c",
  "FirstLine": 170,
  "LineCount": 40
}

Results:
{
  "Contents": " 170:\t\t\tpr_err(\"failed exposing handover FDT in debugfs: %pe\\n\",\n 171:\t\t\t       ERR_PTR(err));\n 172:\t\t}\n 173:\t}\n 174:\t\n 175:\t__init int kho_out_debugfs_init(struct kho_debugfs *dbg)\n 176:\t{\n 177:\t\tstruct dentry *dir, *f, *sub_fdt_dir;\n 178:\t\n 179:\t\tINIT_LIST_HEAD(\u0026dbg-\u003efdt_list);\n 180:\t\n 181:\t\tdir = debugfs_create_dir(\"out\", debugfs_root);\n 182:\t\tif (IS_ERR(dir))\n 183:\t\t\treturn -ENOMEM;\n 184:\t\n 185:\t\tsub_fdt_dir = debugfs_create_dir(\"sub_fdts\", dir);\n 186:\t\tif (IS_ERR(sub_fdt_dir))\n 187:\t\t\tgoto err_rmdir;\n 188:\t\n 189:\t\tf = debugfs_create_file(\"bootmem_phys\", 0400, dir, NULL,\n 190:\t\t\t\t\t\u0026bootmem_phys_fops);\n 191:\t\tif (IS_ERR(f))\n 192:\t\t\tgoto err_rmdir;\n 193:\t\n 194:\t\tf = debugfs_create_file(\"bootmem_len\", 0400, dir, NULL,\n 195:\t\t\t\t\t\u0026bootmem_len_fops);\n 196:\t\tif (IS_ERR(f))\n 197:\t\t\tgoto err_rmdir;\n 198:\t\n 199:\t\tdbg-\u003edir = dir;\n 200:\t\tdbg-\u003esub_fdt_dir = sub_fdt_dir;\n 201:\t\treturn 0;\n 202:\t\n 203:\terr_rmdir:\n 204:\t\tdebugfs_remove_recursive(dir);\n 205:\t\treturn -ENOENT;\n 206:\t}\n 207:\t\n 208:\t__init int kho_debugfs_init(void)\n 209:\t{\n"
}

15/2 2026/09/24 05:46 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 58495
							output: 40
							thoughts: 27
						

Thoughts:
Okay, let's dive into this. Here's my thought process on examining `kexec_handover.c`:

**Analyzing `kho_bootmem` Allocation and Initialization**

Alright, I need to understand how the `kho_bootmem` area is being handled. This is crucial for understanding the memory handover process in kexec, so I'm going to jump straight into `kexec_handover.c`. I need to see exactly where `kho_bootmem` is allocated. Is it using the standard `bootmem` allocator, or something more bespoke? I also want to follow the initialization steps. What data is put into this memory region, and how is it used later during the handover? Knowing the allocation details will impact my understanding of potential fragmentation issues, alignment constraints and the overall reliability of the kexec process.



16/2 2026/09/24 05:46 tool read-file
0m Args:
{
  "File": "kernel/liveupdate/kexec_handover.c",
  "FirstLine": 830,
  "LineCount": 40
}

Results:
{
  "Contents": " 830:\t * problem for us during KHO because we can just move them somewhere else.\n 831:\t */\n 832:\tstatic void __init kho_reserve_bootmem(void)\n 833:\t{\n 834:\t\tphys_addr_t addr, size;\n 835:\t\tint nid, i = 0;\n 836:\t\n 837:\t\tif (!kho_enable)\n 838:\t\t\treturn;\n 839:\t\n 840:\t\tbootmem_size_update();\n 841:\t\n 842:\t\t/* FIXME: deal with node hot-plug/remove */\n 843:\t\tkho_bootmem_cnt = nodes_weight(node_states[N_MEMORY]) + 2;\n 844:\t\tsize = kho_bootmem_cnt * sizeof(*kho_bootmem);\n 845:\t\tkho_bootmem = memblock_alloc(size, PAGE_SIZE);\n 846:\t\tif (!kho_bootmem) {\n 847:\t\t\tpr_err(\"Failed to reserve bootmem array\\n\");\n 848:\t\t\tgoto err_disable_kho;\n 849:\t\t}\n 850:\t\n 851:\t\t/*\n 852:\t\t * reserve bootmem area in low memory for lowmem allocations in the\n 853:\t\t * next kernel\n 854:\t\t */\n 855:\t\tsize = bootmem_size_lowmem;\n 856:\t\taddr = memblock_phys_alloc_range(size, BOOTMEM_ALIGNMENT_BYTES, 0,\n 857:\t\t\t\t\t\t ARCH_LOW_ADDRESS_LIMIT);\n 858:\t\tif (!addr) {\n 859:\t\t\tpr_err(\"Failed to reserve lowmem bootmem\\n\");\n 860:\t\t\tgoto err_free_bootmem_desc;\n 861:\t\t}\n 862:\t\n 863:\t\tkho_bootmem[i].addr = addr;\n 864:\t\tkho_bootmem[i].size = size;\n 865:\t\ti++;\n 866:\t\n 867:\t\t/* reserve large contiguous area for allocations without nid */\n 868:\t\tsize = bootmem_size_global;\n 869:\t\taddr = memblock_phys_alloc(size, BOOTMEM_ALIGNMENT_BYTES);\n"
}

17/2 2026/09/24 05:46 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 59344
							output: 145
							thoughts: 3521
						

Thoughts:
**Analysis of Patch for Fuzzing Eligibility**

Okay, so I've got this patch in front of me, and the question is: does it warrant fuzzing? Let's break this down systematically. Section 1 of the fuzzing guidelines says the goal is to find *new* crashes, regressions, exposed latent bugs, or triggered assertions. The primary gate is reachability – code must be executable in a standard environment. Now, let's be crystal clear: "refactoring" claims are always suspect. We need to look closely if this code even *touches* reachable executable code, or alters the existing compiled C logic.

Section 2 provides the "negative criteria," the conditions under which fuzzing is *not* necessary. My immediate thought is, a pure identifier rename ("kho scratch" to "kho bootmem") across various files *has* to fall under the "Non-kernel and non-executable changes". The renaming of a variable, function or structure *cannot* introduce a crash. It's essentially a nomenclature change. It's like changing the name of a variable, it won't affect the machine code generated by the compiler. It is pure metadata and doesn't change anything at runtime.

I looked at all the code changes again and again, it is pure renaming across: documentation, comments, strings, structure members, enum values, function names, macro names. This is not logic modification. No algorithm flows. No new assertions. No restructuring. Nothing. The exact same binary code is executed. The assertion: `WARN_ON(kho_scratch_overlap(pfn << PAGE_SHIFT, PAGE_SIZE << order))` becomes `WARN_ON(kho_bootmem_overlap(pfn << PAGE_SHIFT, PAGE_SIZE << order))`. It's the exact same condition, the same compiled logic.

The positive criteria, Section 3, are all *completely* irrelevant here. There are *no* logic modifications, *no* data structure restructurings, *no* altered assertions. It's all literally renaming.

And even if we *did* consider fuzzing, what focus symbols would we even choose? `kho_bootmem_overlap`? `setup_kho`? But `setup_kho` is static and `__init` functions cannot be fuzzed! And `kho_bootmem_overlap` is just checking for address overlaps - trivial and highly unlikely to be triggered by fuzzing. Most of the code is also `__init`, meaning it’s gone before the kernel is actually *running* and thus cannot be reached.

So, the conclusion is: **WorthFuzzing = false**. There are *zero* valid focus symbols to supply, so the list will be empty. And finally, there are no additional configurations or reasoning that I should apply to the tooling, because this is a simple nomenclature change. It's a waste of syzkaller resources to even consider it. The changes are all pure nomenclature, purely descriptive.

Therefore the parameters should be:

-   `WorthFuzzing`: false
-   `FocusSymbols`: \[ ]
-   `EnableConfigs`: \[ ]
-   `Reasoning`: Concise explanation that this patch is a pure nomenclature/identifier rename (changing "KHO scratch" to "KHO bootmem" and `MEMBLOCK_KHO_SCRATCH` to `MEMBLOCK_KHO_NOPRSRV`) across documentation, comments, and kernel code. It introduces no logic changes, no restructuring of data structures or algorithm flows, no new or modified assertions, and does not alter compiled C logic or control flow.

And now I'm ready to call the `set-results` command with these parameters.



18/2 2026/09/24 05:46 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "This patch is purely a nomenclature and symbol refactoring that renames Kexec HandOver (KHO) \"scratch\" regions to \"bootmem\" (and MEMBLOCK_KHO_SCRATCH to MEMBLOCK_KHO_NOPRSRV) across documentation, comments, variable/function/type identifiers, debugfs entries, and kernel parameters. It introduces no logic modifications, no restructuring of data structures or algorithm flows, no altered assertions, and does not change any compiled executable C logic or runtime control flow. Therefore, it does not warrant fuzzing.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "This patch is purely a nomenclature and symbol refactoring that renames Kexec HandOver (KHO) \"scratch\" regions to \"bootmem\" (and MEMBLOCK_KHO_SCRATCH to MEMBLOCK_KHO_NOPRSRV) across documentation, comments, variable/function/type identifiers, debugfs entries, and kernel parameters. It introduces no logic modifications, no restructuring of data structures or algorithm flows, no altered assertions, and does not change any compiled executable C logic or runtime control flow. Therefore, it does not warrant fuzzing.",
  "WorthFuzzing": false
}

19/1 2026/09/24 05:46 action If
0m Args:
{
  "WorthFuzzing": false
}

Results:
null

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)