Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

kho: remove finalize state and clients

Eliminate the `kho_finalize()` function and its associated state from the
KHO subsystem. The transition to a radix tree for memory tracking makes
the explicit "finalize" state and its serialization step obsolete.

Remove the `kho_finalize()` and `kho_finalized()` APIs and their stub
implementations. Update KHO client code and the debugfs interface to no
longer call or depend on the `kho_finalize()` mechanism.

Complete the move towards a stateless KHO, simplifying the overall design
by removing unnecessary state management.

Link: https://lkml.kernel.org/r/20260206021428.3386442-3-jasonmiu@google.com
Signed-off-by: Jason Miu <jasonmiu@google.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: Alexander Graf <graf@amazon.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Changyuan Lyu <changyuanl@google.com>
Cc: David Matlack <dmatlack@google.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Ran Xiaokai <ran.xiaokai@zte.com.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Jason Miu and committed by
Andrew Morton
6b0dd42d 3f2ad900

+13 -131
+11 -42
Documentation/admin-guide/mm/kho.rst
··· 28 28 Perform a KHO kexec 29 29 =================== 30 30 31 - First, before you perform a KHO kexec, you need to move the system into 32 - the :ref:`KHO finalization phase <kho-finalization-phase>` :: 33 - 34 - $ echo 1 > /sys/kernel/debug/kho/out/finalize 35 - 36 - After this command, the KHO FDT is available in 37 - ``/sys/kernel/debug/kho/out/fdt``. Other subsystems may also register 38 - their own preserved sub FDTs under 39 - ``/sys/kernel/debug/kho/out/sub_fdts/``. 40 - 41 - Next, load the target payload and kexec into it. It is important that you 42 - use the ``-s`` parameter to use the in-kernel kexec file loader, as user 43 - space kexec tooling currently has no support for KHO with the user space 44 - based file loader :: 31 + To perform a KHO kexec, load the target payload and kexec into it. It 32 + is important that you use the ``-s`` parameter to use the in-kernel 33 + kexec file loader, as user space kexec tooling currently has no 34 + support for KHO with the user space based file loader :: 45 35 46 36 # kexec -l /path/to/bzImage --initrd /path/to/initrd -s 47 37 # kexec -e ··· 42 52 an early memory reservation, the new kernel will have that memory at the 43 53 same physical address as the old kernel. 44 54 45 - Abort a KHO exec 46 - ================ 47 - 48 - You can move the system out of KHO finalization phase again by calling :: 49 - 50 - $ echo 0 > /sys/kernel/debug/kho/out/active 51 - 52 - After this command, the KHO FDT is no longer available in 53 - ``/sys/kernel/debug/kho/out/fdt``. 54 - 55 55 debugfs Interfaces 56 56 ================== 57 + 58 + These debugfs interfaces are available when the kernel is compiled with 59 + ``CONFIG_KEXEC_HANDOVER_DEBUGFS`` enabled. 57 60 58 61 Currently KHO creates the following debugfs interfaces. Notice that these 59 62 interfaces may change in the future. They will be moved to sysfs once KHO is 60 63 stabilized. 61 64 62 - ``/sys/kernel/debug/kho/out/finalize`` 63 - Kexec HandOver (KHO) allows Linux to transition the state of 64 - compatible drivers into the next kexec'ed kernel. To do so, 65 - device drivers will instruct KHO to preserve memory regions, 66 - which could contain serialized kernel state. 67 - While the state is serialized, they are unable to perform 68 - any modifications to state that was serialized, such as 69 - handed over memory allocations. 70 - 71 - When this file contains "1", the system is in the transition 72 - state. When contains "0", it is not. To switch between the 73 - two states, echo the respective number into this file. 74 - 75 65 ``/sys/kernel/debug/kho/out/fdt`` 76 - When KHO state tree is finalized, the kernel exposes the 77 - flattened device tree blob that carries its current KHO 78 - state in this file. Kexec user space tooling can use this 66 + The kernel exposes the flattened device tree blob that carries its 67 + current KHO state in this file. Kexec user space tooling can use this 79 68 as input file for the KHO payload image. 80 69 81 70 ``/sys/kernel/debug/kho/out/scratch_len`` ··· 69 100 it should place its payload images. 70 101 71 102 ``/sys/kernel/debug/kho/out/sub_fdts/`` 72 - In the KHO finalization phase, KHO producers register their own 73 - FDT blob under this directory. 103 + KHO producers can register their own FDT or another binary blob under 104 + this directory. 74 105 75 106 ``/sys/kernel/debug/kho/in/fdt`` 76 107 When the kernel was booted with Kexec HandOver (KHO),
-12
Documentation/core-api/kho/index.rst
··· 71 71 of that memory region may be reserved. These reservations are irrelevant for 72 72 the next KHO, because kexec can overwrite even the original kernel. 73 73 74 - .. _kho-finalization-phase: 75 - 76 - KHO finalization phase 77 - ====================== 78 - 79 - To enable user space based kexec file loader, the kernel needs to be able to 80 - provide the FDT that describes the current kernel's state before 81 - performing the actual kexec. The process of generating that FDT is 82 - called serialization. When the FDT is generated, some properties 83 - of the system may become immutable because they are already written down 84 - in the FDT. That state is called the KHO finalization phase. 85 - 86 74 Kexec Handover Radix Tree 87 75 ========================= 88 76
+1 -20
kernel/liveupdate/kexec_handover.c
··· 68 68 69 69 struct kho_out { 70 70 void *fdt; 71 - bool finalized; 72 - struct mutex lock; /* protects KHO FDT finalization */ 71 + struct mutex lock; /* protects KHO FDT */ 73 72 74 73 struct kho_radix_tree radix_tree; 75 74 struct kho_debugfs dbg; ··· 79 80 .radix_tree = { 80 81 .lock = __MUTEX_INITIALIZER(kho_out.radix_tree.lock), 81 82 }, 82 - .finalized = false, 83 83 }; 84 84 85 85 /** ··· 1238 1240 folio_put(folio); 1239 1241 } 1240 1242 EXPORT_SYMBOL_GPL(kho_restore_free); 1241 - 1242 - int kho_finalize(void) 1243 - { 1244 - if (!kho_enable) 1245 - return -EOPNOTSUPP; 1246 - 1247 - guard(mutex)(&kho_out.lock); 1248 - kho_out.finalized = true; 1249 - 1250 - return 0; 1251 - } 1252 - 1253 - bool kho_finalized(void) 1254 - { 1255 - guard(mutex)(&kho_out.lock); 1256 - return kho_out.finalized; 1257 - } 1258 1243 1259 1244 struct kho_in { 1260 1245 phys_addr_t fdt_phys;
-23
kernel/liveupdate/kexec_handover_debugfs.c
··· 76 76 } 77 77 } 78 78 79 - static int kho_out_finalize_get(void *data, u64 *val) 80 - { 81 - *val = kho_finalized(); 82 - 83 - return 0; 84 - } 85 - 86 - static int kho_out_finalize_set(void *data, u64 val) 87 - { 88 - if (val) 89 - return kho_finalize(); 90 - else 91 - return -EINVAL; 92 - } 93 - 94 - DEFINE_DEBUGFS_ATTRIBUTE(kho_out_finalize_fops, kho_out_finalize_get, 95 - kho_out_finalize_set, "%llu\n"); 96 - 97 79 static int scratch_phys_show(struct seq_file *m, void *v) 98 80 { 99 81 for (int i = 0; i < kho_scratch_cnt; i++) ··· 178 196 179 197 f = debugfs_create_file("scratch_len", 0400, dir, NULL, 180 198 &scratch_len_fops); 181 - if (IS_ERR(f)) 182 - goto err_rmdir; 183 - 184 - f = debugfs_create_file("finalize", 0600, dir, NULL, 185 - &kho_out_finalize_fops); 186 199 if (IS_ERR(f)) 187 200 goto err_rmdir; 188 201
-3
kernel/liveupdate/kexec_handover_internal.h
··· 22 22 extern struct kho_scratch *kho_scratch; 23 23 extern unsigned int kho_scratch_cnt; 24 24 25 - bool kho_finalized(void); 26 - int kho_finalize(void); 27 - 28 25 #ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS 29 26 int kho_debugfs_init(void); 30 27 void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt);
+1 -11
kernel/liveupdate/luo_core.c
··· 230 230 231 231 luo_flb_serialize(); 232 232 233 - err = kho_finalize(); 234 - if (err) { 235 - pr_err("kho_finalize failed %d\n", err); 236 - /* 237 - * kho_finalize() may return libfdt errors, to aboid passing to 238 - * userspace unknown errors, change this to EAGAIN. 239 - */ 240 - err = -EAGAIN; 241 - } 242 - 243 - return err; 233 + return 0; 244 234 } 245 235 246 236 /**
-20
tools/testing/selftests/kho/init.c
··· 11 11 /* from arch/x86/include/asm/setup.h */ 12 12 #define COMMAND_LINE_SIZE 2048 13 13 14 - #define KHO_FINALIZE "/debugfs/kho/out/finalize" 15 14 #define KERNEL_IMAGE "/kernel" 16 15 17 16 static int mount_filesystems(void) ··· 19 20 return -1; 20 21 21 22 return mount("proc", "/proc", "proc", 0, NULL); 22 - } 23 - 24 - static int kho_enable(void) 25 - { 26 - const char enable[] = "1"; 27 - int fd; 28 - 29 - fd = open(KHO_FINALIZE, O_RDWR); 30 - if (fd < 0) 31 - return -1; 32 - 33 - if (write(fd, enable, sizeof(enable)) != sizeof(enable)) 34 - return 1; 35 - 36 - close(fd); 37 - return 0; 38 23 } 39 24 40 25 static long kexec_file_load(int kernel_fd, int initrd_fd, ··· 59 76 int main(int argc, char *argv[]) 60 77 { 61 78 if (mount_filesystems()) 62 - goto err_reboot; 63 - 64 - if (kho_enable()) 65 79 goto err_reboot; 66 80 67 81 if (kexec_load())