[libc-commits] [libc] [libc] implement mlock/mlock2/munlock/mlockall/munlockall (PR #79645)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Tue Jan 30 11:00:07 PST 2024
https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/79645
>From 40e8b2bc5192b8695038ff988d9b99b9d1d8ecf3 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Fri, 26 Jan 2024 15:41:28 -0500
Subject: [PATCH 1/9] [libc] implement mlock/mlock2/munlock/mlockall/munlockall
---
libc/spec/linux.td | 9 +++++++++
libc/spec/posix.td | 20 ++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/libc/spec/linux.td b/libc/spec/linux.td
index eab0a987b920c..0cb8b7f8bf525 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -89,6 +89,15 @@ def Linux : StandardSpec<"Linux"> {
ArgSpec<UnsignedCharPtr>,
]
>,
+ FunctionSpec<
+ "mlock2",
+ RetValSpec<IntType>,
+ [
+ ArgSpec<VoidPtr>,
+ ArgSpec<SizeTType>,
+ ArgSpec<UnsignedIntType>,
+ ]
+ >,
] // Functions
>;
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index 7e1cf892135ac..40a663afd2595 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -289,6 +289,26 @@ def POSIX : StandardSpec<"POSIX"> {
ArgSpec<SizeTType>,
ArgSpec<IntType>]
>,
+ FunctionSpec<
+ "mlock",
+ RetValSpec<IntType>,
+ [ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
+ >,
+ FunctionSpec<
+ "munlock",
+ RetValSpec<IntType>,
+ [ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
+ >,
+ FunctionSpec<
+ "mlockall",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>]
+ >,
+ FunctionSpec<
+ "munlockall",
+ RetValSpec<IntType>,
+ [ArgSpec<VoidType>]
+ >,
]
>;
>From 18a3a8811bc449513683fe7a7f651266a1fad734 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Mon, 29 Jan 2024 12:09:23 -0500
Subject: [PATCH 2/9] add implementations
---
libc/config/linux/aarch64/entrypoints.txt | 4 +
libc/config/linux/riscv/entrypoints.txt | 4 +
libc/config/linux/x86_64/entrypoints.txt | 4 +
libc/src/sys/mman/CMakeLists.txt | 28 ++++
libc/src/sys/mman/linux/CMakeLists.txt | 52 +++++++
libc/src/sys/mman/linux/mlock.cpp | 37 +++++
libc/src/sys/mman/linux/mlockall.cpp | 27 ++++
libc/src/sys/mman/linux/munlock.cpp | 27 ++++
libc/src/sys/mman/linux/munlockall.cpp | 27 ++++
libc/src/sys/mman/mlock.h | 25 ++++
libc/src/sys/mman/mlockall.h | 20 +++
libc/src/sys/mman/munlock.h | 20 +++
libc/src/sys/mman/munlockall.h | 20 +++
libc/test/src/sys/mman/linux/CMakeLists.txt | 24 ++++
libc/test/src/sys/mman/linux/mincore_test.cpp | 11 +-
libc/test/src/sys/mman/linux/mlock_test.cpp | 131 ++++++++++++++++++
16 files changed, 454 insertions(+), 7 deletions(-)
create mode 100644 libc/src/sys/mman/linux/mlock.cpp
create mode 100644 libc/src/sys/mman/linux/mlockall.cpp
create mode 100644 libc/src/sys/mman/linux/munlock.cpp
create mode 100644 libc/src/sys/mman/linux/munlockall.cpp
create mode 100644 libc/src/sys/mman/mlock.h
create mode 100644 libc/src/sys/mman/mlockall.h
create mode 100644 libc/src/sys/mman/munlock.h
create mode 100644 libc/src/sys/mman/munlockall.h
create mode 100644 libc/test/src/sys/mman/linux/mlock_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 52f1d2bce34f4..ad302dbd8c69d 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -137,6 +137,10 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.mman.munmap
libc.src.sys.mman.posix_madvise
libc.src.sys.mman.mincore
+ libc.src.sys.mman.mlock
+ libc.src.sys.mman.munlock
+ libc.src.sys.mman.mlockall
+ libc.src.sys.mman.munlockall
# sys/random.h entrypoints
libc.src.sys.random.getrandom
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index a257f3f8d64ab..60f34032f12fe 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -143,6 +143,10 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.mman.munmap
libc.src.sys.mman.posix_madvise
libc.src.sys.mman.mincore
+ libc.src.sys.mman.mlock
+ libc.src.sys.mman.munlock
+ libc.src.sys.mman.mlockall
+ libc.src.sys.mman.munlockall
# sys/random.h entrypoints
libc.src.sys.random.getrandom
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3812d9586121e..64b146ad5f30b 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -143,6 +143,10 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.mman.munmap
libc.src.sys.mman.posix_madvise
libc.src.sys.mman.mincore
+ libc.src.sys.mman.mlock
+ libc.src.sys.mman.munlock
+ libc.src.sys.mman.mlockall
+ libc.src.sys.mman.munlockall
# sys/random.h entrypoints
libc.src.sys.random.getrandom
diff --git a/libc/src/sys/mman/CMakeLists.txt b/libc/src/sys/mman/CMakeLists.txt
index 2d17429a26b45..5529157d05f99 100644
--- a/libc/src/sys/mman/CMakeLists.txt
+++ b/libc/src/sys/mman/CMakeLists.txt
@@ -43,3 +43,31 @@ add_entrypoint_object(
DEPENDS
.${LIBC_TARGET_OS}.mincore
)
+
+add_entrypoint_object(
+ mlock
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.mlock
+)
+
+add_entrypoint_object(
+ munlock
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.munlock
+)
+
+add_entrypoint_object(
+ mlockall
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.mlockall
+)
+
+add_entrypoint_object(
+ munlockall
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.munlockall
+)
diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt
index ce0cda7f22277..5649b362c902d 100644
--- a/libc/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/src/sys/mman/linux/CMakeLists.txt
@@ -74,3 +74,55 @@ add_entrypoint_object(
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)
+
+add_entrypoint_object(
+ mlock
+ SRCS
+ mlock.cpp
+ HDRS
+ ../mlock.h
+ DEPENDS
+ libc.include.sys_mman
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ munlock
+ SRCS
+ munlock.cpp
+ HDRS
+ ../munlock.h
+ DEPENDS
+ libc.include.sys_mman
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ mlockall
+ SRCS
+ mlockall.cpp
+ HDRS
+ ../mlockall.h
+ DEPENDS
+ libc.include.sys_mman
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ munlockall
+ SRCS
+ munlockall.cpp
+ HDRS
+ ../munlockall.h
+ DEPENDS
+ libc.include.sys_mman
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.errno
+)
diff --git a/libc/src/sys/mman/linux/mlock.cpp b/libc/src/sys/mman/linux/mlock.cpp
new file mode 100644
index 0000000000000..d81b19e9a3935
--- /dev/null
+++ b/libc/src/sys/mman/linux/mlock.cpp
@@ -0,0 +1,37 @@
+//===---------- Linux implementation of the mlock function ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/mman/mlock.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, mlock, (const void *addr, size_t len)) {
+ long ret = syscall_impl(SYS_mlock, cpp::bit_cast<long>(addr), len);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+#ifdef SYS_mlock2
+LLVM_LIBC_FUNCTION(int, mlock2, (const void *addr, size_t len, int flags)) {
+ long ret = syscall_impl(SYS_mlock2, cpp::bit_cast<long>(addr), len, flags);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+#endif
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/linux/mlockall.cpp b/libc/src/sys/mman/linux/mlockall.cpp
new file mode 100644
index 0000000000000..c4af7d8952738
--- /dev/null
+++ b/libc/src/sys/mman/linux/mlockall.cpp
@@ -0,0 +1,27 @@
+//===---------- Linux implementation of the mlockall function -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/mman/mlockall.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, mlockall, (int flags)) {
+ long ret = syscall_impl(SYS_mlockall, flags);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/linux/munlock.cpp b/libc/src/sys/mman/linux/munlock.cpp
new file mode 100644
index 0000000000000..9ee50805ac30e
--- /dev/null
+++ b/libc/src/sys/mman/linux/munlock.cpp
@@ -0,0 +1,27 @@
+//===---------- Linux implementation of the munlock function --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/mman/munlock.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, munlock, (const void *addr, size_t len)) {
+ long ret = syscall_impl(SYS_munlock, cpp::bit_cast<long>(addr), len);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/linux/munlockall.cpp b/libc/src/sys/mman/linux/munlockall.cpp
new file mode 100644
index 0000000000000..d1619d204a90d
--- /dev/null
+++ b/libc/src/sys/mman/linux/munlockall.cpp
@@ -0,0 +1,27 @@
+//===---------- Linux implementation of the munlockall function -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/mman/munlockall.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, munlockall, (void)) {
+ long ret = syscall_impl(SYS_munlockall);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/mlock.h b/libc/src/sys/mman/mlock.h
new file mode 100644
index 0000000000000..f4861560171a3
--- /dev/null
+++ b/libc/src/sys/mman/mlock.h
@@ -0,0 +1,25 @@
+//===-- Implementation header for mlock function ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE {
+
+int mlock(const void *addr, size_t len);
+
+#ifdef SYS_mlock2
+int mlock2(const void *addr, size_t len, int flags);
+#endif
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
diff --git a/libc/src/sys/mman/mlockall.h b/libc/src/sys/mman/mlockall.h
new file mode 100644
index 0000000000000..bb4bd834310ee
--- /dev/null
+++ b/libc/src/sys/mman/mlockall.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for mlockall function -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MLOCKALL_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCKALL_H
+
+#include <sys/mman.h>
+
+namespace LIBC_NAMESPACE {
+
+int mlockall(int flags);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCKALL_H
diff --git a/libc/src/sys/mman/munlock.h b/libc/src/sys/mman/munlock.h
new file mode 100644
index 0000000000000..6aca82dae4533
--- /dev/null
+++ b/libc/src/sys/mman/munlock.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for munlock function --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MUNLOCK_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MUNLOCK_H
+
+#include <sys/mman.h>
+
+namespace LIBC_NAMESPACE {
+
+int munlock(const void *addr, size_t len);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MUNLOCK_H
diff --git a/libc/src/sys/mman/munlockall.h b/libc/src/sys/mman/munlockall.h
new file mode 100644
index 0000000000000..5abd4b873465e
--- /dev/null
+++ b/libc/src/sys/mman/munlockall.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for munlockall function -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MUNLOCKALL_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MUNLOCKALL_H
+
+#include <sys/mman.h>
+
+namespace LIBC_NAMESPACE {
+
+int munlockall(void);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MUNLOCKALL_H
diff --git a/libc/test/src/sys/mman/linux/CMakeLists.txt b/libc/test/src/sys/mman/linux/CMakeLists.txt
index 36557695e503c..64de25320c521 100644
--- a/libc/test/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/test/src/sys/mman/linux/CMakeLists.txt
@@ -77,6 +77,30 @@ add_libc_unittest(
libc.src.sys.mman.munmap
libc.src.sys.mman.madvise
libc.src.sys.mman.mincore
+ libc.src.sys.mman.mlock
+ libc.src.sys.mman.munlock
+ libc.src.unistd.sysconf
+ libc.test.UnitTest.ErrnoSetterMatcher
+)
+
+add_libc_unittest(
+ mlock_test
+ SUITE
+ libc_sys_mman_unittests
+ SRCS
+ mlock_test.cpp
+ DEPENDS
+ libc.include.sys_mman
+ libc.include.unistd
+ libc.src.errno.errno
+ libc.src.sys.mman.mmap
+ libc.src.sys.mman.munmap
+ libc.src.sys.mman.madvise
+ libc.src.sys.mman.mincore
+ libc.src.sys.mman.mlock
+ libc.src.sys.mman.munlock
+ libc.src.sys.mman.mlockall
+ libc.src.sys.mman.munlockall
libc.src.unistd.sysconf
libc.test.UnitTest.ErrnoSetterMatcher
)
diff --git a/libc/test/src/sys/mman/linux/mincore_test.cpp b/libc/test/src/sys/mman/linux/mincore_test.cpp
index 493d748f2c98e..2814694849fc6 100644
--- a/libc/test/src/sys/mman/linux/mincore_test.cpp
+++ b/libc/test/src/sys/mman/linux/mincore_test.cpp
@@ -10,7 +10,9 @@
#include "src/errno/libc_errno.h"
#include "src/sys/mman/madvise.h"
#include "src/sys/mman/mincore.h"
+#include "src/sys/mman/mlock.h"
#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munlock.h"
#include "src/sys/mman/munmap.h"
#include "src/unistd/sysconf.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
@@ -91,16 +93,11 @@ TEST(LlvmLibcMincoreTest, PageOut) {
// touch the page
{
static_cast<char *>(addr)[0] = 0;
- // TODO: use wrapper functions for mlock/munlock once implemented.
- // See issue https://github.com/llvm/llvm-project/issues/79336
- LIBC_NAMESPACE::syscall_impl(
- SYS_mlock, reinterpret_cast<unsigned long>(addr), page_size);
- libc_errno = 0;
+ EXPECT_THAT(LIBC_NAMESPACE::mlock(addr, page_size), Succeeds());
int res = LIBC_NAMESPACE::mincore(addr, 1, &vec);
EXPECT_EQ(vec & 1u, 1u);
EXPECT_THAT(res, Succeeds());
- LIBC_NAMESPACE::syscall_impl(
- SYS_munlock, reinterpret_cast<unsigned long>(addr), page_size);
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(addr, page_size), Succeeds());
}
// page out the memory
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
new file mode 100644
index 0000000000000..eec8446d9ce3f
--- /dev/null
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -0,0 +1,131 @@
+//===-- Unittests for mlock -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/errno/libc_errno.h"
+#include "src/sys/mman/madvise.h"
+#include "src/sys/mman/mincore.h"
+#include "src/sys/mman/mlock.h"
+#include "src/sys/mman/mlockall.h"
+#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munlock.h"
+#include "src/sys/mman/munlockall.h"
+
+#include "src/sys/mman/munmap.h"
+#include "src/unistd/sysconf.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
+#include "test/UnitTest/Test.h"
+
+#include <asm-generic/errno-base.h>
+#include <asm-generic/mman.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+struct PageHolder {
+ size_t size;
+ void *addr;
+
+ PageHolder()
+ : size(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE)),
+ addr(LIBC_NAMESPACE::mmap(nullptr, size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) {}
+ ~PageHolder() {
+ if (addr != MAP_FAILED)
+ LIBC_NAMESPACE::munmap(addr, size);
+ }
+
+ char &operator[](size_t i) { return reinterpret_cast<char *>(addr)[i]; }
+
+ bool is_valid() { return addr != MAP_FAILED; }
+};
+
+TEST(LlvmLibcMlockTest, UnMappedMemory) {
+ EXPECT_THAT(LIBC_NAMESPACE::mlock(nullptr, 1024), Fails(ENOMEM));
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(nullptr, 1024), Fails(ENOMEM));
+}
+
+TEST(LlvmLibcMlockTest, Overflow) {
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ EXPECT_THAT(LIBC_NAMESPACE::mlock(holder.addr, -holder.size), Fails(EINVAL));
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, -holder.size),
+ Fails(EINVAL));
+}
+
+#ifdef SYS_mlock2
+TEST(LlvmLibcMlockTest, MLock2) {
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ EXPECT_THAT(LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
+ Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::mlock2(holder.addr, holder.size, 0), Succeeds());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, holder.size), Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
+ Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::mlock2(holder.addr, holder.size, MLOCK_ONFAULT),
+ Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 0);
+ holder[0] = 1;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, holder.size), Succeeds());
+}
+#endif
+
+TEST(LlvmLibcMlockTest, MLockAll) {
+ {
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ EXPECT_THAT(
+ LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
+ Succeeds());
+ EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_CURRENT), Succeeds());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+ }
+ {
+ EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_FUTURE), Succeeds());
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+ }
+#ifdef MCL_ONFAULT
+ {
+ EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_FUTURE | MCL_ONFAULT), Succeeds());
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 0);
+ holder[0] = 1;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+ }
+#endif
+}
>From ae990b2b06a1c3fadf38ed95dc5ef6757b0e59ff Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Mon, 29 Jan 2024 12:41:41 -0500
Subject: [PATCH 3/9] allow partial failures
---
libc/test/src/sys/mman/linux/mlock_test.cpp | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
index eec8446d9ce3f..8a155d1a35db1 100644
--- a/libc/test/src/sys/mman/linux/mlock_test.cpp
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -95,7 +95,12 @@ TEST(LlvmLibcMlockTest, MLockAll) {
EXPECT_THAT(
LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
Succeeds());
- EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_CURRENT), Succeeds());
+ auto retval = LIBC_NAMESPACE::mlockall(MCL_CURRENT);
+ if (retval == -1) {
+ EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
+ libc_errno = 0;
+ return;
+ }
unsigned char vec;
EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
Succeeds());
@@ -103,7 +108,12 @@ TEST(LlvmLibcMlockTest, MLockAll) {
EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
}
{
- EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_FUTURE), Succeeds());
+ auto retval = LIBC_NAMESPACE::mlockall(MCL_FUTURE);
+ if (retval == -1) {
+ EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
+ libc_errno = 0;
+ return;
+ }
PageHolder holder;
EXPECT_TRUE(holder.is_valid());
unsigned char vec;
@@ -114,7 +124,12 @@ TEST(LlvmLibcMlockTest, MLockAll) {
}
#ifdef MCL_ONFAULT
{
- EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_FUTURE | MCL_ONFAULT), Succeeds());
+ auto retval = LIBC_NAMESPACE::mlockall(MCL_FUTURE | MCL_ONFAULT);
+ if (retval == -1) {
+ EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
+ libc_errno = 0;
+ return;
+ }
PageHolder holder;
EXPECT_TRUE(holder.is_valid());
unsigned char vec;
>From 83d2e56a6960c36ea5c4d77fdb87ecb582964942 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Mon, 29 Jan 2024 13:12:00 -0500
Subject: [PATCH 4/9] separate mlock2
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/src/sys/mman/CMakeLists.txt | 7 ++++++
libc/src/sys/mman/linux/CMakeLists.txt | 13 ++++++++++
libc/src/sys/mman/linux/mlock.cpp | 11 ---------
libc/src/sys/mman/linux/mlock2.cpp | 27 +++++++++++++++++++++
libc/src/sys/mman/mlock.h | 4 ---
libc/src/sys/mman/mlock2.h | 23 ++++++++++++++++++
libc/test/src/sys/mman/linux/CMakeLists.txt | 1 +
libc/test/src/sys/mman/linux/mlock_test.cpp | 1 +
11 files changed, 75 insertions(+), 15 deletions(-)
create mode 100644 libc/src/sys/mman/linux/mlock2.cpp
create mode 100644 libc/src/sys/mman/mlock2.h
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index ad302dbd8c69d..ffb79aa4a252e 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -138,6 +138,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.mman.posix_madvise
libc.src.sys.mman.mincore
libc.src.sys.mman.mlock
+ libc.src.sys.mman.mlock2
libc.src.sys.mman.munlock
libc.src.sys.mman.mlockall
libc.src.sys.mman.munlockall
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 60f34032f12fe..c9adc8852cb92 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -144,6 +144,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.mman.posix_madvise
libc.src.sys.mman.mincore
libc.src.sys.mman.mlock
+ libc.src.sys.mman.mlock2
libc.src.sys.mman.munlock
libc.src.sys.mman.mlockall
libc.src.sys.mman.munlockall
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 64b146ad5f30b..9b3b134ef00ef 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -144,6 +144,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.mman.posix_madvise
libc.src.sys.mman.mincore
libc.src.sys.mman.mlock
+ libc.src.sys.mman.mlock2
libc.src.sys.mman.munlock
libc.src.sys.mman.mlockall
libc.src.sys.mman.munlockall
diff --git a/libc/src/sys/mman/CMakeLists.txt b/libc/src/sys/mman/CMakeLists.txt
index 5529157d05f99..f11f5ac9df9f2 100644
--- a/libc/src/sys/mman/CMakeLists.txt
+++ b/libc/src/sys/mman/CMakeLists.txt
@@ -51,6 +51,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.mlock
)
+add_entrypoint_object(
+ mlock2
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.mlock2
+)
+
add_entrypoint_object(
munlock
ALIAS
diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt
index 5649b362c902d..a6feff1f0bec1 100644
--- a/libc/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/src/sys/mman/linux/CMakeLists.txt
@@ -88,6 +88,19 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ mlock2
+ SRCS
+ mlock2.cpp
+ HDRS
+ ../mlock2.h
+ DEPENDS
+ libc.include.sys_mman
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.errno
+)
+
add_entrypoint_object(
munlock
SRCS
diff --git a/libc/src/sys/mman/linux/mlock.cpp b/libc/src/sys/mman/linux/mlock.cpp
index d81b19e9a3935..9bc5ab9a07863 100644
--- a/libc/src/sys/mman/linux/mlock.cpp
+++ b/libc/src/sys/mman/linux/mlock.cpp
@@ -23,15 +23,4 @@ LLVM_LIBC_FUNCTION(int, mlock, (const void *addr, size_t len)) {
}
return 0;
}
-
-#ifdef SYS_mlock2
-LLVM_LIBC_FUNCTION(int, mlock2, (const void *addr, size_t len, int flags)) {
- long ret = syscall_impl(SYS_mlock2, cpp::bit_cast<long>(addr), len, flags);
- if (ret < 0) {
- libc_errno = static_cast<int>(-ret);
- return -1;
- }
- return 0;
-}
-#endif
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/linux/mlock2.cpp b/libc/src/sys/mman/linux/mlock2.cpp
new file mode 100644
index 0000000000000..71b2b80d99bbf
--- /dev/null
+++ b/libc/src/sys/mman/linux/mlock2.cpp
@@ -0,0 +1,27 @@
+//===---------- Linux implementation of the mlock function ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/mman/mlock2.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+#ifdef SYS_mlock2
+LLVM_LIBC_FUNCTION(int, mlock2, (const void *addr, size_t len, int flags)) {
+ long ret = syscall_impl(SYS_mlock2, cpp::bit_cast<long>(addr), len, flags);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+#endif
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/mlock.h b/libc/src/sys/mman/mlock.h
index f4861560171a3..73f329a0d52dc 100644
--- a/libc/src/sys/mman/mlock.h
+++ b/libc/src/sys/mman/mlock.h
@@ -16,10 +16,6 @@ namespace LIBC_NAMESPACE {
int mlock(const void *addr, size_t len);
-#ifdef SYS_mlock2
-int mlock2(const void *addr, size_t len, int flags);
-#endif
-
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
diff --git a/libc/src/sys/mman/mlock2.h b/libc/src/sys/mman/mlock2.h
new file mode 100644
index 0000000000000..872a7bfc5fba6
--- /dev/null
+++ b/libc/src/sys/mman/mlock2.h
@@ -0,0 +1,23 @@
+//===-- Implementation header for mlock2 function ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MLOCK2_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCK2_H
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE {
+
+#ifdef SYS_mlock2
+int mlock2(const void *addr, size_t len, int flags);
+#endif
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCK2_H
diff --git a/libc/test/src/sys/mman/linux/CMakeLists.txt b/libc/test/src/sys/mman/linux/CMakeLists.txt
index 64de25320c521..a8dcf14ea5d1d 100644
--- a/libc/test/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/test/src/sys/mman/linux/CMakeLists.txt
@@ -98,6 +98,7 @@ add_libc_unittest(
libc.src.sys.mman.madvise
libc.src.sys.mman.mincore
libc.src.sys.mman.mlock
+ libc.src.sys.mman.mlock2
libc.src.sys.mman.munlock
libc.src.sys.mman.mlockall
libc.src.sys.mman.munlockall
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
index 8a155d1a35db1..b1b4e816055e5 100644
--- a/libc/test/src/sys/mman/linux/mlock_test.cpp
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -11,6 +11,7 @@
#include "src/sys/mman/madvise.h"
#include "src/sys/mman/mincore.h"
#include "src/sys/mman/mlock.h"
+#include "src/sys/mman/mlock2.h"
#include "src/sys/mman/mlockall.h"
#include "src/sys/mman/mmap.h"
#include "src/sys/mman/munlock.h"
>From 51a71986b583e63824f5badc79ceee8d80b684af Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Tue, 30 Jan 2024 10:06:22 -0500
Subject: [PATCH 5/9] add additional checks
---
libc/test/src/sys/mman/linux/CMakeLists.txt | 2 ++
libc/test/src/sys/mman/linux/mlock_test.cpp | 35 ++++++++++++++++++---
2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/libc/test/src/sys/mman/linux/CMakeLists.txt b/libc/test/src/sys/mman/linux/CMakeLists.txt
index a8dcf14ea5d1d..09ab5b09be640 100644
--- a/libc/test/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/test/src/sys/mman/linux/CMakeLists.txt
@@ -102,6 +102,8 @@ add_libc_unittest(
libc.src.sys.mman.munlock
libc.src.sys.mman.mlockall
libc.src.sys.mman.munlockall
+ libc.src.sys.resource.getrlimit
+ libc.src.__support.OSUtil.osutil
libc.src.unistd.sysconf
libc.test.UnitTest.ErrnoSetterMatcher
)
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
index b1b4e816055e5..d0ea158bc07d4 100644
--- a/libc/test/src/sys/mman/linux/mlock_test.cpp
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -16,8 +16,8 @@
#include "src/sys/mman/mmap.h"
#include "src/sys/mman/munlock.h"
#include "src/sys/mman/munlockall.h"
-
#include "src/sys/mman/munmap.h"
+#include "src/sys/resource/getrlimit.h"
#include "src/unistd/sysconf.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/LibcTest.h"
@@ -25,7 +25,9 @@
#include <asm-generic/errno-base.h>
#include <asm-generic/mman.h>
+#include <linux/capability.h>
#include <sys/mman.h>
+#include <sys/resource.h>
#include <sys/syscall.h>
#include <unistd.h>
@@ -49,6 +51,28 @@ struct PageHolder {
bool is_valid() { return addr != MAP_FAILED; }
};
+static bool get_capacity(unsigned int cap) {
+ struct __user_cap_header_struct header;
+ header.pid = 0;
+ header.version = _LINUX_CAPABILITY_VERSION_3;
+ struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
+ long res = LIBC_NAMESPACE::syscall_impl(
+ SYS_capget, LIBC_NAMESPACE::cpp::bit_cast<long>(&header),
+ LIBC_NAMESPACE::cpp::bit_cast<long>(&data));
+ if (res < 0)
+ return false;
+ auto idx = CAP_TO_INDEX(cap);
+ auto shift = CAP_TO_MASK(cap);
+ return (data[idx].effective & shift) != 0;
+}
+
+static bool is_permitted_size(size_t size) {
+ struct rlimit rlimits;
+ LIBC_NAMESPACE::getrlimit(RLIMIT_MEMLOCK, &rlimits);
+ return size <= static_cast<size_t>(rlimits.rlim_cur) ||
+ get_capacity(CAP_IPC_LOCK);
+}
+
TEST(LlvmLibcMlockTest, UnMappedMemory) {
EXPECT_THAT(LIBC_NAMESPACE::mlock(nullptr, 1024), Fails(ENOMEM));
EXPECT_THAT(LIBC_NAMESPACE::munlock(nullptr, 1024), Fails(ENOMEM));
@@ -57,9 +81,12 @@ TEST(LlvmLibcMlockTest, UnMappedMemory) {
TEST(LlvmLibcMlockTest, Overflow) {
PageHolder holder;
EXPECT_TRUE(holder.is_valid());
- EXPECT_THAT(LIBC_NAMESPACE::mlock(holder.addr, -holder.size), Fails(EINVAL));
- EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, -holder.size),
- Fails(EINVAL));
+ size_t negative_size = -holder.size;
+ auto expected_errno = is_permitted_size(negative_size) ? EINVAL : ENOMEM;
+ EXPECT_THAT(LIBC_NAMESPACE::mlock(holder.addr, negative_size),
+ Fails(expected_errno));
+ EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, negative_size),
+ Fails(expected_errno));
}
#ifdef SYS_mlock2
>From 1a88d99dfa637a86d8b62acab3718d441261c748 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Tue, 30 Jan 2024 10:37:51 -0500
Subject: [PATCH 6/9] fix
---
libc/test/src/sys/mman/linux/mlock_test.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
index d0ea158bc07d4..1df4d7d1b78e4 100644
--- a/libc/test/src/sys/mman/linux/mlock_test.cpp
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -86,7 +86,7 @@ TEST(LlvmLibcMlockTest, Overflow) {
EXPECT_THAT(LIBC_NAMESPACE::mlock(holder.addr, negative_size),
Fails(expected_errno));
EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, negative_size),
- Fails(expected_errno));
+ Fails(EINVAL));
}
#ifdef SYS_mlock2
>From d1d1581a6f0ae34dbb4957bbfb18f1f0768b0b1c Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Tue, 30 Jan 2024 12:17:12 -0500
Subject: [PATCH 7/9] address CR
---
libc/test/src/sys/mman/linux/mlock_test.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
index 1df4d7d1b78e4..3352fb709a074 100644
--- a/libc/test/src/sys/mman/linux/mlock_test.cpp
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -52,10 +52,12 @@ struct PageHolder {
};
static bool get_capacity(unsigned int cap) {
- struct __user_cap_header_struct header;
+ __user_cap_header_struct header;
header.pid = 0;
header.version = _LINUX_CAPABILITY_VERSION_3;
- struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
+ __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
+ // TODO: use capget wrapper once implemented.
+ // https://github.com/llvm/llvm-project/issues/80037
long res = LIBC_NAMESPACE::syscall_impl(
SYS_capget, LIBC_NAMESPACE::cpp::bit_cast<long>(&header),
LIBC_NAMESPACE::cpp::bit_cast<long>(&data));
@@ -67,7 +69,7 @@ static bool get_capacity(unsigned int cap) {
}
static bool is_permitted_size(size_t size) {
- struct rlimit rlimits;
+ rlimit rlimits;
LIBC_NAMESPACE::getrlimit(RLIMIT_MEMLOCK, &rlimits);
return size <= static_cast<size_t>(rlimits.rlim_cur) ||
get_capacity(CAP_IPC_LOCK);
@@ -82,7 +84,7 @@ TEST(LlvmLibcMlockTest, Overflow) {
PageHolder holder;
EXPECT_TRUE(holder.is_valid());
size_t negative_size = -holder.size;
- auto expected_errno = is_permitted_size(negative_size) ? EINVAL : ENOMEM;
+ int expected_errno = is_permitted_size(negative_size) ? EINVAL : ENOMEM;
EXPECT_THAT(LIBC_NAMESPACE::mlock(holder.addr, negative_size),
Fails(expected_errno));
EXPECT_THAT(LIBC_NAMESPACE::munlock(holder.addr, negative_size),
>From 6779ae20e572f672caa85f1fc798dea481c28f9a Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Tue, 30 Jan 2024 12:18:09 -0500
Subject: [PATCH 8/9] address CR
---
libc/test/src/sys/mman/linux/mlock_test.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
index 3352fb709a074..1e41604db63c7 100644
--- a/libc/test/src/sys/mman/linux/mlock_test.cpp
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -63,8 +63,8 @@ static bool get_capacity(unsigned int cap) {
LIBC_NAMESPACE::cpp::bit_cast<long>(&data));
if (res < 0)
return false;
- auto idx = CAP_TO_INDEX(cap);
- auto shift = CAP_TO_MASK(cap);
+ unsigned idx = CAP_TO_INDEX(cap);
+ unsigned shift = CAP_TO_MASK(cap);
return (data[idx].effective & shift) != 0;
}
>From 256d9bb0452f0ffeba2b1e2a2ee131b65c76f2e3 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Tue, 30 Jan 2024 13:57:45 -0500
Subject: [PATCH 9/9] adopt invalid flag tests Co-authored-by: Sirui Mu
<msrlancern at gmail.com>
---
libc/test/src/sys/mman/linux/mlock_test.cpp | 117 +++++++++++---------
1 file changed, 66 insertions(+), 51 deletions(-)
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
index 1e41604db63c7..6949115c70570 100644
--- a/libc/test/src/sys/mman/linux/mlock_test.cpp
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -118,59 +118,74 @@ TEST(LlvmLibcMlockTest, MLock2) {
}
#endif
-TEST(LlvmLibcMlockTest, MLockAll) {
- {
- PageHolder holder;
- EXPECT_TRUE(holder.is_valid());
- EXPECT_THAT(
- LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
- Succeeds());
- auto retval = LIBC_NAMESPACE::mlockall(MCL_CURRENT);
- if (retval == -1) {
- EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
- libc_errno = 0;
- return;
- }
- unsigned char vec;
- EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
- Succeeds());
- EXPECT_EQ(vec & 1, 1);
- EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
- }
- {
- auto retval = LIBC_NAMESPACE::mlockall(MCL_FUTURE);
- if (retval == -1) {
- EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
- libc_errno = 0;
- return;
- }
- PageHolder holder;
- EXPECT_TRUE(holder.is_valid());
- unsigned char vec;
- EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
- Succeeds());
- EXPECT_EQ(vec & 1, 1);
- EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+TEST(LlvmLibcMlockTest, MLockAll){{PageHolder holder;
+EXPECT_TRUE(holder.is_valid());
+EXPECT_THAT(LIBC_NAMESPACE::madvise(holder.addr, holder.size, MADV_DONTNEED),
+ Succeeds());
+auto retval = LIBC_NAMESPACE::mlockall(MCL_CURRENT);
+if (retval == -1) {
+ EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
+ libc_errno = 0;
+ return;
+}
+unsigned char vec;
+EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+EXPECT_EQ(vec & 1, 1);
+EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+}
+{
+ auto retval = LIBC_NAMESPACE::mlockall(MCL_FUTURE);
+ if (retval == -1) {
+ EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
+ libc_errno = 0;
+ return;
}
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+}
#ifdef MCL_ONFAULT
- {
- auto retval = LIBC_NAMESPACE::mlockall(MCL_FUTURE | MCL_ONFAULT);
- if (retval == -1) {
- EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
- libc_errno = 0;
- return;
- }
- PageHolder holder;
- EXPECT_TRUE(holder.is_valid());
- unsigned char vec;
- EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
- Succeeds());
- EXPECT_EQ(vec & 1, 0);
- holder[0] = 1;
- EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
- Succeeds());
- EXPECT_EQ(vec & 1, 1);
- EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+{
+ auto retval = LIBC_NAMESPACE::mlockall(MCL_FUTURE | MCL_ONFAULT);
+ if (retval == -1) {
+ EXPECT_TRUE(libc_errno == ENOMEM || libc_errno == EPERM);
+ libc_errno = 0;
+ return;
}
+ PageHolder holder;
+ EXPECT_TRUE(holder.is_valid());
+ unsigned char vec;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 0);
+ holder[0] = 1;
+ EXPECT_THAT(LIBC_NAMESPACE::mincore(holder.addr, holder.size, &vec),
+ Succeeds());
+ EXPECT_EQ(vec & 1, 1);
+ EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+}
#endif
}
+
+TEST(LlvmLibcMlockTest, InvalidFlag) {
+ size_t alloc_size = 128; // page size
+ libc_errno = 0;
+ void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ EXPECT_EQ(0, libc_errno);
+ EXPECT_NE(addr, MAP_FAILED);
+
+ // Invalid mlock2 flags.
+ EXPECT_THAT(LIBC_NAMESPACE::mlock2(addr, alloc_size, 1234), Fails(EINVAL));
+
+ // Invalid mlockall flags.
+ EXPECT_THAT(LIBC_NAMESPACE::mlockall(1234), Fails(EINVAL));
+ EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_ONFAULT), Fails(EINVAL));
+
+ LIBC_NAMESPACE::munmap(addr, alloc_size);
+}
More information about the libc-commits
mailing list