From nobody Sat Sep 26 08:37:44 2026 Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) (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 DAA92316905 for ; Thu, 3 Sep 2026 02:34:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.69 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788402904; cv=none; b=hvuqSUUPOmYjrfyZL3AJT0Rj0qMHc28MelJR60/lTiOV58U/dCuh+AfcNx6NUUhXAYgUUS2SfcH9ov/AHHet9qEwY00sNR78T8AD2HH1OXZ1Ch/IbiwGLXr/jsolkx/maF9Ky7b1DT+53+WLslmTY6MVxGVGUOctIrFoluQDs3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788402904; c=relaxed/simple; bh=ZIZ26mrTUuug6bKSq0P9x/4GvGh5nk8/dS3YxH8CAfM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HTZN/n6T5uTjB/3AW+yICn9cbKqcpcbmwJsIfPYmKEJ55HZFQCSORp7Rg8ZXsu9eQgrhcyedyJkOcN8csSuIWqngmSLX1caHsQT7pwOvQ1MeiIQjP78OcRFYvofToHVhyQKLarunbSJ5ANVvCNOVrYdtQzmmUlCVif3KwoLfOIc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--loganodell.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=HwqaWoKc; arc=none smtp.client-ip=209.85.216.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--loganodell.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HwqaWoKc" Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-3823dcc1647so2389774a91.3 for ; Wed, 02 Sep 2026 19:34:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1788402897; x=1789007697; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=NXIsSz+mo8g74Vp8Vf3mNp3/WCeSzCYf+BKqQ2Sb8NU=; b=HwqaWoKcUG6AhIRUEh1WTDNXDD25LQNrceIhMftawpeU3So3kbSQ+nipC65E13GMSz EKAGR1T8yaxnWfDJC/1hQhIl5eGPL9jU8Cf3Ym3qIt38YedjhAdr+WDPm0/kZQ0H5/8Y xvonU5S7zfd4pP/MfIMzkNRJB0Dk2qpHQWft8kX24QSeGiSD4dTCrhGWbG7gmM7D/tAw vZgoCM2/G8kKZFSKGWWJTaweorwRIZAW9ohO9IUf7PxDjJWqMefPRe47jhHeb3HAweT5 cZgVkvxswIG50EMY6x24BXL8XUBL37bolqduZcwKyb27En7vEq68puD0JQeAy9klB2hg 1hJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788402897; x=1789007697; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=NXIsSz+mo8g74Vp8Vf3mNp3/WCeSzCYf+BKqQ2Sb8NU=; b=DZFrbddDVOUytaA9EYIdfqHD2pUBdc61nrx3yk/3IK4eDwC3n50Fsxh/NTP8XluEMP PhuTrKHDKujLqvf+OT4bbOf2sDiR24XxzlDQDAk1SYRdTVBOg+tUGsPv5Xck6AD+rp8n N+Nn9JB6c236jRZ8CMYC6EfNeXXIPcpurSdlFN+srAM4Bn/ygE7gAuNMV4CRXRwXfB0p jBD5/8W64TSoHYtcu+9c/ZbnWMQy35RzUt+6jM9ANbzup2efJviaIdLTjiuC2JGaH0/Z u91MbS3ou+yVGLvUvxEv6fYeS8C9mdMhyGRwXpCyXAdZ/oHHcrtjxvoWlW/1sB4AJlju b/hw== X-Forwarded-Encrypted: i=1; AKwUvBzYRXWIpB0IT0z0ndhy+Sq8ASVjJZKpu7ZY5gp30nqsHc/V4/wgsrSOLEPla2xVGu+K44tbWbn8wH4P1I4=@vger.kernel.org X-Gm-Message-State: AFuF++lnrKbzyBaOzm+j5tTOuH2uwtJrzMi3MDx0RHbi68tvyO4HYtl+ 6JNparhfUw3FJ6AcxHx5EWDOLa6V/s5sXNpq5dvzsFJRpKvh89Ys4xvK8ccW8dfqgMRL2qc3H9+ nTzyIGSVAh0kBx7k8EpbKUw== X-Received: from dld23.prod.google.com ([2002:a05:7022:317:b0:13b:9d65:a542]) (user=loganodell job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2d83:b0:38f:5801:dc0e with SMTP id 98e67ed59e1d1-39aee049464mr14969285a91.15.1788402896637; Wed, 02 Sep 2026 19:34:56 -0700 (PDT) Date: Wed, 2 Sep 2026 19:34:50 -0700 In-Reply-To: <20260903023452.721732-1-loganodell@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260903023452.721732-1-loganodell@google.com> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog Message-ID: <20260903023452.721732-2-loganodell@google.com> Subject: [RFC PATCH 1/3] luo: Move to feature flags instead of compatibility strings From: Logan Odell To: arnd@arndb.de, pasha.tatashin@soleen.com, rppt@kernel.org, pratyush@kernel.org, graf@amazon.com, akpm@linux-foundation.org, pbonzini@redhat.com, maz@kernel.org, oupton@kernel.org, seanjc@google.com, bhelgaas@google.com, alex@shazbot.org, jgg@nvidia.com, kevin.tian@intel.com, dwmw2@infradead.org, baolu.lu@linux.intel.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, kexec@lists.infradead.org, linux-mm@kvack.org, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-pci@vger.kernel.org, iommu@lists.linux.dev, Logan Odell Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Define a 128 byte header that can be used by all live update serialized structures. In this header, we reserve room for 64 features with supported, active, and required bits. Update the top level luo struct to use this instead of compatibility strings. Previous versions of the struct had smaller sizes, so add a minimum size check to avoid collisions with older kernels. Signed-off-by: Logan Odell --- include/linux/kho/abi/luo.h | 74 +++++++++++++++++++++++++++++------- kernel/liveupdate/luo_core.c | 44 +++++++++++++-------- 2 files changed, 90 insertions(+), 28 deletions(-) diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h index 288076de6d4a..0a7662a0cf9a 100644 --- a/include/linux/kho/abi/luo.h +++ b/include/linux/kho/abi/luo.h @@ -13,15 +13,17 @@ * kernel. The ABI is built upon the Kexec HandOver framework and registers * the central `struct luo_ser` via the KHO raw subtree API. * - * This interface is a contract. Any modification to the structure fields, - * compatible strings, or the layout of the `__packed` serialization - * structures defined here constitutes a breaking change. Such changes req= uire - * incrementing the version number in the relevant `_COMPATIBLE` string to - * prevent a new kernel from misinterpreting data from an old kernel. + * This interface is a contract. To ensure the stability of moving between + * kernel versions, any changes to the structures should only be additive + * and should utilize the feature flags to denote the supported, active, a= nd + * required status of the feature. + * + * Features that are entirely optional can be added with the supported and + * active flags both asserted, and the required flag cleared. Features that + * require that the next kernel supports the feature should only be added = as + * supported to allow compatible transition kernels. At a later time, the + * active and required flag should be asserted. * - * Changes are allowed provided the compatibility version is incremented; - * however, backward/forward compatibility is only guaranteed for kernels - * supporting the same ABI version. * * KHO Structure Overview: * The entire LUO state is encapsulated within a single KHO entry named = "LUO". @@ -30,7 +32,7 @@ * Serialization Structures: * - struct luo_ser: * The central ABI structure that contains the overall state of the LU= O. - * It includes the compatibility string, the liveupdate-number, and po= inters + * It includes the feature flags, the liveupdate-number, and pointers * to sessions and FLBs. * * - struct luo_session_ser: @@ -58,19 +60,65 @@ #define _LINUX_KHO_ABI_LUO_H =20 #include +#include #include #include =20 +/** + * struct luo_feature_hdr - Feature negotiation and versioning header. + * @supp: Bitmask of features supported by the producing subsystem. + * @req: Bitmask of features required for safe deserialization by the + * receiving subsystem. + * @active: Bitmask of features actually active/used in the serialized p= ayload. + * @reserved: Reserved for future use. + * + * This header can be embedded at the beginning of any serialized structur= e to + * provide forward and backward compatibility via feature negotiation acro= ss + * live update. + */ +struct luo_feature_hdr { + u64 supp; + u64 req; + u64 active; + u64 reserved[13]; +} __packed; + +#define LUO_FEATURE_ACTIVE(s, f) \ + do { \ + (s)->features.supp |=3D (u64)(f); \ + (s)->features.active |=3D (u64)(f); \ + } while (0) +#define LUO_FEATURE_SUPPORTED(s, f) ((s)->features.supp |=3D (u64)(f)) +#define LUO_FEATURE_REQUIRED(s, f) ((s)->features.req |=3D (u64)(f)) +#define LUO_FEATURE_IS_ACTIVE(s, f) (!!((s)->features.active & (u64)(f))) +#define LUO_FEATURE_IS_SUPPORTED(s, f) (!!((s)->features.supp & (u64)(f))) +#define LUO_FEATURE_IS_REQUIRED(s, f) (!!((s)->features.req & (u64)(f))) + /* * The LUO state is registered under this KHO entry name. */ #define LUO_KHO_ENTRY_NAME "LUO" -#define LUO_ABI_COMPATIBLE "luo-v5" -#define LUO_ABI_COMPAT_LEN ALIGN(sizeof(LUO_ABI_COMPATIBLE), 8) + +/* + * Bits associated with the luo_feature_hdr values. + */ +#define LUO_FEATURE_NUMBER BIT_ULL(0) +#define LUO_FEATURE_SESSIONS BIT_ULL(1) +#define LUO_FEATURE_FLBS BIT_ULL(2) + +#define LUO_CORE_FEATURES_SUPP (LUO_FEATURE_NUMBER | \ + LUO_FEATURE_SESSIONS | \ + LUO_FEATURE_FLBS) +#define LUO_CORE_FEATURES_REQ (LUO_FEATURE_NUMBER | \ + LUO_FEATURE_SESSIONS | \ + LUO_FEATURE_FLBS) +#define LUO_CORE_FEATURES_ACTIVE (LUO_FEATURE_NUMBER | \ + LUO_FEATURE_SESSIONS | \ + LUO_FEATURE_FLBS) =20 /** * struct luo_ser - Centralized LUO ABI header. - * @compatible: Compatibility string identifying the LUO ABI version. + * @features: Bit mask of supported and active features. * @liveupdate_num: A counter tracking the number of successful live updat= es. * @sessions_pa: Physical address of the first session block header. * @flbs_pa: Physical address of the FLB header. @@ -78,7 +126,7 @@ * This structure is the root of all preserved LUO state. */ struct luo_ser { - char compatible[LUO_ABI_COMPAT_LEN]; + struct luo_feature_hdr features; u64 liveupdate_num; u64 sessions_pa; u64 flbs_pa; diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c index 1b2bda22902d..6add1ecc463f 100644 --- a/kernel/liveupdate/luo_core.c +++ b/kernel/liveupdate/luo_core.c @@ -107,26 +107,37 @@ static int __init luo_early_startup(void) return 0; } =20 - if (len < sizeof(*luo_ser)) { - pr_err("LUO state is too small (%zu < %zu)\n", len, sizeof(*luo_ser)); - return -EINVAL; + luo_ser =3D phys_to_virt(luo_ser_phys); + + if (len < sizeof(struct luo_feature_hdr)) { + pr_err("LUO state is too small (%zu < %zu)\n", + len, sizeof(struct luo_feature_hdr)); + err =3D -EINVAL; + goto out_free_ser; } =20 - luo_ser =3D phys_to_virt(luo_ser_phys); - if (strncmp(luo_ser->compatible, LUO_ABI_COMPATIBLE, LUO_ABI_COMPAT_LEN))= { - pr_err("LUO state is incompatible with '%s'\n", LUO_ABI_COMPATIBLE); - return -EINVAL; + if (luo_ser->features.req & ~LUO_CORE_FEATURES_SUPP) { + pr_err("Unsupported required LUO feature (req: 0x%llx, supp: 0x%llx)\n", + luo_ser->features.req, (u64)LUO_CORE_FEATURES_SUPP); + err =3D -EOPNOTSUPP; + goto out_free_ser; } =20 - luo_global.liveupdate_num =3D luo_ser->liveupdate_num; - pr_info("Retrieved live update data, liveupdate number: %lld\n", - luo_global.liveupdate_num); + if (LUO_FEATURE_IS_ACTIVE(luo_ser, LUO_FEATURE_NUMBER)) { + luo_global.liveupdate_num =3D luo_ser->liveupdate_num; + pr_info("Retrieved live update data, liveupdate number: %lld\n", + luo_global.liveupdate_num); + } =20 - err =3D luo_session_setup_incoming(luo_ser->sessions_pa); - if (err) - goto out_free_ser; =20 - luo_flb_setup_incoming(luo_ser->flbs_pa); + if (LUO_FEATURE_IS_ACTIVE(luo_ser, LUO_FEATURE_SESSIONS)) { + err =3D luo_session_setup_incoming(luo_ser->sessions_pa); + if (err) + goto out_free_ser; + } + + if (LUO_FEATURE_IS_ACTIVE(luo_ser, LUO_FEATURE_FLBS)) + luo_flb_setup_incoming(luo_ser->flbs_pa); =20 err =3D 0; =20 @@ -162,7 +173,10 @@ static int __init luo_state_setup(void) return PTR_ERR(luo_ser); } =20 - strscpy(luo_ser->compatible, LUO_ABI_COMPATIBLE, sizeof(luo_ser->compatib= le)); + luo_ser->features.supp =3D LUO_CORE_FEATURES_SUPP; + luo_ser->features.req =3D LUO_CORE_FEATURES_REQ; + luo_ser->features.active =3D LUO_CORE_FEATURES_ACTIVE; + luo_ser->liveupdate_num =3D luo_global.liveupdate_num + 1; =20 luo_session_setup_outgoing(&luo_ser->sessions_pa); --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 08:37:44 2026 Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) (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 F38B235E1B8 for ; Thu, 3 Sep 2026 02:35:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.70 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788402907; cv=none; b=pXMHi6zSuCdgm0hXBVo9GzvUCYIIbt+czF0mY5WInpO8vUPR0X1bZq6RzneBZ7H1X+IbxE4hNOxkt+Rc+de5tJfegGgWrbv1XzlmGpxtXboVk2ehKOldUXFNGPJy4RRTRxCy9NomeOV1JWeAOiGR1LaazudlqeootWhdmnxe/3w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788402907; c=relaxed/simple; bh=/wgIjAR3Nkn0dkLJ5F4noRZR2nevYpV3/NPEpvosUDQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PVjehcJNojY9qHSnmE0ZsBdfdiwMJJVeLYmrnzXyj7TMzgWPc+gXMIODcGuP58N/zy4Vdr9OiHLkN5rUMzByGktaWxmhTSmnzV5ESAht39+JfujW/DFhfWmcC/tvlpltD5o0YZxL2HDqumqUn7S60Tva2TvNa1u9pVjnmYyNbis= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--loganodell.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=f3lZ6ICk; arc=none smtp.client-ip=209.85.216.70 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--loganodell.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="f3lZ6ICk" Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-385d2703b64so551902a91.1 for ; Wed, 02 Sep 2026 19:35:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1788402898; x=1789007698; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=t1Sj3SZIoFO1IrO+MibWwCI7jpIestNZ9bFRqEQ8nhA=; b=f3lZ6ICkbIJFpDxVz8UVHh9oCNeKKlpg0O7UGb/r6FHUQJ/RKpTjOxD1wu1bMtUt+T jonCDqyWb0xSrgy59OkMklvqlrUGhdcjwoZUKlZLDgY6mZNIedvsM2fn82UU+w5X1/N+ EjWvmLxlqfUmMl6tjc51y1mmXx0POeRVSi1TX8prirOYD65FAHWEMRBMx+KmFvMSu4tE Rpq0Jjx25HoQyCpC7YoI32m2caYtHzixf5Ytl2Y98AlRgwozi/+PEECuQMv7An49n45K XapHRLYx02/uobXZOAUW07ETGunKzmH5sD+bodXHMI74YFcVbu2gcWHB4zEIL+g0lEBB aaeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788402898; x=1789007698; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=t1Sj3SZIoFO1IrO+MibWwCI7jpIestNZ9bFRqEQ8nhA=; b=K1w2Tx9ZBMUN/AUm39wNgRL35Z1xBl2hLJb9d4goJ1sDryTUmHrYa7KB/aIJ3TlqZo ospHxHnva3jvZJBOW7Y4Jv8ezMY0tCHhUFnQAjp493bTViLMze/wDlEZ+wnVzcU4dhnI sqnP9LnBFjxh++Lm1g4B3ltqx0RE2ldjnGAbnnIe3kt6FNilJjNc8BlLVgzm7v9ukjaL Nz8MQNtEgERU2WNjWJwrZA9uq2s9hSUnHMeRxDh79oXtcDxfKzvDFdJEYO6/Lm3eYjE+ y/LRyqU6G4QBkILowwlmPq1OYxCr/Yz81rJX4NMeVm0w2vmjCRfPZzotb0iVaaqGnclM a7fg== X-Forwarded-Encrypted: i=1; AKwUvBw/E5RwbgWlEKgY3yxyos4mq62w8eSJioMwUvoIl7GqBN0BXjJUik9HlWOju5aOOyVnO9L4v/nDhmZlNJg=@vger.kernel.org X-Gm-Message-State: AFuF++kyZsUPzBdR+VXxMIo4PU2vPEX/mhLl0hyIUATrD0o9IJZQBuSp WLCsPMx6rmwcEf1eeVJTVd6gjG1TV5GPg/wM/LA69ITT8R8BqlEgwEyDM7W4hzu67VEIonzUQL6 vuuGzJOZ9oBHjYDXfvcRC5g== X-Received: from dybdb19.prod.google.com ([2002:a05:7300:b093:b0:328:684d:3f7]) (user=loganodell job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4b04:b0:396:4ce0:6400 with SMTP id 98e67ed59e1d1-39b07f33963mr3591851a91.2.1788402897557; Wed, 02 Sep 2026 19:34:57 -0700 (PDT) Date: Wed, 2 Sep 2026 19:34:51 -0700 In-Reply-To: <20260903023452.721732-1-loganodell@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260903023452.721732-1-loganodell@google.com> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog Message-ID: <20260903023452.721732-3-loganodell@google.com> Subject: [RFC PATCH 2/3] luo: Export feature support to vmlinux section From: Logan Odell To: arnd@arndb.de, pasha.tatashin@soleen.com, rppt@kernel.org, pratyush@kernel.org, graf@amazon.com, akpm@linux-foundation.org, pbonzini@redhat.com, maz@kernel.org, oupton@kernel.org, seanjc@google.com, bhelgaas@google.com, alex@shazbot.org, jgg@nvidia.com, kevin.tian@intel.com, dwmw2@infradead.org, baolu.lu@linux.intel.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, kexec@lists.infradead.org, linux-mm@kvack.org, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-pci@vger.kernel.org, iommu@lists.linux.dev, Logan Odell Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Create a liveupdate_features section that contains the feature information for a given liveupdate component. Add the LUO component first. These can be compared between two kernels to determine live update compatibility. Features marked as required in the running kernel will need to have that feature marked as supported in the next kernel to be eligible for compatibility. Suggested-by: Pratyush Yadav Signed-off-by: Logan Odell --- include/asm-generic/vmlinux.lds.h | 12 +++++++++++ include/linux/kho/abi/luo.h | 34 +++++++++++++++++++++++++++++++ include/linux/liveupdate.h | 12 +++++++++++ kernel/liveupdate/luo_core.c | 16 +++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinu= x.lds.h index 5659f4b5a125..aed4e282a78c 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -359,6 +359,17 @@ #define THERMAL_TABLE(name) #endif =20 +#ifdef CONFIG_LIVEUPDATE +#define LIVEUPDATE_FEATURES \ + . =3D ALIGN(8); \ + .liveupdate_features : AT(ADDR(.liveupdate_features) - LOAD_OFFSET) { \ + KEEP(*(.liveupdate_sec_hdr)) \ + KEEP(*(.liveupdate_features)) \ + } +#else +#define LIVEUPDATE_FEATURES +#endif + #define KERNEL_DTB() \ STRUCT_ALIGN(); \ __dtb_start =3D .; \ @@ -554,6 +565,7 @@ RO_EXCEPTION_TABLE \ NOTES \ BTF \ + LIVEUPDATE_FEATURES \ \ . =3D ALIGN((align)); \ __end_rodata =3D .; diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h index 0a7662a0cf9a..5b25e1b48cf5 100644 --- a/include/linux/kho/abi/luo.h +++ b/include/linux/kho/abi/luo.h @@ -230,4 +230,38 @@ struct luo_flb_ser { #define LIVEUPDATE_TEST_FLB_COMPATIBLE(i) "liveupdate-test-flb-v" #i #endif =20 +#define LIVEUPDATE_VER_HDR_MAGIC 0x4c565550 /* 'LVUP' */ +#define LIVEUPDATE_VER_HDR_VER 1 + +/** + * struct liveupdate_ver_hdr - Header of vmlinux section with version lists + * @magic: Magic number ('LVUP'). + * @version: Version of the header format. + * + * This struct is the header for the vmlinux section ".liveupdate_features= ". The + * section contains the list of feature/version entries that the kernel su= pports. + */ +struct liveupdate_ver_hdr { + u32 magic; + u32 version; +} __packed; + +/** + * struct liveupdate_feature_entry - Live update feature/version entry + * @name: Name of the subsystem or feature ("luo" for core). + * @feat_bytes: Number of bytes covered by supp, req, and active bitmaps (= e.g. 8). + * @reserved: Reserved / padding for alignment. + * @supp: Bitmask of supported features. + * @req: Bitmask of required features. + * @active: Bitmask of active features. + */ +struct liveupdate_feature_entry { + char name[LIVEUPDATE_HNDL_COMPAT_LENGTH]; + u32 feat_bytes; + u32 reserved; + u64 supp; + u64 req; + u64 active; +} __packed; + #endif /* _LINUX_KHO_ABI_LUO_H */ diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index 6051abc0612c..e058df23fed1 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -229,6 +229,16 @@ struct liveupdate_flb { =20 #ifdef CONFIG_LIVEUPDATE =20 +#define LIVEUPDATE_FEATURE_ENTRY(_id, _name, _supp, _req, _active) \ + static const struct liveupdate_feature_entry __lu_feat_##_id \ + __used __section(".liveupdate_features") __aligned(8) =3D { \ + .name =3D _name, \ + .feat_bytes =3D sizeof(u64), \ + .supp =3D (_supp), \ + .req =3D (_req), \ + .active =3D (_active), \ + } + /* Return true if live update orchestrator is enabled */ bool liveupdate_enabled(void); =20 @@ -259,6 +269,8 @@ int liveupdate_get_token_outgoing(struct liveupdate_ses= sion *s, =20 #else /* CONFIG_LIVEUPDATE */ =20 +#define LIVEUPDATE_FEATURE_ENTRY(_id, _name, _supp, _req, _active) + static inline bool liveupdate_enabled(void) { return false; diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c index 6add1ecc463f..27413f895174 100644 --- a/kernel/liveupdate/luo_core.c +++ b/kernel/liveupdate/luo_core.c @@ -64,6 +64,22 @@ #include "kexec_handover_internal.h" #include "luo_internal.h" =20 +/* + * This is the header for the ".liveupdate_features" section in vmlinux. + * The linker makes sure that this header precedes the entries. + */ +static const struct liveupdate_ver_hdr ver_hdr + __used __section(".liveupdate_sec_hdr") __aligned(8) =3D { + .magic =3D LIVEUPDATE_VER_HDR_MAGIC, + .version =3D LIVEUPDATE_VER_HDR_VER, +}; + +/* Core LUO features */ +LIVEUPDATE_FEATURE_ENTRY(luo_core, "luo", + LUO_CORE_FEATURES_SUPP, + LUO_CORE_FEATURES_REQ, + LUO_CORE_FEATURES_ACTIVE); + static struct { bool enabled; struct luo_ser *luo_ser_out; --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 08:37:44 2026 Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) (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 B37B53515CF for ; Thu, 3 Sep 2026 02:35:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.70 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788402908; cv=none; b=icNuNXjaeVWseL4Xgrl2Ey7t0mpBIHYPZjYOKpj/Ft5pQmLZc6NyCIeEEql8uzAbRt9esaBFfZOxcA4zmLvKeEvS8uqrAyOoDHBfQEsDuMkdG45tm+ttqsIXqIDdAg/IILFH4te+6WlE9J/wQ6hopUDKmcY6HL/ql+Htm9Nrt4I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788402908; c=relaxed/simple; bh=KkllZ0CXRBgyZYgnbfWvEuICZuPWHeEgnlWGgS0PT3U=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=f0ZmexPX/okMYkx3piKySWZe/qpNgO88UhU8Mfn83Qrl7K9SwByrb0+XWXsmE7aiJ6v+1hlmy+8JSW/0B9RMy7l7e2k9hLD1aPlJG9OCXfKdFM9tUuOXt8MykslP+OtnzAbiUbtlNCNi6NWMIksDkh9L5IvtX5HVM27DyWgUIF0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--loganodell.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=uk1Q1YTc; arc=none smtp.client-ip=209.85.216.70 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--loganodell.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="uk1Q1YTc" Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-3968bb86fb7so2384590a91.2 for ; Wed, 02 Sep 2026 19:35:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1788402899; x=1789007699; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=3jZRbPTlJQ2oU3N5reiU/R1oleIxZE7zMycKAHKHmwY=; b=uk1Q1YTctHR1EAEfSx+NSD5Yg4sQUeFkYqL5tLARwc3+BJDmamiVU2FYRiB9Ixk5+C DDYynVGn3pKqg7zwXfGXCn3fMo2PahO3CicpVlLS7N6Tw5J8/a9K02hL5m7SrXKUnZOf 72APtMM3ow1p1G72jInznyzn0OhPKob1EsgsAxcRHwwZUFmYgD4aXvZf1vx9K8SSdd0+ HLnHcoY42rW1FUt0PclLX1fd+DRrMEmsrBwOAiU4oTX42aYsRhRqx8HopGaMqfRBOX+R 6IA/tWHS5uuOGs4xYhrqHhhmmRNZgOokqJHkTfTLED0ECLcCFhzz1/CJdRNFLvPCEa5+ 5ITQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788402899; x=1789007699; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3jZRbPTlJQ2oU3N5reiU/R1oleIxZE7zMycKAHKHmwY=; b=nTivSwg8CXn3XFXXQ8Zdf815U1MoFM2yMAWw5rhnSMoOBP21tBrjKuMubuR+GaOe6F O1yp650YI8UAWdCNSbgjspPFO8a/dp4lnf3wNVoc88djNYU3CPMLogACAU0xy/kz5xxI v2ez8GxY5LaEsXTOj9EDCsPY6bmWbHFpRVQsvxf+FKnMXB3FGuRXY1FIT/sH01XEBWWM RN+xTdfTtyR4CzDbQi/l/32o/NUPJkdUfMPswLvLP7mQwSVkTmV57DM4LdJSq/C6R37F LcZbIC1SMnP0YIcM21Mf9q8Bl8cs/rRlFe0BE60kUZoFQG5qXcjSpHRB9WmAMXvqARKQ qlEw== X-Forwarded-Encrypted: i=1; AKwUvByW9D6v/Cg8oyHOgUD9Y1yTBDen1wl2KHFGRZGNBSadEkxojJtSLv8a6OhLPTTIAEFCHBEb7KnOMRsmZuc=@vger.kernel.org X-Gm-Message-State: AFuF++nQ4R1bH3adNeHSpA5608GfrBY86v8XC89cz5CXfnLGvq+nJan+ DRaQKmSgnUUhYQ2jdHRzKnCAgbmMrXsMn4FbdWa/nRtL5mWRNZ+qur/bZvSJEfKd77N6I2WP5aa 34R8NdyeHalkxuTZytk0KnA== X-Received: from dyboc22.prod.google.com ([2002:a05:7301:3f16:b0:32b:1306:42ad]) (user=loganodell job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:288a:b0:380:21b7:e727 with SMTP id 98e67ed59e1d1-39aee0848bbmr14352175a91.14.1788402898410; Wed, 02 Sep 2026 19:34:58 -0700 (PDT) Date: Wed, 2 Sep 2026 19:34:52 -0700 In-Reply-To: <20260903023452.721732-1-loganodell@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260903023452.721732-1-loganodell@google.com> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog Message-ID: <20260903023452.721732-4-loganodell@google.com> Subject: [RFC PATCH 3/3] luo: memfd: Move to feature flags instead of compatibility strings From: Logan Odell To: arnd@arndb.de, pasha.tatashin@soleen.com, rppt@kernel.org, pratyush@kernel.org, graf@amazon.com, akpm@linux-foundation.org, pbonzini@redhat.com, maz@kernel.org, oupton@kernel.org, seanjc@google.com, bhelgaas@google.com, alex@shazbot.org, jgg@nvidia.com, kevin.tian@intel.com, dwmw2@infradead.org, baolu.lu@linux.intel.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, kexec@lists.infradead.org, linux-mm@kvack.org, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-pci@vger.kernel.org, iommu@lists.linux.dev, Logan Odell Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Update struct memfd_luo_ser to embed struct luo_feature_hdr features. Define feature flags for memfd (MEMFD_LUO_FEATURE_SEALS and MEMFD_LUO_FEATURE_FOLIOS), emit the liveupdate feature entry for memfd, and validate required features and active flags during deserialization. Also replace the version bump requirement for seals with MEMFD_LUO_BASE_SEALS to allow new seals to be introduced granularly as feature bits. Signed-off-by: Logan Odell --- include/linux/kho/abi/luo.h | 8 +++--- include/linux/kho/abi/memfd.h | 41 ++++++++++++++++++++---------- include/linux/liveupdate.h | 10 ++++---- kernel/liveupdate/luo_file.c | 28 ++++++++++----------- kernel/liveupdate/luo_flb.c | 2 +- lib/tests/liveupdate.c | 2 +- mm/memfd_luo.c | 47 +++++++++++++++++++++++++---------- 7 files changed, 87 insertions(+), 51 deletions(-) diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h index 5b25e1b48cf5..450a0e40e2ab 100644 --- a/include/linux/kho/abi/luo.h +++ b/include/linux/kho/abi/luo.h @@ -132,18 +132,18 @@ struct luo_ser { u64 flbs_pa; } __packed; =20 -#define LIVEUPDATE_HNDL_COMPAT_LENGTH 48 +#define LIVEUPDATE_HNDL_NAME_LENGTH 48 =20 /** * struct luo_file_ser - Represents the serialized preserves files. - * @compatible: File handler compatible string. + * @name: File handler name. * @data: Private data * @token: User provided token for this file * * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_file_ser { - char compatible[LIVEUPDATE_HNDL_COMPAT_LENGTH]; + char name[LIVEUPDATE_HNDL_NAME_LENGTH]; u64 data; u64 token; } __packed; @@ -256,7 +256,7 @@ struct liveupdate_ver_hdr { * @active: Bitmask of active features. */ struct liveupdate_feature_entry { - char name[LIVEUPDATE_HNDL_COMPAT_LENGTH]; + char name[LIVEUPDATE_HNDL_NAME_LENGTH]; u32 feat_bytes; u32 reserved; u64 supp; diff --git a/include/linux/kho/abi/memfd.h b/include/linux/kho/abi/memfd.h index 08b10fea2afc..9961df5be423 100644 --- a/include/linux/kho/abi/memfd.h +++ b/include/linux/kho/abi/memfd.h @@ -11,6 +11,8 @@ #ifndef _LINUX_KHO_ABI_MEMFD_H #define _LINUX_KHO_ABI_MEMFD_H =20 +#include +#include #include #include =20 @@ -23,11 +25,20 @@ * The state is serialized into a packed structure `struct memfd_luo_ser` * which is handed over to the next kernel via the KHO mechanism. * - * This interface is a contract. Any modification to the structure layout - * constitutes a breaking change. Such changes require incrementing the - * version number in the MEMFD_LUO_FH_COMPATIBLE string. + * This interface is a contract. Any changes should be additive using feat= ure + * flags to ensure backwards compatibility. */ =20 +#define MEMFD_LUO_FEATURE_SEALS BIT_ULL(0) +#define MEMFD_LUO_FEATURE_FOLIOS BIT_ULL(1) + +#define MEMFD_LUO_FEATURES_SUPP (MEMFD_LUO_FEATURE_SEALS | \ + MEMFD_LUO_FEATURE_FOLIOS) +#define MEMFD_LUO_FEATURES_REQ (MEMFD_LUO_FEATURE_SEALS | \ + MEMFD_LUO_FEATURE_FOLIOS) +#define MEMFD_LUO_FEATURES_ACTIVE (MEMFD_LUO_FEATURE_SEALS | \ + MEMFD_LUO_FEATURE_FOLIOS) + /** * MEMFD_LUO_FOLIO_DIRTY - The folio is dirty. * @@ -57,18 +68,21 @@ struct memfd_luo_folio_ser { } __packed; =20 /* - * The set of seals this version supports preserving. If support for any n= ew - * seals is needed, add it here and bump version. + * The set of base seals supported by MEMFD_LUO_FEATURE_SEALS. + * If support for new seals is needed, define a dedicated feature bit + * (e.g. MEMFD_LUO_FEATURE_SEAL_) to allow granular compatibility. */ -#define MEMFD_LUO_ALL_SEALS (F_SEAL_SEAL | \ - F_SEAL_SHRINK | \ - F_SEAL_GROW | \ - F_SEAL_WRITE | \ - F_SEAL_FUTURE_WRITE | \ - F_SEAL_EXEC) +#define MEMFD_LUO_BASE_SEALS (F_SEAL_SEAL | \ + F_SEAL_SHRINK | \ + F_SEAL_GROW | \ + F_SEAL_WRITE | \ + F_SEAL_FUTURE_WRITE | \ + F_SEAL_EXEC) +#define MEMFD_LUO_ALL_SEALS MEMFD_LUO_BASE_SEALS =20 /** * struct memfd_luo_ser - Main serialization structure for a memfd. + * @features: Bit mask of supported, required, and active features. * @pos: The file's current position (f_pos). * @size: The total size of the file in bytes (i_size). * @seals: The seals present on the memfd. The seals are uABI so it is= safe @@ -79,6 +93,7 @@ struct memfd_luo_folio_ser { * struct memfd_luo_folio_ser. */ struct memfd_luo_ser { + struct luo_feature_hdr features; u64 pos; u64 size; u32 seals; @@ -87,7 +102,7 @@ struct memfd_luo_ser { struct kho_vmalloc folios; } __packed; =20 -/* The compatibility string for memfd file handler */ -#define MEMFD_LUO_FH_COMPATIBLE "memfd-v2" +/* The name for memfd file handler */ +#define MEMFD_LUO_FH_NAME "memfd" =20 #endif /* _LINUX_KHO_ABI_MEMFD_H */ diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index e058df23fed1..4489e344f76f 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -90,10 +90,10 @@ struct liveupdate_file_ops { /** * struct liveupdate_file_handler - Represents a handler for a live-updata= ble file type. * @ops: Callback functions - * @compatible: The compatibility string (e.g., "memfd-v1", "vfiof= d-v1") - * that uniquely identifies the file type this handler - * supports. This is matched against the compatible s= tring - * associated with individual &struct file instances. + * @name: The name (e.g., "memfd", "vfiofd") that uniquely + * identifies the file type this handler supports. Th= is + * is matched against the name associated with indivi= dual + * &struct file instances. * * Modules that want to support live update for specific file types should * register an instance of this structure. LUO uses this registration to @@ -102,7 +102,7 @@ struct liveupdate_file_ops { */ struct liveupdate_file_handler { const struct liveupdate_file_ops *ops; - const char compatible[LIVEUPDATE_HNDL_COMPAT_LENGTH]; + const char name[LIVEUPDATE_HNDL_NAME_LENGTH]; =20 /* private: */ =20 diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c index dbae0715220b..775484af0750 100644 --- a/kernel/liveupdate/luo_file.c +++ b/kernel/liveupdate/luo_file.c @@ -480,13 +480,13 @@ int luo_file_freeze(struct luo_file_set *file_set, err =3D luo_file_freeze_one(file_set, luo_file); if (err < 0) { pr_warn("Freeze failed for token[%#0llx] handler[%s] err[%pe]\n", - luo_file->token, luo_file->fh->compatible, + luo_file->token, luo_file->fh->name, ERR_PTR(err)); goto err_unfreeze; } =20 - strscpy(file_ser->compatible, luo_file->fh->compatible, - sizeof(file_ser->compatible)); + strscpy(file_ser->name, luo_file->fh->name, + sizeof(file_ser->name)); file_ser->data =3D luo_file->serialized_data; file_ser->token =3D luo_file->token; } @@ -732,7 +732,7 @@ static int luo_file_deserialize_one(struct luo_file_set= *file_set, =20 down_read(&luo_register_rwlock); list_private_for_each_entry(fh, &luo_file_handler_list, list) { - if (!strcmp(fh->compatible, ser->compatible)) { + if (!strcmp(fh->name, ser->name)) { if (try_module_get(fh->ops->owner)) handler_found =3D true; break; @@ -741,9 +741,9 @@ static int luo_file_deserialize_one(struct luo_file_set= *file_set, up_read(&luo_register_rwlock); =20 if (!handler_found) { - pr_warn("No registered handler for compatible '%.*s'\n", - (int)sizeof(ser->compatible), - ser->compatible); + pr_warn("No registered handler for name '%.*s'\n", + (int)sizeof(ser->name), + ser->name); return -ENOENT; } =20 @@ -774,9 +774,9 @@ static int luo_file_deserialize_one(struct luo_file_set= *file_set, * in-memory linked list of 'struct luo_file' instances. * * For each serialized entry, it performs the following steps: - * 1. Reads the 'compatible' string. + * 1. Reads the 'name' string. * 2. Searches the global list of registered file handlers for one that - * matches the compatible string. + * matches the name. * 3. Allocates a new 'struct luo_file'. * 4. Populates the new structure with the deserialized data (token, pri= vate * data handle) and links it to the found handler. The 'file' pointer= is @@ -870,7 +870,7 @@ void luo_file_set_destroy(struct luo_file_set *file_set) * liveupdate_register_file_handler - Register a file handler with LUO. * @fh: Pointer to a caller-allocated &struct liveupdate_file_handler. * The caller must initialize this structure, including a unique - * 'compatible' string and a valid 'fh' callbacks. This function adds the + * 'name' string and valid 'fh' callbacks. This function adds the * handler to the global list of supported file handlers. * * Context: Typically called during module initialization for file types t= hat @@ -893,11 +893,11 @@ int liveupdate_register_file_handler(struct liveupdat= e_file_handler *fh) } =20 down_write(&luo_register_rwlock); - /* Check for duplicate compatible strings */ + /* Check for duplicate handler names */ list_private_for_each_entry(fh_iter, &luo_file_handler_list, list) { - if (!strcmp(fh_iter->compatible, fh->compatible)) { - pr_err("File handler registration failed: Compatible string '%s' alread= y registered.\n", - fh->compatible); + if (!strcmp(fh_iter->name, fh->name)) { + pr_err("File handler registration failed: Handler name '%s' already reg= istered.\n", + fh->name); err =3D -EEXIST; goto err_unlock; } diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index cd715a7c1d99..cb8c15f181e0 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -337,7 +337,7 @@ static void luo_flb_unregister_one(struct liveupdate_fi= le_handler *fh, =20 if (!found) { pr_warn("Failed to unregister FLB '%s': not found in file handler '%s'\n= ", - flb->compatible, fh->compatible); + flb->compatible, fh->name); return; } =20 diff --git a/lib/tests/liveupdate.c b/lib/tests/liveupdate.c index 4c08a7c6fb78..d3a8573a648e 100644 --- a/lib/tests/liveupdate.c +++ b/lib/tests/liveupdate.c @@ -135,7 +135,7 @@ void liveupdate_test_register(struct liveupdate_file_ha= ndler *fh) } =20 pr_info("Registered %d FLBs with file handler: [%s]\n", - TEST_NFLBS, fh->compatible); + TEST_NFLBS, fh->name); } =20 MODULE_LICENSE("GPL"); diff --git a/mm/memfd_luo.c b/mm/memfd_luo.c index 59de210bee5f..36ee503672a2 100644 --- a/mm/memfd_luo.c +++ b/mm/memfd_luo.c @@ -52,8 +52,8 @@ * * Seals * File seals set on the memfd are preserved and re-applied on restore. - * Only seals known to this LUO version (see ``MEMFD_LUO_ALL_SEALS``) may - * be present; preservation fails with ``-EOPNOTSUPP`` otherwise. + * Only base seals supported by this LUO version (see ``MEMFD_LUO_BASE_S= EALS``) + * may be present; preservation fails with ``-EOPNOTSUPP`` otherwise. * * Non-Preserved Properties * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D @@ -273,6 +273,10 @@ static int memfd_luo_preserve(struct liveupdate_file_o= p_args *args) goto err_unlock; } =20 + ser->features.supp =3D MEMFD_LUO_FEATURES_SUPP; + ser->features.req =3D MEMFD_LUO_FEATURES_REQ; + ser->features.active =3D MEMFD_LUO_FEATURES_ACTIVE; + seals =3D memfd_get_seals(args->file); if (seals < 0) { err =3D seals; @@ -352,8 +356,9 @@ static void memfd_luo_unpreserve(struct liveupdate_file= _op_args *args) =20 ser =3D phys_to_virt(args->serialized_data); =20 - memfd_luo_unpreserve_folios(&ser->folios, args->private_data, - ser->nr_folios); + if (LUO_FEATURE_IS_ACTIVE(ser, MEMFD_LUO_FEATURE_FOLIOS) && ser->nr_folio= s) + memfd_luo_unpreserve_folios(&ser->folios, args->private_data, + ser->nr_folios); =20 kho_unpreserve_free(ser); inode_unlock(inode); @@ -401,7 +406,7 @@ static void memfd_luo_finish(struct liveupdate_file_op_= args *args) if (!ser) return; =20 - if (ser->nr_folios) { + if (LUO_FEATURE_IS_ACTIVE(ser, MEMFD_LUO_FEATURE_FOLIOS) && ser->nr_folio= s) { folios_ser =3D kho_restore_vmalloc(&ser->folios); if (!folios_ser) goto out; @@ -526,12 +531,21 @@ static int memfd_luo_retrieve(struct liveupdate_file_= op_args *args) if (!ser) return -EINVAL; =20 - /* Make sure the file only has seals supported by this version. */ - if (ser->seals & ~MEMFD_LUO_ALL_SEALS) { + if (ser->features.req & ~MEMFD_LUO_FEATURES_SUPP) { + pr_err("Unsupported required memfd feature (req: 0x%llx, supp: 0x%llx)\n= ", + ser->features.req, (u64)MEMFD_LUO_FEATURES_SUPP); err =3D -EOPNOTSUPP; goto free_ser; } =20 + if (LUO_FEATURE_IS_ACTIVE(ser, MEMFD_LUO_FEATURE_SEALS)) { + /* Make sure the file only has seals supported by this version. */ + if (ser->seals & ~MEMFD_LUO_ALL_SEALS) { + err =3D -EOPNOTSUPP; + goto free_ser; + } + } + /* * The seals are preserved. Allow sealing here so they can be added * later. @@ -543,16 +557,18 @@ static int memfd_luo_retrieve(struct liveupdate_file_= op_args *args) goto free_ser; } =20 - err =3D memfd_add_seals(file, ser->seals); - if (err) { - pr_err("failed to add seals: %pe\n", ERR_PTR(err)); - goto put_file; + if (LUO_FEATURE_IS_ACTIVE(ser, MEMFD_LUO_FEATURE_SEALS)) { + err =3D memfd_add_seals(file, ser->seals); + if (err) { + pr_err("failed to add seals: %pe\n", ERR_PTR(err)); + goto put_file; + } } =20 vfs_setpos(file, ser->pos, MAX_LFS_FILESIZE); i_size_write(file_inode(file), ser->size); =20 - if (ser->nr_folios) { + if (LUO_FEATURE_IS_ACTIVE(ser, MEMFD_LUO_FEATURE_FOLIOS) && ser->nr_folio= s) { folios_ser =3D kho_restore_vmalloc(&ser->folios); if (!folios_ser) { err =3D -EINVAL; @@ -601,9 +617,14 @@ static const struct liveupdate_file_ops memfd_luo_file= _ops =3D { .owner =3D THIS_MODULE, }; =20 +LIVEUPDATE_FEATURE_ENTRY(memfd_luo, MEMFD_LUO_FH_NAME, + MEMFD_LUO_FEATURES_SUPP, + MEMFD_LUO_FEATURES_REQ, + MEMFD_LUO_FEATURES_ACTIVE); + static struct liveupdate_file_handler memfd_luo_handler =3D { .ops =3D &memfd_luo_file_ops, - .compatible =3D MEMFD_LUO_FH_COMPATIBLE, + .name =3D MEMFD_LUO_FH_NAME, }; =20 static int __init memfd_luo_init(void) --=20 2.55.0.979.g7e5102b832-goog