From: Pasha Tatashin <pasha.tatashin@soleen.com>
To: linux-kselftest@vger.kernel.org, rppt@kernel.org,
shuah@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org,
skhan@linuxfoundation.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, corbet@lwn.net,
pasha.tatashin@soleen.com, dmatlack@google.com,
kexec@lists.infradead.org, pratyush@kernel.org,
skhawaja@google.com, graf@amazon.com, roman.gushchin@linux.dev
Subject: Re: [PATCH v4 04/13] liveupdate: register luo_ser as KHO subtree
Date: Sun, 31 May 2026 13:44:36 +0000 [thread overview]
Message-ID: <ahw6Bqllb0CJ88mR@plex> (raw)
In-Reply-To: <20260530221938.115978-5-pasha.tatashin@soleen.com>
On 05-30 22:19, Pasha Tatashin wrote:
> Entirely remove the LUO FDT wrapper since the FDT only carries the
> compatible string and the pointer to the centralized struct luo_ser.
> Instead, register the struct luo_ser via the KHO raw subtree
> API, placing the compatibility string inside the structure itself.
>
> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> ---
> include/linux/kho/abi/luo.h | 57 +++++++++---------------
> kernel/liveupdate/luo_core.c | 85 +++++++++++-------------------------
> 2 files changed, 46 insertions(+), 96 deletions(-)
>
> diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h
> index 1b2f865a771a..9a4fe491812b 100644
> --- a/include/linux/kho/abi/luo.h
> +++ b/include/linux/kho/abi/luo.h
> @@ -10,11 +10,11 @@
> *
> * Live Update Orchestrator uses the stable Application Binary Interface
> * defined below to pass state from a pre-update kernel to a post-update
> - * kernel. The ABI is built upon the Kexec HandOver framework and uses a
> - * Flattened Device Tree to describe the preserved data.
> + * kernel. The ABI is built upon the Kexec HandOver framework and registers
> + * the central `struct luo_ser` via the KHO raw subtree API.
> *
> - * This interface is a contract. Any modification to the FDT structure, node
> - * properties, compatible strings, or the layout of the `__packed` serialization
> + * This interface is a contract. Any modification to the structure fields,
> + * compatible strings, or the layout of the `__packed` serialization
> * structures defined here constitutes a breaking change. Such changes require
> * incrementing the version number in the relevant `_COMPATIBLE` string to
> * prevent a new kernel from misinterpreting data from an old kernel.
> @@ -23,31 +23,15 @@
> * however, backward/forward compatibility is only guaranteed for kernels
> * supporting the same ABI version.
> *
> - * FDT Structure Overview:
> + * KHO Structure Overview:
> * The entire LUO state is encapsulated within a single KHO entry named "LUO".
> - * This entry contains an FDT with the following layout:
> - *
> - * .. code-block:: none
> - *
> - * / {
> - * compatible = "luo-v2";
> - * luo-abi-header = <phys_addr_of_luo_ser>;
> - * };
> - *
> - * Main LUO Node (/):
> - *
> - * - compatible: "luo-v2"
> - * Identifies the overall LUO ABI version.
> - * - luo-abi-header: u64
> - * The physical address of `struct luo_ser`.
> + * This entry contains the `struct luo_ser` structure.
> *
> * Serialization Structures:
> - * The FDT properties point to memory regions containing arrays of simple,
> - * `__packed` structures. These structures contain the actual preserved state.
> - *
> * - struct luo_ser:
> * The central ABI structure that contains the overall state of the LUO.
> - * It includes the liveupdate-number and pointers to sessions and FLBs.
> + * It includes the compatibility string, the liveupdate-number, and pointers
> + * to sessions and FLBs.
> *
> * - struct luo_session_header_ser:
> * Header for the session array. Contains the total page count of the
> @@ -78,26 +62,27 @@
> #ifndef _LINUX_KHO_ABI_LUO_H
> #define _LINUX_KHO_ABI_LUO_H
>
> +#include <linux/align.h>
> #include <uapi/linux/liveupdate.h>
>
> /*
> - * The LUO FDT hooks all LUO state for sessions, fds, etc.
> + * The LUO state is registered under this KHO entry name.
> */
> -#define LUO_FDT_SIZE PAGE_SIZE
> -#define LUO_FDT_KHO_ENTRY_NAME "LUO"
> -#define LUO_FDT_COMPATIBLE "luo-v2"
> -#define LUO_FDT_ABI_HEADER "luo-abi-header"
> +#define LUO_KHO_ENTRY_NAME "LUO"
> +#define LUO_ABI_COMPATIBLE "luo-v3"
> +#define LUO_ABI_COMPAT_LEN ALIGN(sizeof(LUO_ABI_COMPATIBLE), 8)
>
> /**
> * struct luo_ser - Centralized LUO ABI header.
> + * @compatible: Compatibility string identifying the LUO ABI version.
> * @liveupdate_num: A counter tracking the number of successful live updates.
> * @sessions_pa: Physical address of the first session block header.
> * @flbs_pa: Physical address of the FLB header.
> *
> - * This structure is the root of all preserved LUO state. It is pointed to by
> - * the "luo-abi-header" property in the LUO FDT.
> + * This structure is the root of all preserved LUO state.
> */
> struct luo_ser {
> + char compatible[LUO_ABI_COMPAT_LEN];
> u64 liveupdate_num;
> u64 sessions_pa;
> u64 flbs_pa;
> @@ -111,7 +96,7 @@ struct luo_ser {
> * @data: Private data
> * @token: User provided token for this file
> *
> - * If this structure is modified, LUO_SESSION_COMPATIBLE must be updated.
> + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated.
> */
> struct luo_file_ser {
> char compatible[LIVEUPDATE_HNDL_COMPAT_LENGTH];
> @@ -142,7 +127,7 @@ struct luo_file_set_ser {
> * physical memory preserved across the kexec. It provides the necessary
> * metadata to interpret the array of session entries that follow.
> *
> - * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated.
> + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated.
> */
> struct luo_session_header_ser {
> u64 count;
> @@ -159,7 +144,7 @@ struct luo_session_header_ser {
> * session) is created and passed to the new kernel, allowing it to reconstruct
> * the session context.
> *
> - * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated.
> + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated.
> */
> struct luo_session_ser {
> char name[LIVEUPDATE_SESSION_NAME_LENGTH];
> @@ -180,7 +165,7 @@ struct luo_session_ser {
> * This structure is located at the physical address specified by the
> * flbs_pa in luo_ser.
> *
> - * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated.
> + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated.
> */
> struct luo_flb_header_ser {
> u64 pgcnt;
> @@ -202,7 +187,7 @@ struct luo_flb_header_ser {
> * passed to the new kernel. Each entry allows the LUO core to restore one
> * global, shared object.
> *
> - * If this structure is modified, `LUO_FDT_COMPATIBLE` must be updated.
> + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated.
> */
> struct luo_flb_ser {
> char name[LIVEUPDATE_FLB_COMPAT_LENGTH];
> diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c
> index fbc18c5f4230..e261a03a1b47 100644
> --- a/kernel/liveupdate/luo_core.c
> +++ b/kernel/liveupdate/luo_core.c
> @@ -50,7 +50,6 @@
> #include <linux/kexec_handover.h>
> #include <linux/kho/abi/luo.h>
> #include <linux/kobject.h>
> -#include <linux/libfdt.h>
> #include <linux/liveupdate.h>
> #include <linux/miscdevice.h>
> #include <linux/mm.h>
> @@ -63,8 +62,7 @@
>
> static struct {
> bool enabled;
> - void *fdt_out;
> - void *fdt_in;
> + struct luo_ser *luo_ser_out;
> u64 liveupdate_num;
> } luo_global;
>
> @@ -81,11 +79,10 @@ early_param("liveupdate", early_liveupdate_param);
>
> static int __init luo_early_startup(void)
> {
> + phys_addr_t luo_ser_phys;
> struct luo_ser *luo_ser;
> - int err, header_size;
> - phys_addr_t fdt_phys;
> - const void *ptr;
> - u64 luo_ser_pa;
> + size_t len;
> + int err;
>
> if (!kho_is_enabled()) {
> if (liveupdate_enabled())
> @@ -94,40 +91,29 @@ static int __init luo_early_startup(void)
> return 0;
> }
>
> - /* Retrieve LUO subtree, and verify its format. */
> - err = kho_retrieve_subtree(LUO_FDT_KHO_ENTRY_NAME, &fdt_phys, NULL);
> + /* Retrieve LUO state from KHO. */
> + err = kho_retrieve_subtree(LUO_KHO_ENTRY_NAME, &luo_ser_phys, &len);
> if (err) {
> if (err != -ENOENT) {
> - pr_err("failed to retrieve FDT '%s' from KHO: %pe\n",
> - LUO_FDT_KHO_ENTRY_NAME, ERR_PTR(err));
> + pr_err("failed to retrieve LUO state '%s' from KHO: %pe\n",
> + LUO_KHO_ENTRY_NAME, ERR_PTR(err));
> return err;
> }
>
> return 0;
> }
>
> - luo_global.fdt_in = phys_to_virt(fdt_phys);
> - err = fdt_node_check_compatible(luo_global.fdt_in, 0,
> - LUO_FDT_COMPATIBLE);
> - if (err) {
> - pr_err("FDT '%s' is incompatible with '%s' [%d]\n",
> - LUO_FDT_KHO_ENTRY_NAME, LUO_FDT_COMPATIBLE, err);
> -
> + if (len < sizeof(*luo_ser)) {
> + pr_err("LUO state is too small (%zu < %zu)\n", len, sizeof(*luo_ser));
> return -EINVAL;
> }
>
> - header_size = 0;
> - ptr = fdt_getprop(luo_global.fdt_in, 0, LUO_FDT_ABI_HEADER, &header_size);
> - if (!ptr || header_size != sizeof(u64)) {
> - pr_err("Unable to get ABI header '%s' [%d]\n",
> - LUO_FDT_ABI_HEADER, header_size);
> -
> + luo_ser = phys_to_virt(luo_ser_phys);
> + if (strncmp(luo_ser->compatible, LUO_ABI_COMPATIBLE, LUO_ABI_COMPAT_LEN)) {
> + pr_err("LUO state is incompatible with '%s'\n", LUO_ABI_COMPATIBLE);
> return -EINVAL;
> }
From Sashiko:
Does this code leak the preserved luo_ser_phys memory on these early validation
failure paths?
Answer: No, a failure in this function leads to a call to
luo_restore_fail(), which triggers a panic.
Roman: The quality of the Sashiko review is surprisingly weak this time;
was the model switched from 3.1 Pro to something else?
>
> - luo_ser_pa = get_unaligned((u64 *)ptr);
> - luo_ser = phys_to_virt(luo_ser_pa);
> -
> luo_global.liveupdate_num = luo_ser->liveupdate_num;
> pr_info("Retrieved live update data, liveupdate number: %lld\n",
> luo_global.liveupdate_num);
> @@ -160,37 +146,20 @@ static int __init liveupdate_early_init(void)
> }
> early_initcall(liveupdate_early_init);
>
> -/* Called during boot to create outgoing LUO fdt tree */
> -static int __init luo_fdt_setup(void)
> +/* Called during boot to create outgoing LUO state */
> +static int __init luo_state_setup(void)
> {
> struct luo_ser *luo_ser;
> - u64 luo_ser_pa;
> - void *fdt_out;
> int err;
>
> - fdt_out = kho_alloc_preserve(LUO_FDT_SIZE);
> - if (IS_ERR(fdt_out)) {
> - pr_err("failed to allocate/preserve FDT memory\n");
> - return PTR_ERR(fdt_out);
> - }
> -
> luo_ser = kho_alloc_preserve(sizeof(*luo_ser));
> if (IS_ERR(luo_ser)) {
> - err = PTR_ERR(luo_ser);
> - goto exit_free_fdt;
> + pr_err("failed to allocate/preserve LUO state memory\n");
> + return PTR_ERR(luo_ser);
> }
> - luo_ser_pa = virt_to_phys(luo_ser);
> -
> - err = fdt_create(fdt_out, LUO_FDT_SIZE);
> - err |= fdt_finish_reservemap(fdt_out);
> - err |= fdt_begin_node(fdt_out, "");
> - err |= fdt_property_string(fdt_out, "compatible", LUO_FDT_COMPATIBLE);
> - err |= fdt_property(fdt_out, LUO_FDT_ABI_HEADER, &luo_ser_pa,
> - sizeof(luo_ser_pa));
> - err |= fdt_end_node(fdt_out);
> - err |= fdt_finish(fdt_out);
> - if (err)
> - goto exit_free_luo_ser;
> +
> + strscpy(luo_ser->compatible, LUO_ABI_COMPATIBLE, sizeof(luo_ser->compatible));
> + luo_ser->liveupdate_num = luo_global.liveupdate_num + 1;
>
> err = luo_session_setup_outgoing(&luo_ser->sessions_pa);
> if (err)
> @@ -200,21 +169,17 @@ static int __init luo_fdt_setup(void)
> if (err)
> goto exit_free_luo_ser;
>
> - luo_ser->liveupdate_num = luo_global.liveupdate_num + 1;
> -
> - err = kho_add_subtree(LUO_FDT_KHO_ENTRY_NAME, fdt_out,
> - fdt_totalsize(fdt_out));
> + err = kho_add_subtree(LUO_KHO_ENTRY_NAME, luo_ser, sizeof(*luo_ser));
> if (err)
> goto exit_free_luo_ser;
> - luo_global.fdt_out = fdt_out;
> +
> + luo_global.luo_ser_out = luo_ser;
>
> return 0;
>
> exit_free_luo_ser:
> kho_unpreserve_free(luo_ser);
> -exit_free_fdt:
> - kho_unpreserve_free(fdt_out);
> - pr_err("failed to prepare LUO FDT: %d\n", err);
> + pr_err("failed to prepare LUO state: %d\n", err);
>
> return err;
> }
> @@ -230,7 +195,7 @@ static int __init luo_late_startup(void)
> if (!liveupdate_enabled())
> return 0;
>
> - err = luo_fdt_setup();
> + err = luo_state_setup();
> if (err)
> luo_global.enabled = false;
>
> --
> 2.53.0
>
next prev parent reply other threads:[~2026-05-31 13:44 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-30 22:19 [PATCH v4 00/13] liveupdate: Remove limits on sessions and files Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 01/13] liveupdate: change file_set->count type to u64 for type safety Pasha Tatashin
2026-05-31 13:35 ` Pasha Tatashin
2026-06-01 12:08 ` Pratyush Yadav
2026-06-02 8:13 ` Mike Rapoport
2026-05-30 22:19 ` [PATCH v4 02/13] liveupdate: avoid mixing cleanup guards with goto in luo_session_retrieve_fd Pasha Tatashin
2026-05-31 12:52 ` Pasha Tatashin
2026-06-01 12:15 ` Pratyush Yadav
2026-06-02 8:13 ` Mike Rapoport
2026-06-03 3:10 ` Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 03/13] liveupdate: centralize state management into struct luo_ser Pasha Tatashin
2026-06-01 12:19 ` Pratyush Yadav
2026-06-02 8:13 ` Mike Rapoport
2026-06-03 2:57 ` Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 04/13] liveupdate: register luo_ser as KHO subtree Pasha Tatashin
2026-05-31 13:44 ` Pasha Tatashin [this message]
2026-06-01 12:39 ` Pratyush Yadav
2026-06-01 13:50 ` Pasha Tatashin
2026-06-01 14:27 ` Pratyush Yadav
2026-05-30 22:19 ` [PATCH v4 05/13] liveupdate: Extract luo_file_deserialize_one helper Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 06/13] liveupdate: Extract luo_session_deserialize_one helper Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 07/13] kho: add support for linked-block serialization Pasha Tatashin
2026-06-01 13:38 ` Pratyush Yadav
2026-06-01 14:37 ` Pasha Tatashin
2026-06-02 16:43 ` Pratyush Yadav
2026-06-03 2:44 ` Pasha Tatashin
2026-06-02 8:13 ` Mike Rapoport
2026-06-02 9:04 ` Mike Rapoport
2026-06-03 2:21 ` Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 08/13] liveupdate: defer session block allocation and PA setting Pasha Tatashin
2026-06-01 13:47 ` Pratyush Yadav
2026-06-02 8:13 ` Mike Rapoport
2026-06-03 2:50 ` Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 09/13] liveupdate: Remove limit on the number of sessions Pasha Tatashin
2026-06-01 14:03 ` Pratyush Yadav
2026-06-01 14:44 ` Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 10/13] liveupdate: Remove limit on the number of files per session Pasha Tatashin
2026-06-01 14:16 ` Pratyush Yadav
2026-06-01 14:40 ` Pasha Tatashin
2026-05-30 22:19 ` [PATCH v4 11/13] selftests/liveupdate: Test session and file limit removal Pasha Tatashin
2026-06-01 14:17 ` Pratyush Yadav
2026-05-30 22:19 ` [PATCH v4 12/13] selftests/liveupdate: Add stress-sessions kexec test Pasha Tatashin
2026-06-01 14:19 ` Pratyush Yadav
2026-05-30 22:19 ` [PATCH v4 13/13] selftests/liveupdate: Add stress-files " Pasha Tatashin
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=ahw6Bqllb0CJ88mR@plex \
--to=pasha.tatashin@soleen.com \
--cc=akpm@linux-foundation.org \
--cc=corbet@lwn.net \
--cc=dmatlack@google.com \
--cc=graf@amazon.com \
--cc=kexec@lists.infradead.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=pratyush@kernel.org \
--cc=roman.gushchin@linux.dev \
--cc=rppt@kernel.org \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=skhawaja@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.