From: Kevin Brodsky <kevin.brodsky@arm.com>
To: linux-arm-kernel@lists.infradead.org
Cc: Kevin Brodsky <kevin.brodsky@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Joey Gouly <joey.gouly@arm.com>, Mark Brown <broonie@kernel.org>,
Shuah Khan <shuah@kernel.org>, Will Deacon <will@kernel.org>,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [PATCH 2/2] kselftest/arm64: Add test for atomic futex uaccess with POE
Date: Thu, 21 May 2026 10:42:31 +0100 [thread overview]
Message-ID: <20260521-poe_futex-v1-2-1da286b8f9b2@arm.com> (raw)
In-Reply-To: <20260521-poe_futex-v1-0-1da286b8f9b2@arm.com>
Add a new test to ensure that atomic futex uaccess succeeds on
memory mapped with a non-default POIndex/pkey.
In the absence of FEAT_LSUI, atomic futex uaccess operations such as
those triggered by FUTEX_WAKE_OP use privileged atomic load/store
instructions and thus cannot have user permission overlays applied
(as per POR_EL0). In case the kernel enabled POE at EL1, it is worth
checking that PIR_EL1 isn't mistakenly configured to have kernel
overlays (POR_EL1) applied instead, as that would fail for non-zero
pkeys.
Note that if such misconfiguration occurs, futex_wake_op() may get
stuck in an infinite loop because futex_atomic_op_inuser() will fail
but fault_in_user_writeable() will still report success.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/arm64/Makefile | 2 +-
tools/testing/selftests/arm64/poe/.gitignore | 2 +
tools/testing/selftests/arm64/poe/Makefile | 6 +++
tools/testing/selftests/arm64/poe/poe_futex.c | 62 +++++++++++++++++++++++++++
4 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
index e456f3b62fa1..bad5c3b33dce 100644
--- a/tools/testing/selftests/arm64/Makefile
+++ b/tools/testing/selftests/arm64/Makefile
@@ -4,7 +4,7 @@
ARCH ?= $(shell uname -m 2>/dev/null || echo not)
ifneq (,$(filter $(ARCH),aarch64 arm64))
-ARM64_SUBTARGETS ?= tags signal pauth fp mte bti abi gcs
+ARM64_SUBTARGETS ?= tags signal pauth fp mte bti abi gcs poe
else
ARM64_SUBTARGETS :=
endif
diff --git a/tools/testing/selftests/arm64/poe/.gitignore b/tools/testing/selftests/arm64/poe/.gitignore
new file mode 100644
index 000000000000..0dce4a3aa38b
--- /dev/null
+++ b/tools/testing/selftests/arm64/poe/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+poe_futex
diff --git a/tools/testing/selftests/arm64/poe/Makefile b/tools/testing/selftests/arm64/poe/Makefile
new file mode 100644
index 000000000000..2af2bbf3f6d3
--- /dev/null
+++ b/tools/testing/selftests/arm64/poe/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+CFLAGS += $(KHDR_INCLUDES)
+TEST_GEN_PROGS := poe_futex
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/poe/poe_futex.c b/tools/testing/selftests/arm64/poe/poe_futex.c
new file mode 100644
index 000000000000..21a2e109ee43
--- /dev/null
+++ b/tools/testing/selftests/arm64/poe/poe_futex.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <linux/futex.h>
+#include <sys/syscall.h>
+
+#include "kselftest_harness.h"
+
+static int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
+{
+ return syscall(__NR_pkey_alloc, flags, init_val);
+}
+
+static int sys_pkey_mprotect(void *ptr, size_t size, int prot, int pkey)
+{
+ return syscall(__NR_pkey_mprotect, ptr, size, prot, pkey);
+}
+
+static int futex_wake_op(uint32_t *uaddr, uint32_t val, uint32_t val2,
+ uint32_t *uaddr2, uint32_t val3)
+{
+ return syscall(SYS_futex, uaddr, FUTEX_WAKE_OP, val, val2,
+ uaddr2, val3);
+}
+
+/*
+ * Trigger some atomic uaccess on a page mapped with a non-default pkey.
+ *
+ * This ensures that such access is not mistakenly checked against the
+ * kernel's POR_EL1 register.
+ */
+TEST(poe_futex)
+{
+ int ret, pkey;
+ void *ptr;
+ size_t size = getpagesize();
+
+ pkey = sys_pkey_alloc(0, 0);
+
+ if (pkey == -1 && errno == ENOSPC)
+ SKIP(return, "pkeys are not supported");
+
+ ASSERT_GT(pkey, 0);
+
+ ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ ASSERT_NE(ptr, MAP_FAILED);
+
+ ret = sys_pkey_mprotect(ptr, size, PROT_READ | PROT_WRITE, pkey);
+ ASSERT_EQ(ret, 0);
+
+ /*
+ * There is no one to wake up so this syscall boils down to *(ptr+4) = 0
+ * (arch_futex_atomic_op_inuser() called with FUTEX_OP_SET and op_arg=0).
+ */
+ ret = futex_wake_op(ptr, 1, 1, ptr + sizeof(uint32_t), 0);
+ ASSERT_EQ(ret, 0);
+}
+
+TEST_HARNESS_MAIN
--
2.51.2
next prev parent reply other threads:[~2026-05-21 9:42 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-21 9:42 [PATCH 0/2] Add test for atomic uaccess with permission overlay Kevin Brodsky
2026-05-21 9:42 ` [PATCH 1/2] arm64: mm: Add note about overlays in PIE_EL1 Kevin Brodsky
2026-05-21 9:48 ` Kevin Brodsky
2026-05-22 9:20 ` Yeoreum Yun
2026-05-21 9:42 ` Kevin Brodsky [this message]
2026-05-21 11:22 ` [PATCH 2/2] kselftest/arm64: Add test for atomic futex uaccess with POE Mark Brown
2026-05-21 12:01 ` Kevin Brodsky
2026-05-21 12:06 ` Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260521-poe_futex-v1-2-1da286b8f9b2@arm.com \
--to=kevin.brodsky@arm.com \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=joey.gouly@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=shuah@kernel.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®