Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Kevin Brodsky and committed by
Catalin Marinas
49f59573 6e182dc9

+50 -20
+4 -4
tools/testing/selftests/mm/Makefile
··· 105 105 ifeq ($(CAN_BUILD_X86_64),1) 106 106 TEST_GEN_FILES += $(BINARIES_64) 107 107 endif 108 - else 109 108 110 - ifneq (,$(filter $(ARCH),arm64 powerpc)) 109 + else ifeq ($(ARCH),arm64) 111 110 TEST_GEN_FILES += protection_keys 112 - endif 113 - 111 + TEST_GEN_FILES += pkey_sighandler_tests 112 + else ifeq ($(ARCH),powerpc) 113 + TEST_GEN_FILES += protection_keys 114 114 endif 115 115 116 116 ifneq (,$(filter $(ARCH),arm64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64 s390))
+46 -16
tools/testing/selftests/mm/pkey_sighandler_tests.c
··· 60 60 : "=a"(ret) 61 61 : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) 62 62 : "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; 63 76 #else 64 77 # error syscall_raw() not implemented 65 78 #endif 66 79 return ret; 80 + } 81 + 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); 67 99 } 68 100 69 101 /* ··· 326 294 memset(&siginfo, 0, sizeof(siginfo)); 327 295 328 296 /* Use clone to avoid newer glibcs using rseq on new threads */ 329 - long ret = syscall_raw(SYS_clone, 330 - CLONE_VM | CLONE_FS | CLONE_FILES | 331 - CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | 332 - CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | 333 - CLONE_DETACHED, 334 - (long) ((char *)(stack) + STACK_SIZE), 335 - (long) &parent_pid, 336 - (long) &child_pid, 0, 0); 297 + long ret = clone_raw(CLONE_VM | CLONE_FS | CLONE_FILES | 298 + CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | 299 + CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | 300 + CLONE_DETACHED, 301 + stack + STACK_SIZE, 302 + &parent_pid, 303 + &child_pid); 337 304 338 305 if (ret < 0) { 339 306 errno = -ret; ··· 497 466 sigstack.ss_size = STACK_SIZE; 498 467 499 468 /* Use clone to avoid newer glibcs using rseq on new threads */ 500 - long ret = syscall_raw(SYS_clone, 501 - CLONE_VM | CLONE_FS | CLONE_FILES | 502 - CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | 503 - CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | 504 - CLONE_DETACHED, 505 - (long) ((char *)(stack) + STACK_SIZE), 506 - (long) &parent_pid, 507 - (long) &child_pid, 0, 0); 469 + long ret = clone_raw(CLONE_VM | CLONE_FS | CLONE_FILES | 470 + CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | 471 + CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | 472 + CLONE_DETACHED, 473 + stack + STACK_SIZE, 474 + &parent_pid, 475 + &child_pid); 508 476 509 477 if (ret < 0) { 510 478 errno = -ret;