From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.221.171 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794316236; b=IJkb1iIuAK3DccNm8wWCIdLs1iYhdk8tPaL5OsWQA+I3NVwdj8usQGAn2K7XEwA7ZhIw +5qTDsz/c2rlh7p+aKNMvuOElhuBdzFHQrJCzKxFWPo3nzGSIHqZCMn6GLsiEAwBcnUfh /2wy+WetXKiPkanPlUYt54Ac8VwXCjuaNI2q+e3tNNinvp5bml6hCkb0GrteCO333ZZlG 1plLV3ljMUsJcUfUBOcGsabb8GkTpklzPcoknl1wFnzb7stj1NpN0DfY/P9Szf3zKqZUA 9bkChSsWe9lqbxZKwyUA17bQUM+yg3cuVQeSP5eHj3FUD5bS0vOl2llhbyN8ceyT1Sw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794316236; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: Mime-Version:Content-Transfer-Encoding:Content-Type:Date:Message-Id: To:Cc:Subject:From:X-Mailer:References:In-Reply-To; bh=XQDfTOBLyQYKItk/7IbkqTdv3CPMUC9LzGhAb3DHHto=; b=xGSqP6qqVVAk+SYyv4dqFwGMCJANYjMoMZI66V5nv88J19nqswgu/Sf3uEBLHs2VjQ9e 3gNkkBAyS0n1z6zKJ2amPtdrOxEo/4S7f4Q2johcbIoC06jfzKgOAL25iz4LdYeb8SfPF qbz72FC2vAZ+YEG8YzvJYQYpXzfh5I6+Yg4rWLSYt6JoLuw/2bxrg8uQBTgIS75lDqV1J Bo9gGtP3vgF8Lo8DOT0qLTXtVkDprb0oIkb87baTsNhYgfM+vCQ7c+l8iUSutEna+3Mmr BCzRbOlIXYdR27ISr5ukTuVlEttFNAloQiJjPuxeYG2rYDSDIxYhlzq7LvO6f7PitgQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass header.d=soleen.com header.i=@soleen.com header.a=rsa-sha256 header.s=google header.b=giz8XH7k; arc=none smtp.remote-ip=209.85.221.171 Received: from mail-vk1-f171.google.com (mail-vk1-f171.google.com [209.85.221.171]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C543060A2620 for ; Tue, 10 Nov 2026 13:10:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org C543060A2620 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.a=rsa-sha256 header.s=google header.b=giz8XH7k Received: by mail-vk1-f171.google.com with SMTP id 71dfb90a1353d-5e9528732b4so724481e0c.0 for ; Tue, 10 Nov 2026 05:10:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1794316235; x=1794921035; darn=vger.kernel.org; h=in-reply-to:references:from:subject:cc:to:message-id:date :content-type:content-transfer-encoding:mime-version:from:to:cc :subject:date:message-id:reply-to:content-type; bh=XQDfTOBLyQYKItk/7IbkqTdv3CPMUC9LzGhAb3DHHto=; b=giz8XH7kLVNdvxOASwgI4RprGKiyUEsoiMXkvupuqdbq9I7LXpuFZqF9NAaqie1qMr HNJZv2mOnI1c14z3zIJwnN7vIs8ky6CILsvv2CM0qmoOH9g3iRbx1bbXTS7NHMeYMWDc T1E3X751NjsqCQfFyFJFZ/1wwBrMlG9vrd5wNzsn7G8Ze3LfFR7gBEFXW/avDW9IJBDC tg48AzOGXWZzS3cj3uRy9HUOHAvypw2biHfmU5mc8WkPHCq5oCLx7A1KH9y3W7p0DbVV Z8ZPRJ/mvn6eRb0cH+TTlVE5RtTkT5jIfBviqNGhmYhHP7IR91Dl8nmTHPnqTd/K3rGg w4sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1794316235; x=1794921035; h=in-reply-to:references:from:subject:cc:to:message-id:date :content-type:content-transfer-encoding:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=XQDfTOBLyQYKItk/7IbkqTdv3CPMUC9LzGhAb3DHHto=; b=Z9lLxYIaeY8pquEE0IAl/CkUcDdwBzEtNPeC76lTMYXZpgPxXyM5AfyEy1CTDC5N1y NTGxRV+KXvRFOOAor7I0kBpC3oB/uCisprGtR3U4eMh6eEaRC8mhH0zwrPugYU3JZlLy 5F2uKcgqrplDezY0R/App90ZQxoZTo6Cc8xt+h2C0hm1+IhOvLep8Hvty7RYVaqtMvy4 EZc+Ikcnwe3bg/Hf9a7PPmzog0QIvNskvSD6yCU+ZW1Gqdg2sVvl/5V+v14c5lzF9f6m abOSAKPL4SoqB6eI6XMN/6VDqt4zdHTGzaQDbLw9tMIRlCPMHZuxeID7BKp50bcAfAOY KTnw== X-Forwarded-Encrypted: i=1; AL+hErHXbzCOl9syxqo/VqnvXAJHrcJWKSUUwETMAJw5rQeEJExNQ+8udPE8Sr2y+Yz7NX15ynX82Lr8DESI6fo=@vger.kernel.org X-Gm-Message-State: APuU4Z9k+JDEmvAlWuoX/yowfHcsf4i5aNivF4BG0XAt1bT8ZAQiRFc5 2wbh4j00jx1PlOF+66o1pJY/gEKl+NSywyNvin+Pxxo0xAM0LNLaSoYtaP7W84ELbhk= X-Gm-Gg: AYBFou1lyOnWmtLI8KF7MChLbs9ncYrEPjVSDj8jLy32TV5m+wqVYWlJsEkda0jrFwi Youl1itURNOml1OVJi8py95L6cnKi0wWFLjo0wB+N5jLFn0ZoP/7TloC7t1kcVgJQvWLFeCNdVA WZ3Vt7DjXKDpnYw3gX4T6pPa1e6i4qVB0RgPCwemNSqjhKPrs7ZFY1gDoTHAfgcwV+LPxc+Dhf2 tk3DfL5nOgsAzQpZVu5d9VroffP3Oo0obCk0mEf9ETbO/T499ORfZmuoSSLi9f7Ewb6LcZQajYX krTRdaPZfRLNB5GZtgv5hDWSw1v6MfdDlQEUzZ0odv55cT7HET349PfTlK60R0RAWfAhS5Xy5XW R1uFSPO5EviYtdhVEGeortFPeCzD52JJMyfwr3KwOypp3a9XOe/CjZGQRMjEG24+ZZHqW3xhUYh XWULfrvXY1G40i9YDUzW3v595ZDBKL/lqcrS07Ib5Y5/Jw0BYeYjs9uiTGRwjkCM5HBXPA2hYcP AQ79aryzDgBOAoPxOZX3ldPQoqX3MngDER3MwlG1cneScdxYIy9Uv0pUW6lXJdDB2lLEqGnoJUi h1SmJHmtWtgZT08qgw1X+CRbnubK8Zo+LPJY0wusy99PAcVDU3pmRFJA0PpvIOZjIuw6xkOVH9y YWR08vqkW2Yl4O6rhRqMQplyOh3SudxA= X-Received: by 2002:a05:6122:222a:b0:5c7:fbb5:6ea0 with SMTP id 71dfb90a1353d-5ee0d068066mr932090e0c.4.1794316234604; Tue, 10 Nov 2026 05:10:34 -0800 (PST) Received: from localhost (64.167.245.35.bc.googleusercontent.com. [35.245.167.64]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-99c20081409sm1695863241.8.2026.11.10.05.10.33 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 10 Nov 2026 05:10:33 -0800 (PST) X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Tue, 10 Nov 2026 08:10:32 -0500 Message-Id: To: "Tarun Sahu" , "Pasha Tatashin" , "Mike Rapoport" , , , , "David Matlack" , "Alexander Graf" , , , , , , , "Bjorn Helgaas" , , , , , "Andrew Morton" , , Cc: , , "Pratyush Yadav" , , , , , , , , , Subject: Re: [PATCH v4 02/19] kho: block: Record the entry size in the block header From: "Pasha Tatashin" X-Mailer: aerc 0.22.0-39-g5d7784875be2 References: <20261110050202.529473-1-tarunsahu@google.com> <20261110050202.529473-3-tarunsahu@google.com> In-Reply-To: <20261110050202.529473-3-tarunsahu@google.com> On Tue Nov 10, 2026 at 12:01 AM EST, Tarun Sahu wrote: > Subsystems using the KHO Serialization Blocks framework currently do > not record the serialized entry size in the block header. The entry size > is only known to individual callers, which must track and store it in an > owning serialized data structure. If a newer source kernel adds fields > to an entry, the changed entry size breaks the stride when an older > target kernel iterates over blocks. > > Add an entry_size field to struct kho_block_header_ser. On the outgoing > side, record bs->entry_size into every block header during allocation. > During restoration, derive the entry stride directly from the block > header instead of relying on caller-supplied dimensions. The > kho_block_set_init() interface remains unchanged. A zero entry size, > or one that differs between blocks of a set, is rejected during > restoration. > > This change modifies the serialized layout of struct kho_block_header_ser > and shifts the offset of serialized entries within preserved blocks. > Bump KHO_FDT_COMPATIBLE from kho-v4 to kho-v5 so that pre-v5 and post-v5 > kernels cleanly reject mismatched handover state during boot. Also > update the stale compatible string example in the documentation. > > Suggested-by: Pratyush Yadav > Signed-off-by: Tarun Sahu > --- > include/linux/kho/abi/block.h | 10 ++++---- > include/linux/kho/abi/kexec_handover.h | 6 ++--- > kernel/liveupdate/kho_block.c | 32 +++++++++++++++++++++++--- > 3 files changed, 38 insertions(+), 10 deletions(-) > > diff --git a/include/linux/kho/abi/block.h b/include/linux/kho/abi/block.= h > index 36bdbaf9b3b8..a40b0906c821 100644 > --- a/include/linux/kho/abi/block.h > +++ b/include/linux/kho/abi/block.h > @@ -40,9 +40,10 @@ > =20 > /** > * struct kho_block_header_ser - Header for the serialized data block. > - * @next: Physical address of the next struct kho_block_header_ser. > - * @count: The number of entries that immediately follow this header in = the > - * memory block. > + * @next: Physical address of the next struct kho_block_header_ser= . > + * @count: The number of entries that immediately follow this heade= r in the > + * memory block. > + * @entry_size: The size in bytes of each serialized entry in the block. > * > * This structure is located at the beginning of a block of physical mem= ory > * preserved across a kexec. It provides the necessary metadata to inter= pret > @@ -51,9 +52,10 @@ > struct kho_block_header_ser { > u64 next; > u64 count; > + u64 entry_size; > }; > =20 > -static_assert(sizeof(struct kho_block_header_ser) =3D=3D 16); > +static_assert(sizeof(struct kho_block_header_ser) =3D=3D 24); > static_assert(!IS_ENABLED(CONFIG_64BIT) || > __alignof__(struct kho_block_header_ser) =3D=3D 8); The above change goes away once my comment on the previous patch=20 is addressed. > =20 > diff --git a/include/linux/kho/abi/kexec_handover.h b/include/linux/kho/a= bi/kexec_handover.h > index 2f4fb9c63942..6f12f5037ea5 100644 > --- a/include/linux/kho/abi/kexec_handover.h > +++ b/include/linux/kho/abi/kexec_handover.h > @@ -41,7 +41,7 @@ > * restore the preserved data.:: > * > * / { > - * compatible =3D "kho-v3"; > + * compatible =3D "kho-v5"; > * > * preserved-memory-map =3D <0x...>; > * > @@ -62,7 +62,7 @@ > * }; > * > * Root KHO Node (/): > - * - compatible: "kho-v3" > + * - compatible: "kho-v5" These are just examples, don't update them. > * > * Identifies the overall KHO ABI version. > * > @@ -90,7 +90,7 @@ > */ > =20 > /* The compatible string for the KHO FDT root node. */ > -#define KHO_FDT_COMPATIBLE "kho-v4" > +#define KHO_FDT_COMPATIBLE "kho-v5" > =20 > /* The FDT property for the preserved memory map. */ > #define KHO_FDT_MEMORY_MAP_PROP_NAME "preserved-memory-map" > diff --git a/kernel/liveupdate/kho_block.c b/kernel/liveupdate/kho_block.= c > index 0d2a342ef422..9b148009085e 100644 > --- a/kernel/liveupdate/kho_block.c > +++ b/kernel/liveupdate/kho_block.c > @@ -16,6 +16,12 @@ > * array of serialized entries. Multiple blocks are linked together via = a > * physical pointer in the header, forming a linked list that can be eas= ily > * traversed in both the current and the next kernel. > + * > + * Each block header also records the size of its entries. A newer kerne= l may "newer kernel" does not make sense in the documentation comment, as any=20 kernel can do that. I would suggest "outgoing kernel." By the way, in=20 this series you use the terms "source" and "destination" kernel, whereas=20 traditionally we have used "outgoing" and "incoming." While both=20 conventions work, it would be preferable to maintain consistency. > + * append fields to an entry, so the kernel that writes a block and the = kernel > + * that reads it can use different entry sizes. The reader steps through= the > + * entries with the recorded size, so every entry is found, and it does = not read > + * beyond the recorded size of an entry. > */ > =20 > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > @@ -110,6 +116,8 @@ static int kho_block_set_grow_one(struct kho_block_se= t *bs) > if (IS_ERR(ser)) > return PTR_ERR(ser); > =20 > + ser->entry_size =3D bs->entry_size; > + > err =3D kho_block_add(bs, ser); > if (err) { > kho_block_free_ser(bs, ser); > @@ -242,7 +250,8 @@ static bool kho_block_set_is_cyclic(struct kho_block_= set *bs) > * > * Restores a serialized block set from a given physical address. The ca= ller is > * responsible for ensuring that the block set @bs has been allocated an= d > - * initialized prior to calling this function. > + * initialized prior to calling this function. The entry size and the nu= mber > + * of entries per block are taken from the restored block headers. > * > * Return: 0 on success, or a negative errno on failure. > */ > @@ -250,6 +259,7 @@ int kho_block_set_restore(struct kho_block_set *bs, u= 64 head_pa) > { > struct kho_block_header_ser *ser; > u64 next_pa =3D head_pa; > + u64 entry_size =3D 0; > int err; > =20 > /* Restored block sets use size from the previous kernel */ > @@ -264,8 +274,21 @@ int kho_block_set_restore(struct kho_block_set *bs, = u64 head_pa) > } > =20 > while (next_pa) { > + u64 capacity; > + > ser =3D phys_to_virt(next_pa); > - if (!ser->count || ser->count > bs->count_per_block) { > + if (!ser->entry_size || (entry_size && ser->entry_size !=3D entry_size= )) { > + pr_warn("Block contains invalid entry size: %llu\n", > + ser->entry_size); > + err =3D -EINVAL; > + goto err_destroy; > + } > + entry_size =3D ser->entry_size; > + bs->entry_size =3D entry_size; > + capacity =3D (KHO_BLOCK_SIZE - sizeof(*ser)) / bs->entry_size; > + bs->count_per_block =3D capacity; > + > + if (!ser->count || ser->count > capacity) { > pr_warn("Block contains invalid entry count: %llu\n", > ser->count); > err =3D -EINVAL; > @@ -370,7 +393,10 @@ void *kho_block_set_it_reserve_entry(struct kho_bloc= k_set_it *it) > * @it: The block iterator. > * > * Iterates through previously written entries during state deserializat= ion, > - * respecting the actual count stored in each block's header. > + * respecting the actual count stored in each block's header. Entries ar= e > + * spaced by the entry size recorded by the kernel that wrote them, whic= h can > + * be smaller or larger than the caller's structure. Fields beyond that = size > + * are not present in the entry. > * > * Return: A pointer to the next serialized entry, or NULL if all serial= ized > * entries have been read. --=20 Pasha