[PATCH v3 0/2] liveupdate: prevent double preservation

Pasha Tatashin posted 2 patches 1 week, 1 day ago
There is a newer version of this series
kernel/liveupdate/luo_file.c                  | 26 ++++++++++--
.../testing/selftests/liveupdate/liveupdate.c | 41 +++++++++++++++++++
2 files changed, 64 insertions(+), 3 deletions(-)
[PATCH v3 0/2] liveupdate: prevent double preservation
Posted by Pasha Tatashin 1 week, 1 day ago
Currently, LUO does not prevent the same file from being preserved twice
across different active sessions.

Because LUO preserves files of absolutely different types: memfd, and
upcoming vfiofd [1], iommufd [2], guestmefd (and possible kvmfd/cpufd).
There is no common private data or guarantee on how to prevent that the
same file is not preserved twice beside using inode or some slower and
expensive method like hashtables.

[1] https://lore.kernel.org/all/20260129212510.967611-1-dmatlack@google.com
[2] https://lore.kernel.org/all/20260203220948.2176157-1-skhawaja@google.com

Changelog:
v3:
 - Renamed luo_preserved_files_xa to luo_preserved_files (Mike)
 - Added xa inserts during restoration, so a file that is not yet finished is
   not preserved at the same time. (Sashiko)
v2:
 - Because inodes of preserved files can be shared, we cannot rely on a
   flag in the inode. Therefore, use an xarray to prevent preserving
   duplicated files.

Pasha Tatashin (2):
  liveupdate: prevent double management of files
  selftests: liveupdate: add test for double preservation

 kernel/liveupdate/luo_file.c                  | 26 ++++++++++--
 .../testing/selftests/liveupdate/liveupdate.c | 41 +++++++++++++++++++
 2 files changed, 64 insertions(+), 3 deletions(-)


base-commit: 785f0eb2f85decbe7c1ef9ae922931f0194ffc2e
-- 
2.43.0
Re: [PATCH v3 0/2] liveupdate: prevent double preservation
Posted by Andrew Morton 1 week ago
On Wed, 25 Mar 2026 18:20:24 +0000 Pasha Tatashin <pasha.tatashin@soleen.com> wrote:

> Currently, LUO does not prevent the same file from being preserved twice
> across different active sessions.
> 
> Because LUO preserves files of absolutely different types: memfd, and
> upcoming vfiofd [1], iommufd [2], guestmefd (and possible kvmfd/cpufd).
> There is no common private data or guarantee on how to prevent that the
> same file is not preserved twice beside using inode or some slower and
> expensive method like hashtables.
> 

I updated mm.git's mm-new branch to this version.

> Changelog:
> v3:
>  - Renamed luo_preserved_files_xa to luo_preserved_files (Mike)
>  - Added xa inserts during restoration, so a file that is not yet finished is
>    not preserved at the same time. (Sashiko)

Below is how v3 altered mm.git.

It appears that some significant changes are in the works.  Please lmk
if there's actually value in keeping v3 under test, or should I just
drop it?



 kernel/liveupdate/luo_file.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

--- a/kernel/liveupdate/luo_file.c~b
+++ a/kernel/liveupdate/luo_file.c
@@ -117,7 +117,7 @@ static DECLARE_RWSEM(luo_file_handler_lo
 static LIST_HEAD(luo_file_handler_list);
 
 /* Keep track of files being preserved by LUO */
-static DEFINE_XARRAY(luo_preserved_files_xa);
+static DEFINE_XARRAY(luo_preserved_files);
 
 /* 2 4K pages, give space for 128 files per file_set */
 #define LUO_FILE_PGCNT		2ul
@@ -282,7 +282,7 @@ int luo_preserve_file(struct luo_file_se
 	if (err)
 		goto  err_fput;
 
-	err = xa_insert(&luo_preserved_files_xa, (unsigned long)file,
+	err = xa_insert(&luo_preserved_files, (unsigned long)file,
 			file, GFP_KERNEL);
 	if (err)
 		goto err_free_files_mem;
@@ -334,7 +334,7 @@ err_kfree:
 err_flb_unpreserve:
 	luo_flb_file_unpreserve(fh);
 err_erase_xa:
-	xa_erase(&luo_preserved_files_xa, (unsigned long)file);
+	xa_erase(&luo_preserved_files, (unsigned long)file);
 err_free_files_mem:
 	luo_free_files_mem(file_set);
 err_fput:
@@ -378,7 +378,7 @@ void luo_file_unpreserve_files(struct lu
 		luo_file->fh->ops->unpreserve(&args);
 		luo_flb_file_unpreserve(luo_file->fh);
 
-		xa_erase(&luo_preserved_files_xa, (unsigned long)luo_file->file);
+		xa_erase(&luo_preserved_files, (unsigned long)luo_file->file);
 		list_del(&luo_file->list);
 		file_set->count--;
 
@@ -622,6 +622,10 @@ int luo_retrieve_file(struct luo_file_se
 	luo_file->file = args.file;
 	/* Get reference so we can keep this file in LUO until finish */
 	get_file(luo_file->file);
+
+	WARN_ON(xa_insert(&luo_preserved_files, (unsigned long)luo_file->file,
+			  luo_file->file, GFP_KERNEL));
+
 	*filep = luo_file->file;
 	luo_file->retrieve_status = 1;
 
@@ -717,8 +721,11 @@ int luo_file_finish(struct luo_file_set
 
 		luo_file_finish_one(file_set, luo_file);
 
-		if (luo_file->file)
+		if (luo_file->file) {
+			xa_erase(&luo_preserved_files,
+				 (unsigned long)luo_file->file);
 			fput(luo_file->file);
+		}
 		list_del(&luo_file->list);
 		file_set->count--;
 		mutex_destroy(&luo_file->mutex);
_