[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250515182322.117840-8-pasha.tatashin@soleen.com>
Date: Thu, 15 May 2025 18:23:11 +0000
From: Pasha Tatashin <pasha.tatashin@...een.com>
To: pratyush@...nel.org,
jasonmiu@...gle.com,
graf@...zon.com,
changyuanl@...gle.com,
pasha.tatashin@...een.com,
rppt@...nel.org,
dmatlack@...gle.com,
rientjes@...gle.com,
corbet@....net,
rdunlap@...radead.org,
ilpo.jarvinen@...ux.intel.com,
kanie@...ux.alibaba.com,
ojeda@...nel.org,
aliceryhl@...gle.com,
masahiroy@...nel.org,
akpm@...ux-foundation.org,
tj@...nel.org,
yoann.congal@...le.fr,
mmaurer@...gle.com,
roman.gushchin@...ux.dev,
chenridong@...wei.com,
axboe@...nel.dk,
mark.rutland@....com,
jannh@...gle.com,
vincent.guittot@...aro.org,
hannes@...xchg.org,
dan.j.williams@...el.com,
david@...hat.com,
joel.granados@...nel.org,
rostedt@...dmis.org,
anna.schumaker@...cle.com,
song@...nel.org,
zhangguopeng@...inos.cn,
linux@...ssschuh.net,
linux-kernel@...r.kernel.org,
linux-doc@...r.kernel.org,
linux-mm@...ck.org,
gregkh@...uxfoundation.org,
tglx@...utronix.de,
mingo@...hat.com,
bp@...en8.de,
dave.hansen@...ux.intel.com,
x86@...nel.org,
hpa@...or.com,
rafael@...nel.org,
dakr@...nel.org,
bartosz.golaszewski@...aro.org,
cw00.choi@...sung.com,
myungjoo.ham@...sung.com,
yesanishhere@...il.com,
Jonathan.Cameron@...wei.com,
quic_zijuhu@...cinc.com,
aleksander.lobakin@...el.com,
ira.weiny@...el.com,
andriy.shevchenko@...ux.intel.com,
leon@...nel.org,
lukas@...ner.de,
bhelgaas@...gle.com,
wagi@...nel.org,
djeffery@...hat.com,
stuart.w.hayes@...il.com,
ptyadav@...zon.de
Subject: [RFC v2 07/16] luo: luo_subsystems: implement subsystem callbacks
Implement the core logic within luo_subsystems.c to handle the
invocation of registered subsystem callbacks and manage the persistence
of their state via the LUO FDT. This replaces the stub implementations
from the previous patch.
This completes the core mechanism enabling subsystems to actively
participate in the LUO state machine, execute phase-specific logic, and
persist/restore a u64 state across the live update transition
using the FDT.
Signed-off-by: Pasha Tatashin <pasha.tatashin@...een.com>
---
drivers/misc/liveupdate/luo_subsystems.c | 133 ++++++++++++++++++++++-
1 file changed, 131 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/liveupdate/luo_subsystems.c b/drivers/misc/liveupdate/luo_subsystems.c
index 436929a17de0..71f5f0468b0d 100644
--- a/drivers/misc/liveupdate/luo_subsystems.c
+++ b/drivers/misc/liveupdate/luo_subsystems.c
@@ -99,6 +99,66 @@ void __init luo_subsystems_startup(void *fdt)
luo_fdt_in = fdt;
}
+static void __luo_do_subsystems_cancel_calls(struct liveupdate_subsystem *boundary_subsystem)
+{
+ struct liveupdate_subsystem *subsystem;
+
+ list_for_each_entry(subsystem, &luo_subsystems_list, list) {
+ if (subsystem == boundary_subsystem)
+ break;
+
+ if (subsystem->cancel) {
+ subsystem->cancel(subsystem->arg,
+ subsystem->private_data);
+ }
+ subsystem->private_data = 0;
+ }
+}
+
+static void luo_subsystems_retrieve_data_from_fdt(void)
+{
+ struct liveupdate_subsystem *subsystem;
+ int node_offset, prop_len;
+ const void *prop;
+
+ if (!luo_fdt_in)
+ return;
+
+ node_offset = fdt_subnode_offset(luo_fdt_in, 0,
+ LUO_SUBSYSTEMS_NODE_NAME);
+ list_for_each_entry(subsystem, &luo_subsystems_list, list) {
+ prop = fdt_getprop(luo_fdt_in, node_offset,
+ subsystem->name, &prop_len);
+
+ if (!prop || prop_len != sizeof(u64)) {
+ panic("In FDt node '/%s' can't find property '%s': %s\n",
+ LUO_SUBSYSTEMS_NODE_NAME, subsystem->name,
+ fdt_strerror(node_offset));
+ }
+ memcpy(&subsystem->private_data, prop, sizeof(u64));
+ }
+}
+
+static int luo_subsystems_commit_data_to_fdt(void)
+{
+ struct liveupdate_subsystem *subsystem;
+ int ret, node_offset;
+
+ node_offset = fdt_subnode_offset(luo_fdt_out, 0,
+ LUO_SUBSYSTEMS_NODE_NAME);
+ list_for_each_entry(subsystem, &luo_subsystems_list, list) {
+ ret = fdt_setprop(luo_fdt_out, node_offset, subsystem->name,
+ &subsystem->private_data, sizeof(u64));
+ if (ret < 0) {
+ pr_err("Failed to set FDT property for subsystem '%s' %s\n",
+ subsystem->name, fdt_strerror(ret));
+ return -ENOENT;
+ }
+ }
+
+ return 0;
+}
+
/**
* luo_do_subsystems_prepare_calls - Calls prepare callbacks and updates FDT
* if all prepares succeed. Handles cancellation on failure.
@@ -114,7 +174,29 @@ void __init luo_subsystems_startup(void *fdt)
*/
int luo_do_subsystems_prepare_calls(void)
{
- return 0;
+ struct liveupdate_subsystem *subsystem;
+ int ret;
+
+ list_for_each_entry(subsystem, &luo_subsystems_list, list) {
+ if (!subsystem->prepare)
+ continue;
+
+ ret = subsystem->prepare(subsystem->arg,
+ &subsystem->private_data);
+ if (ret < 0) {
+ pr_err("Subsystem '%s' prepare callback failed [%d]\n",
+ subsystem->name, ret);
+ __luo_do_subsystems_cancel_calls(subsystem);
+
+ return ret;
+ }
+ }
+
+ ret = luo_subsystems_commit_data_to_fdt();
+ if (ret)
+ __luo_do_subsystems_cancel_calls(NULL);
+
+ return ret;
}
/**
@@ -132,7 +214,29 @@ int luo_do_subsystems_prepare_calls(void)
*/
int luo_do_subsystems_freeze_calls(void)
{
- return 0;
+ struct liveupdate_subsystem *subsystem;
+ int ret;
+
+ list_for_each_entry(subsystem, &luo_subsystems_list, list) {
+ if (!subsystem->freeze)
+ continue;
+
+ ret = subsystem->freeze(subsystem->arg,
+ &subsystem->private_data);
+ if (ret < 0) {
+ pr_err("Subsystem '%s' freeze callback failed [%d]\n",
+ subsystem->name, ret);
+ __luo_do_subsystems_cancel_calls(subsystem);
+
+ return ret;
+ }
+ }
+
+ ret = luo_subsystems_commit_data_to_fdt();
+ if (ret)
+ __luo_do_subsystems_cancel_calls(NULL);
+
+ return ret;
}
/**
@@ -143,6 +247,16 @@ int luo_do_subsystems_freeze_calls(void)
*/
void luo_do_subsystems_finish_calls(void)
{
+ struct liveupdate_subsystem *subsystem;
+
+ luo_subsystems_retrieve_data_from_fdt();
+
+ list_for_each_entry(subsystem, &luo_subsystems_list, list) {
+ if (subsystem->finish) {
+ subsystem->finish(subsystem->arg,
+ subsystem->private_data);
+ }
+ }
}
/**
@@ -156,6 +270,8 @@ void luo_do_subsystems_finish_calls(void)
*/
void luo_do_subsystems_cancel_calls(void)
{
+ __luo_do_subsystems_cancel_calls(NULL);
+ luo_subsystems_commit_data_to_fdt();
}
/**
@@ -279,6 +395,19 @@ EXPORT_SYMBOL_GPL(liveupdate_unregister_subsystem);
*/
int liveupdate_get_subsystem_data(struct liveupdate_subsystem *h, u64 *data)
{
+ int node_offset, prop_len;
+ const void *prop;
+
+ if (!luo_fdt_in || !liveupdate_state_updated())
+ return -ENOENT;
+
+ node_offset = fdt_subnode_offset(luo_fdt_in, 0,
+ LUO_SUBSYSTEMS_NODE_NAME);
+ prop = fdt_getprop(luo_fdt_in, node_offset, h->name, &prop_len);
+ if (!prop || prop_len != sizeof(u64))
+ return -ENOENT;
+ memcpy(data, prop, sizeof(u64));
+
return 0;
}
EXPORT_SYMBOL_GPL(liveupdate_get_subsystem_data);
--
2.49.0.1101.gccaa498523-goog
Powered by blists - more mailing lists