From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (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 8582934B669 for ; Sat, 18 Apr 2026 11:40:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776512403; cv=none; b=ta7fNPnV5L5JiXX2Fzdx6+eyHgMA1KbXcrgeY0tbN8pEMP9G6aQ81/Zo3Z4dLCPiItfmyBDabsC/pA4kt1GuVzE/PtiRTvTzCB7BKYCPBstu+z2JaWI383JpCCJcLJIRlKZDnxt8AnJeF5CwjOUlByd6I3unqBrCSFuS+kwPhVc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776512403; c=relaxed/simple; bh=eWk3M3LRCVuXcdG4hjAQixCTdAyQ9aUIS4QbUTouYBA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=W0R2u035mSovuOlCr6h8qP3UVhEmwy0taPtHmd5/rDDWk3fbgnbhJxghEX/RZG1qc7f7JvgaN+9YXkE/XQll4tqLt7dYoFWiSY94M84qcxdpOFOz9gv+zIM7ePNJIdZUBdt7944S961aODK6ldp5v1RzXRaasN6lx7gJeaUJxiU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ks/RrPAP; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ks/RrPAP" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-488b8efed61so15415985e9.1 for ; Sat, 18 Apr 2026 04:40:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776512400; x=1777117200; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=CwXFSSY9CL4wYMLHlpKxN2D5JLK22sZ4JptUsMLRIyg=; b=ks/RrPAPYUim+K5e48ThtJefVRJw4DACrR2CeE5ggGOYFkNpil2wX8v6BhAHtM6z2S h44CvnXnsIn25ypDfgugUenysD9jflbAOwmDROca0x8ggWQSqpSHJGUtxEN/YuhS0Xsy fpJKjaa9DNK3cQf6dOX356Q4+oT62zDo618uwik/ygR2f6zGP1WhaxnMJ/vyvvR98jaG E7VN9jzyWjmvY7sbY6A06Ueh1lC5Z22pFqlXbdL31DmxZERTrOYzN738dzwy6YpuCx5l K6+PebnUh6nY4ujHMLamGKNCljuJymi459FQXD6NNDz4YI6Z4TYxM7xewRCcABAWugUq vTlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776512400; x=1777117200; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=CwXFSSY9CL4wYMLHlpKxN2D5JLK22sZ4JptUsMLRIyg=; b=hEYQCrBobTztGBCsbAbn8xe9s91bhRyA1Xk8qtoCB3trs7u569wFnxVCmpoXN66Vpy cnpI3XwQiLdS03EQicu3yO3F0j78qmZaIUNysbe7eg+C0DN9kYz1BSksy5cLwUtI0/IY gwvnLklj+OjMvA3SK59WvabFsLvSvsqoYtdYc378l9IdKF9ppe1DXyyScGTIzmCUg3Pl 05NsA315dSidWfkuY65BLWIix5uzWzesOetekBLF7DS/UDi+LcEWAXXhcK+9UeFWvwXW kxgQQl2syJLxxcK4YZCr8WvxLdYlWvR6ZfkJ1uo3fvID1uxqL84LPAUWBjccemwBZKDe bm8A== X-Forwarded-Encrypted: i=1; AFNElJ+WoxV7/oXpIS0FWcxWzd4YXrC0cyp/oG6CXa0A8D9ErGj8VkYhuIF1g5lxSl2zAbHS6ptJFT1gZ9LETd8=@vger.kernel.org X-Gm-Message-State: AOJu0YznyaJD+8P2IN0PfHaJt4m9HMVXEX6ZPTMoyMhooFmuQRQ6Letw 4x8YD3eSAU+SqVrBZsJI8qFGOFvFHwwbcicoGD2/sfujsHn8+sOGV3IoN0B9IQ== X-Gm-Gg: AeBDieunCdkMEehUSe23k6IzA+nEbBeUTYXiOJY2ZADT1W/GrGG0fYL1FXEibKGzOTG XclHK3EyspYm/QbO3zlIPJLU9utrgfucJvdKfLVOF0Wntlclcghddp3is3u/Fa/Ga+HB2lqM9FV 1dyUQM7DACOpUxXNtMSKKoZUO4Vyw+u67hykGdWa4uQRKKhevJFUC974/5BhjSl1m8q0y/U/ugv 8vgvVc6PNQ1E5K1Da6rQMQpdRsvSfPm8QBTDgxM8UXDLWZFpOzSXunvdtL0TBSVKwty6+EkTywV jsRJCp/sKAkbCHPpL+TkbRd91V49yeKh8ca0XYbWvtW28yCm78fy6WED1Z3u+E7lC4o1NVI1JqJ I/BkEb1uDBCgu78devbYjDE1+GltMAu7gvZ32bO9LrOLIrEZK5pWGoDHlZPcxdHvYeBxwWp/Zb/ GRRnBHOCOkeSUC8Cisj85csOpIiaVVzEX7M3Fjjm8iWCAW29gW5A== X-Received: by 2002:a05:600c:4749:b0:488:c6e9:1e0c with SMTP id 5b1f17b1804b1-488fb889385mr82585635e9.5.1776512399669; Sat, 18 Apr 2026 04:39:59 -0700 (PDT) Received: from localhost ([2a01:4b00:d036:ae00:3ab1:89ce:8d93:ae6c]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-488fc1070bfsm119872455e9.7.2026.04.18.04.39.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Apr 2026 04:39:58 -0700 (PDT) From: luca.boccassi@gmail.com To: kexec@lists.infradead.org Cc: linux-mm@kvack.org, graf@amazon.com, rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org, brauner@kernel.org, linux-kernel@vger.kernel.org, Luca Boccassi Subject: [PATCH v6 1/4] liveupdate: add LUO_SESSION_MAGIC magic inode type Date: Sat, 18 Apr 2026 12:38:38 +0100 Message-ID: <20260418113956.2146648-1-luca.boccassi@gmail.com> X-Mailer: git-send-email 2.47.3 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Luca Boccassi In userspace when managing LUO sessions we want to be able to identify a FD as a LUO session, in order to be able to do the special handling that they require in order to function as intended on kexec. Currently this requires scraping procfs and doing string matching on the prefix of the dname, which is not an ideal interface. Add a singleton inode type with a magic value, so that we can programmatically identify a fd as a LUO session via fstat(). Signed-off-by: Luca Boccassi Reviewed-by: Pasha Tatashin --- This was requested by Lennart and Christian when discussing integration with systemd for LUO management. v2: apply one fix from bot review about cleanup on error path: https://sashiko.dev/#/patchset/20260415184536.1155220-1-luca.boccassi%40gmail.com the other comments are invalid: luo is not a kmod, and the write hooks are not set up v3: add test case to liveupdate selftest v4: split test case in separate follow-up patch v5: add r-b tag, merge series with LIVEUPDATE_SESSION_GET_NAME ioctl as they both change the same unit test source file, to avoid merge conflicts include/uapi/linux/magic.h | 1 + kernel/liveupdate/luo_core.c | 10 ++++- kernel/liveupdate/luo_internal.h | 2 + kernel/liveupdate/luo_session.c | 73 +++++++++++++++++++++++++++++--- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index 4f2da935a76c..4f51005522ff 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h @@ -105,5 +105,6 @@ #define PID_FS_MAGIC 0x50494446 /* "PIDF" */ #define GUEST_MEMFD_MAGIC 0x474d454d /* "GMEM" */ #define NULL_FS_MAGIC 0x4E554C4C /* "NULL" */ +#define LUO_SESSION_MAGIC 0x4c554f53 /* "LUOS" */ #endif /* __LINUX_MAGIC_H__ */ diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c index dda7bb57d421..f1a63ebe4fa4 100644 --- a/kernel/liveupdate/luo_core.c +++ b/kernel/liveupdate/luo_core.c @@ -197,9 +197,17 @@ static int __init luo_late_startup(void) if (!liveupdate_enabled()) return 0; + err = luo_session_fs_init(); + if (err) { + luo_global.enabled = false; + return err; + } + err = luo_fdt_setup(); - if (err) + if (err) { + luo_session_fs_cleanup(); luo_global.enabled = false; + } return err; } diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_internal.h index 8083d8739b09..d4ac7b4c5882 100644 --- a/kernel/liveupdate/luo_internal.h +++ b/kernel/liveupdate/luo_internal.h @@ -79,6 +79,8 @@ struct luo_session { int luo_session_create(const char *name, struct file **filep); int luo_session_retrieve(const char *name, struct file **filep); +int __init luo_session_fs_init(void); +void __init luo_session_fs_cleanup(void); int __init luo_session_setup_outgoing(void *fdt); int __init luo_session_setup_incoming(void *fdt); int luo_session_serialize(void); diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c index 25ae704d7787..5e315cc0dfd5 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -50,7 +50,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include #include #include #include @@ -62,7 +61,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -363,18 +365,58 @@ static const struct file_operations luo_session_fops = { .unlocked_ioctl = luo_session_ioctl, }; +static struct vfsmount *luo_session_mnt __ro_after_init; +static struct inode *luo_session_inode __ro_after_init; + +static char *luo_session_dname(struct dentry *dentry, char *buffer, int buflen) +{ + return dynamic_dname(buffer, buflen, "luo_session:%s", + dentry->d_name.name); +} + +static const struct dentry_operations luo_session_dentry_operations = { + .d_dname = luo_session_dname, +}; + +static int luo_session_init_fs_context(struct fs_context *fc) +{ + struct pseudo_fs_context *ctx; + + ctx = init_pseudo(fc, LUO_SESSION_MAGIC); + if (!ctx) + return -ENOMEM; + + fc->s_iflags |= SB_I_NOEXEC; + fc->s_iflags |= SB_I_NODEV; + ctx->dops = &luo_session_dentry_operations; + return 0; +} + +static struct file_system_type luo_session_fs_type = { + .name = "luo_session", + .init_fs_context = luo_session_init_fs_context, + .kill_sb = kill_anon_super, +}; + /* Create a "struct file" for session */ static int luo_session_getfile(struct luo_session *session, struct file **filep) { - char name_buf[128]; + char name_buf[LIVEUPDATE_SESSION_NAME_LENGTH + 1]; struct file *file; lockdep_assert_held(&session->mutex); - snprintf(name_buf, sizeof(name_buf), "[luo_session] %s", session->name); - file = anon_inode_getfile(name_buf, &luo_session_fops, session, O_RDWR); - if (IS_ERR(file)) + + ihold(luo_session_inode); + + snprintf(name_buf, sizeof(name_buf), "%s", session->name); + file = alloc_file_pseudo(luo_session_inode, luo_session_mnt, name_buf, + O_RDWR, &luo_session_fops); + if (IS_ERR(file)) { + iput(luo_session_inode); return PTR_ERR(file); + } + file->private_data = session; *filep = file; return 0; @@ -649,3 +691,24 @@ void luo_session_resume(void) up_write(&luo_session_global.outgoing.rwsem); up_write(&luo_session_global.incoming.rwsem); } + +int __init luo_session_fs_init(void) +{ + luo_session_mnt = kern_mount(&luo_session_fs_type); + if (IS_ERR(luo_session_mnt)) + return PTR_ERR(luo_session_mnt); + + luo_session_inode = alloc_anon_inode(luo_session_mnt->mnt_sb); + if (IS_ERR(luo_session_inode)) { + kern_unmount(luo_session_mnt); + return PTR_ERR(luo_session_inode); + } + + return 0; +} + +void __init luo_session_fs_cleanup(void) +{ + iput(luo_session_inode); + kern_unmount(luo_session_mnt); +} -- 2.47.3