projects/linux·blob master · refs

928 lines · 30.8 KiB

1// SPDX-License-Identifier: GPL-2.0
2
3/*
4 * Copyright (c) 2025, Google LLC.
5 * Pasha Tatashin <[email protected]>
6 */
7
8/**
9 * DOC: LUO File Descriptors
10 *
11 * LUO provides the infrastructure to preserve specific, stateful file
12 * descriptors across a kexec-based live update. The primary goal is to allow
13 * workloads, such as virtual machines using vfio, memfd, or iommufd, to
14 * retain access to their essential resources without interruption.
15 *
16 * The framework is built around a callback-based handler model and a well-
17 * defined lifecycle for each preserved file.
18 *
19 * Handler Registration:
20 * Kernel modules responsible for a specific file type (e.g., memfd, vfio)
21 * register a &struct liveupdate_file_handler. This handler provides a set of
22 * callbacks that LUO invokes at different stages of the update process, most
23 * notably:
24 *
25 * - can_preserve(): A lightweight check to determine if the handler is
26 * compatible with a given 'struct file'.
27 * - preserve(): The heavyweight operation that saves the file's state and
28 * returns an opaque u64 handle. This is typically performed while the
29 * workload is still active to minimize the downtime during the
30 * actual reboot transition.
31 * - unpreserve(): Cleans up any resources allocated by .preserve(), called
32 * if the preservation process is aborted before the reboot (i.e. session is
33 * closed).
34 * - freeze(): A final pre-reboot opportunity to prepare the state for kexec.
35 * We are already in reboot syscall, and therefore userspace cannot mutate
36 * the file anymore.
37 * - unfreeze(): Undoes the actions of .freeze(), called if the live update
38 * is aborted after the freeze phase.
39 * - retrieve(): Reconstructs the file in the new kernel from the preserved
40 * handle.
41 * - finish(): Performs final check and cleanup in the new kernel. After
42 * succesul finish call, LUO gives up ownership to this file.
43 *
44 * File Preservation Lifecycle happy path:
45 *
46 * 1. Preserve (Normal Operation): A userspace agent preserves files one by one
47 * via an ioctl. For each file, luo_preserve_file() finds a compatible
48 * handler, calls its .preserve() operation, and creates an internal &struct
49 * luo_file to track the live state.
50 *
51 * 2. Freeze (Pre-Reboot): Just before the kexec, luo_file_freeze() is called.
52 * It iterates through all preserved files, calls their respective .freeze()
53 * operation, and serializes their final metadata (compatible string, token,
54 * and data handle) into a contiguous memory block for KHO.
55 *
56 * 3. Deserialize: After kexec, luo_file_deserialize() runs when session gets
57 * deserialized (which is when /dev/liveupdate is first opened). It reads the
58 * serialized data from the KHO memory region and reconstructs the in-memory
59 * list of &struct luo_file instances for the new kernel, linking them to
60 * their corresponding handlers.
61 *
62 * 4. Retrieve (New Kernel - Userspace Ready): The userspace agent can now
63 * restore file descriptors by providing a token. luo_retrieve_file()
64 * searches for the matching token, calls the handler's .retrieve() op to
65 * re-create the 'struct file', and returns a new FD. Files can be
66 * retrieved in ANY order.
67 *
68 * 5. Finish (New Kernel - Cleanup): Once a session retrival is complete,
69 * luo_file_finish() is called. It iterates through all files, invokes their
70 * .finish() operations for final cleanup, and releases all associated kernel
71 * resources.
72 *
73 * File Preservation Lifecycle unhappy paths:
74 *
75 * 1. Abort Before Reboot: If the userspace agent aborts the live update
76 * process before calling reboot (e.g., by closing the session file
77 * descriptor), the session's release handler calls
78 * luo_file_unpreserve_files(). This invokes the .unpreserve() callback on
79 * all preserved files, ensuring all allocated resources are cleaned up and
80 * returning the system to a clean state.
81 *
82 * 2. Freeze Failure: During the reboot() syscall, if any handler's .freeze()
83 * op fails, the .unfreeze() op is invoked on all previously *successful*
84 * freezes to roll back their state. The reboot() syscall then returns an
85 * error to userspace, canceling the live update.
86 *
87 * 3. Finish Failure: In the new kernel, if a handler's .finish() op fails,
88 * the luo_file_finish() operation is aborted. LUO retains ownership of
89 * all files within that session, including those that were not yet
90 * processed. The userspace agent can attempt to call the finish operation
91 * again later. If the issue cannot be resolved, these resources will be held
92 * by LUO until the next live update cycle, at which point they will be
93 * discarded.
94 */
95
96#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
97
98#include <linux/cleanup.h>
99#include <linux/compiler.h>
100#include <linux/err.h>
101#include <linux/errno.h>
102#include <linux/file.h>
103#include <linux/fs.h>
104#include <linux/io.h>
105#include <linux/kexec_handover.h>
106#include <linux/kho/abi/luo.h>
107#include <linux/list_private.h>
108#include <linux/liveupdate.h>
109#include <linux/module.h>
110#include <linux/sizes.h>
111#include <linux/xarray.h>
112#include <linux/slab.h>
113#include <linux/string.h>
114#include "luo_internal.h"
115
116static LIST_HEAD(luo_file_handler_list);
117
118/* Keep track of files being preserved by LUO */
119static DEFINE_XARRAY(luo_preserved_files);
120
121/**
122 * struct luo_file - Represents a single preserved file instance.
123 * @fh: Pointer to the &struct liveupdate_file_handler that manages
124 * this type of file.
125 * @file: Pointer to the kernel's &struct file that is being preserved.
126 * This is NULL in the new kernel until the file is successfully
127 * retrieved.
128 * @serialized_data: The opaque u64 handle to the serialized state of the file.
129 * This handle is passed back to the handler's .freeze(),
130 * .retrieve(), and .finish() callbacks, allowing it to track
131 * and update its serialized state across phases.
132 * @private_data: Pointer to the private data for the file used to hold runtime
133 * state that is not preserved. Set by the handler's .preserve()
134 * callback, and must be freed in the handler's .unpreserve()
135 * callback.
136 * @retrieve_status: Status code indicating whether a user/kernel in the new kernel has
137 * successfully called retrieve() on this file. This prevents
138 * multiple retrieval attempts. A value of 0 means a retrieve()
139 * has not been attempted, a positive value means the retrieve()
140 * was successful, and a negative value means the retrieve()
141 * failed, and the value is the error code of the call.
142 * @mutex: A mutex that protects the fields of this specific instance
143 * (e.g., @retrieved, @file), ensuring that operations like
144 * retrieving or finishing a file are atomic.
145 * @list: The list_head linking this instance into its parent
146 * file_set's list of preserved files.
147 * @token: The user-provided unique token used to identify this file.
148 *
149 * This structure is the core in-kernel representation of a single file being
150 * managed through a live update. An instance is created by luo_preserve_file()
151 * to link a 'struct file' to its corresponding handler, a user-provided token,
152 * and the serialized state handle returned by the handler's .preserve()
153 * operation.
154 *
155 * These instances are tracked in a per-file_set list. The @serialized_data
156 * field, which holds a handle to the file's serialized state, may be updated
157 * during the .freeze() callback before being serialized for the next kernel.
158 * After reboot, these structures are recreated by luo_file_deserialize() and
159 * are finally cleaned up by luo_file_finish().
160 */
161struct luo_file {
162 struct liveupdate_file_handler *fh;
163 struct file *file;
164 u64 serialized_data;
165 void *private_data;
166 int retrieve_status;
167 struct mutex mutex;
168 struct list_head list;
169 u64 token;
170};
171
172static unsigned long luo_get_id(struct liveupdate_file_handler *fh,
173 struct file *file)
174{
175 return fh->ops->get_id ? fh->ops->get_id(file) : (unsigned long)file;
176}
177
178static bool luo_token_is_used(struct luo_file_set *file_set, u64 token)
179{
180 struct luo_file *iter;
181
182 list_for_each_entry(iter, &file_set->files_list, list) {
183 if (iter->token == token)
184 return true;
185 }
186
187 return false;
188}
189
190/**
191 * luo_preserve_file - Initiate the preservation of a file descriptor.
192 * @file_set: The file_set to which the preserved file will be added.
193 * @token: A unique, user-provided identifier for the file.
194 * @fd: The file descriptor to be preserved.
195 *
196 * This function orchestrates the first phase of preserving a file. Upon entry,
197 * it takes a reference to the 'struct file' via fget(), effectively making LUO
198 * a co-owner of the file. This reference is held until the file is either
199 * unpreserved or successfully finished in the next kernel, preventing the file
200 * from being prematurely destroyed.
201 *
202 * This function orchestrates the first phase of preserving a file. It performs
203 * the following steps:
204 *
205 * 1. Validates that the @token is not already in use within the file_set.
206 * 2. Ensures the file_set's memory for files serialization is allocated
207 * (allocates if needed).
208 * 3. Iterates through registered handlers, calling can_preserve() to find one
209 * compatible with the given @fd.
210 * 4. Calls the handler's .preserve() operation, which saves the file's state
211 * and returns an opaque private data handle.
212 * 5. Adds the new instance to the file_set's internal list.
213 *
214 * On success, LUO takes a reference to the 'struct file' and considers it
215 * under its management until it is unpreserved or finished.
216 *
217 * In case of any failure, all intermediate allocations (file reference, memory
218 * for the 'luo_file' struct, etc.) are cleaned up before returning an error.
219 *
220 * Context: Can be called from an ioctl handler during normal system operation.
221 * Return: 0 on success. Returns a negative errno on failure:
222 * -EEXIST if the token is already used.
223 * -EBUSY if the file descriptor is already preserved by another session.
224 * -EBADF if the file descriptor is invalid.
225 * -ENOSPC if the file_set is full.
226 * -ENOENT if no compatible handler is found.
227 * -ENOMEM on memory allocation failure.
228 * Other erros might be returned by .preserve().
229 */
230int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd)
231{
232 struct liveupdate_file_op_args args = {0};
233 struct liveupdate_file_handler *fh;
234 struct luo_file *luo_file;
235 struct file *file;
236 int err;
237
238 if (luo_token_is_used(file_set, token))
239 return -EEXIST;
240
241 err = kho_block_set_grow(&file_set->block_set, file_set->count + 1);
242 if (err)
243 return err;
244
245 file = fget(fd);
246 if (!file) {
247 err = -EBADF;
248 goto err_shrink;
249 }
250
251 err = -ENOENT;
252 down_read(&luo_register_rwlock);
253 list_private_for_each_entry(fh, &luo_file_handler_list, list) {
254 if (fh->ops->can_preserve(fh, file)) {
255 if (try_module_get(fh->ops->owner))
256 err = 0;
257 break;
258 }
259 }
260 up_read(&luo_register_rwlock);
261
262 /* err is still -ENOENT if no handler was found */
263 if (err)
264 goto err_fput;
265
266 err = xa_insert(&luo_preserved_files, luo_get_id(fh, file),
267 file, GFP_KERNEL);
268 if (err)
269 goto err_module_put;
270
271 err = luo_flb_file_preserve(fh);
272 if (err)
273 goto err_erase_xa;
274
275 luo_file = kzalloc_obj(*luo_file);
276 if (!luo_file) {
277 err = -ENOMEM;
278 goto err_flb_unpreserve;
279 }
280
281 luo_file->file = file;
282 luo_file->fh = fh;
283 luo_file->token = token;
284 mutex_init(&luo_file->mutex);
285
286 args.handler = fh;
287 args.file = file;
288 err = fh->ops->preserve(&args);
289 if (err)
290 goto err_kfree;
291
292 luo_file->serialized_data = args.serialized_data;
293 luo_file->private_data = args.private_data;
294 list_add_tail(&luo_file->list, &file_set->files_list);
295 file_set->count++;
296
297 return 0;
298
299err_kfree:
300 kfree(luo_file);
301err_flb_unpreserve:
302 luo_flb_file_unpreserve(fh);
303err_erase_xa:
304 xa_erase(&luo_preserved_files, luo_get_id(fh, file));
305err_module_put:
306 module_put(fh->ops->owner);
307err_fput:
308 fput(file);
309err_shrink:
310 kho_block_set_shrink(&file_set->block_set, file_set->count);
311
312 return err;
313}
314
315/**
316 * luo_file_unpreserve_files - Unpreserves all files from a file_set.
317 * @file_set: The files to be cleaned up.
318 *
319 * This function serves as the primary cleanup path for a file_set. It is
320 * invoked when the userspace agent closes the file_set's file descriptor.
321 *
322 * For each file, it performs the following cleanup actions:
323 * 1. Calls the handler's .unpreserve() callback to allow the handler to
324 * release any resources it allocated.
325 * 2. Removes the file from the file_set's internal tracking list.
326 * 3. Releases the reference to the 'struct file' that was taken by
327 * luo_preserve_file() via fput(), returning ownership.
328 * 4. Frees the memory associated with the internal 'struct luo_file'.
329 *
330 * After all individual files are unpreserved, it frees the contiguous memory
331 * block that was allocated to hold their serialization data.
332 */
333void luo_file_unpreserve_files(struct luo_file_set *file_set)
334{
335 struct luo_file *luo_file;
336
337 while (!list_empty(&file_set->files_list)) {
338 struct liveupdate_file_op_args args = {0};
339
340 luo_file = list_last_entry(&file_set->files_list,
341 struct luo_file, list);
342
343 args.handler = luo_file->fh;
344 args.file = luo_file->file;
345 args.serialized_data = luo_file->serialized_data;
346 args.private_data = luo_file->private_data;
347 luo_file->fh->ops->unpreserve(&args);
348 luo_flb_file_unpreserve(luo_file->fh);
349
350 xa_erase(&luo_preserved_files,
351 luo_get_id(luo_file->fh, luo_file->file));
352 module_put(luo_file->fh->ops->owner);
353
354 list_del(&luo_file->list);
355 file_set->count--;
356 kho_block_set_shrink(&file_set->block_set, file_set->count);
357
358 fput(luo_file->file);
359 mutex_destroy(&luo_file->mutex);
360 kfree(luo_file);
361 }
362
363 kho_block_set_destroy(&file_set->block_set);
364}
365
366static int luo_file_freeze_one(struct luo_file_set *file_set,
367 struct luo_file *luo_file)
368{
369 int err = 0;
370
371 guard(mutex)(&luo_file->mutex);
372
373 if (luo_file->fh->ops->freeze) {
374 struct liveupdate_file_op_args args = {0};
375
376 args.handler = luo_file->fh;
377 args.file = luo_file->file;
378 args.serialized_data = luo_file->serialized_data;
379 args.private_data = luo_file->private_data;
380
381 err = luo_file->fh->ops->freeze(&args);
382 if (!err)
383 luo_file->serialized_data = args.serialized_data;
384 }
385
386 return err;
387}
388
389static void luo_file_unfreeze_one(struct luo_file_set *file_set,
390 struct luo_file *luo_file)
391{
392 guard(mutex)(&luo_file->mutex);
393
394 if (luo_file->fh->ops->unfreeze) {
395 struct liveupdate_file_op_args args = {0};
396
397 args.handler = luo_file->fh;
398 args.file = luo_file->file;
399 args.serialized_data = luo_file->serialized_data;
400 args.private_data = luo_file->private_data;
401
402 luo_file->fh->ops->unfreeze(&args);
403 }
404}
405
406static void __luo_file_unfreeze(struct luo_file_set *file_set,
407 struct luo_file *failed_entry)
408{
409 struct list_head *files_list = &file_set->files_list;
410 struct luo_file *luo_file;
411
412 list_for_each_entry(luo_file, files_list, list) {
413 if (luo_file == failed_entry)
414 break;
415
416 luo_file_unfreeze_one(file_set, luo_file);
417 }
418
419 kho_block_set_clear(&file_set->block_set);
420}
421
422/**
423 * luo_file_freeze - Freezes all preserved files and serializes their metadata.
424 * @file_set: The file_set whose files are to be frozen.
425 * @file_set_ser: Where to put the serialized file_set.
426 *
427 * This function is called from the reboot() syscall path, just before the
428 * kernel transitions to the new image via kexec. Its purpose is to perform the
429 * final preparation and serialization of all preserved files in the file_set.
430 *
431 * It iterates through each preserved file in FIFO order (the order of
432 * preservation) and performs two main actions:
433 *
434 * 1. Freezes the File: It calls the handler's .freeze() callback for each
435 * file. This gives the handler a final opportunity to quiesce the device or
436 * prepare its state for the upcoming reboot. The handler may update its
437 * private data handle during this step.
438 *
439 * 2. Serializes Metadata: After a successful freeze, it copies the final file
440 * metadata—the handler's compatible string, the user token, and the final
441 * private data handle—into the pre-allocated contiguous memory buffer
442 * (file_set->files) that will be handed over to the next kernel via KHO.
443 *
444 * Error Handling (Rollback):
445 * This function is atomic. If any handler's .freeze() operation fails, the
446 * entire live update is aborted. The __luo_file_unfreeze() helper is
447 * immediately called to invoke the .unfreeze() op on all files that were
448 * successfully frozen before the point of failure, rolling them back to a
449 * running state. The function then returns an error, causing the reboot()
450 * syscall to fail.
451 *
452 * Context: Called only from the liveupdate_reboot() path.
453 * Return: 0 on success, or a negative errno on failure.
454 */
455int luo_file_freeze(struct luo_file_set *file_set,
456 struct luo_file_set_ser *file_set_ser)
457{
458 struct luo_file *luo_file;
459 struct kho_block_set_it it;
460 int err;
461
462 if (!file_set->count)
463 return 0;
464
465 kho_block_set_it_init(&it, &file_set->block_set);
466
467 list_for_each_entry(luo_file, &file_set->files_list, list) {
468 struct luo_file_ser *file_ser = kho_block_set_it_reserve_entry(&it);
469
470 /* This should not fail normally as blocks were pre-allocated */
471 if (WARN_ON_ONCE(!file_ser)) {
472 err = -ENOSPC;
473 goto err_unfreeze;
474 }
475
476 err = luo_file_freeze_one(file_set, luo_file);
477 if (err < 0) {
478 pr_warn("Freeze failed for token[%#0llx] handler[%s] err[%pe]\n",
479 luo_file->token, luo_file->fh->compatible,
480 ERR_PTR(err));
481 goto err_unfreeze;
482 }
483
484 strscpy(file_ser->compatible, luo_file->fh->compatible,
485 sizeof(file_ser->compatible));
486 file_ser->data = luo_file->serialized_data;
487 file_ser->token = luo_file->token;
488 }
489
490 file_set_ser->count = file_set->count;
491 file_set_ser->files = kho_block_set_head_pa(&file_set->block_set);
492
493 return 0;
494
495err_unfreeze:
496 __luo_file_unfreeze(file_set, luo_file);
497
498 return err;
499}
500
501/**
502 * luo_file_unfreeze - Unfreezes all files in a file_set and clear serialization
503 * @file_set: The file_set whose files are to be unfrozen.
504 * @file_set_ser: Serialized file_set.
505 *
506 * This function rolls back the state of all files in a file_set after the
507 * freeze phase has begun but must be aborted. It is the counterpart to
508 * luo_file_freeze().
509 *
510 * It invokes the __luo_file_unfreeze() helper with a NULL argument, which
511 * signals the helper to iterate through all files in the file_set and call
512 * their respective .unfreeze() handler callbacks.
513 *
514 * Context: This is called when the live update is aborted during
515 * the reboot() syscall, after luo_file_freeze() has been called.
516 */
517void luo_file_unfreeze(struct luo_file_set *file_set,
518 struct luo_file_set_ser *file_set_ser)
519{
520 if (!file_set->count)
521 return;
522
523 __luo_file_unfreeze(file_set, NULL);
524 memset(file_set_ser, 0, sizeof(*file_set_ser));
525}
526
527/**
528 * luo_retrieve_file - Restores a preserved file from a file_set by its token.
529 * @file_set: The file_set from which to retrieve the file.
530 * @token: The unique token identifying the file to be restored.
531 * @filep: Output parameter; on success, this is populated with a pointer
532 * to the newly retrieved 'struct file'.
533 *
534 * This function is the primary mechanism for recreating a file in the new
535 * kernel after a live update. It searches the file_set's list of deserialized
536 * files for an entry matching the provided @token.
537 *
538 * The operation is idempotent: if a file has already been successfully
539 * retrieved, this function will simply return a pointer to the existing
540 * 'struct file' and report success without re-executing the retrieve
541 * operation. This is handled by checking the 'retrieved' flag under a lock.
542 *
543 * File retrieval can happen in any order; it is not bound by the order of
544 * preservation.
545 *
546 * Context: Can be called from an ioctl or other in-kernel code in the new
547 * kernel.
548 * Return: 0 on success. Returns a negative errno on failure:
549 * -ENOENT if no file with the matching token is found.
550 * Any error code returned by the handler's .retrieve() op.
551 */
552int luo_retrieve_file(struct luo_file_set *file_set, u64 token,
553 struct file **filep)
554{
555 struct liveupdate_file_op_args args = {0};
556 struct luo_file *luo_file;
557 bool found = false;
558 int err;
559
560 if (list_empty(&file_set->files_list))
561 return -ENOENT;
562
563 list_for_each_entry(luo_file, &file_set->files_list, list) {
564 if (luo_file->token == token) {
565 found = true;
566 break;
567 }
568 }
569
570 if (!found)
571 return -ENOENT;
572
573 guard(mutex)(&luo_file->mutex);
574 if (luo_file->retrieve_status < 0) {
575 /* Retrieve was attempted and it failed. Return the error code. */
576 return luo_file->retrieve_status;
577 }
578
579 if (luo_file->retrieve_status > 0) {
580 /*
581 * Someone is asking for this file again, so get a reference
582 * for them.
583 */
584 get_file(luo_file->file);
585 *filep = luo_file->file;
586 return 0;
587 }
588
589 args.handler = luo_file->fh;
590 args.serialized_data = luo_file->serialized_data;
591 err = luo_file->fh->ops->retrieve(&args);
592 if (err) {
593 /* Keep the error code for later use. */
594 luo_file->retrieve_status = err;
595 return err;
596 }
597
598 luo_file->file = args.file;
599 /* Get reference so we can keep this file in LUO until finish */
600 get_file(luo_file->file);
601
602 WARN_ON(xa_insert(&luo_preserved_files,
603 luo_get_id(luo_file->fh, luo_file->file),
604 luo_file->file, GFP_KERNEL));
605
606 *filep = luo_file->file;
607 luo_file->retrieve_status = 1;
608
609 return 0;
610}
611
612static int luo_file_can_finish_one(struct luo_file_set *file_set,
613 struct luo_file *luo_file)
614{
615 bool can_finish = true;
616
617 guard(mutex)(&luo_file->mutex);
618
619 if (luo_file->fh->ops->can_finish) {
620 struct liveupdate_file_op_args args = {0};
621
622 args.handler = luo_file->fh;
623 args.file = luo_file->file;
624 args.serialized_data = luo_file->serialized_data;
625 args.retrieve_status = luo_file->retrieve_status;
626 can_finish = luo_file->fh->ops->can_finish(&args);
627 }
628
629 return can_finish ? 0 : -EBUSY;
630}
631
632static void luo_file_finish_one(struct luo_file_set *file_set,
633 struct luo_file *luo_file)
634{
635 struct liveupdate_file_op_args args = {0};
636
637 guard(mutex)(&luo_file->mutex);
638
639 args.handler = luo_file->fh;
640 args.file = luo_file->file;
641 args.serialized_data = luo_file->serialized_data;
642 args.retrieve_status = luo_file->retrieve_status;
643
644 luo_file->fh->ops->finish(&args);
645 luo_flb_file_finish(luo_file->fh);
646}
647
648/**
649 * luo_file_finish - Completes the lifecycle for all files in a file_set.
650 * @file_set: The file_set to be finalized.
651 *
652 * This function orchestrates the final teardown of a live update file_set in
653 * the new kernel. It should be called after all necessary files have been
654 * retrieved and the userspace agent is ready to release the preserved state.
655 *
656 * The function iterates through all tracked files. For each file, it performs
657 * the following sequence of cleanup actions:
658 *
659 * 1. If file is not yet retrieved, retrieves it, and calls can_finish() on
660 * every file in the file_set. If all can_finish return true, continue to
661 * finish.
662 * 2. Calls the handler's .finish() callback (via luo_file_finish_one) to
663 * allow for final resource cleanup within the handler.
664 * 3. Releases LUO's ownership reference on the 'struct file' via fput(). This
665 * is the counterpart to the get_file() call in luo_retrieve_file().
666 * 4. Removes the 'struct luo_file' from the file_set's internal list.
667 * 5. Frees the memory for the 'struct luo_file' instance itself.
668 *
669 * After successfully finishing all individual files, it frees the
670 * contiguous memory block that was used to transfer the serialized metadata
671 * from the previous kernel.
672 *
673 * Error Handling (Atomic Failure):
674 * This operation is atomic. If any handler's .can_finish() op fails, the entire
675 * function aborts immediately and returns an error.
676 *
677 * Context: Can be called from an ioctl handler in the new kernel.
678 * Return: 0 on success, or a negative errno on failure.
679 */
680int luo_file_finish(struct luo_file_set *file_set)
681{
682 struct list_head *files_list = &file_set->files_list;
683 struct luo_file *luo_file;
684 int err;
685
686 if (!file_set->count)
687 return 0;
688
689 list_for_each_entry(luo_file, files_list, list) {
690 err = luo_file_can_finish_one(file_set, luo_file);
691 if (err)
692 return err;
693 }
694
695 while (!list_empty(&file_set->files_list)) {
696 luo_file = list_last_entry(&file_set->files_list,
697 struct luo_file, list);
698
699 luo_file_finish_one(file_set, luo_file);
700
701 if (luo_file->file) {
702 xa_erase(&luo_preserved_files,
703 luo_get_id(luo_file->fh, luo_file->file));
704 fput(luo_file->file);
705 }
706 module_put(luo_file->fh->ops->owner);
707 list_del(&luo_file->list);
708 file_set->count--;
709 kho_block_set_shrink(&file_set->block_set, file_set->count);
710 mutex_destroy(&luo_file->mutex);
711 kfree(luo_file);
712 }
713
714 kho_block_set_destroy(&file_set->block_set);
715
716 return 0;
717}
718
719static int luo_file_deserialize_one(struct luo_file_set *file_set,
720 struct luo_file_ser *ser)
721{
722 struct liveupdate_file_handler *fh;
723 bool handler_found = false;
724 struct luo_file *luo_file;
725
726 down_read(&luo_register_rwlock);
727 list_private_for_each_entry(fh, &luo_file_handler_list, list) {
728 if (!strcmp(fh->compatible, ser->compatible)) {
729 if (try_module_get(fh->ops->owner))
730 handler_found = true;
731 break;
732 }
733 }
734 up_read(&luo_register_rwlock);
735
736 if (!handler_found) {
737 pr_warn("No registered handler for compatible '%.*s'\n",
738 (int)sizeof(ser->compatible),
739 ser->compatible);
740 return -ENOENT;
741 }
742
743 luo_file = kzalloc_obj(*luo_file);
744 if (!luo_file) {
745 module_put(fh->ops->owner);
746 return -ENOMEM;
747 }
748
749 luo_file->fh = fh;
750 luo_file->file = NULL;
751 luo_file->serialized_data = ser->data;
752 luo_file->token = ser->token;
753 mutex_init(&luo_file->mutex);
754 list_add_tail(&luo_file->list, &file_set->files_list);
755
756 return 0;
757}
758
759/**
760 * luo_file_deserialize - Reconstructs the list of preserved files in the new kernel.
761 * @file_set: The incoming file_set to fill with deserialized data.
762 * @file_set_ser: Serialized KHO file_set data from the previous kernel.
763 *
764 * This function is called during the early boot process of the new kernel. It
765 * takes the raw, contiguous memory block of 'struct luo_file_ser' entries,
766 * provided by the previous kernel, and transforms it back into a live,
767 * in-memory linked list of 'struct luo_file' instances.
768 *
769 * For each serialized entry, it performs the following steps:
770 * 1. Reads the 'compatible' string.
771 * 2. Searches the global list of registered file handlers for one that
772 * matches the compatible string.
773 * 3. Allocates a new 'struct luo_file'.
774 * 4. Populates the new structure with the deserialized data (token, private
775 * data handle) and links it to the found handler. The 'file' pointer is
776 * initialized to NULL, as the file has not been retrieved yet.
777 * 5. Adds the new 'struct luo_file' to the file_set's files_list.
778 *
779 * This prepares the file_set for userspace, which can later call
780 * luo_retrieve_file() to restore the actual file descriptors.
781 *
782 * Context: Called from session deserialization.
783 */
784int luo_file_deserialize(struct luo_file_set *file_set,
785 struct luo_file_set_ser *file_set_ser)
786{
787 struct luo_file_ser *file_ser;
788 struct kho_block_set_it it;
789 int err;
790
791 if (!file_set_ser->files) {
792 WARN_ON(file_set_ser->count);
793 return 0;
794 }
795
796 file_set->count = 0;
797 err = kho_block_set_restore(&file_set->block_set, file_set_ser->files);
798 if (err)
799 return err;
800
801 /*
802 * Note on error handling:
803 *
804 * If deserialization fails (e.g., allocation failure or corrupt data),
805 * we intentionally skip cleanup of files that were already restored.
806 *
807 * A partial failure leaves the preserved state inconsistent.
808 * Implementing a safe "undo" to unwind complex dependencies (sessions,
809 * files, hardware state) is error-prone and provides little value, as
810 * the system is effectively in a broken state.
811 *
812 * We treat these resources as leaked. The expected recovery path is for
813 * userspace to detect the failure and trigger a reboot, which will
814 * reliably reset devices and reclaim memory.
815 */
816 kho_block_set_it_init(&it, &file_set->block_set);
817 while ((file_ser = kho_block_set_it_read_entry(&it))) {
818 err = luo_file_deserialize_one(file_set, file_ser);
819 if (err)
820 goto err_destroy_blocks;
821 file_set->count++;
822 }
823
824 if (file_set->count != file_set_ser->count) {
825 pr_warn("File count mismatch: expected %llu, found %llu\n",
826 file_set_ser->count, file_set->count);
827 err = -EINVAL;
828 goto err_destroy_blocks;
829 }
830
831 return 0;
832
833err_destroy_blocks:
834 while (!list_empty(&file_set->files_list)) {
835 struct luo_file *luo_file;
836
837 luo_file = list_first_entry(&file_set->files_list,
838 struct luo_file, list);
839 list_del(&luo_file->list);
840 module_put(luo_file->fh->ops->owner);
841 mutex_destroy(&luo_file->mutex);
842 kfree(luo_file);
843 }
844 file_set->count = 0;
845 kho_block_set_destroy(&file_set->block_set);
846 return err;
847}
848
849void luo_file_set_init(struct luo_file_set *file_set)
850{
851 INIT_LIST_HEAD(&file_set->files_list);
852 kho_block_set_init(&file_set->block_set, sizeof(struct luo_file_ser));
853}
854
855void luo_file_set_destroy(struct luo_file_set *file_set)
856{
857 WARN_ON(file_set->count);
858 WARN_ON(!list_empty(&file_set->files_list));
859 WARN_ON(!kho_block_set_is_empty(&file_set->block_set));
860}
861
862/**
863 * liveupdate_register_file_handler - Register a file handler with LUO.
864 * @fh: Pointer to a caller-allocated &struct liveupdate_file_handler.
865 * The caller must initialize this structure, including a unique
866 * 'compatible' string and a valid 'fh' callbacks. This function adds the
867 * handler to the global list of supported file handlers.
868 *
869 * Context: Typically called during module initialization for file types that
870 * support live update preservation.
871 *
872 * Return: 0 on success. Negative errno on failure.
873 */
874int liveupdate_register_file_handler(struct liveupdate_file_handler *fh)
875{
876 struct liveupdate_file_handler *fh_iter;
877 int err;
878
879 if (!liveupdate_enabled())
880 return -EOPNOTSUPP;
881
882 /* Sanity check that all required callbacks are set */
883 if (!fh->ops->preserve || !fh->ops->unpreserve || !fh->ops->retrieve ||
884 !fh->ops->finish || !fh->ops->can_preserve) {
885 return -EINVAL;
886 }
887
888 down_write(&luo_register_rwlock);
889 /* Check for duplicate compatible strings */
890 list_private_for_each_entry(fh_iter, &luo_file_handler_list, list) {
891 if (!strcmp(fh_iter->compatible, fh->compatible)) {
892 pr_err("File handler registration failed: Compatible string '%s' already registered.\n",
893 fh->compatible);
894 err = -EEXIST;
895 goto err_unlock;
896 }
897 }
898
899 INIT_LIST_HEAD(&ACCESS_PRIVATE(fh, flb_list));
900 INIT_LIST_HEAD(&ACCESS_PRIVATE(fh, list));
901 list_add_tail(&ACCESS_PRIVATE(fh, list), &luo_file_handler_list);
902 up_write(&luo_register_rwlock);
903
904 liveupdate_test_register(fh);
905
906 return 0;
907
908err_unlock:
909 up_write(&luo_register_rwlock);
910 return err;
911}
912
913/**
914 * liveupdate_unregister_file_handler - Unregister a liveupdate file handler
915 * @fh: The file handler to unregister
916 *
917 * Unregisters the file handler from the liveupdate core. This function
918 * reverses the operations of liveupdate_register_file_handler().
919 */
920void liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh)
921{
922 if (!liveupdate_enabled())
923 return;
924
925 guard(rwsem_write)(&luo_register_rwlock);
926 luo_flb_unregister_all(fh);
927 list_del(&ACCESS_PRIVATE(fh, list));
928}