From: tarunsahu@google.com
To: Jonathan Corbet <corbet@lwn.net>,
vannapurve@google.com, fvdl@google.com,
Pasha Tatashin <pasha.tatashin@soleen.com>,
Shuah Khan <skhan@linuxfoundation.org>,
sagis@google.com, aneesh.kumar@kernel.org, skhawaja@google.com,
vipinsh@google.com, ackerleytng@google.com,
Pratyush Yadav <pratyush@kernel.org>,
david@redhat.com, dmatlack@google.com, mark.rutland@arm.com,
Paolo Bonzini <pbonzini@redhat.com>,
Mike Rapoport <rppt@kernel.org>, Alexander Graf <graf@amazon.com>,
seanjc@google.com, axelrasmussen@google.com
Cc: linux-kselftest@vger.kernel.org, kexec@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
kvm@vger.kernel.org, linux-mm@kvack.org
Subject: Re: [RFC PATCH v2 01/10] liveupdate: luo_file: Add internal APIs for file preservation
Date: Sun, 07 Jun 2026 00:35:35 +0000 [thread overview]
Message-ID: <9huzik7vxk4o.fsf@tarunix.c.googlers.com> (raw)
In-Reply-To: <c054ba0fb2639932bbe354420d3f4f84cce84905.1780676742.git.tarunsahu@google.com>
Hi,
I am sorry for incorrect layout of this series. After copy-pasting
I forgot to change the message id in header and the cover letter is not
attached to the same thread.
Please find the V2 cover letter here:
https://lore.kernel.org/all/cover.1780667929.git.tarunsahu@google.com/
Also for latest discussion related to scope:
https://lore.kernel.org/all/9huzldcrxkch.fsf@tarunix.c.googlers.com/
Thankyou
Tarun Sahu <tarunsahu@google.com> writes:
> From: Pasha Tatashin <pasha.tatashin@soleen.com>
>
> The core liveupdate mechanism allows userspace to preserve file
> descriptors. However, kernel subsystems often manage struct file
> objects directly and need to participate in the preservation process
> programmatically without relying solely on userspace interaction.
>
> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
> Signed-off-by: Tarun Sahu <tarunsahu@google.com>
> ---
> include/linux/liveupdate.h | 21 ++++++++++
> kernel/liveupdate/luo_file.c | 69 ++++++++++++++++++++++++++++++++
> kernel/liveupdate/luo_internal.h | 17 ++++++++
> 3 files changed, 107 insertions(+)
>
> diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h
> index 30c5a39ff9e9..de052438eaac 100644
> --- a/include/linux/liveupdate.h
> +++ b/include/linux/liveupdate.h
> @@ -24,6 +24,7 @@ struct file;
> /**
> * struct liveupdate_file_op_args - Arguments for file operation callbacks.
> * @handler: The file handler being called.
> + * @session: The session this file belongs to.
> * @retrieve_status: The retrieve status for the 'can_finish / finish'
> * operation. A value of 0 means the retrieve has not been
> * attempted, a positive value means the retrieve was
> @@ -44,6 +45,7 @@ struct file;
> */
> struct liveupdate_file_op_args {
> struct liveupdate_file_handler *handler;
> + struct liveupdate_session *session;
> int retrieve_status;
> struct file *file;
> u64 serialized_data;
> @@ -240,6 +242,13 @@ void liveupdate_unregister_flb(struct liveupdate_file_handler *fh,
>
> int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, void **objp);
> int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, void **objp);
> +/* kernel can internally retrieve files */
> +int liveupdate_get_file_incoming(struct liveupdate_session *s, u64 token,
> + struct file **filep);
> +
> +/* Get a token for an outgoing file, or -ENOENT if file is not preserved */
> +int liveupdate_get_token_outgoing(struct liveupdate_session *s,
> + struct file *file, u64 *tokenp);
>
> #else /* CONFIG_LIVEUPDATE */
>
> @@ -285,5 +294,17 @@ static inline int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb,
> return -EOPNOTSUPP;
> }
>
> +static inline int liveupdate_get_file_incoming(struct liveupdate_session *s,
> + u64 token, struct file **filep)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> +static inline int liveupdate_get_token_outgoing(struct liveupdate_session *s,
> + struct file *file, u64 *tokenp)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> #endif /* CONFIG_LIVEUPDATE */
> #endif /* _LINUX_LIVEUPDATE_H */
> diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c
> index a0a419085e28..0aa0b4e5339f 100644
> --- a/kernel/liveupdate/luo_file.c
> +++ b/kernel/liveupdate/luo_file.c
> @@ -323,6 +323,7 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd)
> mutex_init(&luo_file->mutex);
>
> args.handler = fh;
> + args.session = luo_session_from_file_set(file_set);
> args.file = file;
> err = fh->ops->preserve(&args);
> if (err)
> @@ -380,6 +381,7 @@ void luo_file_unpreserve_files(struct luo_file_set *file_set)
> struct luo_file, list);
>
> args.handler = luo_file->fh;
> + args.session = luo_session_from_file_set(file_set);
> args.file = luo_file->file;
> args.serialized_data = luo_file->serialized_data;
> args.private_data = luo_file->private_data;
> @@ -411,6 +413,7 @@ static int luo_file_freeze_one(struct luo_file_set *file_set,
> struct liveupdate_file_op_args args = {0};
>
> args.handler = luo_file->fh;
> + args.session = luo_session_from_file_set(file_set);
> args.file = luo_file->file;
> args.serialized_data = luo_file->serialized_data;
> args.private_data = luo_file->private_data;
> @@ -432,6 +435,7 @@ static void luo_file_unfreeze_one(struct luo_file_set *file_set,
> struct liveupdate_file_op_args args = {0};
>
> args.handler = luo_file->fh;
> + args.session = luo_session_from_file_set(file_set);
> args.file = luo_file->file;
> args.serialized_data = luo_file->serialized_data;
> args.private_data = luo_file->private_data;
> @@ -621,6 +625,7 @@ int luo_retrieve_file(struct luo_file_set *file_set, u64 token,
> }
>
> args.handler = luo_file->fh;
> + args.session = luo_session_from_file_set(file_set);
> args.serialized_data = luo_file->serialized_data;
> err = luo_file->fh->ops->retrieve(&args);
> if (err) {
> @@ -654,6 +659,7 @@ static int luo_file_can_finish_one(struct luo_file_set *file_set,
> struct liveupdate_file_op_args args = {0};
>
> args.handler = luo_file->fh;
> + args.session = luo_session_from_file_set(file_set);
> args.file = luo_file->file;
> args.serialized_data = luo_file->serialized_data;
> args.retrieve_status = luo_file->retrieve_status;
> @@ -671,6 +677,7 @@ static void luo_file_finish_one(struct luo_file_set *file_set,
> guard(mutex)(&luo_file->mutex);
>
> args.handler = luo_file->fh;
> + args.session = luo_session_from_file_set(file_set);
> args.file = luo_file->file;
> args.serialized_data = luo_file->serialized_data;
> args.retrieve_status = luo_file->retrieve_status;
> @@ -924,3 +931,65 @@ void liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh)
> luo_flb_unregister_all(fh);
> list_del(&ACCESS_PRIVATE(fh, list));
> }
> +EXPORT_SYMBOL_GPL(liveupdate_unregister_file_handler);
> +
> +/**
> + * liveupdate_get_token_outgoing - Get the token for a preserved file.
> + * @s: The outgoing liveupdate session.
> + * @file: The file object to search for.
> + * @tokenp: Output parameter for the found token.
> + *
> + * Searches the list of preserved files in an outgoing session for a matching
> + * file object. If found, the corresponding user-provided token is returned.
> + *
> + * This function is intended for in-kernel callers that need to correlate a
> + * file with its liveupdate token.
> + *
> + * Context: It must be called with session mutex acquired.
> + * Return: 0 on success, -ENOENT if the file is not preserved in this session.
> + */
> +int liveupdate_get_token_outgoing(struct liveupdate_session *s,
> + struct file *file, u64 *tokenp)
> +{
> + struct luo_file_set *file_set = luo_file_set_from_session_locked(s);
> + struct luo_file *luo_file;
> + int err = -ENOENT;
> +
> + list_for_each_entry(luo_file, &file_set->files_list, list) {
> + if (luo_file->file == file) {
> + if (tokenp)
> + *tokenp = luo_file->token;
> + err = 0;
> + break;
> + }
> + }
> +
> + return err;
> +}
> +
> +/**
> + * liveupdate_get_file_incoming - Retrieves a preserved file for in-kernel use.
> + * @s: The incoming liveupdate session (restored from the previous kernel).
> + * @token: The unique token identifying the file to retrieve.
> + * @filep: On success, this will be populated with a pointer to the retrieved
> + * 'struct file'.
> + *
> + * Provides a kernel-internal API for other subsystems to retrieve their
> + * preserved files after a live update. This function is a simple wrapper
> + * around luo_retrieve_file(), allowing callers to find a file by its token.
> + *
> + * The caller receives a new reference to the file and must call fput() when it
> + * is no longer needed. The file's lifetime is managed by LUO and any userspace
> + * file descriptors. If the caller needs to hold a reference to the file beyond
> + * the immediate scope, it must call get_file() itself.
> + *
> + * Context: It must be called with session mutex acquired of a restored session.
> + * Return: 0 on success. Returns -ENOENT if no file with the matching token is
> + * found, or any other negative errno on failure.
> + */
> +int liveupdate_get_file_incoming(struct liveupdate_session *s, u64 token,
> + struct file **filep)
> +{
> + return luo_retrieve_file(luo_file_set_from_session_locked(s),
> + token, filep);
> +}
> diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_internal.h
> index 875844d7a41d..08b198802e7f 100644
> --- a/kernel/liveupdate/luo_internal.h
> +++ b/kernel/liveupdate/luo_internal.h
> @@ -79,6 +79,23 @@ struct luo_session {
>
> extern struct rw_semaphore luo_register_rwlock;
>
> +static inline struct liveupdate_session *luo_session_from_file_set(struct luo_file_set *file_set)
> +{
> + struct luo_session *session;
> +
> + session = container_of(file_set, struct luo_session, file_set);
> +
> + return (struct liveupdate_session *)session;
> +}
> +
> +static inline struct luo_file_set *luo_file_set_from_session_locked(struct liveupdate_session *s)
> +{
> + struct luo_session *session = (struct luo_session *)s;
> +
> + lockdep_assert_held(&session->mutex);
> + return &session->file_set;
> +}
> +
> int luo_session_create(const char *name, struct file **filep);
> int luo_session_retrieve(const char *name, struct file **filep);
> int __init luo_session_setup_outgoing(void *fdt);
> --
> 2.54.0.1032.g2f8565e1d1-goog
next prev parent reply other threads:[~2026-06-07 0:35 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1780676742.git.tarunsahu@google.com>
2026-06-05 17:08 ` Tarun Sahu
2026-06-07 0:35 ` tarunsahu [this message]
2026-06-05 17:08 ` [RFC PATCH v2 02/10] liveupdate: Add LIVEUPDATE_GUEST_MEMFD config option Tarun Sahu
2026-06-05 17:08 ` [RFC PATCH v2 03/10] kvm: Prepare core VM structs and helpers for LUO support Tarun Sahu
2026-06-22 23:59 ` Ackerley Tng
2026-06-23 12:48 ` tarunsahu
2026-06-23 15:33 ` tarunsahu
2026-06-05 17:08 ` [RFC PATCH v2 04/10] kvm: kvm_luo: Allow kvm preservation with LUO Tarun Sahu
2026-06-05 17:08 ` [RFC PATCH v2 05/10] kvm: guest_memfd: Move internal definitions and helper to new header Tarun Sahu
2026-06-05 17:08 ` [RFC PATCH v2 06/10] kvm: guest_memfd: Add support for freezing and unfreezing mappings Tarun Sahu
2026-06-22 23:54 ` Ackerley Tng
2026-06-23 0:09 ` Sean Christopherson
2026-06-23 14:03 ` tarunsahu
2026-06-23 14:02 ` tarunsahu
2026-06-23 14:36 ` tarunsahu
2026-06-23 16:14 ` Pratyush Yadav
2026-06-23 20:06 ` tarunsahu
2026-06-24 9:00 ` Pratyush Yadav
2026-06-05 17:08 ` [RFC PATCH v2 07/10] kvm: guest_memfd_luo: add support for guest_memfd preservation Tarun Sahu
2026-06-22 23:27 ` Ackerley Tng
2026-06-23 15:26 ` tarunsahu
2026-06-05 17:08 ` [RFC PATCH v2 08/10] docs: add documentation for guest_memfd preservation via LUO Tarun Sahu
2026-06-05 17:08 ` [RFC PATCH v2 09/10] selftests: kvm: Split ____vm_create() to expose init helpers Tarun Sahu
2026-06-05 17:08 ` [RFC PATCH v2 10/10] selftests: kvm: Add guest_memfd_preservation_test Tarun Sahu
2026-06-22 23:01 ` Ackerley Tng
2026-06-23 19:50 ` tarunsahu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9huzik7vxk4o.fsf@tarunix.c.googlers.com \
--to=tarunsahu@google.com \
--cc=ackerleytng@google.com \
--cc=aneesh.kumar@kernel.org \
--cc=axelrasmussen@google.com \
--cc=corbet@lwn.net \
--cc=david@redhat.com \
--cc=dmatlack@google.com \
--cc=fvdl@google.com \
--cc=graf@amazon.com \
--cc=kexec@lists.infradead.org \
--cc=kvm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mark.rutland@arm.com \
--cc=pasha.tatashin@soleen.com \
--cc=pbonzini@redhat.com \
--cc=pratyush@kernel.org \
--cc=rppt@kernel.org \
--cc=sagis@google.com \
--cc=seanjc@google.com \
--cc=skhan@linuxfoundation.org \
--cc=skhawaja@google.com \
--cc=vannapurve@google.com \
--cc=vipinsh@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox