From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92443C2D0CD for ; Thu, 15 May 2025 18:23:44 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2FF886B00B1; Thu, 15 May 2025 14:23:36 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 2140F6B00B2; Thu, 15 May 2025 14:23:36 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EE4746B00B3; Thu, 15 May 2025 14:23:35 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id BDDF96B00B1 for ; Thu, 15 May 2025 14:23:35 -0400 (EDT) Received: from smtpin02.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id BDF91E0611 for ; Thu, 15 May 2025 18:23:36 +0000 (UTC) X-FDA: 83445965232.02.68651E1 Received: from mail-qk1-f182.google.com (mail-qk1-f182.google.com [209.85.222.182]) by imf27.hostedemail.com (Postfix) with ESMTP id 2ADDE4000E for ; Thu, 15 May 2025 18:23:35 +0000 (UTC) Authentication-Results: imf27.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=xfd1LmpA; dmarc=pass (policy=none) header.from=soleen.com; spf=pass (imf27.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.182 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1747333415; a=rsa-sha256; cv=none; b=4jkVMcBH4Dl7E0blr9KmtRPjB2YSgZobD64GqBB6onI0OCaAyRpBj/pPUVsR61Cm+dG8TR 2l0Xrybtryx5o5UuK3aSDk0QUDH9pZfHzaInvUQmr7wYLXaNPtuINKHiM++spO0evNwCw6 vAhHcD5Y6l0KYmnj4eR17UdurXdxPuw= ARC-Authentication-Results: i=1; imf27.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=xfd1LmpA; dmarc=pass (policy=none) header.from=soleen.com; spf=pass (imf27.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.182 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1747333415; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=eCL7Dl0fUJFgtoGMLDnQRSnzltXuASvUYx206SfRPVk=; b=D8PzuP2Kmnb4aw7qmiUcf+hNzjtKhznN36DXzKx4g0bOJLidNtgXLmGplhMtx/lzvSVB22 H3g49LpK65lX6joolC14yRuvywVtDPrVeYpJNRtg0oMwbwAQq1tZ6nzk46kxmu7tMOpWNS w7Djec5yAR0OanWMtzWzqH8qp8jeguQ= Received: by mail-qk1-f182.google.com with SMTP id af79cd13be357-7c5f720c717so289340885a.0 for ; Thu, 15 May 2025 11:23:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen-com.20230601.gappssmtp.com; s=20230601; t=1747333414; x=1747938214; darn=kvack.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=eCL7Dl0fUJFgtoGMLDnQRSnzltXuASvUYx206SfRPVk=; b=xfd1LmpA2KCxecvJ8yKzHTL2Xd+fUTfSm+UEwSiC3LUQZ+QNHq0YkLzYLQ/j6rjvaT lBMspQSUYE9exYCYChBD7fNHjf1g5vR67hL8PSx9rTJdTnMk03S/yh+zxZxB36re22B/ B1Lw8EbnAKfIrs3wHdcF2NGa5kzSm5E3mb4rs+SNWwpsYU+tOammt9L60yWtWyQTADII xZTVjXAQqhfwAiG+6tn0LwUf+hiPAUYyybCs7aD2nZ8k1yDZVTSfnn2/1v2P1FRaa2S6 rGBxcJET2SWSGX/mfW5sfw74nsybfyxLAKLcL1OzX1FVPq4zkwQomTu94JFnhZn0M59T Y3Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747333414; x=1747938214; 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=eCL7Dl0fUJFgtoGMLDnQRSnzltXuASvUYx206SfRPVk=; b=FyJq7lkLuBLRRTemFXE0wyYR1zxY2/XQbdW128eNL154CgkWskX/X4NXsklqRj/f4j 5+5U9U7XNx3tGi441ATW6buSA4hft68LvPU3YqCOo9oRzfgIZZA/eJtJcdLzX+I+K2sC CwNU+pih1PCoFUdz5ZbM6C3+0QcaHEJrcn5IUxq5NNxVM3N9C0QoOBWqoa/rntQB6D1a CQ2HJr8XvT9wYg7K+EcmeR2LL/Dqj5GgdH5a9MHHz326P31Ye49fd+AXb4gtW3vjSDXv xgLiJGdjKO24vya+FTWRsG0Uc4bsfWPXHfNAxa6Ys2NFY4ju2JNYZDrbXmC6wam7RbeY fitw== X-Forwarded-Encrypted: i=1; AJvYcCXxXSbNf8NM2z0mnXWM2JVXCGJD3zTn2aebb4oaajevf6IMnSJGwmUeBQDEu44XzNaVgjYAsHt58A==@kvack.org X-Gm-Message-State: AOJu0YxtExfCH25Lf0CR5cqRTS6DzkjoF4Vt+xMtsk6KHSRVrfxFPJcB sT7TSXdBcpT9xztejWZZiNZoMsaYsO+G8NpEmqo5bt8tIQiSG4qOPyVgTgodlg9rcU8= X-Gm-Gg: ASbGncv+DR9U8yMVMJYP2wSToLcnb6gyGd4YG0EwAtA8Y0V9bA67Q/9vonvaBLM+T27 UD2D1vKV8Bu0fIzoaBmmQWIMigWEIYQDBJwWnTyYetWmBOyXXXoUmEaO662lSDKtEZ8RriqE1IQ D+0dL2GhNrtgbh+8xbA1foJvoB18DONoDD4KSP53ttegPGz2shm/bA9AHEkiEGVrUNh01nFwVAR W/Fhp3GvEiqA/Z0AfDbULX4BUL4LyqJ7aeyiXiWYh3dsJYgl1gaak9qjS5TAhvWga13C+odzzR9 XK1PSgwrQIaARq2+TU/pewQNnKhsXh1nR3vkc0weKJbLvewpkXxaf5UT/j99Py85tWsVxsZyyx4 mCp4AYu4oXCXyStK9FqOt7JtWQvzArLFlDvT9TEwJaaMs X-Google-Smtp-Source: AGHT+IGyVx7YT2wET1Kp1qNiBNOANi4Vf79w65s/UaK8dJtraKWXto4zccTg9syrNS2nds1eQAId/g== X-Received: by 2002:a05:620a:2890:b0:7c9:65cb:6214 with SMTP id af79cd13be357-7cd46b14da4mr55322585a.17.1747333414011; Thu, 15 May 2025 11:23:34 -0700 (PDT) Received: from soleen.c.googlers.com.com (138.200.150.34.bc.googleusercontent.com. [34.150.200.138]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7cd466fc2afsm18218685a.0.2025.05.15.11.23.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 May 2025 11:23:32 -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 Subject: [RFC v2 05/16] luo: luo_core: integrate with KHO Date: Thu, 15 May 2025 18:23:09 +0000 Message-ID: <20250515182322.117840-6-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.49.0.1101.gccaa498523-goog In-Reply-To: <20250515182322.117840-1-pasha.tatashin@soleen.com> References: <20250515182322.117840-1-pasha.tatashin@soleen.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: 2ADDE4000E X-Rspam-User: X-Stat-Signature: shrj6khpbwe73jkubaixdchwrfdjkrh1 X-HE-Tag: 1747333415-888682 X-HE-Meta: U2FsdGVkX19SJpqUs9cdyL6eI4PJPzbv8hC3gEJNASkaJ8sP/UWM0uxBMY+HucWrYrfOD8WpdJ23BfBaHv+juSV0wzg1TNAcmQNa8kUSPt71fDuf2HGh5azE2PQeEjgUHfwOSfyOPt577OCNBp59VqnqK+YWDC1DYKfAyKk3RgmSid3DiGZouZUyNzYLpwfCI03pKtOCnidtMmbEdymafV9Z9JbRnkI0hnAEhPGuS6JUeoJkK0IUzUHs43ycEp1zo1tSS/kEDKLQSMm5zjYCf5veWTNNkjMkG4u65f8Otx3qrfYJ2gh2mvkiUC/guJbx50gD2W8Jb4On0tW1GD41nBadVvNG3+XGpUZ4K4coxBCpLce4y9ithIZMrGCVFuY01Ti9XYXW3L82EXgQKOfKEdj+dwTFv5jfUn3/5XcCo3ThN5uc5RvCo2hHQwtt1GtJbfkqAfC+wsdR4fmtnhjyZTTb53Vw010q68mBYrCI/NB4Ds6QfAAZEwXsd3FwOVVBp2f7HT78GA29Ql6fvRNdzpoyrvXADj8GmeHBuLtvrkGGWU3zlK1vXovKLfG1ui86mBBo5Nd597jZAz71yTJtLE+t1uv5smnNIavx28IjoowjbEVdZzmyCYa80GDuyUwGlpkW8pYDP4kQJZTuFQ6+Jseak1TL+HuQZ8nYECBJCWAJae5veuijiXdu6HSAe2I6v7mrk1KwMCjRdwTCwFT7J5BZgRcYqiO+LHl2nVcDjzp6qF14Q6dAcAe+pfzUn8+LgFbH6M1geHlUyXcQNf6MRr/F8HDVu/aokAA58hViEo8Vc9KNzo2SySnThVS7roetKvCPB4szVi//MDpedV9WwyXASrprkuIsP4Aeo0CNNjuszXfaJt2PDLroLkz2X+Yc1J36SIHKmcYgNuaXirEV2qleoTbDDNprZOF23E7xnQ4YcjHzYTmv+6/+AT9DExUgKsJOV+cBjrJNOQ/x7MW 8taxmW+x +KIdsYvAok+kxTUXAGLvLncIe9bb105d7k1tcWLyH3KrojwYJHSEHDa6DGXm0/Qd+uaYC7vnXTsdERfn48BskRH10Wc+wUSbvee2cBC0sgI0CRWUZqGm9NF6A1hrRJfnQpWGtoUGxYit974zuJLxze9js14IxS8tAKQq92JwY39lyxD2/uquRZWXw1KLvGuSswe22Z+tuj3EFcq0= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Integrate the LUO with the KHO framework to enable passing LUO state across a kexec reboot. This patch introduces the following changes: - During the KHO finalization phase allocate FDT blob. - Populate this FDT with a LUO compatibility string ("luo-v1") and the current LUO state (`luo_state`). - Implement a KHO notifier LUO now depends on `CONFIG_KEXEC_HANDOVER`. The core state transition logic (`luo_do_*_calls`) remains unimplemented in this patch. Signed-off-by: Pasha Tatashin --- drivers/misc/liveupdate/luo_core.c | 222 ++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 3 deletions(-) diff --git a/drivers/misc/liveupdate/luo_core.c b/drivers/misc/liveupdate/luo_core.c index 919c37b0b4d1..a76e886bc3b1 100644 --- a/drivers/misc/liveupdate/luo_core.c +++ b/drivers/misc/liveupdate/luo_core.c @@ -36,9 +36,12 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include +#include #include #include +#include #include #include "luo_internal.h" @@ -55,6 +58,12 @@ const char *const luo_state_str[] = { bool luo_enabled; +static void *luo_fdt_out; +static void *luo_fdt_in; +#define LUO_FDT_SIZE SZ_1M +#define LUO_KHO_ENTRY_NAME "LUO" +#define LUO_COMPATIBLE "luo-v1" + static int __init early_liveupdate_param(char *buf) { return kstrtobool(buf, &luo_enabled); @@ -79,6 +88,60 @@ static inline void luo_set_state(enum liveupdate_state state) __luo_set_state(state); } +/* Called during the prepare phase, to create LUO fdt tree */ +static int luo_fdt_setup(struct kho_serialization *ser) +{ + void *fdt_out; + int ret; + + fdt_out = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, + get_order(LUO_FDT_SIZE)); + if (!fdt_out) { + pr_err("failed to allocate FDT memory\n"); + return -ENOMEM; + } + + ret = fdt_create_empty_tree(fdt_out, LUO_FDT_SIZE); + if (ret) + goto exit_free; + + ret = fdt_setprop(fdt_out, 0, "compatible", LUO_COMPATIBLE, + strlen(LUO_COMPATIBLE) + 1); + if (ret) + goto exit_free; + + ret = kho_preserve_phys(__pa(fdt_out), LUO_FDT_SIZE); + if (ret) + goto exit_free; + + ret = kho_add_subtree(ser, LUO_KHO_ENTRY_NAME, fdt_out); + if (ret) + goto exit_unpreserve; + luo_fdt_out = fdt_out; + + return 0; + +exit_unpreserve: + kho_unpreserve_phys(__pa(fdt_out), LUO_FDT_SIZE); +exit_free: + free_pages((unsigned long)fdt_out, get_order(LUO_FDT_SIZE)); + pr_err("failed to prepare LUO FDT: %d\n", ret); + + return ret; +} + +static void luo_fdt_destroy(void) +{ + kho_unpreserve_phys(__pa(luo_fdt_out), LUO_FDT_SIZE); + free_pages((unsigned long)luo_fdt_out, get_order(LUO_FDT_SIZE)); + luo_fdt_out = NULL; +} + +static int luo_do_prepare_calls(void) +{ + return 0; +} + static int luo_do_freeze_calls(void) { return 0; @@ -88,11 +151,111 @@ static void luo_do_finish_calls(void) { } -int luo_prepare(void) +static void luo_do_cancel_calls(void) +{ +} + +static int __luo_prepare(struct kho_serialization *ser) { + int ret; + + if (down_write_killable(&luo_state_rwsem)) { + pr_warn("[prepare] event canceled by user\n"); + return -EAGAIN; + } + + if (!is_current_luo_state(LIVEUPDATE_STATE_NORMAL)) { + pr_warn("Can't switch to [%s] from [%s] state\n", + luo_state_str[LIVEUPDATE_STATE_PREPARED], + LUO_STATE_STR); + ret = -EINVAL; + goto exit_unlock; + } + + ret = luo_fdt_setup(ser); + if (ret) + goto exit_unlock; + + ret = luo_do_prepare_calls(); + if (ret) + goto exit_unlock; + + luo_set_state(LIVEUPDATE_STATE_PREPARED); + +exit_unlock: + up_write(&luo_state_rwsem); + + return ret; +} + +static int __luo_cancel(void) +{ + if (down_write_killable(&luo_state_rwsem)) { + pr_warn("[cancel] event canceled by user\n"); + return -EAGAIN; + } + + if (!is_current_luo_state(LIVEUPDATE_STATE_PREPARED) && + !is_current_luo_state(LIVEUPDATE_STATE_FROZEN)) { + pr_warn("Can't switch to [%s] from [%s] state\n", + luo_state_str[LIVEUPDATE_STATE_NORMAL], + LUO_STATE_STR); + up_write(&luo_state_rwsem); + + return -EINVAL; + } + + luo_do_cancel_calls(); + luo_fdt_destroy(); + luo_set_state(LIVEUPDATE_STATE_NORMAL); + + up_write(&luo_state_rwsem); + return 0; } +static int luo_kho_notifier(struct notifier_block *self, + unsigned long cmd, void *v) +{ + int ret; + + switch (cmd) { + case KEXEC_KHO_FINALIZE: + ret = __luo_prepare((struct kho_serialization *)v); + break; + case KEXEC_KHO_ABORT: + ret = __luo_cancel(); + break; + default: + return NOTIFY_BAD; + } + + return notifier_from_errno(ret); +} + +static struct notifier_block luo_kho_notifier_nb = { + .notifier_call = luo_kho_notifier, +}; + +/** + * luo_prepare - Initiate the live update preparation phase. + * + * This function is called to begin the live update process. It attempts to + * transition the luo to the ``LIVEUPDATE_STATE_PREPARED`` state. + * + * If the calls complete successfully, the orchestrator state is set + * to ``LIVEUPDATE_STATE_PREPARED``. If any call fails a + * ``LIVEUPDATE_CANCEL`` is sent to roll back any actions. + * + * @return 0 on success, ``-EAGAIN`` if the state change was cancelled by the + * user while waiting for the lock, ``-EINVAL`` if the orchestrator is not in + * the normal state, or a negative error code returned by the calls. + */ +int luo_prepare(void) +{ + return kho_finalize(); +} + /** * luo_freeze() - Initiate the final freeze notification phase for live update. * @@ -188,9 +351,23 @@ int luo_finish(void) return 0; } +/** + * luo_cancel - Cancel the ongoing live update from prepared or frozen states. + * + * This function is called to abort a live update that is currently in the + * ``LIVEUPDATE_STATE_PREPARED`` state. + * + * If the state is correct, it triggers the ``LIVEUPDATE_CANCEL`` notifier chain + * to allow subsystems to undo any actions performed during the prepare or + * freeze events. Finally, the orchestrator state is transitioned back to + * ``LIVEUPDATE_STATE_NORMAL``. + * + * @return 0 on success, or ``-EAGAIN`` if the state change was cancelled by the + * user while waiting for the lock. + */ int luo_cancel(void) { - return 0; + return kho_abort(); } void luo_state_read_enter(void) @@ -205,7 +382,46 @@ void luo_state_read_exit(void) static int __init luo_startup(void) { - __luo_set_state(LIVEUPDATE_STATE_NORMAL); + phys_addr_t fdt_phys; + int ret; + + if (!kho_is_enabled()) { + if (luo_enabled) + pr_warn("Disabling liveupdate because KHO is disabled\n"); + luo_enabled = false; + return 0; + } + + ret = register_kho_notifier(&luo_kho_notifier_nb); + if (ret) { + luo_enabled = false; + pr_warn("Failed to register with KHO [%d]\n", ret); + } + + /* + * Retrieve LUO subtree, and verify its format. Panic in case of + * exceptions, since machine devices and memory is in unpredictable + * state. + */ + ret = kho_retrieve_subtree(LUO_KHO_ENTRY_NAME, &fdt_phys); + if (ret) { + if (ret != -ENOENT) { + panic("failed to retrieve FDT '%s' from KHO: %d\n", + LUO_KHO_ENTRY_NAME, ret); + } + __luo_set_state(LIVEUPDATE_STATE_NORMAL); + + return 0; + } + + luo_fdt_in = __va(fdt_phys); + ret = fdt_node_check_compatible(luo_fdt_in, 0, LUO_COMPATIBLE); + if (ret) { + panic("FDT '%s' is incompatible with '%s' [%d]\n", + LUO_KHO_ENTRY_NAME, LUO_COMPATIBLE, ret); + } + + __luo_set_state(LIVEUPDATE_STATE_UPDATED); return 0; } -- 2.49.0.1101.gccaa498523-goog