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

selftests/mm: use sys_pkey helpers consistently

sys_pkey_alloc, sys_pkey_free and sys_mprotect_pkey are currently used in
protections_keys.c, while pkey_sighandler_tests.c calls the libc wrappers
directly (e.g. pkey_mprotect()). This is probably ok when using glibc
(those symbols appeared a while ago), but Musl does not currently provide
them. The logging in the helpers from pkey-helpers.h can also come in
handy.

Make things more consistent by using the sys_pkey helpers in
pkey_sighandler_tests.c too. To that end their implementation is moved to
a common .c file (pkey_util.c). This also enables calling
is_pkeys_supported() outside of protections_keys.c, since it relies on
sys_pkey_{alloc,free}.

[kevin.brodsky@arm.com: fix dependency on pkey_util.c]
Link: https://lkml.kernel.org/r/20241216092849.2140850-1-kevin.brodsky@arm.com
Link: https://lkml.kernel.org/r/20241209095019.1732120-12-kevin.brodsky@arm.com
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Joey Gouly <joey.gouly@arm.com>
Cc: Keith Lucas <keith.lucas@oracle.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Kevin Brodsky and committed by
Andrew Morton
50910acd b0cc2984

+50 -39
+4
tools/testing/selftests/mm/Makefile
··· 158 158 159 159 $(OUTPUT)/uffd-stress: uffd-common.c 160 160 $(OUTPUT)/uffd-unit-tests: uffd-common.c 161 + $(OUTPUT)/protection_keys: pkey_util.c 162 + $(OUTPUT)/pkey_sighandler_tests: pkey_util.c 161 163 162 164 ifeq ($(ARCH),x86_64) 163 165 BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32)) 164 166 BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64)) 167 + 168 + $(BINARIES_32) $(BINARIES_64): pkey_util.c 165 169 166 170 define gen-target-rule-32 167 171 $(1) $(1)_32: $(OUTPUT)/$(1)_32
+2
tools/testing/selftests/mm/pkey-helpers.h
··· 89 89 90 90 int sys_pkey_alloc(unsigned long flags, unsigned long init_val); 91 91 int sys_pkey_free(unsigned long pkey); 92 + int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot, 93 + unsigned long pkey); 92 94 93 95 /* For functions called from protection_keys.c only */ 94 96 noinline int read_ptr(int *ptr);
+4 -4
tools/testing/selftests/mm/pkey_sighandler_tests.c
··· 311 311 __write_pkey_reg(pkey_reg); 312 312 313 313 /* Protect the new stack with MPK 1 */ 314 - pkey = pkey_alloc(0, 0); 315 - pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey); 314 + pkey = sys_pkey_alloc(0, 0); 315 + sys_mprotect_pkey(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey); 316 316 317 317 /* Set up alternate signal stack that will use the default MPK */ 318 318 sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, ··· 484 484 __write_pkey_reg(pkey_reg); 485 485 486 486 /* Protect the stack with MPK 2 */ 487 - pkey = pkey_alloc(0, 0); 488 - pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey); 487 + pkey = sys_pkey_alloc(0, 0); 488 + sys_mprotect_pkey(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey); 489 489 490 490 /* Set up alternate signal stack that will use the default MPK */ 491 491 sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
+40
tools/testing/selftests/mm/pkey_util.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + #include <sys/syscall.h> 3 + #include <unistd.h> 4 + 5 + #include "pkey-helpers.h" 6 + 7 + int sys_pkey_alloc(unsigned long flags, unsigned long init_val) 8 + { 9 + int ret = syscall(SYS_pkey_alloc, flags, init_val); 10 + dprintf1("%s(flags=%lx, init_val=%lx) syscall ret: %d errno: %d\n", 11 + __func__, flags, init_val, ret, errno); 12 + return ret; 13 + } 14 + 15 + int sys_pkey_free(unsigned long pkey) 16 + { 17 + int ret = syscall(SYS_pkey_free, pkey); 18 + dprintf1("%s(pkey=%ld) syscall ret: %d\n", __func__, pkey, ret); 19 + return ret; 20 + } 21 + 22 + int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot, 23 + unsigned long pkey) 24 + { 25 + int sret; 26 + 27 + dprintf2("%s(0x%p, %zx, prot=%lx, pkey=%lx)\n", __func__, 28 + ptr, size, orig_prot, pkey); 29 + 30 + errno = 0; 31 + sret = syscall(__NR_pkey_mprotect, ptr, size, orig_prot, pkey); 32 + if (errno) { 33 + dprintf2("SYS_mprotect_key sret: %d\n", sret); 34 + dprintf2("SYS_mprotect_key prot: 0x%lx\n", orig_prot); 35 + dprintf2("SYS_mprotect_key failed, errno: %d\n", errno); 36 + if (DEBUG_LEVEL >= 2) 37 + perror("SYS_mprotect_pkey"); 38 + } 39 + return sret; 40 + }
-35
tools/testing/selftests/mm/protection_keys.c
··· 460 460 return forkret; 461 461 } 462 462 463 - int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot, 464 - unsigned long pkey) 465 - { 466 - int sret; 467 - 468 - dprintf2("%s(0x%p, %zx, prot=%lx, pkey=%lx)\n", __func__, 469 - ptr, size, orig_prot, pkey); 470 - 471 - errno = 0; 472 - sret = syscall(__NR_pkey_mprotect, ptr, size, orig_prot, pkey); 473 - if (errno) { 474 - dprintf2("SYS_mprotect_key sret: %d\n", sret); 475 - dprintf2("SYS_mprotect_key prot: 0x%lx\n", orig_prot); 476 - dprintf2("SYS_mprotect_key failed, errno: %d\n", errno); 477 - if (DEBUG_LEVEL >= 2) 478 - perror("SYS_mprotect_pkey"); 479 - } 480 - return sret; 481 - } 482 - 483 - int sys_pkey_alloc(unsigned long flags, unsigned long init_val) 484 - { 485 - int ret = syscall(SYS_pkey_alloc, flags, init_val); 486 - dprintf1("%s(flags=%lx, init_val=%lx) syscall ret: %d errno: %d\n", 487 - __func__, flags, init_val, ret, errno); 488 - return ret; 489 - } 490 - 491 463 static int alloc_pkey(void) 492 464 { 493 465 int ret; ··· 503 531 " shadow: 0x%016llx\n", 504 532 __func__, __LINE__, ret, __read_pkey_reg(), 505 533 shadow_pkey_reg); 506 - return ret; 507 - } 508 - 509 - int sys_pkey_free(unsigned long pkey) 510 - { 511 - int ret = syscall(SYS_pkey_free, pkey); 512 - dprintf1("%s(pkey=%ld) syscall ret: %d\n", __func__, pkey, ret); 513 534 return ret; 514 535 } 515 536