Skip to contentSkip to conversation

Providing mount for memfd_restricted() syscall

RFC PATCH Superseded Ackerley Tng 3 participants 6 messages Feb 16, 2023 – Feb 24, 2023

Subsystems (7)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

cover Providing mount for memfd_restricted() syscall

Hello,

This patchset builds upon the memfd_restricted() system call that has been discussed in the ‘KVM: mm: fd-based approach for supporting KVM’ patch series, at
https://lore.kernel.org/lkml/[email protected]/T/#m7e944d7892afdd1d62a03a287bd488c56e377b0c

The tree can be found at:
https://github.com/googleprodkernel/linux-cc/tree/restrictedmem-provide-mount-path

In this patchset, a modification to the memfd_restricted() syscall is proposed, which allows userspace to provide a mount, on which the file will be created and returned from the memfd_restricted().

Allowing userspace to provide a mount allows userspace to control various memory binding policies via tmpfs mount options, such as Transparent HugePage memory allocation policy through ‘huge=always/never’ and NUMA memory allocation policy through ‘mpol=local/bind:*’.

Dependencies:
+ Sean’s iteration of the ‘KVM: mm: fd-based approach for supporting
KVM’ patch series at
https://github.com/sean-jc/linux/tree/x86/upm_base_support
+ Proposed fixes for these issues mentioned on the mailing list:
+ https://lore.kernel.org/lkml/[email protected]/

Future work/TODOs:
+ man page for the memfd_restricted() syscall
+ Support for per file Transparent HugePage allocation hints
+ Support for per file NUMA binding hints

Ackerley Tng (2):
mm: restrictedmem: Allow userspace to specify mount_path for
memfd_restricted
selftests: restrictedmem: Check hugepage-ness of shmem file backing
restrictedmem fd

 include/linux/syscalls.h                      |   2 +-
 include/uapi/linux/restrictedmem.h            |   8 +
 mm/restrictedmem.c                            |  63 +++-
 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 ++++++++++++++++++
 9 files changed, 445 insertions(+), 7 deletions(-)
 create mode 100644 include/uapi/linux/restrictedmem.h
 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

--
2.39.1.637.g21b0678d19-goog

#1 lore raw

RFC PATCH 1/2 mm: restrictedmem: Allow userspace to specify mount_path for memfd_restricted

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.

---
 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
include/linux/syscalls.h +1 -1
index f9e9e0c820c5..4b8efe9a8680 100644
@@ -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
include/uapi/linux/restrictedmem.h new file +8 -0
new file mode 100644
index 000000000000..9f108dd1ac4c
@@ -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 */
mm/restrictedmem.c +57 -6

93 lines not on this page · raw message

Signature · 1 line
2.39.1.637.g21b0678d19-goog
#2 lore raw

Re: [RFC PATCH 1/2] mm: restrictedmem: Allow userspace to specify mount_path for memfd_restricted

Quoted 27 lines · Ackerley Tng

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.

---
 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
include/linux/syscalls.h +0 -0
index f9e9e0c820c5..4b8efe9a8680 100644

include/linux/syscalls.h asmlinkage long sys_memfd_secret(unsigned int flags); · line 1062

Quoted 8 lines
include/linux/syscalls.h +1 -1
@@ -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

I'm not sure what the right practice now: do we provide string that contains mount path or fd that represents the filesystem (returned from fsmount(2) or open_tree(2)).

fd seems more flexible: it allows to specify unbind mounts.

Signature · 1 line
  Kiryl Shutsemau / Kirill A. Shutemov
#3 lore raw

Re: [RFC PATCH 1/2] mm: restrictedmem: Allow userspace to specify mount_path for memfd_restricted

Quoted 37 lines · Kirill A. Shutemov
Quoted 35 lines · Ackerley Tng

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.

---
  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

include/linux/syscalls.h +1 -1
index f9e9e0c820c5..4b8efe9a8680 100644
@@ -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);
Quoted 8 lines
Quoted 2 lines

/*
* Architecture-specific system calls

I'm not sure what the right practice now: do we provide string that contains mount path or fd that represents the filesystem (returned from fsmount(2) or open_tree(2)).

fd seems more flexible: it allows to specify unbind mounts.

I tried out the suggestion of passing fds to memfd_restricted() instead of strings.

One benefit I see of using fds is interface uniformity: it feels more aligned with other syscalls like fsopen(), fsconfig(), and fsmount() in terms of using and passing around fds.

Other than being able to use a mount without a path attached to the mount, are there any other benefits of using fds over using the path string?

Should I post the patches that allows specifying a mount using fds? Should I post them as a separate RFC, or as a new revision to this RFC?

#4 lore raw

Re: [RFC PATCH 1/2] mm: restrictedmem: Allow userspace to specify mount_path for memfd_restricted

Quoted 52 lines · Ackerley Tng
Quoted 37 lines · Kirill A. Shutemov
Quoted 35 lines · Ackerley Tng

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.

---
  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

include/linux/syscalls.h +1 -1
index f9e9e0c820c5..4b8efe9a8680 100644
@@ -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);
Quoted 8 lines
Quoted 2 lines

/*
* Architecture-specific system calls

I'm not sure what the right practice now: do we provide string that contains mount path or fd that represents the filesystem (returned from fsmount(2) or open_tree(2)).

fd seems more flexible: it allows to specify unbind mounts.

I tried out the suggestion of passing fds to memfd_restricted() instead of strings.

Quoted 6 lines

One benefit I see of using fds is interface uniformity: it feels more aligned with other syscalls like fsopen(), fsconfig(), and fsmount() in terms of using and passing around fds.

Other than being able to use a mount without a path attached to the mount, are there any other benefits of using fds over using the path string?

It would be nice if anyone from fs folks comment on this.

Quoted 2 lines

Should I post the patches that allows specifying a mount using fds? Should I post them as a separate RFC, or as a new revision to this RFC?

Let's first decide what the right direction is.

Signature · 1 line
  Kiryl Shutsemau / Kirill A. Shutemov
#5 lore raw

RFC PATCH 2/2 selftests: restrictedmem: Check hugepage-ness of shmem file backing restrictedmem fd

In reply to Ackerley Tng

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.

---
 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
tools/testing/selftests/Makefile +1 -0
index f07aef7c592c..44078eeefb79 100644
@@ -60,6 +60,7 @@ TARGETS += pstore
 TARGETS += ptrace
 TARGETS += openat2
 TARGETS += resctrl
+TARGETS += restrictedmem
 TARGETS += rlimits
 TARGETS += rseq
 TARGETS += rtc
tools/testing/selftests/restrictedmem/.gitignore new file +3 -0
new file mode 100644
index 000000000000..2581bcc8ff29
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+restrictedmem_hugepage_test
tools/testing/selftests/restrictedmem/Makefile new file +14 -0
new file mode 100644
index 000000000000..da9665718c8a
@@ -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
tools/testing/selftests/restrictedmem/common.c new file +9 -0
new file mode 100644
index 000000000000..79b2ac98cc89
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <sys/syscall.h>
+#include <unistd.h>
+
+int memfd_restricted(unsigned int flags, char *mount_path)
+{
+	return syscall(__NR_memfd_restricted, flags, mount_path);
+}
tools/testing/selftests/restrictedmem/common.h new file +8 -0
new file mode 100644
index 000000000000..5d59edc4f23f
@@ -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
tools/testing/selftests/restrictedmem/restrictedmem_hugepage_test.c new file +344 -0

344 lines not on this page · raw message

Signature · 1 line
2.39.1.637.g21b0678d19-goog