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>
This commit is contained in:
Kevin Brodsky 2024-10-29 14:45:39 +00:00 committed by Catalin Marinas
parent 6e182dc9f2
commit 49f59573e9
2 changed files with 50 additions and 20 deletions

View File

@ -105,12 +105,12 @@ endif
ifeq ($(CAN_BUILD_X86_64),1)
TEST_GEN_FILES += $(BINARIES_64)
endif
else
ifneq (,$(filter $(ARCH),arm64 powerpc))
else ifeq ($(ARCH),arm64)
TEST_GEN_FILES += protection_keys
TEST_GEN_FILES += pkey_sighandler_tests
else ifeq ($(ARCH),powerpc)
TEST_GEN_FILES += protection_keys
endif
endif
ifneq (,$(filter $(ARCH),arm64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64 s390))

View File

@ -60,12 +60,44 @@ long syscall_raw(long n, long a1, long a2, long a3, long a4, long a5, long a6)
: "=a"(ret)
: "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5)
: "memory");
#elif defined __aarch64__
register long x0 asm("x0") = a1;
register long x1 asm("x1") = a2;
register long x2 asm("x2") = a3;
register long x3 asm("x3") = a4;
register long x4 asm("x4") = a5;
register long x5 asm("x5") = a6;
register long x8 asm("x8") = n;
asm volatile ("svc #0"
: "=r"(x0)
: "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5), "r"(x8)
: "memory");
ret = x0;
#else
# error syscall_raw() not implemented
#endif
return ret;
}
static inline long clone_raw(unsigned long flags, void *stack,
int *parent_tid, int *child_tid)
{
long a1 = flags;
long a2 = (long)stack;
long a3 = (long)parent_tid;
#if defined(__x86_64__) || defined(__i386)
long a4 = (long)child_tid;
long a5 = 0;
#elif defined(__aarch64__)
long a4 = 0;
long a5 = (long)child_tid;
#else
# error clone_raw() not implemented
#endif
return syscall_raw(SYS_clone, a1, a2, a3, a4, a5, 0);
}
/*
* Returns the most restrictive pkey register value that can be used by the
* tests.
@ -294,14 +326,13 @@ static void test_sigsegv_handler_with_different_pkey_for_stack(void)
memset(&siginfo, 0, sizeof(siginfo));
/* Use clone to avoid newer glibcs using rseq on new threads */
long ret = syscall_raw(SYS_clone,
CLONE_VM | CLONE_FS | CLONE_FILES |
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
CLONE_DETACHED,
(long) ((char *)(stack) + STACK_SIZE),
(long) &parent_pid,
(long) &child_pid, 0, 0);
long ret = clone_raw(CLONE_VM | CLONE_FS | CLONE_FILES |
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
CLONE_DETACHED,
stack + STACK_SIZE,
&parent_pid,
&child_pid);
if (ret < 0) {
errno = -ret;
@ -466,14 +497,13 @@ static void test_pkru_sigreturn(void)
sigstack.ss_size = STACK_SIZE;
/* Use clone to avoid newer glibcs using rseq on new threads */
long ret = syscall_raw(SYS_clone,
CLONE_VM | CLONE_FS | CLONE_FILES |
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
CLONE_DETACHED,
(long) ((char *)(stack) + STACK_SIZE),
(long) &parent_pid,
(long) &child_pid, 0, 0);
long ret = clone_raw(CLONE_VM | CLONE_FS | CLONE_FILES |
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
CLONE_DETACHED,
stack + STACK_SIZE,
&parent_pid,
&child_pid);
if (ret < 0) {
errno = -ret;