Skip to content

Commit 49f5957

Browse files
kevin-brodsky-armctmarinas
authored andcommitted
selftests/mm: Enable pkey_sighandler_tests on arm64
pkey_sighandler_tests.c makes raw syscalls using its own helper, syscall_raw(). One of those syscalls is clone, which is problematic as every architecture has a different opinion on the order of its arguments. To complete arm64 support, we therefore add an appropriate implementation in syscall_raw(), and introduce a clone_raw() helper that shuffles arguments as needed for each arch. Having done this, we enable building pkey_sighandler_tests for arm64 in the Makefile. Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com> Link: https://lore.kernel.org/r/20241029144539.111155-6-kevin.brodsky@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent 6e182dc commit 49f5957

File tree

2 files changed

+50
-20
lines changed

2 files changed

+50
-20
lines changed

tools/testing/selftests/mm/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ endif
105105
ifeq ($(CAN_BUILD_X86_64),1)
106106
TEST_GEN_FILES += $(BINARIES_64)
107107
endif
108-
else
109108

110-
ifneq (,$(filter $(ARCH),arm64 powerpc))
109+
else ifeq ($(ARCH),arm64)
110+
TEST_GEN_FILES += protection_keys
111+
TEST_GEN_FILES += pkey_sighandler_tests
112+
else ifeq ($(ARCH),powerpc)
111113
TEST_GEN_FILES += protection_keys
112-
endif
113-
114114
endif
115115

116116
ifneq (,$(filter $(ARCH),arm64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64 s390))

tools/testing/selftests/mm/pkey_sighandler_tests.c

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,44 @@ long syscall_raw(long n, long a1, long a2, long a3, long a4, long a5, long a6)
6060
: "=a"(ret)
6161
: "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5)
6262
: "memory");
63+
#elif defined __aarch64__
64+
register long x0 asm("x0") = a1;
65+
register long x1 asm("x1") = a2;
66+
register long x2 asm("x2") = a3;
67+
register long x3 asm("x3") = a4;
68+
register long x4 asm("x4") = a5;
69+
register long x5 asm("x5") = a6;
70+
register long x8 asm("x8") = n;
71+
asm volatile ("svc #0"
72+
: "=r"(x0)
73+
: "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5), "r"(x8)
74+
: "memory");
75+
ret = x0;
6376
#else
6477
# error syscall_raw() not implemented
6578
#endif
6679
return ret;
6780
}
6881

82+
static inline long clone_raw(unsigned long flags, void *stack,
83+
int *parent_tid, int *child_tid)
84+
{
85+
long a1 = flags;
86+
long a2 = (long)stack;
87+
long a3 = (long)parent_tid;
88+
#if defined(__x86_64__) || defined(__i386)
89+
long a4 = (long)child_tid;
90+
long a5 = 0;
91+
#elif defined(__aarch64__)
92+
long a4 = 0;
93+
long a5 = (long)child_tid;
94+
#else
95+
# error clone_raw() not implemented
96+
#endif
97+
98+
return syscall_raw(SYS_clone, a1, a2, a3, a4, a5, 0);
99+
}
100+
69101
/*
70102
* Returns the most restrictive pkey register value that can be used by the
71103
* tests.
@@ -294,14 +326,13 @@ static void test_sigsegv_handler_with_different_pkey_for_stack(void)
294326
memset(&siginfo, 0, sizeof(siginfo));
295327

296328
/* Use clone to avoid newer glibcs using rseq on new threads */
297-
long ret = syscall_raw(SYS_clone,
298-
CLONE_VM | CLONE_FS | CLONE_FILES |
299-
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
300-
CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
301-
CLONE_DETACHED,
302-
(long) ((char *)(stack) + STACK_SIZE),
303-
(long) &parent_pid,
304-
(long) &child_pid, 0, 0);
329+
long ret = clone_raw(CLONE_VM | CLONE_FS | CLONE_FILES |
330+
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
331+
CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
332+
CLONE_DETACHED,
333+
stack + STACK_SIZE,
334+
&parent_pid,
335+
&child_pid);
305336

306337
if (ret < 0) {
307338
errno = -ret;
@@ -466,14 +497,13 @@ static void test_pkru_sigreturn(void)
466497
sigstack.ss_size = STACK_SIZE;
467498

468499
/* Use clone to avoid newer glibcs using rseq on new threads */
469-
long ret = syscall_raw(SYS_clone,
470-
CLONE_VM | CLONE_FS | CLONE_FILES |
471-
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
472-
CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
473-
CLONE_DETACHED,
474-
(long) ((char *)(stack) + STACK_SIZE),
475-
(long) &parent_pid,
476-
(long) &child_pid, 0, 0);
500+
long ret = clone_raw(CLONE_VM | CLONE_FS | CLONE_FILES |
501+
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
502+
CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
503+
CLONE_DETACHED,
504+
stack + STACK_SIZE,
505+
&parent_pid,
506+
&child_pid);
477507

478508
if (ret < 0) {
479509
errno = -ret;

0 commit comments

Comments
 (0)