From nobody Sun Oct 5 09:22:01 2025 Received: from mail-qt1-f181.google.com (mail-qt1-f181.google.com [209.85.160.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F2BC1D9A5F for ; Mon, 29 Sep 2025 01:03:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759107830; cv=none; b=BUjsXy4puYAXFZl7igcoocKmIILXwq0UYiH51ZfqlM2mpLdR/eF8QfMjEIgD+R+nMNGMbsScF44zmOm2MkEtPHlw55qV3lguWeDtMEHG6apWQaQZ8ybA/OaA+QgEbUQsLvsQBZyhhlp6O/hFx5Hv2wyGMtJe2QAlXqVvTZ4xQRE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759107830; c=relaxed/simple; bh=1eYRhAZ5gxArkp6W4PjKuMPzvA3/DnYF8EhUap2c5NM=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i9GF9exY4Vf+DiCmGyS8URXRW4+KJP4Uk39NKwSYsOscBDyAY1t707q/OS8rSGUasrjhW6Wi6ieSOAaJZN4tFzGEsdnRnEDts/SKkB1AtaXYCRBeyiiJSD/jUroUcqQBGwttosTuhHOo0PZF3SpSn1ndtwsJpGgC0bmEu5BSVQw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=NiVqUYoh; arc=none smtp.client-ip=209.85.160.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="NiVqUYoh" Received: by mail-qt1-f181.google.com with SMTP id d75a77b69052e-4da894db6e9so37096681cf.0 for ; Sun, 28 Sep 2025 18:03:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759107826; x=1759712626; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=qNgtpsyj7RLAHZgXPkVDbvjA113c53pRuAQVjz5hWqc=; b=NiVqUYohbc56gOCJnWj2aj9O10RP3g7MoGPa5exk1sHV7V/1h5hbbsycPvcyca70hW /tA8ACR6010OsdseTkQKj1jf051DBYyY3fYlgENFYAN0LhhG6i4SoT96Vx5SRpvp8cVA U058h7v/8XjOkkruVMgEPu2QX1F3QIMjWgYLUwu9QnePwj/0il+P5QP6GgRN7LRoCvjf EdlIy2P0N9nAzLksJQpfn+NWWVWf3LcYqOHMnF1p1+7FRbGivaltBaKd/MCST8kW5Loc iVjKlHPHZBy7YXf4sO7pCCh0DLFIGNfBu68mnfioYvPq0YlImmbZj0UPXDEX3Syt4oni A0CA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759107826; x=1759712626; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qNgtpsyj7RLAHZgXPkVDbvjA113c53pRuAQVjz5hWqc=; b=dK6PkCS/0IZ7pZyV6cQIybN62Dyi+ENEKM/g12FMSwsRl7G4UL/MroujcwCA1hCLSD EX6RUdrpQ4PEYrEpr0EOs0ZbW79PDfPYZad0/DwD3Eu1BsmO70nb10IhNrCODsiZg+nE 7ps2684vZLaqLiIzC+g4XNDF3sFfJU+br7IHAGheev032o4QGelLuEKntRVvwHD3MSq+ XnSqxKM388fw6WLgf3LnnQZMczfccq5plWJYmTANnKGOtvrzkEB2sAdciykn1P5vbLVC QJnbWqnULeiAkN5KG4FJCvcaiMA3OQb1UO/Tt9jP0v5HBl02UhmPwTgD6znDXWTqBtAb xqgA== X-Forwarded-Encrypted: i=1; AJvYcCVTF9nyuh6sR8N2j5Ygz9mA6OrOwmCFci/KHB11kcqa2nIxWpVi/WpUvnvHdqy96tYnWyhgqFceyQa3wME=@vger.kernel.org X-Gm-Message-State: AOJu0YydsWIVIZCC49Gb6cEX9jGi0a6v+xLeSChXC2lWdD5j55HYi1Rm fLfqH3rgUXBWrF3Ev+BjvOsJPprxkXTqjec8IlkmV2UTi/jOP0KGSslAbIaLXy4t5g8= X-Gm-Gg: ASbGncveow+OXORkelinW9EAOCG/qiAcTXkXcvdJMceLiBT6fUCIxN3mW61hX86QRNJ jRmCwlmjx+pvs9mBM6gVDZUdT936qh0qO0/Sxmu2FMghnK2IqPa1pTX5XgAUKOJAT6B7EuW6zzF JCRyOdvBmX422CTSXttsU/vA/qcz0/uhWu+Q8Wb2CglOOSGw8Oac2WoPIaKkuqPRdV2/CPr6NfD BP4PE4Hj3UnAIscVM1M0bbDa5O8lW9/Hk6M8PcfdrLCztphqB6z6F87eLnDObnhVhWSp/s1aobI +2tMHX34y35FOiHbi/7aDVeYQOP0NWEfz8zlEeFnab9sb8YfjPOQ3U8GM0GkSLG/0jEJi5+/wXE dDvuIV1ZBEVzXzRodmCiE0Kp+hyaPSqzwJSkrt8L+ljsMjWbiejmF4rn7CElZObyAJ8W6qMyKY2 ep1t0dub2KXtCFzudFgg== X-Google-Smtp-Source: AGHT+IHxH0LChANCVLQGPE4rLJ8RYbxJBPP7307a2p1i+UBLkReBGwGJRjYxsz6FhDJmrWtglXB3xA== X-Received: by 2002:ac8:5fc5:0:b0:4e0:b72b:7f6d with SMTP id d75a77b69052e-4e0b72b8612mr35576991cf.29.1759107825963; Sun, 28 Sep 2025 18:03:45 -0700 (PDT) Received: from soleen.c.googlers.com.com (53.47.86.34.bc.googleusercontent.com. [34.86.47.53]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-4db0c0fbe63sm64561521cf.23.2025.09.28.18.03.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Sep 2025 18:03:45 -0700 (PDT) From: Pasha Tatashin To: pratyush@kernel.org, jasonmiu@google.com, graf@amazon.com, changyuanl@google.com, pasha.tatashin@soleen.com, rppt@kernel.org, dmatlack@google.com, rientjes@google.com, corbet@lwn.net, rdunlap@infradead.org, ilpo.jarvinen@linux.intel.com, kanie@linux.alibaba.com, ojeda@kernel.org, aliceryhl@google.com, masahiroy@kernel.org, akpm@linux-foundation.org, tj@kernel.org, yoann.congal@smile.fr, mmaurer@google.com, roman.gushchin@linux.dev, chenridong@huawei.com, axboe@kernel.dk, mark.rutland@arm.com, jannh@google.com, vincent.guittot@linaro.org, hannes@cmpxchg.org, dan.j.williams@intel.com, david@redhat.com, joel.granados@kernel.org, rostedt@goodmis.org, anna.schumaker@oracle.com, song@kernel.org, zhangguopeng@kylinos.cn, linux@weissschuh.net, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, gregkh@linuxfoundation.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, rafael@kernel.org, dakr@kernel.org, bartosz.golaszewski@linaro.org, cw00.choi@samsung.com, myungjoo.ham@samsung.com, yesanishhere@gmail.com, Jonathan.Cameron@huawei.com, quic_zijuhu@quicinc.com, aleksander.lobakin@intel.com, ira.weiny@intel.com, andriy.shevchenko@linux.intel.com, leon@kernel.org, lukas@wunner.de, bhelgaas@google.com, wagi@kernel.org, djeffery@redhat.com, stuart.w.hayes@gmail.com, ptyadav@amazon.de, lennart@poettering.net, brauner@kernel.org, linux-api@vger.kernel.org, linux-fsdevel@vger.kernel.org, saeedm@nvidia.com, ajayachandra@nvidia.com, jgg@nvidia.com, parav@nvidia.com, leonro@nvidia.com, witu@nvidia.com, hughd@google.com, skhawaja@google.com, chrisl@kernel.org, steven.sistare@oracle.com Subject: [PATCH v4 10/30] liveupdate: luo_subsystems: implement subsystem callbacks Date: Mon, 29 Sep 2025 01:03:01 +0000 Message-ID: <20250929010321.3462457-11-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.536.g15c5d4f767-goog In-Reply-To: <20250929010321.3462457-1-pasha.tatashin@soleen.com> References: <20250929010321.3462457-1-pasha.tatashin@soleen.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- kernel/liveupdate/luo_subsystems.c | 167 ++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 3 deletions(-) diff --git a/kernel/liveupdate/luo_subsystems.c b/kernel/liveupdate/luo_sub= systems.c index 69f00d5c000e..ebb7c0db08f3 100644 --- a/kernel/liveupdate/luo_subsystems.c +++ b/kernel/liveupdate/luo_subsystems.c @@ -101,8 +101,81 @@ void __init luo_subsystems_startup(void *fdt) luo_fdt_in =3D fdt; } =20 +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 =3D=3D boundary_subsystem) + break; + + if (subsystem->ops->cancel) { + subsystem->ops->cancel(subsystem, + subsystem->private_data); + } + subsystem->private_data =3D 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 =3D fdt_subnode_offset(luo_fdt_in, 0, + LUO_SUBSYSTEMS_NODE_NAME); + list_for_each_entry(subsystem, &luo_subsystems_list, list) { + prop =3D fdt_getprop(luo_fdt_in, node_offset, + subsystem->name, &prop_len); + + if (!prop || prop_len !=3D sizeof(u64)) { + luo_restore_fail("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 =3D fdt_subnode_offset(luo_fdt_out, 0, + LUO_SUBSYSTEMS_NODE_NAME); + list_for_each_entry(subsystem, &luo_subsystems_list, list) { + ret =3D 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; +} + static int luo_get_subsystem_data(struct liveupdate_subsystem *h, u64 *dat= a) { + int node_offset, prop_len; + const void *prop; + + node_offset =3D fdt_subnode_offset(luo_fdt_in, 0, + LUO_SUBSYSTEMS_NODE_NAME); + prop =3D fdt_getprop(luo_fdt_in, node_offset, h->name, &prop_len); + if (!prop || prop_len !=3D sizeof(u64)) { + luo_state_read_exit(); + return -ENOENT; + } + memcpy(data, prop, sizeof(u64)); + return 0; } =20 @@ -121,7 +194,30 @@ static int luo_get_subsystem_data(struct liveupdate_su= bsystem *h, u64 *data) */ int luo_do_subsystems_prepare_calls(void) { - return 0; + struct liveupdate_subsystem *subsystem; + int ret; + + guard(mutex)(&luo_subsystem_list_mutex); + list_for_each_entry(subsystem, &luo_subsystems_list, list) { + if (!subsystem->ops->prepare) + continue; + + ret =3D subsystem->ops->prepare(subsystem, + &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 =3D luo_subsystems_commit_data_to_fdt(); + if (ret) + __luo_do_subsystems_cancel_calls(NULL); + + return ret; } =20 /** @@ -139,7 +235,30 @@ int luo_do_subsystems_prepare_calls(void) */ int luo_do_subsystems_freeze_calls(void) { - return 0; + struct liveupdate_subsystem *subsystem; + int ret; + + guard(mutex)(&luo_subsystem_list_mutex); + list_for_each_entry(subsystem, &luo_subsystems_list, list) { + if (!subsystem->ops->freeze) + continue; + + ret =3D subsystem->ops->freeze(subsystem, + &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 =3D luo_subsystems_commit_data_to_fdt(); + if (ret) + __luo_do_subsystems_cancel_calls(NULL); + + return ret; } =20 /** @@ -150,6 +269,18 @@ int luo_do_subsystems_freeze_calls(void) */ void luo_do_subsystems_finish_calls(void) { + struct liveupdate_subsystem *subsystem; + + guard(mutex)(&luo_subsystem_list_mutex); + luo_subsystems_retrieve_data_from_fdt(); + + list_for_each_entry(subsystem, &luo_subsystems_list, list) { + if (subsystem->ops->finish) { + subsystem->ops->finish(subsystem, + subsystem->private_data); + } + subsystem->private_data =3D 0; + } } =20 /** @@ -163,6 +294,9 @@ void luo_do_subsystems_finish_calls(void) */ void luo_do_subsystems_cancel_calls(void) { + guard(mutex)(&luo_subsystem_list_mutex); + __luo_do_subsystems_cancel_calls(NULL); + luo_subsystems_commit_data_to_fdt(); } =20 /** @@ -285,7 +419,34 @@ int liveupdate_unregister_subsystem(struct liveupdate_= subsystem *h) return ret; } =20 +/** + * liveupdate_get_subsystem_data - Retrieve raw private data for a subsyst= em + * from FDT. + * @h: Pointer to the liveupdate_subsystem structure representing the + * subsystem instance. The 'name' field is used to find the property. + * @data: Output pointer where the subsystem's raw private u64 data will= be + * stored via memcpy. + * + * Reads the 8-byte data property associated with the subsystem @h->name + * directly from the '/subsystems' node within the globally accessible + * 'luo_fdt_in' blob. Returns appropriate error codes if inputs are invali= d, or + * nodes/properties are missing or invalid. + * + * Return: 0 on success. -ENOENT on error. + */ int liveupdate_get_subsystem_data(struct liveupdate_subsystem *h, u64 *dat= a) { - return 0; + int ret; + + luo_state_read_enter(); + if (WARN_ON_ONCE(!luo_fdt_in || !liveupdate_state_updated())) { + luo_state_read_exit(); + return -ENOENT; + } + + scoped_guard(mutex, &luo_subsystem_list_mutex) + ret =3D luo_get_subsystem_data(h, data); + luo_state_read_exit(); + + return ret; } --=20 2.51.0.536.g15c5d4f767-goog