Re: [PATCH 15/14] selftests: futex: Add tests for robust unlock within the critical section.
From: André Almeida
Date: Fri May 22 2026 - 18:21:06 EST
Em 04/04/2026 06:39, Sebastian Andrzej Siewior escreveu:
From: Sebastian Andrzej Siewior <sebastian@xxxxxxxxxxxxx>
I took Thomas’ initial test case from the cover letter and reworked it
so that it uses ptrace() to single‑step through the VDSO unlock
operation. The test expects the lock to remain locked, with
`list_op_pending' pointing somewhere, when entering the VDSO unlock
path. Once execution steps into the critical section, it expects the
kernel to perform the fixup that is, to unlock the lock and clear
`list_op_pending'.
The test requires VDSO debug symbols, typically provided by
vdso64.so.dbg or vdso32.so.dbg. It attempts to locate the appropriate
file automatically, but the user may override this by setting the
VDSO_DBG environment variable. If neither method succeeds, libelf falls
back to its usual lookup mechanism under /usr/lib/debug/.build-id/
Tested on x86 and arm64 and it worked, thanks!
Signed-off-by: Sebastian Andrzej Siewior <sebastian@xxxxxxxxxxxxx>
---
.../selftests/futex/functional/Makefile | 3 +-
.../futex/functional/robust_list_critical.c | 402 ++++++++++++++++++
2 files changed, 404 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/futex/functional/robust_list_critical.c
Missing the addition to .gitignore.
[...]
+static bool pc_is_within(struct user_regs_struct *regs, uint64_t start, uint64_t end)
+{
+ unsigned long pc;
+
+#if defined(__x86_64__)
+ pc = regs->rip;
+#elif defined(__riscv)
+ pc = reg->pc;
I think this should be regs as well.
And this is what I changed to make it work with arm64:
---
.../futex/functional/robust_list_critical.c | 24 +++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/futex/functional/robust_list_critical.c b/tools/testing/selftests/futex/functional/robust_list_critical.c
index b9490d24eb10..89062c921054 100644
--- a/tools/testing/selftests/futex/functional/robust_list_critical.c
+++ b/tools/testing/selftests/futex/functional/robust_list_critical.c
@@ -67,6 +67,9 @@ static bool pc_is_within(struct user_regs_struct *regs, uint64_t start, uint64_t
pc = regs->rip;
#elif defined(__riscv)
pc = reg->pc;
+#elif defined(__aarch64__)
+ pc = regs->pc;
+#else
# error Missing ptrace support
#endif
if (pc >= (long) start && pc < end)
@@ -219,6 +222,23 @@ enum trace_state {
STATE_LEAVE_VDSO,
};
+static int ptrace_get_regs(struct user_regs_struct *regs, pid_t child)
+{
+#if defined(__x86_64__)
+
+ return ptrace(PTRACE_GETREGS, child, 0, regs);
+
+#elif defined(__aarch64__)
+
+ struct iovec io;
+ io.iov_base = regs;
+ io.iov_len = sizeof(struct user_regs_struct);
+
+ return ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, &io);
+
+#endif
+}
+
static void trace_child(struct __test_metadata *_metadata, pid_t child, bool is_32bit)
{
int state = STATE_WAIT;
@@ -247,8 +267,8 @@ static void trace_child(struct __test_metadata *_metadata, pid_t child, bool is_
return;
}
- if (ptrace(PTRACE_GETREGS, child, 0, ®s) != 0)
- errx(1, "PTRACE_GETREGS");
+ if (ptrace_get_regs(®s, child) == -1)
+ errx(1, "ptrace_get_regs");
if (is_32bit) {
in_vdso = pc_is_within(®s, (long)frtu32, frtu32_end);
--
2.54.0