All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v1] mremap07.c: New case check mremap with MREMAP_DONTUNMAP
@ 2025-08-27 23:02 Wei Gao via ltp
  2025-10-15  3:15 ` [LTP] [PATCH v2] " Wei Gao via ltp
  0 siblings, 1 reply; 23+ messages in thread
From: Wei Gao via ltp @ 2025-08-27 23:02 UTC (permalink / raw)
  To: ltp

This case test mremap() with MREMAP_DONTUNMAP and use userfaultfd
verifies fault which triggered by accessing old memory region.

Fixes: #1168
Signed-off-by: Wei Gao <wegao@suse.com>
---
 runtest/syscalls                            |   1 +
 testcases/kernel/syscalls/mremap/.gitignore |   1 +
 testcases/kernel/syscalls/mremap/mremap07.c | 154 ++++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 testcases/kernel/syscalls/mremap/mremap07.c

diff --git a/runtest/syscalls b/runtest/syscalls
index f15331da3..14ceb7696 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -916,6 +916,7 @@ mremap03 mremap03
 mremap04 mremap04
 mremap05 mremap05
 mremap06 mremap06
+mremap07 mremap07
 
 mseal01 mseal01
 mseal02 mseal02
diff --git a/testcases/kernel/syscalls/mremap/.gitignore b/testcases/kernel/syscalls/mremap/.gitignore
index ec15a19cd..292899e03 100644
--- a/testcases/kernel/syscalls/mremap/.gitignore
+++ b/testcases/kernel/syscalls/mremap/.gitignore
@@ -4,3 +4,4 @@
 /mremap04
 /mremap05
 /mremap06
+/mremap07
diff --git a/testcases/kernel/syscalls/mremap/mremap07.c b/testcases/kernel/syscalls/mremap/mremap07.c
new file mode 100644
index 000000000..084803775
--- /dev/null
+++ b/testcases/kernel/syscalls/mremap/mremap07.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Wei Gao <wegao@suse.com>
+ */
+
+/*\
+ * LTP test case for mremap() with MREMAP_DONTUNMAP and userfaultfd.
+ *
+ * This test verifies a fault is triggered on the old memory region
+ * and is then correctly handled by a userfaultfd handler.
+ */
+
+#define _GNU_SOURCE
+#include <poll.h>
+#include <pthread.h>
+
+#include "tst_test.h"
+#include "tst_safe_pthread.h"
+#include "lapi/userfaultfd.h"
+
+static int page_size;
+static int uffd;
+static char *fault_addr;
+static char *new_remap_addr;
+
+static const char *test_string = "Hello, world! This is a test string that fills up a page.";
+
+static int sys_userfaultfd(int flags)
+{
+	return tst_syscall(__NR_userfaultfd, flags);
+}
+
+static void fault_handler_thread(void)
+{
+	struct uffd_msg msg;
+	struct uffdio_copy uffdio_copy;
+
+	TST_CHECKPOINT_WAIT(0);
+
+	struct pollfd pollfd;
+
+	pollfd.fd = uffd;
+	pollfd.events = POLLIN;
+
+	int nready = poll(&pollfd, 1, -1);
+
+	if (nready <= 0)
+		tst_brk(TBROK | TERRNO, "Poll on uffd failed");
+
+	SAFE_READ(1, uffd, &msg, sizeof(msg));
+
+	if (msg.event != UFFD_EVENT_PAGEFAULT)
+		tst_brk(TBROK, "Received unexpected UFFD_EVENT: %d", msg.event);
+
+	if ((char *)msg.arg.pagefault.address != fault_addr)
+		tst_brk(TBROK, "Page fault on unexpected address: %p", (void *)msg.arg.pagefault.address);
+
+	tst_res(TINFO, "Userfaultfd handler caught a page fault at %p", (void *)msg.arg.pagefault.address);
+
+	uffdio_copy.src = (unsigned long)new_remap_addr;
+	uffdio_copy.dst = (unsigned long)fault_addr;
+	uffdio_copy.len = page_size;
+	uffdio_copy.mode = 0;
+	uffdio_copy.copy = 0;
+
+	SAFE_IOCTL(uffd, UFFDIO_COPY, &uffdio_copy);
+	tst_res(TPASS, "Userfaultfd handler successfully handled the fault.");
+}
+
+static void setup(void)
+{
+	page_size = getpagesize();
+	struct uffdio_api uffdio_api;
+	struct uffdio_register uffdio_register;
+
+	TEST(sys_userfaultfd(O_CLOEXEC | O_NONBLOCK));
+	if (TST_RET == -1) {
+		if (TST_ERR == EPERM) {
+			tst_res(TCONF, "Hint: check /proc/sys/vm/unprivileged_userfaultfd");
+			tst_brk(TCONF | TTERRNO, "userfaultfd() requires CAP_SYS_PTRACE on this system");
+		} else {
+			tst_brk(TBROK | TTERRNO, "Could not create userfault file descriptor");
+		}
+	}
+
+	uffd = TST_RET;
+	uffdio_api.api = UFFD_API;
+	uffdio_api.features = 0;
+	SAFE_IOCTL(uffd, UFFDIO_API, &uffdio_api);
+
+	fault_addr = SAFE_MMAP(NULL, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+	tst_res(TINFO, "Original mapping created at %p", (void *)fault_addr);
+
+	strcpy(fault_addr, "ABCD");
+
+	uffdio_register.range.start = (unsigned long)fault_addr;
+	uffdio_register.range.len = page_size;
+	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
+	SAFE_IOCTL(uffd, UFFDIO_REGISTER, &uffdio_register);
+}
+
+static void cleanup(void)
+{
+	if (new_remap_addr != NULL)
+		SAFE_MUNMAP(new_remap_addr, page_size);
+
+	if (fault_addr != NULL)
+		SAFE_MUNMAP(fault_addr, page_size);
+
+	if (uffd != -1)
+		SAFE_CLOSE(uffd);
+}
+
+static void run(void)
+{
+	pthread_t handler_thread;
+
+	SAFE_PTHREAD_CREATE(&handler_thread, NULL,
+		(void * (*)(void *))fault_handler_thread, NULL);
+
+	new_remap_addr = mremap(fault_addr, page_size, page_size, MREMAP_DONTUNMAP | MREMAP_MAYMOVE);
+	if (new_remap_addr == MAP_FAILED)
+		tst_brk(TBROK | TTERRNO, "mremap failed");
+
+	tst_res(TINFO, "New mapping created at %p", (void *)new_remap_addr);
+
+	strcpy(new_remap_addr, test_string);
+
+	TST_CHECKPOINT_WAKE(0);
+
+	tst_res(TINFO, "Main thread accessing old address %p to trigger fault. Access Content is \"%s\"",
+			(void *)fault_addr, fault_addr);
+
+	SAFE_PTHREAD_JOIN(handler_thread, NULL);
+
+	if (strcmp(fault_addr, test_string) != 0)
+		tst_res(TFAIL, "Verification failed: Content at old address is '%s', expected '%s'", fault_addr, test_string);
+	else
+		tst_res(TPASS, "Verification passed: Content at old address is correct after fault handling.");
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.needs_checkpoints = 1,
+	.cleanup = cleanup,
+	.needs_root = 1,
+	.needs_kconfigs = (const char *[]) {
+		"CONFIG_USERFAULTFD=y",
+		NULL,
+	},
+	.min_kver = "5.7",
+};
-- 
2.43.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2026-04-22  2:31 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-27 23:02 [LTP] [PATCH v1] mremap07.c: New case check mremap with MREMAP_DONTUNMAP Wei Gao via ltp
2025-10-15  3:15 ` [LTP] [PATCH v2] " Wei Gao via ltp
2025-10-16 13:32   ` Petr Vorel
2025-10-17  7:51     ` Wei Gao via ltp
2025-10-30 19:39       ` Petr Vorel
2025-11-01  8:47         ` Wei Gao via ltp
2025-10-30  5:40   ` [LTP] [PATCH v3] " Wei Gao via ltp
2025-10-30 20:07     ` Petr Vorel
2026-02-25  9:05     ` [LTP] [PATCH v4] " Wei Gao via ltp
2026-03-23  7:03       ` Andrea Cervesato via ltp
2026-03-25  1:15       ` [LTP] [PATCH v5] " Wei Gao via ltp
2026-03-26 10:01         ` Andrea Cervesato via ltp
2026-04-10  2:31         ` [LTP] [PATCH v6] " Wei Gao via ltp
2026-04-17  6:53           ` [LTP] [PATCH v7] mremap07.c: New test for mremap() " Wei Gao via ltp
2026-04-17  7:55             ` [LTP] " linuxtestproject.agent
2026-04-17  8:00               ` Andrea Cervesato via ltp
2026-04-17 12:27             ` [LTP] [PATCH v8] " Wei Gao via ltp
2026-04-17 13:26               ` [LTP] " linuxtestproject.agent
2026-04-19  1:22                 ` Wei Gao via ltp
2026-04-20 10:12               ` [LTP] [PATCH v8] " Li Wang
2026-04-21  8:20                 ` Wei Gao via ltp
2026-04-21  9:11                   ` Li Wang
2026-04-22  2:30               ` [LTP] [PATCH v9] " Wei Gao via ltp

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.