From nobody Fri Dec 19 07:03:23 2025 Received: from mail-vk1-f181.google.com (mail-vk1-f181.google.com [209.85.221.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 9166F7464 for ; Tue, 7 Oct 2025 03:31:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807870; cv=none; b=iTLO1U2nkfL9hF0m2ypZwMu13Jb6dHIAM+2mZJ1M4nlCf8wLNCROqGd4h7mUIJWgtm7kxmZ8Tuw2oSWXlfXXPTdO9eF5Q+Sv6G4vvwoJJW8fUh90BFOqHG5aj/ZfA5avg36PPGIMxKv6nVehsXwl1tIkrs/bBQEfeRt5Z5gtb3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807870; c=relaxed/simple; bh=/fll/of95rQWwNDdp7em7nO/Y9F6lxz5T9wJPKWVKi0=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KDIOHRrOTOKx81dFpB87kyBqh7rT7oVtu7zhueFbPZc+RotubCC6meJPN6O78odG0QNC5lmQEcnAMy/swerTesR4osRVN4ipjdDKkCBiN0CskInvaWILJjUCUMi/BRw0oPEKFaFTDfaiXNT7f/4py967HnW0vkwneSTMC6L2r94= 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=fK9CsyzM; arc=none smtp.client-ip=209.85.221.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="fK9CsyzM" Received: by mail-vk1-f181.google.com with SMTP id 71dfb90a1353d-54bbf3329c1so5327881e0c.1 for ; Mon, 06 Oct 2025 20:31:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759807867; x=1760412667; 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=pb2j8N8Az+uWt45nNFfEUmcYJA7/O93dKo/dsaUrS7Y=; b=fK9CsyzM/WiXFRmOL9nd20G0NhzsxKur5anC5bQTbNxTeWydxWXaRIBajBezvKsPmm PFQm5Nz97r/BTXWpLt+1S8OQ4NH7112W30C4pqVXBJxG+59/HAkHkgy8fDBby6go7HrE NclW6CKwV7N27GB+o44uh1TUF87Ut2yaynL9TC1LC59rJWeQ2pM1pg4MVCkYHXhziEcn klwR3Udv8t/A3wglxYZaTQuFyDhMubPZqjX0U/LOnuZpdvpSBvIagJP8qFR/w5yibZNi 9f8zwtKstG5CUj9j3B2Kgw6m2nwETkY6mHlnpaTOQBKgJ9PU1hrN6qUIC6bJUdPyVW9r G22Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759807867; x=1760412667; 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=pb2j8N8Az+uWt45nNFfEUmcYJA7/O93dKo/dsaUrS7Y=; b=xHO7mv4cRNaDP2PpBhxP6SCZK544fZU6WCH8/zNzKNjZ+tvrEe+iVCztNDsITqRzP5 5gtyesl1Haf5ef40e248ugH2ck4pg0lt5iiZiNNNb6YNSsC4GpEXyJJ5ITTciTQfvi+z I2yBsZmzENkJNxrIsSLIRFRpGnVRH2W4GhV+915O240j13oXUfsBqq8+SZE3kTKM/sPJ povf39vIabYxa8qkiUv30wUNQu6C+TlVWTa7WA5ZLzEuSi9pjisv0HQyk4hHvwIcEoQ8 fsl7ZfzxR+0xs5Et04xZX/E770DEmtSCGgBmVxWE9B003Wq9j2dJOfszMz/8vSrajHTt TvHA== X-Forwarded-Encrypted: i=1; AJvYcCUmFG0ZkidrFMNIuU6ECjIm8wyP4I7sOJcQ2dZgZiVqcHjisuOfMRjiS4WcIl/8jleqBnYR9NHG5n0sgHw=@vger.kernel.org X-Gm-Message-State: AOJu0Yy9dkcj5Sy/IOeTrEqZi3e6OeRTuPeLnSkJwiIj67YQcpwPekNM zSpgczp/BSavCK+nPoWK/DexHZEtvT9rDv0DD5JoRkeiaenesZ0xAP6Hbrv6nLAtTdg= X-Gm-Gg: ASbGncuUZNb6So61nMM6zRgFzluwjYbreHNHzeKnbFTFU5NH2ZuUuZe9pqib4drcMY6 cdUfJe6+6+yBQo8AkCuBMRiGRMGjuhFHNSk9sMIhU/5jQUsNLvARCYxSsNSDq8YnOhVKSLW/qdz BilaCvDW7Sz7sEpIZuvVtnu8G4EEwd0G4eC7eW0AUrqD4crACyZo+Ibl/w8HJzAgSxO4Ewvkxe1 Y6X2GzyMCn9HcdjYMzFxoQmUG792FC/k63o1EzFU2P94HxIQpoUBvjjchCa/78FZVqJF25HzLOO NWeUkYVxShLeGWcNE+Q6xq427V6H7zVqiR7Kd6vlV+ZNPx/Bs+bpETPotkfLdZTfNJzmqA6k6UL sdah+l5l8FTLKoeM2rpvfjzp2sxbpMUVerUm7BKRl5ip9aHEQefGr1SR6NSWA0/Yr1LgWS6yXYy zTtZmuBUnAv8vL8XjXXxzo0HjaKY0D660= X-Google-Smtp-Source: AGHT+IHKWYvZiwypYwTwT1zKSJgyEU7e/SRkQV11sdxCZs7Hd6H9BMFs3IwoGAGyQxuhUHEh8cuY/A== X-Received: by 2002:a05:6122:8cd:b0:552:3366:e822 with SMTP id 71dfb90a1353d-554a8d1b310mr1055414e0c.1.1759807867441; Mon, 06 Oct 2025 20:31:07 -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 71dfb90a1353d-552ea335f07sm2446030e0c.15.2025.10.06.20.31.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Oct 2025 20:31:06 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org Subject: [PATCH v5 1/7] kho: allow to drive kho from within kernel Date: Tue, 7 Oct 2025 03:30:54 +0000 Message-ID: <20251007033100.836886-2-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog In-Reply-To: <20251007033100.836886-1-pasha.tatashin@soleen.com> References: <20251007033100.836886-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" Allow to do finalize and abort from kernel modules, so LUO could drive the KHO sequence via its own state machine. Signed-off-by: Pasha Tatashin Reviewed-by: Pratyush Yadav --- include/linux/kexec_handover.h | 15 +++++++ kernel/kexec_handover.c | 74 ++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 25042c1d8d54..04d0108db98e 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -67,6 +67,10 @@ void kho_memory_init(void); =20 void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_p= hys, u64 scratch_len); + +int kho_finalize(void); +int kho_abort(void); + #else static inline bool kho_is_enabled(void) { @@ -139,6 +143,17 @@ static inline void kho_populate(phys_addr_t fdt_phys, = u64 fdt_len, phys_addr_t scratch_phys, u64 scratch_len) { } + +static inline int kho_finalize(void) +{ + return -EOPNOTSUPP; +} + +static inline int kho_abort(void) +{ + return -EOPNOTSUPP; +} + #endif /* CONFIG_KEXEC_HANDOVER */ =20 #endif /* LINUX_KEXEC_HANDOVER_H */ diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index 76f0940fb485..76c34ea923f0 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -1067,7 +1067,7 @@ static int kho_out_update_debugfs_fdt(void) return err; } =20 -static int kho_abort(void) +static int __kho_abort(void) { int err; unsigned long order; @@ -1100,7 +1100,27 @@ static int kho_abort(void) return err; } =20 -static int kho_finalize(void) +int kho_abort(void) +{ + int ret =3D 0; + + if (!kho_enable) + return -EOPNOTSUPP; + + guard(mutex)(&kho_out.lock); + if (!kho_out.finalized) + return -ENOENT; + + ret =3D __kho_abort(); + if (ret) + return ret; + + kho_out.finalized =3D false; + + return kho_out_update_debugfs_fdt(); +} + +static int __kho_finalize(void) { int err =3D 0; u64 *preserved_mem_map; @@ -1143,12 +1163,32 @@ static int kho_finalize(void) abort: if (err) { pr_err("Failed to convert KHO state tree: %d\n", err); - kho_abort(); + __kho_abort(); } =20 return err; } =20 +int kho_finalize(void) +{ + int ret; + + if (!kho_enable) + return -EOPNOTSUPP; + + guard(mutex)(&kho_out.lock); + if (kho_out.finalized) + return -EEXIST; + + ret =3D __kho_finalize(); + if (ret) + return ret; + + kho_out.finalized =3D true; + + return kho_out_update_debugfs_fdt(); +} + static int kho_out_finalize_get(void *data, u64 *val) { mutex_lock(&kho_out.lock); @@ -1160,33 +1200,7 @@ static int kho_out_finalize_get(void *data, u64 *val) =20 static int kho_out_finalize_set(void *data, u64 _val) { - int ret =3D 0; - bool val =3D !!_val; - - mutex_lock(&kho_out.lock); - - if (val =3D=3D kho_out.finalized) { - if (kho_out.finalized) - ret =3D -EEXIST; - else - ret =3D -ENOENT; - goto unlock; - } - - if (val) - ret =3D kho_finalize(); - else - ret =3D kho_abort(); - - if (ret) - goto unlock; - - kho_out.finalized =3D val; - ret =3D kho_out_update_debugfs_fdt(); - -unlock: - mutex_unlock(&kho_out.lock); - return ret; + return (!!_val) ? kho_finalize() : kho_abort(); } =20 DEFINE_DEBUGFS_ATTRIBUTE(fops_kho_out_finalize, kho_out_finalize_get, --=20 2.51.0.618.g983fd99d29-goog From nobody Fri Dec 19 07:03:23 2025 Received: from mail-vk1-f179.google.com (mail-vk1-f179.google.com [209.85.221.179]) (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 E7E2D1F463E for ; Tue, 7 Oct 2025 03:31:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807872; cv=none; b=jrSKvQ2/IUfVcg6vUd+QC3BtVpHLiS8T8lLe6KQX8R2XyLhq++tSPatSMbL1v7X/XPRlJ2hT4ePd9DvgD9aPAo1zmlCKrL/rHjJ0ctdKr7HBP7nRsSTIxk0FkfSV9Klr/Ji+jV9va2N91bIn0bKEF93WN9gNalZRQe5Usmt0qF0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807872; c=relaxed/simple; bh=g1Il+TFGDLrGFUmJb7mLr9b87faBHG4T9M5bk5mlfLs=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ps8Gwn6naczuA4JfIK2HhXIYgZUZJaeZx+vL4KXNGdq4xK1zo7MjHgO/t5yW5MP4S0iTSnwmECKpp+pZ2idGh/fkYAYvB5sNDkf+gKZGZWsX4PYexmCPbfnAuggN8LMuQ7ebX1q8lrJPrCEXVAnZDx7nkB4Y+wGNLIimQsRq6O4= 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=WJp7dLI/; arc=none smtp.client-ip=209.85.221.179 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="WJp7dLI/" Received: by mail-vk1-f179.google.com with SMTP id 71dfb90a1353d-54bd3158f7bso4340887e0c.0 for ; Mon, 06 Oct 2025 20:31:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759807869; x=1760412669; 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=ibvELv1DY2+vIcA7qwUjdArdZEQD1fTrYRAZviRoTvY=; b=WJp7dLI/u5KI7knhyyUvAo7V9zFbVa2kGOn6jOxVhDd+JO2kAkBlXeqwCkpq1xgFQn MXv80DhqVT+KKEnLTtGbQ2rnjcIW6movwgwS/0IaILT8SAUjCpCWTC+SCxkRmdgLqIHK Ksdt2tdSzaf7Sq0XVwGB1t98BjnEN47+oOxzzKlqZcokLlZtmL3O9XOHaSHQNZ1sVuXA KvZDckzqvhnDyo0FZOXB1LvdeNe+iJzHslLna5iqf00tbqKMshFShsZb2LgwLEZ4B2p5 WZk0LSjTA3mfYKpBk7N+uwyUyB35XFrZTrXnok9g4mNpxtcfLT3gZ6j/BnnsF7m9T636 x5ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759807869; x=1760412669; 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=ibvELv1DY2+vIcA7qwUjdArdZEQD1fTrYRAZviRoTvY=; b=eKCS7s2iFAP5M+3dQ3hk3e9yzrIaXv0IYkOe42EMYshqk9qktu36fD02xthP514ZRG Fewgu2dVnLCYrVh4B3QeOSSFuFGfwLXyOhu4BoH7dbeiPGkw58sKimeqUZ7z2TuGDw/P CdxlaMSnP+HuZ7vJbomuQM9QzyttjAt/qS5j3Z/sd4X6sR9dpQLlcym7vNIAPRzbnBGT qZCIhz+evW38KENwGLE7O6EhWdupimQzWFZSBymBSqtdH6VcdqDgjnE31lTqE/CkkSfS hfam0gdmuAS5PhNJUtBoS6KRdWLh+cQaPGu+rghBmix9vwZn/FeJFOpjckj2U9mq9khm RE5Q== X-Forwarded-Encrypted: i=1; AJvYcCWmCLBs9vaNntKgdw5t9KgsGE7E1+L3jCl7cmhqkdoXmDV+qwpKs3i3qRvEQ5Ll7BICQH7etfr5hDREOlc=@vger.kernel.org X-Gm-Message-State: AOJu0YxIE47QLSPS6xzquNyMPEK7bQCrZsCGvQdrUUqLDIuTDW3x/9iw nYlfJltsf6OY73nFtoWoi48B7l8s+RzBjUfgRxpFqjT74PiZSrMxA7vZcUakKZodwpA= X-Gm-Gg: ASbGncu+1dCjGWzEX37V+dZ2o+G7RzVTcmvReoNbfQCmKM9tSN39PzpdmSIjwwDxMET RzLEqUN0yW7ALDm79Vx88WI867V9LOCSgtKLtqsaEGbwSyPxNJ+qNax5u4v7dBquQ6Txl2x+74q pqZ/NfmVthEWkWjrShgifMTk2LXqx43ajMIKh7jzeryGg+2R2pfKSWtj43abc75M56Mbe7e4yIz HBxy+7/MwcA61ERgq20QIePKFyRgiskZzRY/AvMtPeA1CPtuuJNfua5UhyCyai7+U7yEeLDemuB ZB4fse/gCgbVT+h97wWv4G2XAC+2wv3ypHl/S19I9ZGVlH+37aZ8ZqNFKh1is4vfJilbDwkp/82 Gx1kU93UNEs1lxpRzXjSzxSsYw6+X89NvMm1Y4MxFkWJ+ygMMu0mlOUwCZTrx3lcAE/KZ1zBhN3 CEOZ0hWTxlNsFnGvNgvKMZb6s4kIHi4jo= X-Google-Smtp-Source: AGHT+IFPTwIt7nEjlmvRxp5PL1S4hQtURwGy/5RtjK3MnXQGFAvywh+tGC7FpmbU5zh5Lt8qYg6brA== X-Received: by 2002:a05:6122:17a9:b0:54b:d7b6:2edb with SMTP id 71dfb90a1353d-5524e934263mr5092007e0c.8.1759807868739; Mon, 06 Oct 2025 20:31:08 -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 71dfb90a1353d-552ea335f07sm2446030e0c.15.2025.10.06.20.31.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Oct 2025 20:31:07 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org Subject: [PATCH v5 2/7] kho: make debugfs interface optional Date: Tue, 7 Oct 2025 03:30:55 +0000 Message-ID: <20251007033100.836886-3-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog In-Reply-To: <20251007033100.836886-1-pasha.tatashin@soleen.com> References: <20251007033100.836886-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" Currently, KHO is controlled via debugfs interface, but once LUO is introduced, it can control KHO, and the debug interface becomes optional. Add a separate config CONFIG_KEXEC_HANDOVER_DEBUGFS that enables the debugfs interface, and allows to inspect the tree. Move all debugfs related code to a new file to keep the .c files clear of ifdefs. Co-developed-by: Mike Rapoport (Microsoft) Signed-off-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin --- MAINTAINERS | 3 +- kernel/Kconfig.kexec | 10 ++ kernel/Makefile | 1 + kernel/kexec_handover.c | 223 +++----------------------- kernel/kexec_handover_debug.c | 213 ++++++++++++++++++++++++ kernel/kexec_handover_internal.h | 44 +++++ tools/testing/selftests/kho/vmtest.sh | 1 + 7 files changed, 290 insertions(+), 205 deletions(-) create mode 100644 kernel/kexec_handover_debug.c create mode 100644 kernel/kexec_handover_internal.h diff --git a/MAINTAINERS b/MAINTAINERS index 3773c74b31d6..49e8fc4a393e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13770,13 +13770,14 @@ KEXEC HANDOVER (KHO) M: Alexander Graf M: Mike Rapoport M: Changyuan Lyu +M: Pasha Tatashin L: kexec@lists.infradead.org L: linux-mm@kvack.org S: Maintained F: Documentation/admin-guide/mm/kho.rst F: Documentation/core-api/kho/* F: include/linux/kexec_handover.h -F: kernel/kexec_handover.c +F: kernel/kexec_handover* F: tools/testing/selftests/kho/ =20 KEYS-ENCRYPTED diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec index 422270d64820..03c3aa6263d3 100644 --- a/kernel/Kconfig.kexec +++ b/kernel/Kconfig.kexec @@ -109,6 +109,16 @@ config KEXEC_HANDOVER to keep data or state alive across the kexec. For this to work, both source and target kernels need to have this option enabled. =20 +config KEXEC_HANDOVER_DEBUGFS + bool "kexec handover debugfs interface" + depends on KEXEC_HANDOVER + depends on DEBUG_FS + help + Allow to control kexec handover device tree via debugfs + interface, i.e. finalize the state or aborting the finalization. + Also, enables inspecting the KHO fdt trees with the debugfs binary + blobs. + config CRASH_DUMP bool "kernel crash dumps" default ARCH_DEFAULT_CRASH_DUMP diff --git a/kernel/Makefile b/kernel/Makefile index df3dd8291bb6..f21d8c98d857 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -83,6 +83,7 @@ obj-$(CONFIG_KEXEC) +=3D kexec.o obj-$(CONFIG_KEXEC_FILE) +=3D kexec_file.o obj-$(CONFIG_KEXEC_ELF) +=3D kexec_elf.o obj-$(CONFIG_KEXEC_HANDOVER) +=3D kexec_handover.o +obj-$(CONFIG_KEXEC_HANDOVER_DEBUGFS) +=3D kexec_handover_debug.o obj-$(CONFIG_BACKTRACE_SELF_TEST) +=3D backtracetest.o obj-$(CONFIG_COMPAT) +=3D compat.o obj-$(CONFIG_CGROUPS) +=3D cgroup/ diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index 76c34ea923f0..f3627430b3c3 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -10,7 +10,6 @@ =20 #include #include -#include #include #include #include @@ -28,6 +27,7 @@ */ #include "../mm/internal.h" #include "kexec_internal.h" +#include "kexec_handover_internal.h" =20 #define KHO_FDT_COMPATIBLE "kho-v1" #define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map" @@ -101,8 +101,6 @@ struct khoser_mem_chunk; =20 struct kho_serialization { struct page *fdt; - struct list_head fdt_list; - struct dentry *sub_fdt_dir; struct kho_mem_track track; /* First chunk of serialized preserved memory map */ struct khoser_mem_chunk *preserved_mem_map; @@ -110,20 +108,16 @@ struct kho_serialization { =20 struct kho_out { struct blocking_notifier_head chain_head; - - struct dentry *dir; - struct mutex lock; /* protects KHO FDT finalization */ - struct kho_serialization ser; bool finalized; + struct kho_debugfs dbg; }; =20 static struct kho_out kho_out =3D { .chain_head =3D BLOCKING_NOTIFIER_INIT(kho_out.chain_head), .lock =3D __MUTEX_INITIALIZER(kho_out.lock), .ser =3D { - .fdt_list =3D LIST_HEAD_INIT(kho_out.ser.fdt_list), .track =3D { .orders =3D XARRAY_INIT(kho_out.ser.track.orders, 0), }, @@ -465,8 +459,8 @@ static void __init kho_mem_deserialize(const void *fdt) * area for early allocations that happen before page allocator is * initialized. */ -static struct kho_scratch *kho_scratch; -static unsigned int kho_scratch_cnt; +struct kho_scratch *kho_scratch; +unsigned int kho_scratch_cnt; =20 /* * The scratch areas are scaled by default as percent of memory allocated = from @@ -662,37 +656,6 @@ static void __init kho_reserve_scratch(void) kho_enable =3D false; } =20 -struct fdt_debugfs { - struct list_head list; - struct debugfs_blob_wrapper wrapper; - struct dentry *file; -}; - -static int kho_debugfs_fdt_add(struct list_head *list, struct dentry *dir, - const char *name, const void *fdt) -{ - struct fdt_debugfs *f; - struct dentry *file; - - f =3D kmalloc(sizeof(*f), GFP_KERNEL); - if (!f) - return -ENOMEM; - - f->wrapper.data =3D (void *)fdt; - f->wrapper.size =3D fdt_totalsize(fdt); - - file =3D debugfs_create_blob(name, 0400, dir, &f->wrapper); - if (IS_ERR(file)) { - kfree(f); - return PTR_ERR(file); - } - - f->file =3D file; - list_add(&f->list, list); - - return 0; -} - /** * kho_add_subtree - record the physical address of a sub FDT in KHO root = tree. * @ser: serialization control object passed by KHO notifiers. @@ -704,7 +667,8 @@ static int kho_debugfs_fdt_add(struct list_head *list, = struct dentry *dir, * by KHO for the new kernel to retrieve it after kexec. * * A debugfs blob entry is also created at - * ``/sys/kernel/debug/kho/out/sub_fdts/@name``. + * ``/sys/kernel/debug/kho/out/sub_fdts/@name`` when kernel is configured = with + * CONFIG_KEXEC_HANDOVER_DEBUGFS * * Return: 0 on success, error code on failure */ @@ -721,7 +685,7 @@ int kho_add_subtree(struct kho_serialization *ser, cons= t char *name, void *fdt) if (err) return err; =20 - return kho_debugfs_fdt_add(&ser->fdt_list, ser->sub_fdt_dir, name, fdt); + return kho_debugfs_fdt_add(&kho_out.dbg, name, fdt, false); } EXPORT_SYMBOL_GPL(kho_add_subtree); =20 @@ -1044,29 +1008,6 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *= preservation) } EXPORT_SYMBOL_GPL(kho_restore_vmalloc); =20 -/* Handling for debug/kho/out */ - -static struct dentry *debugfs_root; - -static int kho_out_update_debugfs_fdt(void) -{ - int err =3D 0; - struct fdt_debugfs *ff, *tmp; - - if (kho_out.finalized) { - err =3D kho_debugfs_fdt_add(&kho_out.ser.fdt_list, kho_out.dir, - "fdt", page_to_virt(kho_out.ser.fdt)); - } else { - list_for_each_entry_safe(ff, tmp, &kho_out.ser.fdt_list, list) { - debugfs_remove(ff->file); - list_del(&ff->list); - kfree(ff); - } - } - - return err; -} - static int __kho_abort(void) { int err; @@ -1116,8 +1057,9 @@ int kho_abort(void) return ret; =20 kho_out.finalized =3D false; + kho_debugfs_cleanup(&kho_out.dbg); =20 - return kho_out_update_debugfs_fdt(); + return 0; } =20 static int __kho_finalize(void) @@ -1186,89 +1128,23 @@ int kho_finalize(void) =20 kho_out.finalized =3D true; =20 - return kho_out_update_debugfs_fdt(); -} - -static int kho_out_finalize_get(void *data, u64 *val) -{ - mutex_lock(&kho_out.lock); - *val =3D kho_out.finalized; - mutex_unlock(&kho_out.lock); - - return 0; -} - -static int kho_out_finalize_set(void *data, u64 _val) -{ - return (!!_val) ? kho_finalize() : kho_abort(); -} - -DEFINE_DEBUGFS_ATTRIBUTE(fops_kho_out_finalize, kho_out_finalize_get, - kho_out_finalize_set, "%llu\n"); - -static int scratch_phys_show(struct seq_file *m, void *v) -{ - for (int i =3D 0; i < kho_scratch_cnt; i++) - seq_printf(m, "0x%llx\n", kho_scratch[i].addr); - - return 0; -} -DEFINE_SHOW_ATTRIBUTE(scratch_phys); - -static int scratch_len_show(struct seq_file *m, void *v) -{ - for (int i =3D 0; i < kho_scratch_cnt; i++) - seq_printf(m, "0x%llx\n", kho_scratch[i].size); - - return 0; + return kho_debugfs_fdt_add(&kho_out.dbg, "fdt", + page_to_virt(kho_out.ser.fdt), true); } -DEFINE_SHOW_ATTRIBUTE(scratch_len); =20 -static __init int kho_out_debugfs_init(void) +bool kho_finalized(void) { - struct dentry *dir, *f, *sub_fdt_dir; - - dir =3D debugfs_create_dir("out", debugfs_root); - if (IS_ERR(dir)) - return -ENOMEM; - - sub_fdt_dir =3D debugfs_create_dir("sub_fdts", dir); - if (IS_ERR(sub_fdt_dir)) - goto err_rmdir; - - f =3D debugfs_create_file("scratch_phys", 0400, dir, NULL, - &scratch_phys_fops); - if (IS_ERR(f)) - goto err_rmdir; - - f =3D debugfs_create_file("scratch_len", 0400, dir, NULL, - &scratch_len_fops); - if (IS_ERR(f)) - goto err_rmdir; - - f =3D debugfs_create_file("finalize", 0600, dir, NULL, - &fops_kho_out_finalize); - if (IS_ERR(f)) - goto err_rmdir; - - kho_out.dir =3D dir; - kho_out.ser.sub_fdt_dir =3D sub_fdt_dir; - return 0; - -err_rmdir: - debugfs_remove_recursive(dir); - return -ENOENT; + guard(mutex)(&kho_out.lock); + return kho_out.finalized; } =20 struct kho_in { - struct dentry *dir; phys_addr_t fdt_phys; phys_addr_t scratch_phys; - struct list_head fdt_list; + struct kho_debugfs dbg; }; =20 static struct kho_in kho_in =3D { - .fdt_list =3D LIST_HEAD_INIT(kho_in.fdt_list), }; =20 static const void *kho_get_fdt(void) @@ -1332,56 +1208,6 @@ int kho_retrieve_subtree(const char *name, phys_addr= _t *phys) } EXPORT_SYMBOL_GPL(kho_retrieve_subtree); =20 -/* Handling for debugfs/kho/in */ - -static __init int kho_in_debugfs_init(const void *fdt) -{ - struct dentry *sub_fdt_dir; - int err, child; - - kho_in.dir =3D debugfs_create_dir("in", debugfs_root); - if (IS_ERR(kho_in.dir)) - return PTR_ERR(kho_in.dir); - - sub_fdt_dir =3D debugfs_create_dir("sub_fdts", kho_in.dir); - if (IS_ERR(sub_fdt_dir)) { - err =3D PTR_ERR(sub_fdt_dir); - goto err_rmdir; - } - - err =3D kho_debugfs_fdt_add(&kho_in.fdt_list, kho_in.dir, "fdt", fdt); - if (err) - goto err_rmdir; - - fdt_for_each_subnode(child, fdt, 0) { - int len =3D 0; - const char *name =3D fdt_get_name(fdt, child, NULL); - const u64 *fdt_phys; - - fdt_phys =3D fdt_getprop(fdt, child, "fdt", &len); - if (!fdt_phys) - continue; - if (len !=3D sizeof(*fdt_phys)) { - pr_warn("node `%s`'s prop `fdt` has invalid length: %d\n", - name, len); - continue; - } - err =3D kho_debugfs_fdt_add(&kho_in.fdt_list, sub_fdt_dir, name, - phys_to_virt(*fdt_phys)); - if (err) { - pr_warn("failed to add fdt `%s` to debugfs: %d\n", name, - err); - continue; - } - } - - return 0; - -err_rmdir: - debugfs_remove_recursive(kho_in.dir); - return err; -} - static __init int kho_init(void) { int err =3D 0; @@ -1396,27 +1222,16 @@ static __init int kho_init(void) goto err_free_scratch; } =20 - debugfs_root =3D debugfs_create_dir("kho", NULL); - if (IS_ERR(debugfs_root)) { - err =3D -ENOENT; + err =3D kho_debugfs_init(); + if (err) goto err_free_fdt; - } =20 - err =3D kho_out_debugfs_init(); + err =3D kho_out_debugfs_init(&kho_out.dbg); if (err) goto err_free_fdt; =20 if (fdt) { - err =3D kho_in_debugfs_init(fdt); - /* - * Failure to create /sys/kernel/debug/kho/in does not prevent - * reviving state from KHO and setting up KHO for the next - * kexec. - */ - if (err) - pr_err("failed exposing handover FDT in debugfs: %d\n", - err); - + kho_in_debugfs_init(&kho_in.dbg, fdt); return 0; } =20 diff --git a/kernel/kexec_handover_debug.c b/kernel/kexec_handover_debug.c new file mode 100644 index 000000000000..edd080c42f1c --- /dev/null +++ b/kernel/kexec_handover_debug.c @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * kexec_handover.c - kexec handover metadata processing + * Copyright (C) 2023 Alexander Graf + * Copyright (C) 2025 Microsoft Corporation, Mike Rapoport + * Copyright (C) 2025 Google LLC, Changyuan Lyu + * Copyright (C) 2025 Google LLC, Pasha Tatashin + */ + +#define pr_fmt(fmt) "KHO: " fmt + +#include +#include +#include +#include +#include "kexec_handover_internal.h" + +static struct dentry *debugfs_root; + +struct fdt_debugfs { + struct list_head list; + struct debugfs_blob_wrapper wrapper; + struct dentry *file; +}; + +static int __kho_debugfs_fdt_add(struct list_head *list, struct dentry *di= r, + const char *name, const void *fdt) +{ + struct fdt_debugfs *f; + struct dentry *file; + + f =3D kmalloc(sizeof(*f), GFP_KERNEL); + if (!f) + return -ENOMEM; + + f->wrapper.data =3D (void *)fdt; + f->wrapper.size =3D fdt_totalsize(fdt); + + file =3D debugfs_create_blob(name, 0400, dir, &f->wrapper); + if (IS_ERR(file)) { + kfree(f); + return PTR_ERR(file); + } + + f->file =3D file; + list_add(&f->list, list); + + return 0; +} + +int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name, + const void *fdt, bool root) +{ + struct dentry *dir; + + if (root) + dir =3D dbg->dir; + else + dir =3D dbg->sub_fdt_dir; + + return __kho_debugfs_fdt_add(&dbg->fdt_list, dir, name, fdt); +} + +void kho_debugfs_cleanup(struct kho_debugfs *dbg) +{ + struct fdt_debugfs *ff, *tmp; + + list_for_each_entry_safe(ff, tmp, &dbg->fdt_list, list) { + debugfs_remove(ff->file); + list_del(&ff->list); + kfree(ff); + } +} + +static int kho_out_finalize_get(void *data, u64 *val) +{ + *val =3D kho_finalized(); + + return 0; +} + +static int kho_out_finalize_set(void *data, u64 _val) +{ + return (!!_val) ? kho_finalize() : kho_abort(); +} + +DEFINE_DEBUGFS_ATTRIBUTE(kho_out_finalize_fops, kho_out_finalize_get, + kho_out_finalize_set, "%llu\n"); + +static int scratch_phys_show(struct seq_file *m, void *v) +{ + for (int i =3D 0; i < kho_scratch_cnt; i++) + seq_printf(m, "0x%llx\n", kho_scratch[i].addr); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(scratch_phys); + +static int scratch_len_show(struct seq_file *m, void *v) +{ + for (int i =3D 0; i < kho_scratch_cnt; i++) + seq_printf(m, "0x%llx\n", kho_scratch[i].size); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(scratch_len); + +__init void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt) +{ + struct dentry *dir, *sub_fdt_dir; + int err, child; + + INIT_LIST_HEAD(&dbg->fdt_list); + + dir =3D debugfs_create_dir("in", debugfs_root); + if (IS_ERR(dir)) { + err =3D PTR_ERR(dir); + goto err_out; + } + + sub_fdt_dir =3D debugfs_create_dir("sub_fdts", dir); + if (IS_ERR(sub_fdt_dir)) { + err =3D PTR_ERR(sub_fdt_dir); + goto err_rmdir; + } + + err =3D __kho_debugfs_fdt_add(&dbg->fdt_list, dir, "fdt", fdt); + if (err) + goto err_rmdir; + + fdt_for_each_subnode(child, fdt, 0) { + int len =3D 0; + const char *name =3D fdt_get_name(fdt, child, NULL); + const u64 *fdt_phys; + + fdt_phys =3D fdt_getprop(fdt, child, "fdt", &len); + if (!fdt_phys) + continue; + if (len !=3D sizeof(*fdt_phys)) { + pr_warn("node %s prop fdt has invalid length: %d\n", + name, len); + continue; + } + err =3D __kho_debugfs_fdt_add(&dbg->fdt_list, sub_fdt_dir, name, + phys_to_virt(*fdt_phys)); + if (err) { + pr_warn("failed to add fdt %s to debugfs: %d\n", name, + err); + continue; + } + } + + dbg->dir =3D dir; + dbg->sub_fdt_dir =3D sub_fdt_dir; + + return; +err_rmdir: + debugfs_remove_recursive(dir); +err_out: + /* + * Failure to create /sys/kernel/debug/kho/in does not prevent + * reviving state from KHO and setting up KHO for the next + * kexec. + */ + if (err) + pr_err("failed exposing handover FDT in debugfs: %d\n", err); +} + +__init int kho_out_debugfs_init(struct kho_debugfs *dbg) +{ + struct dentry *dir, *f, *sub_fdt_dir; + + INIT_LIST_HEAD(&dbg->fdt_list); + + dir =3D debugfs_create_dir("out", debugfs_root); + if (IS_ERR(dir)) + return -ENOMEM; + + sub_fdt_dir =3D debugfs_create_dir("sub_fdts", dir); + if (IS_ERR(sub_fdt_dir)) + goto err_rmdir; + + f =3D debugfs_create_file("scratch_phys", 0400, dir, NULL, + &scratch_phys_fops); + if (IS_ERR(f)) + goto err_rmdir; + + f =3D debugfs_create_file("scratch_len", 0400, dir, NULL, + &scratch_len_fops); + if (IS_ERR(f)) + goto err_rmdir; + + f =3D debugfs_create_file("finalize", 0600, dir, NULL, + &kho_out_finalize_fops); + if (IS_ERR(f)) + goto err_rmdir; + + dbg->dir =3D dir; + dbg->sub_fdt_dir =3D sub_fdt_dir; + return 0; + +err_rmdir: + debugfs_remove_recursive(dir); + return -ENOENT; +} + +__init int kho_debugfs_init(void) +{ + debugfs_root =3D debugfs_create_dir("kho", NULL); + if (IS_ERR(debugfs_root)) + return -ENOENT; + return 0; +} diff --git a/kernel/kexec_handover_internal.h b/kernel/kexec_handover_inter= nal.h new file mode 100644 index 000000000000..042c189af768 --- /dev/null +++ b/kernel/kexec_handover_internal.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_KEXEC_HANDOVER_INTERNAL_H +#define LINUX_KEXEC_HANDOVER_INTERNAL_H + +#include +#include +#include + +#ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS +#include + +struct kho_debugfs { + struct dentry *dir; + struct dentry *sub_fdt_dir; + struct list_head fdt_list; +}; + +#else +struct kho_debugfs {}; +#endif + +extern struct kho_scratch *kho_scratch; +extern unsigned int kho_scratch_cnt; + +bool kho_finalized(void); + +#ifdef CONFIG_KEXEC_HANDOVER_DEBUGFS +int kho_debugfs_init(void); +void kho_in_debugfs_init(struct kho_debugfs *dbg, const void *fdt); +int kho_out_debugfs_init(struct kho_debugfs *dbg); +int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name, + const void *fdt, bool root); +void kho_debugfs_cleanup(struct kho_debugfs *dbg); +#else +static inline int kho_debugfs_init(void) { return 0; } +static inline void kho_in_debugfs_init(struct kho_debugfs *dbg, + const void *fdt) { } +static inline int kho_out_debugfs_init(struct kho_debugfs *dbg) { return 0= ; } +static inline int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char = *name, + const void *fdt, bool root) { return 0; } +static inline void kho_debugfs_cleanup(struct kho_debugfs *dbg) {} +#endif /* CONFIG_KEXEC_HANDOVER_DEBUGFS */ + +#endif /* LINUX_KEXEC_HANDOVER_INTERNAL_H */ diff --git a/tools/testing/selftests/kho/vmtest.sh b/tools/testing/selftest= s/kho/vmtest.sh index 3f6c17166846..49fdac8e8b15 100755 --- a/tools/testing/selftests/kho/vmtest.sh +++ b/tools/testing/selftests/kho/vmtest.sh @@ -59,6 +59,7 @@ function build_kernel() { tee "$kconfig" > "$kho_config" <; Tue, 7 Oct 2025 03:31:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807874; cv=none; b=SCZKYdcoEu/H6ZM9pVAaiSW8NCmJkUm0d1dc8GxZNpkEI9Gy6Y1Q88OwddpwNxVjGpp67gHghqYAI8XV8OFjfFgQ3HfxAe0btBC3GE38CIcpi1B9OhPQrCPlvlrCq8kz8hT8bGNmNE/3cDhdMHE6Y69vy51cvZm8b4vlyxcGKEU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807874; c=relaxed/simple; bh=atkQCMNvrpZMViTM52/PINz9xm4XeXCE1Cj5cu3jsuA=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=drs1fH5mn7KCi+fMs0xD5Mk8Z/Oq/5ysPumTUjWzT13snrqZgXien5c+sm7hw/eK/adREZFurkUttBFoq4bawKom5CHewY3lZXhQE2NAg+CZgTVCKNp5O80tDiZb6hypk3qO2VLkQFbD1TdG/nQmfWhUaHMkwN1DI6K9RLIY1ZY= 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=OhFPqi3w; arc=none smtp.client-ip=209.85.221.169 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="OhFPqi3w" Received: by mail-vk1-f169.google.com with SMTP id 71dfb90a1353d-54aa4b86b09so3011734e0c.0 for ; Mon, 06 Oct 2025 20:31:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759807870; x=1760412670; 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=Hc+5bAoG3TM9kcaUm1KO8uk0lemQxPABg9qHjeAsd0s=; b=OhFPqi3wlx/6YmP8wQM9afE8+VlwqdukUlixzLWy9AOYZjSoSdHnTd0KzTVuiToyVu GTAH2Sq64CSbINsFHRbAoG+fAomSeDDDAJ2szEgMa2lc1EtxUnKR0yfVitKHQAQ7k4j1 1FHRW/uDsTRelenF4tnuLniUzpGTjdoJb1pVUvFcP2YHvcvv5CJOIMt9g1o9hprZu30z 2dKk4zRaZdW3bvJ+i+jEbrs3YHF1JKyAOUX1RCupT5DKUvNcvM8qqe9jpbFKSczu9ijG roNLpNgVDqUZj5ECnd6nnWa8e3le0VSCnXC6c1gCuwfWFwDCQ2hMHmzNKp3x1YGNzcyY IBPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759807870; x=1760412670; 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=Hc+5bAoG3TM9kcaUm1KO8uk0lemQxPABg9qHjeAsd0s=; b=VkBSUEpQmILLgMfewm4n+cqjeJNqsGcEdDg0hULmOjclOW4WD8XzTkBUpLv/oN47h/ Eg/XQ5zEZs03zM32ZRHpuoVjXuENua0BE7bbug0mxNwhx5+WbPdRuUtxgDSVLfdufND8 SxeIDBufMLHom9ULuRh8S4X1ZJt7HiT5fkfA4hJV/u7KsaqxRkMOE4i82TmEkkkO0+55 bTTa+2AyGtCiOfi/MMosKj9EfT80Wq1iGEKTaANyM9fR2gBGbl93OPgwC1aiswu+zczd tNZWtLk0PuyoogcbP1kOsa9VqlfilHkhyyXyiAqgWacT/XpJ+xclbGNrjpcM4k65dsIJ gNWg== X-Forwarded-Encrypted: i=1; AJvYcCXaZjfDuQmWwgNM8SplJbYLnFb3UaWNHs7NBHiJZ9HvzNu/Qw0gjv5bu85MDhtZYEuESIuIiCLGyLiuoBg=@vger.kernel.org X-Gm-Message-State: AOJu0YyrKmK/MyoswiHjgMiAsesBNxF1L2z9c9q45uvrb0t5plNKx+zT aCajQxfpWqLD+U1zQ7J5ghtb3XfeKG+9WnngVCmtMVOzWDB4TatACJKI7mICT/5xG14= X-Gm-Gg: ASbGncvs3lNH2ZEEJp1jYRlm5B5JXqSTQfE/VaKawbx0xNt4XkAvgww7Fox4DK0oUgZ h+RIGVT969eD9cIXWU1Uu3Xo/BcyEzYo/HdOycrHM11LAfl93LNppFbQHqJest+SqJKOayJLQUk tXex7+guGCW/XyFHHoNe6qV+7OJBKSQy0HqO9IeJFxd3eR29MsOqf7MCkzTzHb1D3qZXiO3WI9g ZOmRqX9OklCZ5dnugi7WdZnKuuAJASxMKa9NrqY4m/19Ny1he2KimN4R4vnqe3Wth9RH5+3Xes5 Cb+SQPE4+8MBMMSLkfW3FkD4ESvWji42BJrB1tDr/C26VggLnE98yvap/lfFEfOnR36uTQhwpNc oEJvvPBLAAcj6NNjbvcZKKOzGTgEZ16fj1wYcC5NGic5O19mdEhkEK72x5Snmn3sxjhpn0Q7oc8 FY7Hm1/I5lLLwR9xxECGKGvk877sy56o8= X-Google-Smtp-Source: AGHT+IG2z15j5VqzNyJC+9nOTGyx5nJ8jMWPtG3hpaemmVCy8leNqRwJ9jgDFgspDxfn4+jCSocBkA== X-Received: by 2002:a05:6102:3a0e:b0:522:f65e:c76d with SMTP id ada2fe7eead31-5d41d107efamr5328283137.23.1759807870040; Mon, 06 Oct 2025 20:31:10 -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 71dfb90a1353d-552ea335f07sm2446030e0c.15.2025.10.06.20.31.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Oct 2025 20:31:09 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org Subject: [PATCH v5 3/7] kho: drop notifiers Date: Tue, 7 Oct 2025 03:30:56 +0000 Message-ID: <20251007033100.836886-4-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog In-Reply-To: <20251007033100.836886-1-pasha.tatashin@soleen.com> References: <20251007033100.836886-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" From: "Mike Rapoport (Microsoft)" The KHO framework uses a notifier chain as the mechanism for clients to participate in the finalization process. While this works for a single, central state machine, it is too restrictive for kernel-internal components like pstore/reserve_mem or IMA. These components need a simpler, direct way to register their state for preservation (e.g., during their initcall) without being part of a complex, shutdown-time notifier sequence. The notifier model forces all participants into a single finalization flow and makes direct preservation from an arbitrary context difficult. This patch refactors the client participation model by removing the notifier chain and introducing a direct API for managing FDT subtrees. The core kho_finalize() and kho_abort() state machine remains, but clients now register their data with KHO beforehand. Signed-off-by: Mike Rapoport (Microsoft) Signed-off-by: Pasha Tatashin --- include/linux/kexec_handover.h | 28 +----- kernel/kexec_handover.c | 164 +++++++++++++++++-------------- kernel/kexec_handover_debug.c | 17 ++-- kernel/kexec_handover_internal.h | 5 +- lib/test_kho.c | 30 +----- mm/memblock.c | 60 +++-------- 6 files changed, 125 insertions(+), 179 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 04d0108db98e..2faf290803ce 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -10,14 +10,7 @@ struct kho_scratch { phys_addr_t size; }; =20 -/* KHO Notifier index */ -enum kho_event { - KEXEC_KHO_FINALIZE =3D 0, - KEXEC_KHO_ABORT =3D 1, -}; - struct folio; -struct notifier_block; struct page; =20 #define DECLARE_KHOSER_PTR(name, type) \ @@ -37,8 +30,6 @@ struct page; (typeof((s).ptr))((s).phys ? phys_to_virt((s).phys) : NULL); \ }) =20 -struct kho_serialization; - struct kho_vmalloc_chunk; struct kho_vmalloc { DECLARE_KHOSER_PTR(first, struct kho_vmalloc_chunk *); @@ -57,12 +48,10 @@ int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc = *preservation); struct folio *kho_restore_folio(phys_addr_t phys); struct page *kho_restore_pages(phys_addr_t phys, unsigned int nr_pages); void *kho_restore_vmalloc(const struct kho_vmalloc *preservation); -int kho_add_subtree(struct kho_serialization *ser, const char *name, void = *fdt); +int kho_add_subtree(const char *name, void *fdt); +void kho_remove_subtree(void *fdt); int kho_retrieve_subtree(const char *name, phys_addr_t *phys); =20 -int register_kho_notifier(struct notifier_block *nb); -int unregister_kho_notifier(struct notifier_block *nb); - void kho_memory_init(void); =20 void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_p= hys, @@ -114,23 +103,16 @@ static inline void *kho_restore_vmalloc(const struct = kho_vmalloc *preservation) return NULL; } =20 -static inline int kho_add_subtree(struct kho_serialization *ser, - const char *name, void *fdt) +static inline int kho_add_subtree(const char *name, void *fdt) { return -EOPNOTSUPP; } =20 -static inline int kho_retrieve_subtree(const char *name, phys_addr_t *phys) +static inline void kho_remove_subtree(void *fdt) { - return -EOPNOTSUPP; } =20 -static inline int register_kho_notifier(struct notifier_block *nb) -{ - return -EOPNOTSUPP; -} - -static inline int unregister_kho_notifier(struct notifier_block *nb) +static inline int kho_retrieve_subtree(const char *name, phys_addr_t *phys) { return -EOPNOTSUPP; } diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index f3627430b3c3..846fb4aa6948 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include =20 @@ -99,29 +98,34 @@ struct kho_mem_track { =20 struct khoser_mem_chunk; =20 -struct kho_serialization { - struct page *fdt; - struct kho_mem_track track; - /* First chunk of serialized preserved memory map */ - struct khoser_mem_chunk *preserved_mem_map; +struct kho_sub_fdt { + struct list_head l; + const char *name; + void *fdt; }; =20 struct kho_out { - struct blocking_notifier_head chain_head; - struct mutex lock; /* protects KHO FDT finalization */ - struct kho_serialization ser; + void *fdt; bool finalized; + struct mutex lock; /* protects KHO FDT finalization */ + + struct list_head sub_fdts; + struct mutex fdts_lock; + + struct kho_mem_track track; + /* First chunk of serialized preserved memory map */ + struct khoser_mem_chunk *preserved_mem_map; + struct kho_debugfs dbg; }; =20 static struct kho_out kho_out =3D { - .chain_head =3D BLOCKING_NOTIFIER_INIT(kho_out.chain_head), .lock =3D __MUTEX_INITIALIZER(kho_out.lock), - .ser =3D { - .track =3D { - .orders =3D XARRAY_INIT(kho_out.ser.track.orders, 0), - }, + .track =3D { + .orders =3D XARRAY_INIT(kho_out.track.orders, 0), }, + .sub_fdts =3D LIST_HEAD_INIT(kho_out.sub_fdts), + .fdts_lock =3D __MUTEX_INITIALIZER(kho_out.fdts_lock), .finalized =3D false, }; =20 @@ -362,14 +366,14 @@ static void kho_mem_ser_free(struct khoser_mem_chunk = *first_chunk) } } =20 -static int kho_mem_serialize(struct kho_serialization *ser) +static int kho_mem_serialize(struct kho_out *kho_out) { struct khoser_mem_chunk *first_chunk =3D NULL; struct khoser_mem_chunk *chunk =3D NULL; struct kho_mem_phys *physxa; unsigned long order; =20 - xa_for_each(&ser->track.orders, order, physxa) { + xa_for_each(&kho_out->track.orders, order, physxa) { struct kho_mem_phys_bits *bits; unsigned long phys; =20 @@ -397,7 +401,7 @@ static int kho_mem_serialize(struct kho_serialization *= ser) } } =20 - ser->preserved_mem_map =3D first_chunk; + kho_out->preserved_mem_map =3D first_chunk; =20 return 0; =20 @@ -658,7 +662,6 @@ static void __init kho_reserve_scratch(void) =20 /** * kho_add_subtree - record the physical address of a sub FDT in KHO root = tree. - * @ser: serialization control object passed by KHO notifiers. * @name: name of the sub tree. * @fdt: the sub tree blob. * @@ -672,34 +675,45 @@ static void __init kho_reserve_scratch(void) * * Return: 0 on success, error code on failure */ -int kho_add_subtree(struct kho_serialization *ser, const char *name, void = *fdt) +int kho_add_subtree(const char *name, void *fdt) { - int err =3D 0; - u64 phys =3D (u64)virt_to_phys(fdt); - void *root =3D page_to_virt(ser->fdt); + struct kho_sub_fdt *sub_fdt; + int err; =20 - err |=3D fdt_begin_node(root, name); - err |=3D fdt_property(root, PROP_SUB_FDT, &phys, sizeof(phys)); - err |=3D fdt_end_node(root); + sub_fdt =3D kmalloc(sizeof(*sub_fdt), GFP_KERNEL); + if (!sub_fdt) + return -ENOMEM; =20 - if (err) - return err; + INIT_LIST_HEAD(&sub_fdt->l); + sub_fdt->name =3D name; + sub_fdt->fdt =3D fdt; =20 - return kho_debugfs_fdt_add(&kho_out.dbg, name, fdt, false); + mutex_lock(&kho_out.fdts_lock); + list_add_tail(&sub_fdt->l, &kho_out.sub_fdts); + err =3D kho_debugfs_fdt_add(&kho_out.dbg, name, fdt, false); + mutex_unlock(&kho_out.fdts_lock); + + return err; } EXPORT_SYMBOL_GPL(kho_add_subtree); =20 -int register_kho_notifier(struct notifier_block *nb) +void kho_remove_subtree(void *fdt) { - return blocking_notifier_chain_register(&kho_out.chain_head, nb); -} -EXPORT_SYMBOL_GPL(register_kho_notifier); + struct kho_sub_fdt *sub_fdt; + + mutex_lock(&kho_out.fdts_lock); + list_for_each_entry(sub_fdt, &kho_out.sub_fdts, l) { + if (sub_fdt->fdt =3D=3D fdt) { + list_del(&sub_fdt->l); + kfree(sub_fdt); + kho_debugfs_fdt_remove(&kho_out.dbg, fdt); + break; + } + } + mutex_unlock(&kho_out.fdts_lock); =20 -int unregister_kho_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&kho_out.chain_head, nb); } -EXPORT_SYMBOL_GPL(unregister_kho_notifier); +EXPORT_SYMBOL_GPL(kho_remove_subtree); =20 /** * kho_preserve_folio - preserve a folio across kexec. @@ -714,7 +728,7 @@ int kho_preserve_folio(struct folio *folio) { const unsigned long pfn =3D folio_pfn(folio); const unsigned int order =3D folio_order(folio); - struct kho_mem_track *track =3D &kho_out.ser.track; + struct kho_mem_track *track =3D &kho_out.track; =20 return __kho_preserve_order(track, pfn, order); } @@ -732,7 +746,7 @@ EXPORT_SYMBOL_GPL(kho_preserve_folio); */ int kho_preserve_pages(struct page *page, unsigned int nr_pages) { - struct kho_mem_track *track =3D &kho_out.ser.track; + struct kho_mem_track *track =3D &kho_out.track; const unsigned long start_pfn =3D page_to_pfn(page); const unsigned long end_pfn =3D start_pfn + nr_pages; unsigned long pfn =3D start_pfn; @@ -828,7 +842,7 @@ static struct kho_vmalloc_chunk *new_vmalloc_chunk(stru= ct kho_vmalloc_chunk *cur =20 static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk) { - struct kho_mem_track *track =3D &kho_out.ser.track; + struct kho_mem_track *track =3D &kho_out.track; unsigned long pfn =3D PHYS_PFN(virt_to_phys(chunk)); =20 __kho_unpreserve(track, pfn, pfn + 1); @@ -1010,11 +1024,11 @@ EXPORT_SYMBOL_GPL(kho_restore_vmalloc); =20 static int __kho_abort(void) { - int err; + int err =3D 0; unsigned long order; struct kho_mem_phys *physxa; =20 - xa_for_each(&kho_out.ser.track.orders, order, physxa) { + xa_for_each(&kho_out.track.orders, order, physxa) { struct kho_mem_phys_bits *bits; unsigned long phys; =20 @@ -1024,17 +1038,13 @@ static int __kho_abort(void) xa_destroy(&physxa->phys_bits); kfree(physxa); } - xa_destroy(&kho_out.ser.track.orders); + xa_destroy(&kho_out.track.orders); =20 - if (kho_out.ser.preserved_mem_map) { - kho_mem_ser_free(kho_out.ser.preserved_mem_map); - kho_out.ser.preserved_mem_map =3D NULL; + if (kho_out.preserved_mem_map) { + kho_mem_ser_free(kho_out.preserved_mem_map); + kho_out.preserved_mem_map =3D NULL; } =20 - err =3D blocking_notifier_call_chain(&kho_out.chain_head, KEXEC_KHO_ABORT, - NULL); - err =3D notifier_to_errno(err); - if (err) pr_err("Failed to abort KHO finalization: %d\n", err); =20 @@ -1057,7 +1067,8 @@ int kho_abort(void) return ret; =20 kho_out.finalized =3D false; - kho_debugfs_cleanup(&kho_out.dbg); + + kho_debugfs_fdt_remove(&kho_out.dbg, kho_out.fdt); =20 return 0; } @@ -1066,41 +1077,46 @@ static int __kho_finalize(void) { int err =3D 0; u64 *preserved_mem_map; - void *fdt =3D page_to_virt(kho_out.ser.fdt); + void *root =3D kho_out.fdt; + struct kho_sub_fdt *fdt; =20 - err |=3D fdt_create(fdt, PAGE_SIZE); - err |=3D fdt_finish_reservemap(fdt); - err |=3D fdt_begin_node(fdt, ""); - err |=3D fdt_property_string(fdt, "compatible", KHO_FDT_COMPATIBLE); + err |=3D fdt_create(root, PAGE_SIZE); + err |=3D fdt_finish_reservemap(root); + err |=3D fdt_begin_node(root, ""); + err |=3D fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); /** * Reserve the preserved-memory-map property in the root FDT, so * that all property definitions will precede subnodes created by * KHO callers. */ - err |=3D fdt_property_placeholder(fdt, PROP_PRESERVED_MEMORY_MAP, + err |=3D fdt_property_placeholder(root, PROP_PRESERVED_MEMORY_MAP, sizeof(*preserved_mem_map), (void **)&preserved_mem_map); if (err) goto abort; =20 - err =3D kho_preserve_folio(page_folio(kho_out.ser.fdt)); + err =3D kho_preserve_folio(virt_to_folio(kho_out.fdt)); if (err) goto abort; =20 - err =3D blocking_notifier_call_chain(&kho_out.chain_head, - KEXEC_KHO_FINALIZE, &kho_out.ser); - err =3D notifier_to_errno(err); + err =3D kho_mem_serialize(&kho_out); if (err) goto abort; =20 - err =3D kho_mem_serialize(&kho_out.ser); - if (err) - goto abort; + *preserved_mem_map =3D (u64)virt_to_phys(kho_out.preserved_mem_map); + + mutex_lock(&kho_out.fdts_lock); + list_for_each_entry(fdt, &kho_out.sub_fdts, l) { + phys_addr_t phys =3D virt_to_phys(fdt->fdt); =20 - *preserved_mem_map =3D (u64)virt_to_phys(kho_out.ser.preserved_mem_map); + err |=3D fdt_begin_node(root, fdt->name); + err |=3D fdt_property(root, PROP_SUB_FDT, &phys, sizeof(phys)); + err |=3D fdt_end_node(root); + }; + mutex_unlock(&kho_out.fdts_lock); =20 - err |=3D fdt_end_node(fdt); - err |=3D fdt_finish(fdt); + err |=3D fdt_end_node(root); + err |=3D fdt_finish(root); =20 abort: if (err) { @@ -1129,7 +1145,7 @@ int kho_finalize(void) kho_out.finalized =3D true; =20 return kho_debugfs_fdt_add(&kho_out.dbg, "fdt", - page_to_virt(kho_out.ser.fdt), true); + kho_out.fdt, true); } =20 bool kho_finalized(void) @@ -1212,15 +1228,17 @@ static __init int kho_init(void) { int err =3D 0; const void *fdt =3D kho_get_fdt(); + struct page *fdt_page; =20 if (!kho_enable) return 0; =20 - kho_out.ser.fdt =3D alloc_page(GFP_KERNEL); - if (!kho_out.ser.fdt) { + fdt_page =3D alloc_page(GFP_KERNEL); + if (!fdt_page) { err =3D -ENOMEM; goto err_free_scratch; } + kho_out.fdt =3D page_to_virt(fdt_page); =20 err =3D kho_debugfs_init(); if (err) @@ -1248,8 +1266,8 @@ static __init int kho_init(void) return 0; =20 err_free_fdt: - put_page(kho_out.ser.fdt); - kho_out.ser.fdt =3D NULL; + put_page(fdt_page); + kho_out.fdt =3D NULL; err_free_scratch: for (int i =3D 0; i < kho_scratch_cnt; i++) { void *start =3D __va(kho_scratch[i].addr); @@ -1260,7 +1278,7 @@ static __init int kho_init(void) kho_enable =3D false; return err; } -late_initcall(kho_init); +fs_initcall(kho_init); =20 static void __init kho_release_scratch(void) { @@ -1396,7 +1414,7 @@ int kho_fill_kimage(struct kimage *image) if (!kho_out.finalized) return 0; =20 - image->kho.fdt =3D page_to_phys(kho_out.ser.fdt); + image->kho.fdt =3D virt_to_phys(kho_out.fdt); =20 scratch_size =3D sizeof(*kho_scratch) * kho_scratch_cnt; scratch =3D (struct kexec_buf){ diff --git a/kernel/kexec_handover_debug.c b/kernel/kexec_handover_debug.c index edd080c42f1c..d4ac78d53a39 100644 --- a/kernel/kexec_handover_debug.c +++ b/kernel/kexec_handover_debug.c @@ -61,14 +61,17 @@ int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const = char *name, return __kho_debugfs_fdt_add(&dbg->fdt_list, dir, name, fdt); } =20 -void kho_debugfs_cleanup(struct kho_debugfs *dbg) +void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, void *fdt) { - struct fdt_debugfs *ff, *tmp; - - list_for_each_entry_safe(ff, tmp, &dbg->fdt_list, list) { - debugfs_remove(ff->file); - list_del(&ff->list); - kfree(ff); + struct fdt_debugfs *ff; + + list_for_each_entry(ff, &dbg->fdt_list, list) { + if (ff->wrapper.data =3D=3D fdt) { + debugfs_remove(ff->file); + list_del(&ff->list); + kfree(ff); + break; + } } } =20 diff --git a/kernel/kexec_handover_internal.h b/kernel/kexec_handover_inter= nal.h index 042c189af768..de90a678274d 100644 --- a/kernel/kexec_handover_internal.h +++ b/kernel/kexec_handover_internal.h @@ -30,7 +30,7 @@ void kho_in_debugfs_init(struct kho_debugfs *dbg, const v= oid *fdt); int kho_out_debugfs_init(struct kho_debugfs *dbg); int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name, const void *fdt, bool root); -void kho_debugfs_cleanup(struct kho_debugfs *dbg); +void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, void *fdt); #else static inline int kho_debugfs_init(void) { return 0; } static inline void kho_in_debugfs_init(struct kho_debugfs *dbg, @@ -38,7 +38,8 @@ static inline void kho_in_debugfs_init(struct kho_debugfs= *dbg, static inline int kho_out_debugfs_init(struct kho_debugfs *dbg) { return 0= ; } static inline int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char = *name, const void *fdt, bool root) { return 0; } -static inline void kho_debugfs_cleanup(struct kho_debugfs *dbg) {} +static inline void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, + void *fdt) { } #endif /* CONFIG_KEXEC_HANDOVER_DEBUGFS */ =20 #endif /* LINUX_KEXEC_HANDOVER_INTERNAL_H */ diff --git a/lib/test_kho.c b/lib/test_kho.c index 60cd899ea745..8d57049e8c8c 100644 --- a/lib/test_kho.c +++ b/lib/test_kho.c @@ -39,33 +39,17 @@ struct kho_test_state { =20 static struct kho_test_state kho_test_state; =20 -static int kho_test_notifier(struct notifier_block *self, unsigned long cm= d, - void *v) +static int kho_test(void) { struct kho_test_state *state =3D &kho_test_state; - struct kho_serialization *ser =3D v; int err =3D 0; =20 - switch (cmd) { - case KEXEC_KHO_ABORT: - return NOTIFY_DONE; - case KEXEC_KHO_FINALIZE: - /* Handled below */ - break; - default: - return NOTIFY_BAD; - } - err |=3D kho_preserve_folio(state->fdt); - err |=3D kho_add_subtree(ser, KHO_TEST_FDT, folio_address(state->fdt)); + err |=3D kho_add_subtree(KHO_TEST_FDT, folio_address(state->fdt)); =20 return err ? NOTIFY_BAD : NOTIFY_DONE; } =20 -static struct notifier_block kho_test_nb =3D { - .notifier_call =3D kho_test_notifier, -}; - static int kho_test_save_data(struct kho_test_state *state, void *fdt) { phys_addr_t *folios_info __free(kvfree) =3D NULL; @@ -102,6 +86,9 @@ static int kho_test_save_data(struct kho_test_state *sta= te, void *fdt) if (!err) state->folios_info =3D no_free_ptr(folios_info); =20 + if (!err) + err =3D kho_test(); + return err; } =20 @@ -203,14 +190,8 @@ static int kho_test_save(void) if (err) goto err_free_folios; =20 - err =3D register_kho_notifier(&kho_test_nb); - if (err) - goto err_free_fdt; - return 0; =20 -err_free_fdt: - folio_put(state->fdt); err_free_folios: kvfree(folios); return err; @@ -326,7 +307,6 @@ static void kho_test_cleanup(void) =20 static void __exit kho_test_exit(void) { - unregister_kho_notifier(&kho_test_nb); kho_test_cleanup(); } module_exit(kho_test_exit); diff --git a/mm/memblock.c b/mm/memblock.c index e23e16618e9b..c4b2d4e4c715 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -2444,53 +2444,18 @@ int reserve_mem_release_by_name(const char *name) #define MEMBLOCK_KHO_FDT "memblock" #define MEMBLOCK_KHO_NODE_COMPATIBLE "memblock-v1" #define RESERVE_MEM_KHO_NODE_COMPATIBLE "reserve-mem-v1" -static struct page *kho_fdt; - -static int reserve_mem_kho_finalize(struct kho_serialization *ser) -{ - int err =3D 0, i; - - for (i =3D 0; i < reserved_mem_count; i++) { - struct reserve_mem_table *map =3D &reserved_mem_table[i]; - struct page *page =3D phys_to_page(map->start); - unsigned int nr_pages =3D map->size >> PAGE_SHIFT; - - err |=3D kho_preserve_pages(page, nr_pages); - } - - err |=3D kho_preserve_folio(page_folio(kho_fdt)); - err |=3D kho_add_subtree(ser, MEMBLOCK_KHO_FDT, page_to_virt(kho_fdt)); - - return notifier_from_errno(err); -} - -static int reserve_mem_kho_notifier(struct notifier_block *self, - unsigned long cmd, void *v) -{ - switch (cmd) { - case KEXEC_KHO_FINALIZE: - return reserve_mem_kho_finalize((struct kho_serialization *)v); - case KEXEC_KHO_ABORT: - return NOTIFY_DONE; - default: - return NOTIFY_BAD; - } -} - -static struct notifier_block reserve_mem_kho_nb =3D { - .notifier_call =3D reserve_mem_kho_notifier, -}; =20 static int __init prepare_kho_fdt(void) { int err =3D 0, i; + struct page *fdt_page; void *fdt; =20 - kho_fdt =3D alloc_page(GFP_KERNEL); - if (!kho_fdt) + fdt_page =3D alloc_page(GFP_KERNEL); + if (!fdt_page) return -ENOMEM; =20 - fdt =3D page_to_virt(kho_fdt); + fdt =3D page_to_virt(fdt_page); =20 err |=3D fdt_create(fdt, PAGE_SIZE); err |=3D fdt_finish_reservemap(fdt); @@ -2499,7 +2464,10 @@ static int __init prepare_kho_fdt(void) err |=3D fdt_property_string(fdt, "compatible", MEMBLOCK_KHO_NODE_COMPATI= BLE); for (i =3D 0; i < reserved_mem_count; i++) { struct reserve_mem_table *map =3D &reserved_mem_table[i]; + struct page *page =3D phys_to_page(map->start); + unsigned int nr_pages =3D map->size >> PAGE_SHIFT; =20 + err |=3D kho_preserve_pages(page, nr_pages); err |=3D fdt_begin_node(fdt, map->name); err |=3D fdt_property_string(fdt, "compatible", RESERVE_MEM_KHO_NODE_COM= PATIBLE); err |=3D fdt_property(fdt, "start", &map->start, sizeof(map->start)); @@ -2507,13 +2475,14 @@ static int __init prepare_kho_fdt(void) err |=3D fdt_end_node(fdt); } err |=3D fdt_end_node(fdt); - err |=3D fdt_finish(fdt); =20 + err |=3D kho_preserve_folio(page_folio(fdt_page)); + err |=3D kho_add_subtree(MEMBLOCK_KHO_FDT, fdt); + if (err) { pr_err("failed to prepare memblock FDT for KHO: %d\n", err); - put_page(kho_fdt); - kho_fdt =3D NULL; + put_page(fdt_page); } =20 return err; @@ -2529,13 +2498,6 @@ static int __init reserve_mem_init(void) err =3D prepare_kho_fdt(); if (err) return err; - - err =3D register_kho_notifier(&reserve_mem_kho_nb); - if (err) { - put_page(kho_fdt); - kho_fdt =3D NULL; - } - return err; } late_initcall(reserve_mem_init); --=20 2.51.0.618.g983fd99d29-goog From nobody Fri Dec 19 07:03:23 2025 Received: from mail-vk1-f174.google.com (mail-vk1-f174.google.com [209.85.221.174]) (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 831B2218AD1 for ; Tue, 7 Oct 2025 03:31:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807874; cv=none; b=nWUxaIfDG0HALtTTD0HQXUBdSr+P694qE+7lDz7T7aSAdjnCKHftzgMJU07ogTKy35vrhaWZzoV584YF4kieLosQ8l7qep9z0oazZAMa/45sgbm1RN+WJwmfOju8dEiUHr+jzJNZfZWPbvb5uMFBLvdJ6Et4Y31bl7nkrVxmj/4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807874; c=relaxed/simple; bh=7rwOb8p11Fksxm3ge+XkaEBcZqh7fpI8ewXvuhI4bgY=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IAEYaL2DyejLbZjhhxNCeQ83eFVQWaTQTDfyQ1EjHRR4bolWATPl1sFEuDcIbCouebKUrt6qEmyRluvGokWzsGtjlJ4iePCJtwGeWO5JWmqy3ET6Qz19q7fA9xjq8ngaQXHkzJoXUuA8L3T+70gnGZPQyMedO3ZrhY8wHpntofk= 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=P/xT3tRZ; arc=none smtp.client-ip=209.85.221.174 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="P/xT3tRZ" Received: by mail-vk1-f174.google.com with SMTP id 71dfb90a1353d-54aa789f9b5so4366981e0c.1 for ; Mon, 06 Oct 2025 20:31:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759807871; x=1760412671; 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=d75MC7yX8fTJ3DXLRKGrsbPruNC6LGxufxG+WL9vn/A=; b=P/xT3tRZgLa9EwMvlLuS35/cGd2UZD/wyfTjmP9HG8VdLLXGxyBxKB/3ftfiWAFBKK qFe0ivJBTKxL34I/ehujZQA5DN8504P40lUrDFo5YvTrjGQxcaDf0c53t48E4I6AfefN XtVLA7KU5mEtvPpS69JLwhcM+ccnCGRzl28ytWuhkF82o7hhuUaKwNuqc2hlLmKvdiOn UJEIEmp/dnzHQvJXGsMJBP7MUR4Yeb+bU0sg6DGrx/HJy1ZpDQcCNg21bA0+1Y9oUfbe 8yTILitv7lxyhSJ/Nl1c3I109Z52jodZfUMZ4IBZdPoLghJfGPUR0rM8B0HjucTpScAJ ljEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759807871; x=1760412671; 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=d75MC7yX8fTJ3DXLRKGrsbPruNC6LGxufxG+WL9vn/A=; b=cWS4Y+/0yzoV+NUm/f3Grn2HbLUYSdgEyz6inyJC3iUlMYU4Gbs4HicCBzB1mLploe Vz4xK6xVEFXSyunymUpyAyU15zFaCERBx5Ts1Wd78pXOqagA1rBvhdzCajLSeYOo3C3m LLg2rfYxErJTzcCq7mhmHXS1WNr/badylCblZqtUXIj4ja2mUnrfzPhlOWxBoisY8C9Z WBlxEBjBlcWBBGOsOJozk3hAAh1CY0MPihfEKfsJrOM/IMIkTM2QzksWq7VZWKzJPcHF VHJd1U2Mofyg7hX/bHNX0TfzRS3JM6xHQczHlGd3kS4cN7MN9XabA17I1LMA5BEOjh2j RO+g== X-Forwarded-Encrypted: i=1; AJvYcCV/AE577bF9HKYQu+OHBN+gkTM2BqxM/cpHgvNSecMduxRKsD1rlhWNPVy7sgcAc+jG5vwREmPs/MO5MiA=@vger.kernel.org X-Gm-Message-State: AOJu0Yyoh85wiWxjdXCuY5ApbZYBoU1iDuYUqKFjdkQpVRoDItFOpgUS 9AHh78N3vEHatDGH7NpGoWj+1ldp1r3SaVjIHlfpkFn8Pz2lIMCK4kD+TLuzHXCRAoU= X-Gm-Gg: ASbGncvPwrRA1jDTy7zF9CqSmYA1A5jaQ+12Kb9Q42KhZoQwkUbj2AYy371/WooH3qQ MitUp9X//3JpXhIQ6d6kv9ccLjt2TeEhF7YEpqNM5E4JjZ3n+4EuirnkTWSiXENNEfT3GCnVdVN btY9npJarDcfHweHA/IILz5271Xy5q27hVf/wxD4/bJbnJVCF3nViikQzXXVKPWPILGYl6Y0+n/ QBSx0uD5AWnnxbCSjrQu79z8H8PApl4ISpZA4OKxHaX2dkZqqbW/pjgaqtu43WCt/qwzOGpO90u hg9e+8RTsEtOWIghaKssb/BIzoouU/DIqoUa++luJQeqSgERsGy8jRBH883TSQOSNtM9vZGKcp+ xEStpiMinHqpQZ8nvT/nixCk1BYWidK/jz2suPKDJraXWeAryeRCiz0nbOCmZ6v36wuZpdl2efX RNPOhfOWkMutMc2ghwbemZKTXj7NfqFEA= X-Google-Smtp-Source: AGHT+IFIriag8/rRrhYuf3ipZRqogDe9fVyFCNEZ9cflZH8v8IsXkHoHC8oknMO6yF3MW6LcKWyWVA== X-Received: by 2002:a05:6122:1823:b0:539:44bc:7904 with SMTP id 71dfb90a1353d-5524e8b6931mr5202328e0c.5.1759807871292; Mon, 06 Oct 2025 20:31:11 -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 71dfb90a1353d-552ea335f07sm2446030e0c.15.2025.10.06.20.31.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Oct 2025 20:31:10 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org Subject: [PATCH v5 4/7] kho: add interfaces to unpreserve folios and page ranes Date: Tue, 7 Oct 2025 03:30:57 +0000 Message-ID: <20251007033100.836886-5-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog In-Reply-To: <20251007033100.836886-1-pasha.tatashin@soleen.com> References: <20251007033100.836886-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" Allow users of KHO to cancel the previous preservation by adding the necessary interfaces to unpreserve folio and pages. Signed-off-by: Pasha Tatashin --- include/linux/kexec_handover.h | 12 +++++ kernel/kexec_handover.c | 85 ++++++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 13 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 2faf290803ce..4ba145713838 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -43,7 +43,9 @@ bool kho_is_enabled(void); bool is_kho_boot(void); =20 int kho_preserve_folio(struct folio *folio); +int kho_unpreserve_folio(struct folio *folio); int kho_preserve_pages(struct page *page, unsigned int nr_pages); +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages); int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation); struct folio *kho_restore_folio(phys_addr_t phys); struct page *kho_restore_pages(phys_addr_t phys, unsigned int nr_pages); @@ -76,11 +78,21 @@ static inline int kho_preserve_folio(struct folio *foli= o) return -EOPNOTSUPP; } =20 +static inline int kho_unpreserve_folio(struct folio *folio) +{ + return -EOPNOTSUPP; +} + static inline int kho_preserve_pages(struct page *page, unsigned int nr_pa= ges) { return -EOPNOTSUPP; } =20 +static inline int kho_unpreserve_pages(struct page *page, unsigned int nr_= pages) +{ + return -EOPNOTSUPP; +} + static inline int kho_preserve_vmalloc(void *ptr, struct kho_vmalloc *preservation) { diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index 846fb4aa6948..77fd7dd991d2 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -153,26 +153,33 @@ static void *xa_load_or_alloc(struct xarray *xa, unsi= gned long index, size_t sz) return elm; } =20 -static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pf= n, - unsigned long end_pfn) +static void __kho_unpreserve_order(struct kho_mem_track *track, unsigned l= ong pfn, + unsigned int order) { struct kho_mem_phys_bits *bits; struct kho_mem_phys *physxa; + const unsigned long pfn_high =3D pfn >> order; =20 - while (pfn < end_pfn) { - const unsigned int order =3D - min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); - const unsigned long pfn_high =3D pfn >> order; + physxa =3D xa_load(&track->orders, order); + if (!physxa) + return; + + bits =3D xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); + if (!bits) + return; =20 - physxa =3D xa_load(&track->orders, order); - if (!physxa) - continue; + clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); +} + +static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pf= n, + unsigned long end_pfn) +{ + unsigned int order; =20 - bits =3D xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); - if (!bits) - continue; + while (pfn < end_pfn) { + order =3D min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); =20 - clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); + __kho_unpreserve_order(track, pfn, order); =20 pfn +=3D 1 << order; } @@ -734,6 +741,30 @@ int kho_preserve_folio(struct folio *folio) } EXPORT_SYMBOL_GPL(kho_preserve_folio); =20 +/** + * kho_unpreserve_folio - unpreserve a folio. + * @folio: folio to unpreserve. + * + * Instructs KHO to unpreserve a folio that was preserved by + * kho_preserve_folio() before. The provided @folio (pfn and order) + * must exactly match a previously preserved folio. + * + * Return: 0 on success, error code on failure + */ +int kho_unpreserve_folio(struct folio *folio) +{ + const unsigned long pfn =3D folio_pfn(folio); + const unsigned int order =3D folio_order(folio); + struct kho_mem_track *track =3D &kho_out.track; + + if (kho_out.finalized) + return -EBUSY; + + __kho_unpreserve_order(track, pfn, order); + return 0; +} +EXPORT_SYMBOL_GPL(kho_unpreserve_folio); + /** * kho_preserve_pages - preserve contiguous pages across kexec * @page: first page in the list. @@ -773,6 +804,34 @@ int kho_preserve_pages(struct page *page, unsigned int= nr_pages) } EXPORT_SYMBOL_GPL(kho_preserve_pages); =20 +/** + * kho_unpreserve_pages - unpreserve contiguous pages. + * @page: first page in the list. + * @nr_pages: number of pages. + * + * Instructs KHO to unpreserve @nr_pages contigious pages starting from @= page. + * This call must exactly match a granularity at which memory was original= ly + * preserved by kho_preserve_pages, call with the same @page and + * @nr_pages). Unpreserving arbitrary sub-ranges of larger preserved block= s is + * not supported. + * + * Return: 0 on success, error code on failure + */ +int kho_unpreserve_pages(struct page *page, unsigned int nr_pages) +{ + struct kho_mem_track *track =3D &kho_out.track; + const unsigned long start_pfn =3D page_to_pfn(page); + const unsigned long end_pfn =3D start_pfn + nr_pages; + + if (kho_out.finalized) + return -EBUSY; + + __kho_unpreserve(track, start_pfn, end_pfn); + + return 0; +} +EXPORT_SYMBOL_GPL(kho_unpreserve_pages); + struct kho_vmalloc_hdr { DECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *); }; --=20 2.51.0.618.g983fd99d29-goog From nobody Fri Dec 19 07:03:23 2025 Received: from mail-vk1-f173.google.com (mail-vk1-f173.google.com [209.85.221.173]) (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 ABE0921B8F7 for ; Tue, 7 Oct 2025 03:31:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807875; cv=none; b=Xb8Skyxa886vpCkNqT7vP8GB5MdxDn5HlU4aptww97IQw18099cwAABJYS/6PmZHKg4Hwmod56hiljLRGT0b5PH85aCYBw2tRE6vIDTpoAlh09vNNNBVw2hl0LBy/emV6V9OJBylJx/iIOdH2bMh8LKgGNY7WiM9rXxqPZ3zuwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807875; c=relaxed/simple; bh=hXIL+PGMExM2O36pRQKCAP7Iwodxl63KTYS1axPZkVc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OAN44j6HAg7Sn7rtpBKMBUPWp1JREQWw5eaACxsNPxLRnqigUTNGZ/0crGqoaU0n0e5bRfqlgRPLMZzGXL7LFM1BK8ouJTgFZo3RZeuJoN9SkOAbrwv+wf5LYiU/QpcPjVyrozgwLbTnG9bDvdcCdLAuyi3jqd6AWmD1x3v1oV4= 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=Co96UKJO; arc=none smtp.client-ip=209.85.221.173 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="Co96UKJO" Received: by mail-vk1-f173.google.com with SMTP id 71dfb90a1353d-551b9d94603so2084723e0c.1 for ; Mon, 06 Oct 2025 20:31:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759807872; x=1760412672; 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=7z64stFRl040LRM1yj9RgVROnladG4B1zFYyNLh4mpw=; b=Co96UKJOs/lXYzPcofkU0LI9M0SCJ2pozA7yEb7maXn//ZwO3mq4yiKKUFHfXvtmTa AvWpWbQIHXhwTAB3z0RIlJwHVrmk/uO7DRB63FbfZeXIKhMOHrTNb9LuKoWH+mfvLib/ Su0/d3YQ+C/ZIAjwpOUU3kR8bwH+TsEBXrltPxzfvuL372xlHsysKEuAnPWsKFkPQuJU Ply/2T/8LozOQjOXBeaC+u0BsdGEavLj8/Km/WFyfILCzcmxiiu3X6Z/c5AqewjV+HvR nS2YBMeJ9gw46WHHWL3UDlColw79UE5ZKGsfn8DmeEoD9gXInF+1MrJCtTMIUJ9BGNC1 fjzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759807872; x=1760412672; 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=7z64stFRl040LRM1yj9RgVROnladG4B1zFYyNLh4mpw=; b=qPrIwmspU7DqzzGI8ezfKzSNefqzY27LVVRIfiO0+aPUqhOf3LyD0ZejNJ3nmDVZsm tC9bpWQK43xDeZ7PO/d+z32/2mFNAX4BR/cizdWox/g4S92Omzz1Rap+MyhD2LDTwLpS 2LiqZkO5sQeJui2ayMQSJt7cgAmPAQJiSNqoKb2+NWV83TYRsJSmkol4v9/ZdT1SmypZ CXDYE7o/dWyuIY0lLpdNGSkMEmv8NQKVB1rmVIDdLZSXxTr4Y1ffy4UbR9kjt0WgOjtI /vxgihrv0axsyoGt/N8OgU8BpdgyqZ3DrJTX1Bb/5OwIWZEAH4yLHWGxOS4d/eSr+nD1 MdnQ== X-Forwarded-Encrypted: i=1; AJvYcCUEA3LYWmXBtX80bN9Fb+K11V4hykEMtbcnjYvprqdTYAYIXBvgyJin+pXD/QZEfGGNfFi3sXNNq2ZEAw4=@vger.kernel.org X-Gm-Message-State: AOJu0YwFCXowE4KLbkWFxTTGzkU+FWWsEdYIkhedZch0foWpUuAFNgYi 57nXy1GRLwSq5SkglAXLjZIyrZttKoC2vSKo186LZiEhMIgtl8V4ON+THZPfF5ZEFEM= X-Gm-Gg: ASbGncu+z1z5OlRNEXOoqTteAdt4szpH8ZRqy9uKApn7lx3CsvxFKRPzeDfDOBD4V5H b7dkbVdrHDqt/ov5RXmvYxT6TZvoN0jhz4M15pZZ7Hf2gU4o8dklixYj6Cqa8qxBipznrZit7PY 0sL+STnBgg3xxP2RR7Y6KnZ+nEbJ8U5ZDtpXEidhDnPkhdBX8xeBt9tILd/Z4sayDEyjaOcYKLT A5/EPwsmb2cxnkRjGeUEOPY7a3lYM1h6OwqP4EZ2v+7UR3zGMm59ptNXkjyXxwMDDRR5yquIKeU w+rwL8oVIP870vX+GGtTL0gNDvQflZ9nO8rR9P54fIDaey/7U36iwFxU+/bNUSsn0ZKUX1g28WV xCMkw0jEU4NKOHyr8EKkueVLdH3uf+Ni0Hy3zQrUmGfOiWMmWzTkJHwdwxg135f6MbyXd8U9D5j qGHeo39UF/HcjgBKADYp2jsdLceROJtDE= X-Google-Smtp-Source: AGHT+IE4EXqWZRhl2HTUQHS0IRjtbgPekpf92eZABSKl8jPdM7uErllIFBlkrwrXfARb9nmkBXCE5Q== X-Received: by 2002:a05:6122:20a5:b0:54b:bea6:a226 with SMTP id 71dfb90a1353d-5524ea29092mr4456170e0c.11.1759807872536; Mon, 06 Oct 2025 20:31:12 -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 71dfb90a1353d-552ea335f07sm2446030e0c.15.2025.10.06.20.31.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Oct 2025 20:31:11 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org Subject: [PATCH v5 5/7] kho: don't unpreserve memory during abort Date: Tue, 7 Oct 2025 03:30:58 +0000 Message-ID: <20251007033100.836886-6-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog In-Reply-To: <20251007033100.836886-1-pasha.tatashin@soleen.com> References: <20251007033100.836886-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" KHO allows clients to preserve memory regions at any point before the KHO state is finalized. The finalization process itself involves KHO performing its own actions, such as serializing the overall preserved memory map. If this finalization process is aborted, the current implementation destroys KHO's internal memory tracking structures (`kho_out.ser.track.orders`). This behavior effectively unpreserves all memory from KHO's perspective, regardless of whether those preservations were made by clients before the finalization attempt or by KHO itself during finalization. This premature unpreservation is incorrect. An abort of the finalization process should only undo actions taken by KHO as part of that specific finalization attempt. Individual memory regions preserved by clients prior to finalization should remain preserved, as their lifecycle is managed by the clients themselves. These clients might still need to call kho_unpreserve_folio() or kho_unpreserve_phys() based on their own logic, even after a KHO finalization attempt is aborted. Signed-off-by: Pasha Tatashin --- kernel/kexec_handover.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index 77fd7dd991d2..902c30feae09 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -1083,31 +1083,12 @@ EXPORT_SYMBOL_GPL(kho_restore_vmalloc); =20 static int __kho_abort(void) { - int err =3D 0; - unsigned long order; - struct kho_mem_phys *physxa; - - xa_for_each(&kho_out.track.orders, order, physxa) { - struct kho_mem_phys_bits *bits; - unsigned long phys; - - xa_for_each(&physxa->phys_bits, phys, bits) - kfree(bits); - - xa_destroy(&physxa->phys_bits); - kfree(physxa); - } - xa_destroy(&kho_out.track.orders); - if (kho_out.preserved_mem_map) { kho_mem_ser_free(kho_out.preserved_mem_map); kho_out.preserved_mem_map =3D NULL; } =20 - if (err) - pr_err("Failed to abort KHO finalization: %d\n", err); - - return err; + return 0; } =20 int kho_abort(void) --=20 2.51.0.618.g983fd99d29-goog From nobody Fri Dec 19 07:03:23 2025 Received: from mail-vk1-f179.google.com (mail-vk1-f179.google.com [209.85.221.179]) (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 C4F9A21CA13 for ; Tue, 7 Oct 2025 03:31:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807876; cv=none; b=IYrpg94FT2gIcEYzywClMSKp1Yl5PXwZVqyUoVwRKcaBAminL7i7AiJ6nOPmGrJEdn1MiJXRg6k3HWwA0UdrcJwbG72viUnrzw3onkwLhVxamv/wYS7p2A3Br+8TW4oq3rRB40nhOQXEHeX2Oa+V2EBMJ7ULXB/IvwtDshyPPC4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807876; c=relaxed/simple; bh=Tfwqw8OEZOL2ezVx8JcOcQZ0zoAFvd3pQ2ktx/jzJV4=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ze/4H2Uo9wwX8KAnRAvqW2wygNgLNP2tOpxPutCxSAUOTozh6y6aKzuA9YS6oC3trwgafqyUh7G/fUQcrIMSZ/iYctkS6YjF3BFkGarJakxIPldRWLDnFHr7iIGaH9UPUW/8/0TaAC2GOZKS6B9kO+qG3f0KF/+dYJQot1GiqzQ= 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=POuQW/Gp; arc=none smtp.client-ip=209.85.221.179 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="POuQW/Gp" Received: by mail-vk1-f179.google.com with SMTP id 71dfb90a1353d-54bbc2a8586so2042411e0c.2 for ; Mon, 06 Oct 2025 20:31:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759807874; x=1760412674; 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=m5YiQ5dlO7dBlobQ5XJDQPeGxLG7MsQM1BhS0aByLIw=; b=POuQW/GphTtx/g0bYDP7JsT5yiw4/p6PmhL9ELi6ZtJEm/EEIflHspws3y3Ig/j4LU tByGbVV9vhizVhGhrDzXbuofmZvH7qgyBZdvgxRtRiM8iBNj/HfoX7gOazkvHEa6bQ6d FLcWZk3jwpLA7mUM7o/1gjcQDcePHC0Ohp+15cdi0zYP49uF0BlI2veVFpBhZ2Pi6xhL zZ3Xb1Rx04/Fvx3nFqePZQt+1We8eVblgWQyNW67SqJRJD/vgnbFIE3CuleY9WYkLfkj 6QJm+Uk9HBv/ZwzkV9vmColBSgyWASE2UCX+AxVn2OfVEB5ozwKXdiujI2tmtaQnY4Ov mKPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759807874; x=1760412674; 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=m5YiQ5dlO7dBlobQ5XJDQPeGxLG7MsQM1BhS0aByLIw=; b=aihMM8TgzjCSA+zrg+nEp0gVUEIUH7aJ1Xij8fTUzlFLWIiPCX6d7wKMszPYjVZtlo o4KBnYgnHyR6B6Llo6MM7zDilt9m6C3dVjc3R1ZwJr1VfrTrFWuT3s9LGY3OJjdzHtQs MKO4pe/88cdRdU4dkOdJmRnmbj+1sD6Kx5vmOAhF6niS5BNEiqM5WZ8/HlkgTpqEJhbg 2+lNnkfmE9+t4APeF2eZEqEmatkizsdMXCcZOiNkiAMrJDEUTKyzrWzQfcBUpg1EwDq5 a3HBTPhyOFMc/KfASMiVtmAcHgUxX+MkbbL4uoDAKN/r/BJbzsfJr6FJB69Q113pqGX1 qh/w== X-Forwarded-Encrypted: i=1; AJvYcCWRiMLNoY3pG+EydnPKbZjY0in36dJC5wwrywn1iWZXWLdmWY49GPp5m3CAx/NkRA1Twc+Erk0i0fFCZjs=@vger.kernel.org X-Gm-Message-State: AOJu0YxAaoJCP74YRFwHsb/16FnK2n7gf/wG/B5yhmpJXS/y+GBmwOf7 d8dmL1OhRjjFasiN/yYWtJgqlEkaRaoVGa8Y6btb4UGWPmseY18N6IUwLGRAL/qLXTA= X-Gm-Gg: ASbGncuZiCx6zkfpO3KrSro4R3WFmGBLy01KXcEmME0xaNYwB9olEsLITuWjoGQgDEC VX3yyHeP0vDmurDhfTmqkdV4FByrmjVIP2ZPcqmqyUMaTyP9O9FmY4M41YEL5AfOsNsjfnFdpqS rZw3mRhq77/3p7VmDdpzv4tokn1PcMnVIFkTQ7tEVEb92IWCLn+jbiqXBE8vKkVLJMGP+goHQC6 sZUxyoc64k1Igvx9SsOncSBinU7QcJdHaJNSLkm+UJ4TwCfEZOAMGZHOTuxp0XVpghJiTy9Tem2 fqFusTnlWxfQZEolHRwjK1m2Yq8QdR0PbBDHR7W9d6uM9PQ5SgdfXECpOJzkimtx9bgBvCkdd5L 6Engb+32LlIRyu1mb3fs1DaYNq42/WlyFU9Ta37R5hLu8GJy4AqmBFlo9JgftP8xGUMoWf6BH5M hRFx9A7/RuFzY/WW8U2VFGVcSZLpJ4gvY= X-Google-Smtp-Source: AGHT+IHeIDZnOswf52ELEZYN9Eapu+gsyWvQ4kUElr+dQYU/Cq4+N/m+PwBTQ8uS2hlStxD8ANRbMQ== X-Received: by 2002:a05:6122:8d3:b0:54b:c215:8c0 with SMTP id 71dfb90a1353d-5524e417161mr4784194e0c.0.1759807873730; Mon, 06 Oct 2025 20:31:13 -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 71dfb90a1353d-552ea335f07sm2446030e0c.15.2025.10.06.20.31.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Oct 2025 20:31:13 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org Subject: [PATCH v5 6/7] liveupdate: kho: move to kernel/liveupdate Date: Tue, 7 Oct 2025 03:30:59 +0000 Message-ID: <20251007033100.836886-7-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog In-Reply-To: <20251007033100.836886-1-pasha.tatashin@soleen.com> References: <20251007033100.836886-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" Move KHO to kernel/liveupdate/ in preparation of placing all Live Update core kernel related files to the same place. Signed-off-by: Pasha Tatashin Reviewed-by: Jason Gunthorpe --- Documentation/core-api/kho/concepts.rst | 2 +- MAINTAINERS | 2 +- init/Kconfig | 2 ++ kernel/Kconfig.kexec | 25 ---------------- kernel/Makefile | 3 +- kernel/liveupdate/Kconfig | 30 +++++++++++++++++++ kernel/liveupdate/Makefile | 4 +++ kernel/{ =3D> liveupdate}/kexec_handover.c | 6 ++-- .../{ =3D> liveupdate}/kexec_handover_debug.c | 0 .../kexec_handover_internal.h | 0 10 files changed, 42 insertions(+), 32 deletions(-) create mode 100644 kernel/liveupdate/Kconfig create mode 100644 kernel/liveupdate/Makefile rename kernel/{ =3D> liveupdate}/kexec_handover.c (99%) rename kernel/{ =3D> liveupdate}/kexec_handover_debug.c (100%) rename kernel/{ =3D> liveupdate}/kexec_handover_internal.h (100%) diff --git a/Documentation/core-api/kho/concepts.rst b/Documentation/core-a= pi/kho/concepts.rst index 36d5c05cfb30..d626d1dbd678 100644 --- a/Documentation/core-api/kho/concepts.rst +++ b/Documentation/core-api/kho/concepts.rst @@ -70,5 +70,5 @@ in the FDT. That state is called the KHO finalization pha= se. =20 Public API =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -.. kernel-doc:: kernel/kexec_handover.c +.. kernel-doc:: kernel/liveupdate/kexec_handover.c :export: diff --git a/MAINTAINERS b/MAINTAINERS index 49e8fc4a393e..c1c4291556aa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13777,7 +13777,7 @@ S: Maintained F: Documentation/admin-guide/mm/kho.rst F: Documentation/core-api/kho/* F: include/linux/kexec_handover.h -F: kernel/kexec_handover* +F: kernel/liveupdate/kexec_handover* F: tools/testing/selftests/kho/ =20 KEYS-ENCRYPTED diff --git a/init/Kconfig b/init/Kconfig index cab3ad28ca49..0605de5d96c0 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2138,6 +2138,8 @@ config TRACEPOINTS =20 source "kernel/Kconfig.kexec" =20 +source "kernel/liveupdate/Kconfig" + endmenu # General setup =20 source "arch/Kconfig" diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec index 03c3aa6263d3..15632358bcf7 100644 --- a/kernel/Kconfig.kexec +++ b/kernel/Kconfig.kexec @@ -94,31 +94,6 @@ config KEXEC_JUMP Jump between original kernel and kexeced kernel and invoke code in physical address mode via KEXEC =20 -config KEXEC_HANDOVER - bool "kexec handover" - depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE - depends on !DEFERRED_STRUCT_PAGE_INIT - select MEMBLOCK_KHO_SCRATCH - select KEXEC_FILE - select DEBUG_FS - select LIBFDT - select CMA - help - Allow kexec to hand over state across kernels by generating and - passing additional metadata to the target kernel. This is useful - to keep data or state alive across the kexec. For this to work, - both source and target kernels need to have this option enabled. - -config KEXEC_HANDOVER_DEBUGFS - bool "kexec handover debugfs interface" - depends on KEXEC_HANDOVER - depends on DEBUG_FS - help - Allow to control kexec handover device tree via debugfs - interface, i.e. finalize the state or aborting the finalization. - Also, enables inspecting the KHO fdt trees with the debugfs binary - blobs. - config CRASH_DUMP bool "kernel crash dumps" default ARCH_DEFAULT_CRASH_DUMP diff --git a/kernel/Makefile b/kernel/Makefile index f21d8c98d857..e83669841b8c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -52,6 +52,7 @@ obj-y +=3D printk/ obj-y +=3D irq/ obj-y +=3D rcu/ obj-y +=3D livepatch/ +obj-y +=3D liveupdate/ obj-y +=3D dma/ obj-y +=3D entry/ obj-y +=3D unwind/ @@ -82,8 +83,6 @@ obj-$(CONFIG_CRASH_DUMP_KUNIT_TEST) +=3D crash_core_test.o obj-$(CONFIG_KEXEC) +=3D kexec.o obj-$(CONFIG_KEXEC_FILE) +=3D kexec_file.o obj-$(CONFIG_KEXEC_ELF) +=3D kexec_elf.o -obj-$(CONFIG_KEXEC_HANDOVER) +=3D kexec_handover.o -obj-$(CONFIG_KEXEC_HANDOVER_DEBUGFS) +=3D kexec_handover_debug.o obj-$(CONFIG_BACKTRACE_SELF_TEST) +=3D backtracetest.o obj-$(CONFIG_COMPAT) +=3D compat.o obj-$(CONFIG_CGROUPS) +=3D cgroup/ diff --git a/kernel/liveupdate/Kconfig b/kernel/liveupdate/Kconfig new file mode 100644 index 000000000000..522b9f74d605 --- /dev/null +++ b/kernel/liveupdate/Kconfig @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-only + +menu "Live Update" + +config KEXEC_HANDOVER + bool "kexec handover" + depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE + depends on !DEFERRED_STRUCT_PAGE_INIT + select MEMBLOCK_KHO_SCRATCH + select KEXEC_FILE + select DEBUG_FS + select LIBFDT + select CMA + help + Allow kexec to hand over state across kernels by generating and + passing additional metadata to the target kernel. This is useful + to keep data or state alive across the kexec. For this to work, + both source and target kernels need to have this option enabled. + +config KEXEC_HANDOVER_DEBUGFS + bool "kexec handover debugfs interface" + depends on KEXEC_HANDOVER + depends on DEBUG_FS + help + Allow to control kexec handover device tree via debugfs + interface, i.e. finalize the state or aborting the finalization. + Also, enables inspecting the KHO fdt trees with the debugfs binary + blobs. + +endmenu diff --git a/kernel/liveupdate/Makefile b/kernel/liveupdate/Makefile new file mode 100644 index 000000000000..9a702edc1dec --- /dev/null +++ b/kernel/liveupdate/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_KEXEC_HANDOVER) +=3D kexec_handover.o +obj-$(CONFIG_KEXEC_HANDOVER_DEBUGFS) +=3D kexec_handover_debug.o diff --git a/kernel/kexec_handover.c b/kernel/liveupdate/kexec_handover.c similarity index 99% rename from kernel/kexec_handover.c rename to kernel/liveupdate/kexec_handover.c index 902c30feae09..5da21f1510cc 100644 --- a/kernel/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -24,8 +24,8 @@ * KHO is tightly coupled with mm init and needs access to some of mm * internal APIs. */ -#include "../mm/internal.h" -#include "kexec_internal.h" +#include "../../mm/internal.h" +#include "../kexec_internal.h" #include "kexec_handover_internal.h" =20 #define KHO_FDT_COMPATIBLE "kho-v1" @@ -1124,7 +1124,7 @@ static int __kho_finalize(void) err |=3D fdt_finish_reservemap(root); err |=3D fdt_begin_node(root, ""); err |=3D fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE); - /** + /* * Reserve the preserved-memory-map property in the root FDT, so * that all property definitions will precede subnodes created by * KHO callers. diff --git a/kernel/kexec_handover_debug.c b/kernel/liveupdate/kexec_handov= er_debug.c similarity index 100% rename from kernel/kexec_handover_debug.c rename to kernel/liveupdate/kexec_handover_debug.c diff --git a/kernel/kexec_handover_internal.h b/kernel/liveupdate/kexec_han= dover_internal.h similarity index 100% rename from kernel/kexec_handover_internal.h rename to kernel/liveupdate/kexec_handover_internal.h --=20 2.51.0.618.g983fd99d29-goog From nobody Fri Dec 19 07:03:23 2025 Received: from mail-vk1-f172.google.com (mail-vk1-f172.google.com [209.85.221.172]) (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 56DD02222AC for ; Tue, 7 Oct 2025 03:31:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807879; cv=none; b=Go01B38Se+0+Y7gKO4b+SEzMf91ijqaDvmts5VTUPOlEPjth+TFK9W/ODsJOcpfRC3XNRWUQFaHva7i3wcg6fu2PqkeFVJ1cLtrwhtFahYAPZnx3wmWfwm10HeKdk4ITtqKQXTl5nzLLLVYsSi2aidZSp+dfhouyAwNVl3Xlbp0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759807879; c=relaxed/simple; bh=/drT+47PUHF+YSiTzIpGKzopMpsKtV8QOoOnRRft+BU=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k7rZ9DdkUSq/T4pEaxWVdtTWMDneiNfEfEqABhb+2mNOK6KXSFm2dyEHykYqPqor9GmFOgxoEvUM5O87z4wBwUj7sqWc0YfIVeuljjuTIICyMSVzEYUmJrckNYRf+b073e+sbbBQ1YmDTsv8EiaMWX7cBTO9wKynxl9kzTGmwLc= 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=I3Ny6C9G; arc=none smtp.client-ip=209.85.221.172 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="I3Ny6C9G" Received: by mail-vk1-f172.google.com with SMTP id 71dfb90a1353d-54a81bf36ebso845252e0c.3 for ; Mon, 06 Oct 2025 20:31:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1759807875; x=1760412675; 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=3VBEGNGPrHJLgeZc8OwSpyVwglko2eCUcGTlg3MZ+0E=; b=I3Ny6C9GAT7H9+IIQk958hQxvMob44/CThPUWbMSYbFTUhb0Z+ylVI59lJ6VgBY161 6xtYxs5qS0mM0q8L+05vkrmGP+cridOwC6GYmTPQkgh0RWBcdvdnqT28xTyo+0sx2r1g 5Slf6k5moAw4wGDKEwRgVz1nTaU8nbJUX0Rb35N0WV48eRLeJtgKd1s0U4WVXxx3OYiG AAoTzr6sQNfVs3+poRCXU8vwlrplDxIITFxwfP/Vfxm4TFeR0BLn/9ZkA0RY8ns6rvEA pEXdPCKMS5P+neIfNPA8RuSIBUgO0s0orGvG5MbAaMbZQ8jiOjiXV74PotKKXi5K43zJ 1btQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759807875; x=1760412675; 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=3VBEGNGPrHJLgeZc8OwSpyVwglko2eCUcGTlg3MZ+0E=; b=gmsvV7cp1szl3JvU0B9xo9dFIF3VlalH73IPew1+Az5cdpksCDjm148xRoVijsaVuI nQsFujaLhpT4UvRYipQC2rUBcIgLDGvqKMtSA/jJBnUAkbh9tAuD0Zci8Nbr/WNocY5f gGkevOMTFWcYAJyZ72RnlO0zC4ajcPUWJzVYibnckrgcLA30RcBUanvjLSHvRbDc8+sX Zn3XjP9pNUwGySkLXdgfo7qsl5TDGyeJqJpfq1F67a2sqRoaw+Ud7O31G5IC4/9qel86 HBcOAVCM7aODbnY3i+Q/vf3bqx2NYAsNQPiz6AJjuy7ed1l4mrSxmbyfcaPZlWd7COgL weEQ== X-Forwarded-Encrypted: i=1; AJvYcCXzB6yVs3hdxuXhxWm54dqYiWDQxlskvTsmpDXwALfcHXeE2SbtE0092VYCIqSEzc5LrzwQtwhQjpDM/t4=@vger.kernel.org X-Gm-Message-State: AOJu0YxiCiRYUxYaazIo+7eCtDbAR7ybv0foIubTFGEzZYktu3xVF6tW pNDgnLeORMhQNxh4J5oB7vUyK+0gr9IqkuJ5DTA7dh+jmB9EkXJRYOpkhQkaCjchfKE= X-Gm-Gg: ASbGncur2lm+NZgsIVR01qzrfKaz+lTvCjcgK6IA9zW5j2juBymlXpnkeiKItYrWeR1 QAiscOu+VBDhCYayupAo9DJITc/oc4YnHXmJyWfhNYLlbKJnQYqkE68VDJjZUx0K9podp0x/C9Q /qENYorgMb8aSwXZq1y6HfdgEHKn6rV9ujHBdcF9zR0JP5EnoMawLPEsb5U3pafyQFQkqxEBnVQ 06F7oSfMQEGfAD9Octyka/xTawuiZ+IoY6LvtOLdNhsyweKbw4wwEufGbu/ZpFIRu79napCQ+sS YKwcSwFMZ4hUDJdbk32Dki6uSYUF/aorSFxznmNRhJByFP5a4JHLHSnFEEg4FwQZTeqEI/1hRn2 +P48U9aZG6vmhrP6GpmHJjJcVoccTvVdQyXM2PjAMFXtisLrKcmj5Xp3GPNH+JZzMF4m42+ZY1e mhMUsMXGtpCBox4AjySsgN0WAfR0uwzRCEOveS6KRJWA== X-Google-Smtp-Source: AGHT+IEm4J6yFD10/rZ/XdNA9W6YeHZUIRIn81vHOvDBC4QHa+8Eq0vvy55tHiaoLOJh8X8oN4bNLg== X-Received: by 2002:a05:6122:1781:b0:54a:9e47:7624 with SMTP id 71dfb90a1353d-5524ea910damr5388462e0c.14.1759807875038; Mon, 06 Oct 2025 20:31:15 -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 71dfb90a1353d-552ea335f07sm2446030e0c.15.2025.10.06.20.31.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Oct 2025 20:31:14 -0700 (PDT) From: Pasha Tatashin To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net, graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, masahiroy@kernel.org, ojeda@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org Subject: [PATCH v5 7/7] kho: move kho debugfs directory to liveupdate Date: Tue, 7 Oct 2025 03:31:00 +0000 Message-ID: <20251007033100.836886-8-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog In-Reply-To: <20251007033100.836886-1-pasha.tatashin@soleen.com> References: <20251007033100.836886-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" Now, that LUO and KHO both live under kernel/liveupdate, it makes sense to also move the kho debugfs files to liveupdate/ The old names: /sys/kernel/debug/kho/out/ /sys/kernel/debug/kho/in/ The new names: /sys/kernel/debug/liveupdate/kho_out/ /sys/kernel/debug/liveupdate/kho_in/ Also, export the liveupdate_debufs_root, so future LUO selftests could use it as well. Signed-off-by: Pasha Tatashin --- kernel/liveupdate/kexec_handover_debug.c | 10 +++++----- kernel/liveupdate/kexec_handover_internal.h | 2 ++ tools/testing/selftests/kho/init.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/kernel/liveupdate/kexec_handover_debug.c b/kernel/liveupdate/k= exec_handover_debug.c index d4ac78d53a39..eb47f000887d 100644 --- a/kernel/liveupdate/kexec_handover_debug.c +++ b/kernel/liveupdate/kexec_handover_debug.c @@ -15,7 +15,7 @@ #include #include "kexec_handover_internal.h" =20 -static struct dentry *debugfs_root; +struct dentry *liveupdate_debugfs_root; =20 struct fdt_debugfs { struct list_head list; @@ -115,7 +115,7 @@ __init void kho_in_debugfs_init(struct kho_debugfs *dbg= , const void *fdt) =20 INIT_LIST_HEAD(&dbg->fdt_list); =20 - dir =3D debugfs_create_dir("in", debugfs_root); + dir =3D debugfs_create_dir("kho_in", liveupdate_debugfs_root); if (IS_ERR(dir)) { err =3D PTR_ERR(dir); goto err_out; @@ -175,7 +175,7 @@ __init int kho_out_debugfs_init(struct kho_debugfs *dbg) =20 INIT_LIST_HEAD(&dbg->fdt_list); =20 - dir =3D debugfs_create_dir("out", debugfs_root); + dir =3D debugfs_create_dir("kho_out", liveupdate_debugfs_root); if (IS_ERR(dir)) return -ENOMEM; =20 @@ -209,8 +209,8 @@ __init int kho_out_debugfs_init(struct kho_debugfs *dbg) =20 __init int kho_debugfs_init(void) { - debugfs_root =3D debugfs_create_dir("kho", NULL); - if (IS_ERR(debugfs_root)) + liveupdate_debugfs_root =3D debugfs_create_dir("liveupdate", NULL); + if (IS_ERR(liveupdate_debugfs_root)) return -ENOENT; return 0; } diff --git a/kernel/liveupdate/kexec_handover_internal.h b/kernel/liveupdat= e/kexec_handover_internal.h index de90a678274d..b3fc1957affa 100644 --- a/kernel/liveupdate/kexec_handover_internal.h +++ b/kernel/liveupdate/kexec_handover_internal.h @@ -15,6 +15,8 @@ struct kho_debugfs { struct list_head fdt_list; }; =20 +extern struct dentry *liveupdate_debugfs_root; + #else struct kho_debugfs {}; #endif diff --git a/tools/testing/selftests/kho/init.c b/tools/testing/selftests/k= ho/init.c index 6d9e91d55d68..f0136a30ce8b 100644 --- a/tools/testing/selftests/kho/init.c +++ b/tools/testing/selftests/kho/init.c @@ -11,7 +11,7 @@ /* from arch/x86/include/asm/setup.h */ #define COMMAND_LINE_SIZE 2048 =20 -#define KHO_FINALIZE "/debugfs/kho/out/finalize" +#define KHO_FINALIZE "/debugfs/liveupdate/kho_out/finalize" #define KERNEL_IMAGE "/kernel" =20 static int mount_filesystems(void) --=20 2.51.0.618.g983fd99d29-goog