From patchwork Thu Feb 16 00:41:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ackerley Tng X-Patchwork-Id: 13142345 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69D17C64ED8 for ; Thu, 16 Feb 2023 00:41:38 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A036D6B0073; Wed, 15 Feb 2023 19:41:37 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 9B3746B0074; Wed, 15 Feb 2023 19:41:37 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 806BF6B0078; Wed, 15 Feb 2023 19:41:37 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 6CA536B0073 for ; Wed, 15 Feb 2023 19:41:37 -0500 (EST) Received: from smtpin17.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 3B8DE810D4 for ; Thu, 16 Feb 2023 00:41:37 +0000 (UTC) X-FDA: 80471301834.17.21880A9 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) by imf13.hostedemail.com (Postfix) with ESMTP id 7E53020008 for ; Thu, 16 Feb 2023 00:41:35 +0000 (UTC) Authentication-Results: imf13.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=cINlncli; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf13.hostedemail.com: domain of 3vnvtYwsKCJEvx5zC6zJE8119916z.x97638FI-775Gvx5.9C1@flex--ackerleytng.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=3vnvtYwsKCJEvx5zC6zJE8119916z.x97638FI-775Gvx5.9C1@flex--ackerleytng.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1676508095; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=xFJSOOgmL/+0yEbfXc6ryYjQyU1/3hcKBEe5blgULG8=; b=thfNDPfejGzI/W1zbweU8gHqo5SscSKzlc910sTcQkcJEGmXgJ3tFUtayRV7fOz08Ph8u3 RZrpo4GVnU2nnSyCiAbwJ533u4YI986Z7wtCovr9oQ48Khthd5YWZK4fdZubTGYgcY86+m EHhetSuXXcT1nyq+tWK1ViY/PMi7e3k= ARC-Authentication-Results: i=1; imf13.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=cINlncli; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf13.hostedemail.com: domain of 3vnvtYwsKCJEvx5zC6zJE8119916z.x97638FI-775Gvx5.9C1@flex--ackerleytng.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=3vnvtYwsKCJEvx5zC6zJE8119916z.x97638FI-775Gvx5.9C1@flex--ackerleytng.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1676508095; a=rsa-sha256; cv=none; b=gMIuLY6kqCuu2wxdxrSrE0hwjYEd03Zdie3ZXgUF+D6V9Jvf5/Q2WDuyCbIoDnm0/3VUsv d/53lq5uMVYhUoP/gJ558y4mHQxa/5fDglEhJxSuwCkrKJ6JYXJKAT4ku0DwA/J2sdCnb6 QCoGN49/k+Nd9LP+19lemSMtB1KLpJs= Received: by mail-pg1-f202.google.com with SMTP id r126-20020a632b84000000b004393806c06eso160003pgr.4 for ; Wed, 15 Feb 2023 16:41:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=xFJSOOgmL/+0yEbfXc6ryYjQyU1/3hcKBEe5blgULG8=; b=cINlnclit+qIhReE+Kd7SxHPyCpYVP+gHpr/lFZIYMsvtqPRMGMguGhZ+AmtA8dFRc Djw+CXsM0iFzwsMurICuBsTP1scpM+tCEPKY9d7bDxdD5YrTS/xTPWBYVcL8YG0s8lEx aufd0oD+1ETay2cKPepbBkhK2DjZdGGh9+sIqO+Vcbz+DiP+awtJagXFXVVgNQbNgyf4 dLNAd50vYgR4BhTu4f/JtATvZK4wp3PfCPiwj0DiDlPx+B7yfpqr/PRhgYcbi/fNtz/R 06dsNug5WVXeH5PztldqJP7IVZaS+IwS51Y4HyfEGNLXO726iXRISqbDJTUc9PcT6yga oL2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=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; bh=xFJSOOgmL/+0yEbfXc6ryYjQyU1/3hcKBEe5blgULG8=; b=jmcPmVhNJuGzOP1+CpWn6zjX74R4lgcHVKSjMDTeBUt/Xas9VzwjBbre7HgMBbMkci BxjETgnap49bJ+jqJhPyhvNiygGimyvjm7gLc6BhmQG7+coKrawdU2kY+vnlSENXSluY vWPolRyGUEOXMC2Py3aty1xrBTZ3TU06LwIkEd/7HF8X0GaNyL4lup69EXB2nmeIJt1e THnl1F4nWRPzWDeNSYqxBOM78bxZ/h+JFvVrJ7eh4LX6Wlrw5gZzv7rtPhPwsnaOpsoQ zM77CKSCowGq4oNYUXPMysWIYlVEHuikDBbSFo2eaDRZ5w9yYOiufe8Mh2JuIBuG1VTL d+yA== X-Gm-Message-State: AO0yUKXpO1ppWPo4388XsMl+fLFAwPf/B3OHR1gW1h6sORn842b/vls+ V1LYZ+MwZr/XO8rhEb9KjgMu/roRfRxLIYfHhg== X-Google-Smtp-Source: AK7set92BIhFB8ochMzD8hkP3RpOuPg2nKV+W2zZrkSmVY9pLWldFkNDjP8CHQ6b9e/hAQ6o5kRRc8iwgxT607mX7Q== X-Received: from ackerleytng-cloudtop.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1f5f]) (user=ackerleytng job=sendgmr) by 2002:a63:33ce:0:b0:4e7:79c5:d682 with SMTP id z197-20020a6333ce000000b004e779c5d682mr625417pgz.9.1676508094293; Wed, 15 Feb 2023 16:41:34 -0800 (PST) Date: Thu, 16 Feb 2023 00:41:16 +0000 In-Reply-To: Mime-Version: 1.0 References: X-Mailer: git-send-email 2.39.1.637.g21b0678d19-goog Message-ID: <176081a4817e492965a864a8bc8bacb7d2c05078.1676507663.git.ackerleytng@google.com> Subject: [RFC PATCH 1/2] mm: restrictedmem: Allow userspace to specify mount_path for memfd_restricted From: Ackerley Tng To: kvm@vger.kernel.org, linux-api@vger.kernel.org, linux-arch@vger.kernel.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, qemu-devel@nongnu.org Cc: chao.p.peng@linux.intel.com, aarcange@redhat.com, ak@linux.intel.com, akpm@linux-foundation.org, arnd@arndb.de, bfields@fieldses.org, bp@alien8.de, corbet@lwn.net, dave.hansen@intel.com, david@redhat.com, ddutile@redhat.com, dhildenb@redhat.com, hpa@zytor.com, hughd@google.com, jlayton@kernel.org, jmattson@google.com, joro@8bytes.org, jun.nakajima@intel.com, kirill.shutemov@linux.intel.com, linmiaohe@huawei.com, luto@kernel.org, mail@maciej.szmigiero.name, mhocko@suse.com, michael.roth@amd.com, mingo@redhat.com, naoya.horiguchi@nec.com, pbonzini@redhat.com, qperret@google.com, rppt@kernel.org, seanjc@google.com, shuah@kernel.org, steven.price@arm.com, tabba@google.com, tglx@linutronix.de, vannapurve@google.com, vbabka@suse.cz, vkuznets@redhat.com, wanpengli@tencent.com, wei.w.wang@intel.com, x86@kernel.org, yu.c.zhang@linux.intel.com, Ackerley Tng X-Rspamd-Queue-Id: 7E53020008 X-Rspamd-Server: rspam09 X-Rspam-User: X-Stat-Signature: u84316q49yotwdhcsj5mzwc99gy93g1x X-HE-Tag: 1676508095-398088 X-HE-Meta: U2FsdGVkX1/77JkVHk1JsmiEC12IhM/JKQ2yaf3a1FdPiOgfYGEPNQKxuVib6Rs78FzMNL/HZyrona5I2C26OUslVv/gDLhml1VChGxLcj10hmh8Vr/mUd4580ROgFCUXzlkvy3qdkF9F64iKPha9iTKwcg92gDR5BdbECTrDHAvQdrDFDCD4HaONhYhMbbDR/Z2Z6/G4JVMylAkf+SrTPRObhRRZFWpnL5SzuZKgMlxBRT1k6FvyA9+cGqB82Gmj0orjeSqN3NPcDbbbnWcyjKHREJlJalQaZ4srLNaKwB9pzu36JMYkKD+7AlePAtmLC0QM7WIwqYe+EC0Q1eV3y5EcGmFY+G4f7qHaoW7mbSCW8nkaR8rMo5yx8569cFjFO2Si0xdjqbqd91wIK4d/z6vYadH4WEWMKgJAYKbMMKgPCMSxoKnDCE1vD85AomvcgHjQM5dc8MX8DPqRZxGpz2Vpglc7p+PQnB7ZU79IKkk5n6giN9YMi7jFkgMYhbn9AHCyKy4NtpZPTS0TMHFA9wYh+6sna3d8DGX74pc5BTsZfEJDRVuZTRtR3l5vLehM+Vsf38cmKDpUudaGAj45Qh9XKClHMtQAaqZMxUNC5HUYPBfWYBT6jJmRqCrjcvsTfPskLjw4FBo1zulrLSOnrXBhFk8fsvocTPO/SA69e6WzIr6gCfmYDkXPqXmrbj9BBv5nOKAGilFdS5B1E9me3FoQXVQcy6nlBLeefhqJYmMesTask/9nKgIRRuij6yMIkGl5VUmJje9+HgXQrUTlq47/RJzKOEk+USs4U+URAIRFXY4j+Nhq+NPv90Tiq28GSCiodTuAUnC4G2+nA9p5MXs2t7/kdekis9fh+mXdOGGUOGBbXXS+K0cHlOvPLJYsdiHgE4eKUz68Vs37Xt6sdZh3zJJUBdXxzHLmJAjUewzXqRtCwoYI90BY4VKGWd3Urf4Z9EglDEHMaWHpBq NdXxBUvq RYsBQIZE8u0xw1MZY+C4EoP5gj0sVJjRShAo0rf/bHFlfCVScbpWxPK063Fizh+sSRs9IxfosTjlS4KiJu0qlpbvZCthhl/j7HKeS1S+/Rtk8N9zbSMK23rvo/krqlJ/k7I0AbJGMaLSnTnBJUGK1PkI6GlodpL47Ra/wUIM4SBAGGLLcvy1ImVfev4G8dpZn/cFNO53q1jg6f/VOOj4ccRLTWw4w/6tQT9kictZsoMfpKFtXakfP4vyPup23sQ0S8PhHcu+ebmks6TI/fL8bN59YovTi5k1jQ/+3GkaAqxlC99/j5IRT/gQ8ZUnw6TSgTzPqUAA6vj/EX/Q6juGpn4GbWnfLsY/ereOMIINV42MlmDwuvR/UtxMwhPV6M52Adv2Jby2x3f+6gKsFlkIcEjEGhquCckejXCVLoO1I5Uj1ZlW78Yjkve6E4C8lT+E4xlpKsIvessDJWS8YS4X4vOlTxJxWBC4nC+k4sjIT9UeSlB+PZ9Ew9ATj4X4LDeWHEwZw/1h4SIQwzTXWjisrmHdx/QyypBZN8RvIHHSTTuHvClf/OVi1sBde8a4QIpI48f3S6du+3OnugyjPenZImTiII8D/xe1CWvQGbq5QQAhwA6sRUiDF9bhebSyT6EWonsHyy+09mc2gJpMtM6IUNbeFZITVzRqI6/57pyMBditwIj8G7101lrEab/MyIG2dwvYNnHt/vAWsnP28/I4vnDwhmQ== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: By default, the backing shmem file for a restrictedmem fd is created on shmem's kernel space mount. With this patch, an optional tmpfs mount can be specified, which will be used as the mountpoint for backing the shmem file associated with a restrictedmem fd. This change is modeled after how sys_open() can create an unnamed temporary file in a given directory with O_TMPFILE. This will help restrictedmem fds inherit the properties of the provided tmpfs mounts, for example, hugepage allocation hints, NUMA binding hints, etc. Signed-off-by: Ackerley Tng --- include/linux/syscalls.h | 2 +- include/uapi/linux/restrictedmem.h | 8 ++++ mm/restrictedmem.c | 63 +++++++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 include/uapi/linux/restrictedmem.h diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index f9e9e0c820c5..4b8efe9a8680 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1056,7 +1056,7 @@ asmlinkage long sys_memfd_secret(unsigned int flags); asmlinkage long sys_set_mempolicy_home_node(unsigned long start, unsigned long len, unsigned long home_node, unsigned long flags); -asmlinkage long sys_memfd_restricted(unsigned int flags); +asmlinkage long sys_memfd_restricted(unsigned int flags, const char __user *mount_path); /* * Architecture-specific system calls diff --git a/include/uapi/linux/restrictedmem.h b/include/uapi/linux/restrictedmem.h new file mode 100644 index 000000000000..9f108dd1ac4c --- /dev/null +++ b/include/uapi/linux/restrictedmem.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_RESTRICTEDMEM_H +#define _UAPI_LINUX_RESTRICTEDMEM_H + +/* flags for memfd_restricted */ +#define RMFD_TMPFILE 0x0001U + +#endif /* _UAPI_LINUX_RESTRICTEDMEM_H */ diff --git a/mm/restrictedmem.c b/mm/restrictedmem.c index c5d869d8c2d8..97f3e2159e8b 100644 --- a/mm/restrictedmem.c +++ b/mm/restrictedmem.c @@ -1,11 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 -#include "linux/sbitmap.h" +#include #include #include #include #include #include #include +#include #include struct restrictedmem { @@ -189,19 +190,20 @@ static struct file *restrictedmem_file_create(struct file *memfd) return file; } -SYSCALL_DEFINE1(memfd_restricted, unsigned int, flags) +static int restrictedmem_create(struct vfsmount *mount) { struct file *file, *restricted_file; int fd, err; - if (flags) - return -EINVAL; - fd = get_unused_fd_flags(0); if (fd < 0) return fd; - file = shmem_file_setup("memfd:restrictedmem", 0, VM_NORESERVE); + if (mount) + file = shmem_file_setup_with_mnt(mount, "memfd:restrictedmem", 0, VM_NORESERVE); + else + file = shmem_file_setup("memfd:restrictedmem", 0, VM_NORESERVE); + if (IS_ERR(file)) { err = PTR_ERR(file); goto err_fd; @@ -223,6 +225,55 @@ SYSCALL_DEFINE1(memfd_restricted, unsigned int, flags) return err; } +static bool is_shmem_mount(struct vfsmount *mnt) +{ + return mnt->mnt_sb->s_magic == TMPFS_MAGIC; +} + +static int restrictedmem_create_from_path(const char __user *mount_path) +{ + int ret; + struct path path; + + ret = user_path_at(AT_FDCWD, mount_path, + LOOKUP_FOLLOW | LOOKUP_MOUNTPOINT, + &path); + if (ret) + return ret; + + if (!is_shmem_mount(path.mnt)) { + ret = -EINVAL; + goto out; + } + + ret = mnt_want_write(path.mnt); + if (unlikely(ret)) + goto out; + + ret = restrictedmem_create(path.mnt); + + mnt_drop_write(path.mnt); +out: + path_put(&path); + + return ret; +} + +SYSCALL_DEFINE2(memfd_restricted, unsigned int, flags, const char __user *, mount_path) +{ + if (flags & ~RMFD_TMPFILE) + return -EINVAL; + + if (flags == RMFD_TMPFILE) { + if (!mount_path) + return -EINVAL; + + return restrictedmem_create_from_path(mount_path); + } else { + return restrictedmem_create(NULL); + } +} + int restrictedmem_bind(struct file *file, pgoff_t start, pgoff_t end, struct restrictedmem_notifier *notifier, bool exclusive) { From patchwork Thu Feb 16 00:41:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ackerley Tng X-Patchwork-Id: 13142346 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id AABABC636CC for ; Thu, 16 Feb 2023 00:41:41 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 437246B0078; Wed, 15 Feb 2023 19:41:41 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 3C0716B007B; Wed, 15 Feb 2023 19:41:41 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 212556B007D; Wed, 15 Feb 2023 19:41:41 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 091C66B0078 for ; Wed, 15 Feb 2023 19:41:41 -0500 (EST) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id C6B64C096E for ; Thu, 16 Feb 2023 00:41:40 +0000 (UTC) X-FDA: 80471301960.21.7208132 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) by imf19.hostedemail.com (Postfix) with ESMTP id EAAE31A000A for ; Thu, 16 Feb 2023 00:41:38 +0000 (UTC) Authentication-Results: imf19.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b="a6/aZwZM"; spf=pass (imf19.hostedemail.com: domain of 3wXvtYwsKCJQy082F92MHB44CC492.0CA96BIL-AA8Jy08.CF4@flex--ackerleytng.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=3wXvtYwsKCJQy082F92MHB44CC492.0CA96BIL-AA8Jy08.CF4@flex--ackerleytng.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1676508099; a=rsa-sha256; cv=none; b=bL/S5LuOsMtLy5NfFQKNyb7sy960l6hg9nNdi+nxdb3E0Q/rOrApbN9vh1duaT/8jJYRwU CDxdbCYcR96IqQRsTdcyoy7ZT2KWd/doSAmaUyBgJXppH4mTNwBpZKRxlPcDpcT20OdVCw ihoKUkwQfJ9s08N8kxti1UX88OwvPuc= ARC-Authentication-Results: i=1; imf19.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b="a6/aZwZM"; spf=pass (imf19.hostedemail.com: domain of 3wXvtYwsKCJQy082F92MHB44CC492.0CA96BIL-AA8Jy08.CF4@flex--ackerleytng.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=3wXvtYwsKCJQy082F92MHB44CC492.0CA96BIL-AA8Jy08.CF4@flex--ackerleytng.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1676508099; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=RwSw3tYb5bXq9fGeFYVzZ4Uji8t9bzNp02Nu0wqGVr8=; b=NSIQfnuhI7EF9sk8pKVF+t61zEOCpesEo0QNLs1dZP80zbp7aO1SXEYzoMfe/DHrgDpKn+ pi7ij3X+hm9hDFTT0ZA1XKxD2vTVZ7De9FsXVc99kTaZEaVGa01EhGPqpdIlYVcCIEv+WG 5MVtxUb+WZ0miRObyQoPfNp6Of3Yv5U= Received: by mail-pj1-f74.google.com with SMTP id jp14-20020a17090ae44e00b0022a03158ec6so187253pjb.9 for ; Wed, 15 Feb 2023 16:41:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=RwSw3tYb5bXq9fGeFYVzZ4Uji8t9bzNp02Nu0wqGVr8=; b=a6/aZwZMKgM9Qwg+eZcRGVXefYnK2gekXci5+402C9kYjaRKvCntG9/9UB64dqHJj4 utKOg+syvAUy0EV4DBkBSn9lMSketoQ/IKXaOt1Z/yjVFG1HfWHMlNFXX4aNcRKANnmH eAPnL1XgdbYfIT8hZYQ8fObP+OEaQS1UkFxrNAsWasJb6HEbZXTNCOF/s33NcZRZ+OQk BqNQ/CyZLmfjBzr7r1oNqVmOkPA5/8tV65euXIZEud6Iazk/zMeKJDYccPllrwFkPAEO ukqjTuuwoXWvGYWEq+OSuWeuT3TY7Y2Z+KS2DU57mQtp8rwmzmbo5nddYHr9bU6Se8r/ J7Rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=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; bh=RwSw3tYb5bXq9fGeFYVzZ4Uji8t9bzNp02Nu0wqGVr8=; b=43oV0AF6P1Yw5Kk9cqh1rtEzTQKtQ9a3zxsLSBE+3PWCuhdI6p/lZ3p5MB4nsIYWVK buokuN5vx7Bz/uj15VMoKIUqB8roRyYJUEM3sRQXmTfc2J1vwz3tytC6VkPgWfKyoszE jtL6GZsgiiGHedfLPlBjLpINWoaBh3kOIaqdiBqxjD/DRz63uXPSTldlv70eSVMQYba7 eT2fAgRTmSz7SvQyr/Wn+kv0rLFKj1hEYU40aAxvarZQIRhWBhR7XY7EGeRnjpr0SSB1 HZqZasw4WfiNfgoSrmbIDIWzts3UICe66wOEECIWYNkMh6ONB3k5KkzqkoZ9QrwcJIss z6qA== X-Gm-Message-State: AO0yUKXjVPNsDemI/I2mo4lE9Qkhm2HbZgMDGkwbPpmz/uq8JQJ2xzOl hU7vqNEufHJRe2o7qc3EqN3I4+md6kqERWUCUw== X-Google-Smtp-Source: AK7set+Z1QsboPNl7B2dUCqzJnv4n3cQF2QXtmZ8FpQ59D9VPXhoYAFz0KibJoYgA3wgebXfV3oTbIw8kSpaDzjaOg== X-Received: from ackerleytng-cloudtop.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1f5f]) (user=ackerleytng job=sendgmr) by 2002:a17:903:2594:b0:19a:b107:bd11 with SMTP id jb20-20020a170903259400b0019ab107bd11mr951631plb.29.1676508097502; Wed, 15 Feb 2023 16:41:37 -0800 (PST) Date: Thu, 16 Feb 2023 00:41:17 +0000 In-Reply-To: Mime-Version: 1.0 References: X-Mailer: git-send-email 2.39.1.637.g21b0678d19-goog Message-ID: <06098450437ba5ed2011090d95f6ccb817728710.1676507663.git.ackerleytng@google.com> Subject: [RFC PATCH 2/2] selftests: restrictedmem: Check hugepage-ness of shmem file backing restrictedmem fd From: Ackerley Tng To: kvm@vger.kernel.org, linux-api@vger.kernel.org, linux-arch@vger.kernel.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, qemu-devel@nongnu.org Cc: chao.p.peng@linux.intel.com, aarcange@redhat.com, ak@linux.intel.com, akpm@linux-foundation.org, arnd@arndb.de, bfields@fieldses.org, bp@alien8.de, corbet@lwn.net, dave.hansen@intel.com, david@redhat.com, ddutile@redhat.com, dhildenb@redhat.com, hpa@zytor.com, hughd@google.com, jlayton@kernel.org, jmattson@google.com, joro@8bytes.org, jun.nakajima@intel.com, kirill.shutemov@linux.intel.com, linmiaohe@huawei.com, luto@kernel.org, mail@maciej.szmigiero.name, mhocko@suse.com, michael.roth@amd.com, mingo@redhat.com, naoya.horiguchi@nec.com, pbonzini@redhat.com, qperret@google.com, rppt@kernel.org, seanjc@google.com, shuah@kernel.org, steven.price@arm.com, tabba@google.com, tglx@linutronix.de, vannapurve@google.com, vbabka@suse.cz, vkuznets@redhat.com, wanpengli@tencent.com, wei.w.wang@intel.com, x86@kernel.org, yu.c.zhang@linux.intel.com, Ackerley Tng X-Rspam-User: X-Rspamd-Queue-Id: EAAE31A000A X-Rspamd-Server: rspam01 X-Stat-Signature: qq685xi7hiiypzx3xxnqwm61m9siy3zk X-HE-Tag: 1676508098-402946 X-HE-Meta: U2FsdGVkX19c1BrP/W+o/GX0Ir7XyEa/lee2fQjUwGwXMnTTy0AmjFmtC56MBRWaxM2iH5J1Z0eAUZ3KrbX/VCuztzv6jqYHedwiU7XDt386vrbckQdw7fm1JYQcK2FYZbOV3JhL+BmKlsjxvVv2TdnRBP20gogtFvzVxJuZtleE9Q0YWCARRExKxNWyo0P3LksB1n7sqZUOdixpSWt8o+cjVTc0eV68t36qlCnyrPxHqzA9oTrpYBCcnnWQsHVZU63+xkSQIEZerPQDBuC6xQFIQxWAwG4gE0vdqHOl/ZuhOeW2VodtkyUpcmMkieQUYTKyuTRJ9WdiLAv7w7XpYpoICe5k6LyGEqcZg5fykjL8RKI+SQbSVsdeQSdK0J+27R6tcHTpGJzSipd0ZykKe3nPUATDPyB3fk3YK2mGVh7Lxyw4FnlJ0h7yaMikOQ6DiNjScGSzmZQPMvKlImfMoHTLf+PEmxkIN3vXA2DsiL8FKI/6MJukmqDbVhfknolHhOGom+Av2onJBJpwN2Wfc5qR58LqxdgK3AvvFlYmuSdgr0heb8pd5RRB1S+2Hb0mJPk9k/N8LYgoCKT4+onvWhXlsrQB9snX0KfkRAcVIgqUIPplt1G5euGraYyOZjEdbc+50kOAeFHbqz0cy3JqM3ArD5dkWFbg7w/5bnHj3TAXin0IHOvC0O2AFOuzeu2AF45JKXCyjm36zlvyE90LUmZRSg8CmGpX/rPhHtkK+sH24StOvX65VaBPXxuW+uF8JCfhnp7c+XAVhgo0lyKXefziPYWrNfxrKyZ8xibaP1HaTgHkfXN1wpZPFTe5IZEIx2P3VngtSSwe7uOgJL1BbNjwcNWmM6zHYcG5mOrmLfrmwd3ZTJ9ozoFxMrL3evmP6xSICuQLvHntKvih9kvHSDoVstbqXg1aghWy+P0IKn7rtN97IA8F0vQdRIqP8MuYH5D6Vzq3OCTwNjzFqe/ Z9RqNoT5 09q1+H/c98/YDwkgXQZ6PUr8RGo+6mct8F+Ag5h8eHsx95PMI55Rw0OqPVB97BQulCNYnX6X7ovXIwVTEXtztP7ttYBzx3WL3o6aSl6FaEzM2nXHhVCNcZor7jd2LVutxH3mkjY4fdN9qxlVPdlHadnWPWXUXQBmqFh1K2nVHDDMUfjEJmQ/mbrrr0Ejd+M1Oq3eMZCvs4BpXKFaC3UFUOrrITp5XPgF7ew/jCEZQq7gJaGMJmIkL0tT59dQDTD4Y8O1usb6HmPceoTsvZ6eMVyYqFUJ7OwG6aBXWHtVnVYPZ9exkdYO3G9QxQQwKEfDSGf6U61Q63DpwuMz31sdNC1vBGD3HU7Nuy6tb/8nVvRUk/i0A9wTCENZPc/BD0NuVi8SnwBf6FOviAdYjONwaRj+6L2IyusYF0BdCM5I63a71Sl1GvRH2W55HHK24htirgL2dzfilzeQ+CjaKdyWffMus/tOkxsKXX0EyPaLkHEFOMs5ISVeS+WJQXfZt4JOp2xSLO4MPbEBwCfIVHSOQ3BMrSDRXSGtvxiDYJ6Zcl6OtZcbUM7Df2aCZ6pECNoMT3P85HxzCom3ppvhPL/eKnllfaGo4HFt7W/XP4kweQMdmCMLBb7zY6YPmlSV4AOb3nJ1sDaIwBCX6hQObpul7Jkvzm5eJ2SPixL1W X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: For memfd_restricted() calls without a userspace mount, the backing file should be the shmem mount in the kernel, and the size of backing pages should be as defined by system-wide shmem configuration. If a userspace mount is provided, the size of backing pages should be as defined in the mount. Signed-off-by: Ackerley Tng --- tools/testing/selftests/Makefile | 1 + .../selftests/restrictedmem/.gitignore | 3 + .../testing/selftests/restrictedmem/Makefile | 14 + .../testing/selftests/restrictedmem/common.c | 9 + .../testing/selftests/restrictedmem/common.h | 8 + .../restrictedmem_hugepage_test.c | 344 ++++++++++++++++++ 6 files changed, 379 insertions(+) create mode 100644 tools/testing/selftests/restrictedmem/.gitignore create mode 100644 tools/testing/selftests/restrictedmem/Makefile create mode 100644 tools/testing/selftests/restrictedmem/common.c create mode 100644 tools/testing/selftests/restrictedmem/common.h create mode 100644 tools/testing/selftests/restrictedmem/restrictedmem_hugepage_test.c diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index f07aef7c592c..44078eeefb79 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -60,6 +60,7 @@ TARGETS += pstore TARGETS += ptrace TARGETS += openat2 TARGETS += resctrl +TARGETS += restrictedmem TARGETS += rlimits TARGETS += rseq TARGETS += rtc diff --git a/tools/testing/selftests/restrictedmem/.gitignore b/tools/testing/selftests/restrictedmem/.gitignore new file mode 100644 index 000000000000..2581bcc8ff29 --- /dev/null +++ b/tools/testing/selftests/restrictedmem/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +restrictedmem_hugepage_test diff --git a/tools/testing/selftests/restrictedmem/Makefile b/tools/testing/selftests/restrictedmem/Makefile new file mode 100644 index 000000000000..da9665718c8a --- /dev/null +++ b/tools/testing/selftests/restrictedmem/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 + +CFLAGS = $(KHDR_INCLUDES) + +TEST_GEN_PROGS += restrictedmem_hugepage_test + +include ../lib.mk + +EXTRA_CLEAN = $(OUTPUT)/common.o + +$(OUTPUT)/common.o: common.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@ + +$(TEST_GEN_PROGS): $(OUTPUT)/common.o diff --git a/tools/testing/selftests/restrictedmem/common.c b/tools/testing/selftests/restrictedmem/common.c new file mode 100644 index 000000000000..79b2ac98cc89 --- /dev/null +++ b/tools/testing/selftests/restrictedmem/common.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include + +int memfd_restricted(unsigned int flags, char *mount_path) +{ + return syscall(__NR_memfd_restricted, flags, mount_path); +} diff --git a/tools/testing/selftests/restrictedmem/common.h b/tools/testing/selftests/restrictedmem/common.h new file mode 100644 index 000000000000..5d59edc4f23f --- /dev/null +++ b/tools/testing/selftests/restrictedmem/common.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SELFTESTS_RESTRICTEDMEM_COMMON_H +#define SELFTESTS_RESTRICTEDMEM_COMMON_H + +int memfd_restricted(unsigned int flags, char *mount_path); + +#endif // SELFTESTS_RESTRICTEDMEM_COMMON_H diff --git a/tools/testing/selftests/restrictedmem/restrictedmem_hugepage_test.c b/tools/testing/selftests/restrictedmem/restrictedmem_hugepage_test.c new file mode 100644 index 000000000000..0d9cf2ced754 --- /dev/null +++ b/tools/testing/selftests/restrictedmem/restrictedmem_hugepage_test.c @@ -0,0 +1,344 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "linux/limits.h" +#include +#include +#include +#include +#include +#include +#include + +#include "linux/restrictedmem.h" + +#include "common.h" +#include "../kselftest_harness.h" + +static int get_hpage_pmd_size(void) +{ + FILE *fp; + char buf[100]; + char *ret; + int size; + + fp = fopen("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", "r"); + if (!fp) + return -1; + + ret = fgets(buf, 100, fp); + if (ret != buf) { + size = -1; + goto out; + } + + if (sscanf(buf, "%d\n", &size) != 1) + size = -1; + +out: + fclose(fp); + + return size; +} + +static bool is_valid_shmem_thp_policy(char *policy) +{ + if (strcmp(policy, "always") == 0) + return true; + if (strcmp(policy, "within_size") == 0) + return true; + if (strcmp(policy, "advise") == 0) + return true; + if (strcmp(policy, "never") == 0) + return true; + if (strcmp(policy, "deny") == 0) + return true; + if (strcmp(policy, "force") == 0) + return true; + + return false; +} + +static int get_shmem_thp_policy(char *policy) +{ + FILE *fp; + char buf[100]; + char *left = NULL; + char *right = NULL; + int ret = -1; + + fp = fopen("/sys/kernel/mm/transparent_hugepage/shmem_enabled", "r"); + if (!fp) + return -1; + + if (fgets(buf, 100, fp) != buf) + goto out; + + /* + * Expect shmem_enabled to be of format like "always within_size advise + * [never] deny force" + */ + left = memchr(buf, '[', 100); + if (!left) + goto out; + + right = memchr(buf, ']', 100); + if (!right) + goto out; + + memcpy(policy, left + 1, right - left - 1); + + ret = !is_valid_shmem_thp_policy(policy); + +out: + fclose(fp); + return ret; +} + +static int set_shmem_thp_policy(char *policy) +{ + FILE *fp; + size_t len = strlen(policy); + int ret = -1; + + if (!is_valid_shmem_thp_policy(policy)) + return ret; + + fp = fopen("/sys/kernel/mm/transparent_hugepage/shmem_enabled", "w"); + if (!fp) + return ret; + + if (fwrite(policy, 1, len, fp) != len) + goto out; + + if (fwrite("\n", 1, 1, fp) != 1) + goto out; + + ret = 0; + +out: + fclose(fp); + return ret; +} + +FIXTURE(reset_shmem_enabled) +{ + /* + * Expect shmem_enabled to be one of always, within_size, advise, never, + * deny, force + */ + char shmem_enabled[12]; +}; + +FIXTURE_SETUP(reset_shmem_enabled) +{ + memset(self->shmem_enabled, 0, 12); + ASSERT_EQ(0, get_shmem_thp_policy(self->shmem_enabled)); +} + +FIXTURE_TEARDOWN(reset_shmem_enabled) +{ + ASSERT_EQ(0, set_shmem_thp_policy(self->shmem_enabled)); +} + +TEST_F(reset_shmem_enabled, restrictedmem_fstat_shmem_enabled_never) +{ + int mfd = -1; + struct stat stat; + char *orig_shmem_enabled; + + ASSERT_EQ(0, set_shmem_thp_policy("never")); + + mfd = memfd_restricted(0, NULL); + ASSERT_NE(-1, mfd); + + ASSERT_EQ(0, fstat(mfd, &stat)); + + /* + * st_blksize is set based on the superblock's s_blocksize_bits. For + * shmem, this is set to PAGE_SHIFT + */ + ASSERT_EQ(stat.st_blksize, getpagesize()); + + close(mfd); +} + +TEST_F(reset_shmem_enabled, restrictedmem_fstat_shmem_enabled_always) +{ + int mfd = -1; + struct stat stat; + char *orig_shmem_enabled; + + ASSERT_EQ(0, set_shmem_thp_policy("always")); + + mfd = memfd_restricted(0, NULL); + ASSERT_NE(-1, mfd); + + ASSERT_EQ(0, fstat(mfd, &stat)); + + ASSERT_EQ(stat.st_blksize, get_hpage_pmd_size()); + + close(mfd); +} + +TEST(restrictedmem_tmpfile_no_mount_path) +{ + int mfd = memfd_restricted(RMFD_TMPFILE, NULL); + + ASSERT_EQ(-1, mfd); + ASSERT_EQ(EINVAL, errno); +} + +TEST(restrictedmem_tmpfile_nonexistent_mount_path) +{ + int mfd = memfd_restricted(RMFD_TMPFILE, + "/nonexistent/nonexistent/nonexistent"); + + ASSERT_EQ(-1, mfd); + ASSERT_EQ(ENOENT, errno); +} + +TEST(restrictedmem_tmpfile_not_tmpfs_mount) +{ + int mfd = memfd_restricted(RMFD_TMPFILE, "/proc"); + + ASSERT_EQ(-1, mfd); + ASSERT_EQ(EINVAL, errno); +} + +static bool directory_exists(const char *path) +{ + struct stat sb; + + return stat(path, &sb) == 0 && S_ISDIR(sb.st_mode); +} + +FIXTURE(tmpfs_hugepage_mount_path) +{ + char *mount_path; +}; + +FIXTURE_SETUP(tmpfs_hugepage_mount_path) +{ + int ret = -1; + + /* /tmp is an FHS-mandated world-writable directory */ + self->mount_path = "/tmp/restrictedmem-selftest-mnt"; + + if (!directory_exists(self->mount_path)) { + ret = mkdir(self->mount_path, 0777); + ASSERT_EQ(0, ret); + } +} + +FIXTURE_TEARDOWN(tmpfs_hugepage_mount_path) +{ + int ret = -1; + + if (!directory_exists(self->mount_path)) + return; + + ret = umount2(self->mount_path, MNT_FORCE); + EXPECT_EQ(0, ret); + if (ret == -1 && errno == EINVAL) + fprintf(stderr, "%s was not mounted\n", self->mount_path); + + ret = rmdir(self->mount_path); + ASSERT_EQ(0, ret); +} + +TEST_F(tmpfs_hugepage_mount_path, restrictedmem_fstat_tmpfs_huge_always) +{ + int ret = -1; + int mfd = -1; + struct stat stat; + + ret = mount("name", self->mount_path, "tmpfs", 0, "huge=always"); + ASSERT_EQ(0, ret); + + mfd = memfd_restricted(RMFD_TMPFILE, self->mount_path); + ASSERT_NE(-1, mfd); + + ret = fstat(mfd, &stat); + ASSERT_EQ(0, ret); + ASSERT_EQ(stat.st_blksize, get_hpage_pmd_size()); + + close(mfd); +} + +TEST_F(tmpfs_hugepage_mount_path, restrictedmem_fstat_tmpfs_huge_never) +{ + int ret = -1; + int mfd = -1; + struct stat stat; + + ret = mount("name", self->mount_path, "tmpfs", 0, "huge=never"); + ASSERT_EQ(0, ret); + + mfd = memfd_restricted(RMFD_TMPFILE, self->mount_path); + ASSERT_NE(-1, mfd); + + ret = fstat(mfd, &stat); + ASSERT_EQ(0, ret); + ASSERT_EQ(stat.st_blksize, getpagesize()); + + close(mfd); +} + +TEST_F(tmpfs_hugepage_mount_path, restrictedmem_umount_rmdir_while_file_open) +{ + int ret = -1; + int mfd = -1; + + ret = mount("name", self->mount_path, "tmpfs", 0, "huge=always"); + ASSERT_EQ(0, ret); + + mfd = memfd_restricted(RMFD_TMPFILE, self->mount_path); + ASSERT_NE(-1, mfd); + + ret = umount2(self->mount_path, MNT_FORCE); + ASSERT_EQ(-1, ret); + ASSERT_EQ(EBUSY, errno); + + ret = rmdir(self->mount_path); + ASSERT_EQ(-1, ret); + ASSERT_EQ(EBUSY, errno); + + close(mfd); +} + +TEST_F(tmpfs_hugepage_mount_path, restrictedmem_provide_mount_subdir) +{ + int ret = -1; + int mfd = -1; + struct stat stat; + char subdir_path[PATH_MAX] = {0}; + + ret = mount("name", self->mount_path, "tmpfs", 0, "huge=always"); + ASSERT_EQ(0, ret); + + snprintf(subdir_path, PATH_MAX, "%s/%s", self->mount_path, "subdir"); + ret = mkdir(subdir_path, 0777); + ASSERT_EQ(0, ret); + + /* + * Any subdirectory of a tmpfs mount can be provided to memfd_restricted + * as a reference to a mount + */ + mfd = memfd_restricted(RMFD_TMPFILE, subdir_path); + ASSERT_NE(-1, mfd); + + ret = fstat(mfd, &stat); + ASSERT_EQ(0, ret); + ASSERT_EQ(stat.st_blksize, get_hpage_pmd_size()); + + /* + * shmem file is created at the mount, so the subdirectory can be + * removed without issues. + */ + ret = rmdir(subdir_path); + ASSERT_EQ(0, ret); + + close(mfd); +} + +TEST_HARNESS_MAIN