diff mbox series

[11/14] selftests/mm: Use sys_pkey helpers consistently

Message ID 20241209095019.1732120-12-kevin.brodsky@arm.com
State New
Headers show
Series pkeys kselftests improvements | expand

Commit Message

Kevin Brodsky Dec. 9, 2024, 9:50 a.m. UTC
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}.

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 tools/testing/selftests/mm/Makefile           |  4 +-
 tools/testing/selftests/mm/pkey-helpers.h     |  2 +
 .../selftests/mm/pkey_sighandler_tests.c      |  8 ++--
 tools/testing/selftests/mm/pkey_util.c        | 40 +++++++++++++++++++
 tools/testing/selftests/mm/protection_keys.c  | 35 ----------------
 5 files changed, 48 insertions(+), 41 deletions(-)
 create mode 100644 tools/testing/selftests/mm/pkey_util.c

Comments

Alexander Gordeev Dec. 15, 2024, 10:09 p.m. UTC | #1
On Mon, Dec 09, 2024 at 09:50:16AM +0000, Kevin Brodsky wrote:

Hi Kevin, Andrew,

> diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
> index 814b17a43385..1f0743d9459d 100644
> --- a/tools/testing/selftests/mm/Makefile
> +++ b/tools/testing/selftests/mm/Makefile
> @@ -147,8 +147,8 @@ TEST_FILES += write_hugetlb_memory.sh
>  
>  include ../lib.mk
>  
> -$(TEST_GEN_PROGS): vm_util.c thp_settings.c
> -$(TEST_GEN_FILES): vm_util.c thp_settings.c
> +$(TEST_GEN_PROGS): vm_util.c thp_settings.c pkey_util.c
> +$(TEST_GEN_FILES): vm_util.c thp_settings.c pkey_util.c

This patch breaks s390 in -next with the below error messages:

In file included from pkey_util.c:5:
pkey-helpers.h:109:2: error: #error Architecture not supported
  109 | #error Architecture not supported
      |  ^~~~~
pkey-helpers.h: In function ‘set_pkey_bits’:
pkey-helpers.h:126:21: error: implicit declaration of function ‘pkey_bit_position’ [-Wimplicit-function-declaration]
  126 |         u32 shift = pkey_bit_position(pkey);
      |                     ^~~~~~~~~~~~~~~~~
pkey-helpers.h: In function ‘_read_pkey_reg’:
pkey-helpers.h:151:24: error: implicit declaration of function ‘__read_pkey_reg’; did you mean ‘_read_pkey_reg’? [-Wimplicit-function-declaration]
  151 |         u64 pkey_reg = __read_pkey_reg();
      |                        ^~~~~~~~~~~~~~~
      |                        _read_pkey_reg
pkey-helpers.h: In function ‘write_pkey_reg’:
pkey-helpers.h:165:18: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 3 has type ‘int’ [-Wformat=]
  165 |         dprintf4("%s() changing %016llx to %016llx\n", __func__,
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  166 |                         __read_pkey_reg(), pkey_reg);
      |                         ~~~~~~~~~~~~~~~~~
      |                         |
      |                         int
pkey-helpers.h:62:32: note: in definition of macro ‘dprintf_level’
   62 |                 sigsafe_printf(args);           \
      |                                ^~~~
pkey-helpers.h:165:9: note: in expansion of macro ‘dprintf4’
  165 |         dprintf4("%s() changing %016llx to %016llx\n", __func__,
      |         ^~~~~~~~
pkey-helpers.h:165:39: note: format string is defined here
  165 |         dprintf4("%s() changing %016llx to %016llx\n", __func__,
      |                                 ~~~~~~^
      |                                       |
      |                                       long long unsigned int
      |                                 %016x
pkey-helpers.h:169:9: error: implicit declaration of function ‘__write_pkey_reg’; did you mean ‘write_pkey_reg’? [-Wimplicit-function-declaration]
  169 |         __write_pkey_reg(pkey_reg);
      |         ^~~~~~~~~~~~~~~~
      |         write_pkey_reg
pkey-helpers.h:171:18: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 4 has type ‘int’ [-Wformat=]
  171 |         dprintf4("%s(%016llx) pkey_reg: %016llx\n", __func__,
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  172 |                         pkey_reg, __read_pkey_reg());
      |                                   ~~~~~~~~~~~~~~~~~
      |                                   |
      |                                   int
pkey-helpers.h:62:32: note: in definition of macro ‘dprintf_level’
   62 |                 sigsafe_printf(args);           \
      |                                ^~~~
pkey-helpers.h:171:9: note: in expansion of macro ‘dprintf4’
  171 |         dprintf4("%s(%016llx) pkey_reg: %016llx\n", __func__,
      |         ^~~~~~~~
pkey-helpers.h:171:47: note: format string is defined here
  171 |         dprintf4("%s(%016llx) pkey_reg: %016llx\n", __func__,
      |                                         ~~~~~~^
      |                                               |
      |                                               long long unsigned int
      |                                         %016x
pkey-helpers.h: In function ‘is_pkeys_supported’:
pkey-helpers.h:207:14: error: implicit declaration of function ‘cpu_has_pkeys’; did you mean ‘kernel_has_pkeys’? [-Wimplicit-function-declaration]
  207 |         if (!cpu_has_pkeys()) {
      |              ^~~~~~~~~~~~~
      |              kernel_has_pkeys

Please, let me know if I am missing something.

>  $(OUTPUT)/uffd-stress: uffd-common.c
>  $(OUTPUT)/uffd-unit-tests: uffd-common.c

Thanks!
diff mbox series

Patch

diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index 814b17a43385..1f0743d9459d 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -147,8 +147,8 @@  TEST_FILES += write_hugetlb_memory.sh
 
 include ../lib.mk
 
-$(TEST_GEN_PROGS): vm_util.c thp_settings.c
-$(TEST_GEN_FILES): vm_util.c thp_settings.c
+$(TEST_GEN_PROGS): vm_util.c thp_settings.c pkey_util.c
+$(TEST_GEN_FILES): vm_util.c thp_settings.c pkey_util.c
 
 $(OUTPUT)/uffd-stress: uffd-common.c
 $(OUTPUT)/uffd-unit-tests: uffd-common.c
diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index 6f0ab7b42738..f080e97b39be 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -89,6 +89,8 @@  extern void abort_hooks(void);
 
 int sys_pkey_alloc(unsigned long flags, unsigned long init_val);
 int sys_pkey_free(unsigned long pkey);
+int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
+		unsigned long pkey);
 
 /* For functions called from protection_keys.c only */
 noinline int read_ptr(int *ptr);
diff --git a/tools/testing/selftests/mm/pkey_sighandler_tests.c b/tools/testing/selftests/mm/pkey_sighandler_tests.c
index e1aaeb65cfae..c73cee192b88 100644
--- a/tools/testing/selftests/mm/pkey_sighandler_tests.c
+++ b/tools/testing/selftests/mm/pkey_sighandler_tests.c
@@ -311,8 +311,8 @@  static void test_sigsegv_handler_with_different_pkey_for_stack(void)
 	__write_pkey_reg(pkey_reg);
 
 	/* Protect the new stack with MPK 1 */
-	pkey = pkey_alloc(0, 0);
-	pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
+	pkey = sys_pkey_alloc(0, 0);
+	sys_mprotect_pkey(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
 
 	/* Set up alternate signal stack that will use the default MPK */
 	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
@@ -484,8 +484,8 @@  static void test_pkru_sigreturn(void)
 	__write_pkey_reg(pkey_reg);
 
 	/* Protect the stack with MPK 2 */
-	pkey = pkey_alloc(0, 0);
-	pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
+	pkey = sys_pkey_alloc(0, 0);
+	sys_mprotect_pkey(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);
 
 	/* Set up alternate signal stack that will use the default MPK */
 	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
diff --git a/tools/testing/selftests/mm/pkey_util.c b/tools/testing/selftests/mm/pkey_util.c
new file mode 100644
index 000000000000..ca4ad0d44ab2
--- /dev/null
+++ b/tools/testing/selftests/mm/pkey_util.c
@@ -0,0 +1,40 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#include "pkey-helpers.h"
+
+int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
+{
+	int ret = syscall(SYS_pkey_alloc, flags, init_val);
+	dprintf1("%s(flags=%lx, init_val=%lx) syscall ret: %d errno: %d\n",
+			__func__, flags, init_val, ret, errno);
+	return ret;
+}
+
+int sys_pkey_free(unsigned long pkey)
+{
+	int ret = syscall(SYS_pkey_free, pkey);
+	dprintf1("%s(pkey=%ld) syscall ret: %d\n", __func__, pkey, ret);
+	return ret;
+}
+
+int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
+		unsigned long pkey)
+{
+	int sret;
+
+	dprintf2("%s(0x%p, %zx, prot=%lx, pkey=%lx)\n", __func__,
+			ptr, size, orig_prot, pkey);
+
+	errno = 0;
+	sret = syscall(__NR_pkey_mprotect, ptr, size, orig_prot, pkey);
+	if (errno) {
+		dprintf2("SYS_mprotect_key sret: %d\n", sret);
+		dprintf2("SYS_mprotect_key prot: 0x%lx\n", orig_prot);
+		dprintf2("SYS_mprotect_key failed, errno: %d\n", errno);
+		if (DEBUG_LEVEL >= 2)
+			perror("SYS_mprotect_pkey");
+	}
+	return sret;
+}
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index f43cf3b75d8e..3688571e6b39 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -460,34 +460,6 @@  static pid_t fork_lazy_child(void)
 	return forkret;
 }
 
-int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
-		unsigned long pkey)
-{
-	int sret;
-
-	dprintf2("%s(0x%p, %zx, prot=%lx, pkey=%lx)\n", __func__,
-			ptr, size, orig_prot, pkey);
-
-	errno = 0;
-	sret = syscall(__NR_pkey_mprotect, ptr, size, orig_prot, pkey);
-	if (errno) {
-		dprintf2("SYS_mprotect_key sret: %d\n", sret);
-		dprintf2("SYS_mprotect_key prot: 0x%lx\n", orig_prot);
-		dprintf2("SYS_mprotect_key failed, errno: %d\n", errno);
-		if (DEBUG_LEVEL >= 2)
-			perror("SYS_mprotect_pkey");
-	}
-	return sret;
-}
-
-int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
-{
-	int ret = syscall(SYS_pkey_alloc, flags, init_val);
-	dprintf1("%s(flags=%lx, init_val=%lx) syscall ret: %d errno: %d\n",
-			__func__, flags, init_val, ret, errno);
-	return ret;
-}
-
 static int alloc_pkey(void)
 {
 	int ret;
@@ -534,13 +506,6 @@  static int alloc_pkey(void)
 	return ret;
 }
 
-int sys_pkey_free(unsigned long pkey)
-{
-	int ret = syscall(SYS_pkey_free, pkey);
-	dprintf1("%s(pkey=%ld) syscall ret: %d\n", __func__, pkey, ret);
-	return ret;
-}
-
 /*
  * I had a bug where pkey bits could be set by mprotect() but
  * not cleared.  This ensures we get lots of random bit sets