selftests/powerpc: Move pkey helpers to headers
authorSandipan Das <sandipan@linux.ibm.com>
Mon, 27 Jul 2020 04:00:35 +0000 (09:30 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 29 Jul 2020 11:02:10 +0000 (21:02 +1000)
This moves all the pkey-related helpers to a new header
file and also a helper to print error messages in signal
handlers to the existing utils header file.

Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/28e633fa9ec1a6500c12188e09ea1887b10a10c1.1595821792.git.sandipan@linux.ibm.com
tools/testing/selftests/powerpc/include/pkeys.h [new file with mode: 0644]
tools/testing/selftests/powerpc/include/utils.h
tools/testing/selftests/powerpc/mm/pkey_exec_prot.c

diff --git a/tools/testing/selftests/powerpc/include/pkeys.h b/tools/testing/selftests/powerpc/include/pkeys.h
new file mode 100644 (file)
index 0000000..9b53a97
--- /dev/null
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020, Sandipan Das, IBM Corp.
+ */
+
+#ifndef _SELFTESTS_POWERPC_PKEYS_H
+#define _SELFTESTS_POWERPC_PKEYS_H
+
+#include <sys/mman.h>
+
+#include "reg.h"
+#include "utils.h"
+
+/*
+ * Older versions of libc use the Intel-specific access rights.
+ * Hence, override the definitions as they might be incorrect.
+ */
+#undef PKEY_DISABLE_ACCESS
+#define PKEY_DISABLE_ACCESS    0x3
+
+#undef PKEY_DISABLE_WRITE
+#define PKEY_DISABLE_WRITE     0x2
+
+#undef PKEY_DISABLE_EXECUTE
+#define PKEY_DISABLE_EXECUTE   0x4
+
+/* Older versions of libc do not not define this */
+#ifndef SEGV_PKUERR
+#define SEGV_PKUERR    4
+#endif
+
+#define SI_PKEY_OFFSET 0x20
+
+#define SYS_pkey_mprotect      386
+#define SYS_pkey_alloc         384
+#define SYS_pkey_free          385
+
+#define PKEY_BITS_PER_PKEY     2
+#define NR_PKEYS               32
+#define PKEY_BITS_MASK         ((1UL << PKEY_BITS_PER_PKEY) - 1)
+
+inline unsigned long pkeyreg_get(void)
+{
+       return mfspr(SPRN_AMR);
+}
+
+inline void pkeyreg_set(unsigned long amr)
+{
+       set_amr(amr);
+}
+
+void pkey_set_rights(int pkey, unsigned long rights)
+{
+       unsigned long amr, shift;
+
+       shift = (NR_PKEYS - pkey - 1) * PKEY_BITS_PER_PKEY;
+       amr = pkeyreg_get();
+       amr &= ~(PKEY_BITS_MASK << shift);
+       amr |= (rights & PKEY_BITS_MASK) << shift;
+       pkeyreg_set(amr);
+}
+
+int sys_pkey_mprotect(void *addr, size_t len, int prot, int pkey)
+{
+       return syscall(SYS_pkey_mprotect, addr, len, prot, pkey);
+}
+
+int sys_pkey_alloc(unsigned long flags, unsigned long rights)
+{
+       return syscall(SYS_pkey_alloc, flags, rights);
+}
+
+int sys_pkey_free(int pkey)
+{
+       return syscall(SYS_pkey_free, pkey);
+}
+
+int pkeys_unsupported(void)
+{
+       bool hash_mmu = false;
+       int pkey;
+
+       /* Protection keys are currently supported on Hash MMU only */
+       FAIL_IF(using_hash_mmu(&hash_mmu));
+       SKIP_IF(!hash_mmu);
+
+       /* Check if the system call is supported */
+       pkey = sys_pkey_alloc(0, 0);
+       SKIP_IF(pkey < 0);
+       sys_pkey_free(pkey);
+
+       return 0;
+}
+
+int siginfo_pkey(siginfo_t *si)
+{
+       /*
+        * In older versions of libc, siginfo_t does not have si_pkey as
+        * a member.
+        */
+#ifdef si_pkey
+       return si->si_pkey;
+#else
+       return *((int *)(((char *) si) + SI_PKEY_OFFSET));
+#endif
+}
+
+#endif /* _SELFTESTS_POWERPC_PKEYS_H */
index 9dbe607..7f259f3 100644 (file)
@@ -97,6 +97,10 @@ do {                                                         \
 #define _str(s) #s
 #define str(s) _str(s)
 
+#define sigsafe_err(msg)       ({ \
+               ssize_t nbytes __attribute__((unused)); \
+               nbytes = write(STDERR_FILENO, msg, strlen(msg)); })
+
 /* POWER9 feature */
 #ifndef PPC_FEATURE2_ARCH_3_00
 #define PPC_FEATURE2_ARCH_3_00 0x00800000
index 7c7c934..1253ad6 100644 (file)
 #include <signal.h>
 
 #include <unistd.h>
-#include <sys/mman.h>
 
-#include "reg.h"
-#include "utils.h"
-
-/*
- * Older versions of libc use the Intel-specific access rights.
- * Hence, override the definitions as they might be incorrect.
- */
-#undef PKEY_DISABLE_ACCESS
-#define PKEY_DISABLE_ACCESS    0x3
-
-#undef PKEY_DISABLE_WRITE
-#define PKEY_DISABLE_WRITE     0x2
-
-#undef PKEY_DISABLE_EXECUTE
-#define PKEY_DISABLE_EXECUTE   0x4
-
-/* Older versions of libc do not not define this */
-#ifndef SEGV_PKUERR
-#define SEGV_PKUERR    4
-#endif
-
-#define SI_PKEY_OFFSET 0x20
-
-#define SYS_pkey_mprotect      386
-#define SYS_pkey_alloc         384
-#define SYS_pkey_free          385
-
-#define PKEY_BITS_PER_PKEY     2
-#define NR_PKEYS               32
-#define PKEY_BITS_MASK         ((1UL << PKEY_BITS_PER_PKEY) - 1)
+#include "pkeys.h"
 
 #define PPC_INST_NOP   0x60000000
 #define PPC_INST_TRAP  0x7fe00008
 #define PPC_INST_BLR   0x4e800020
 
-#define sigsafe_err(msg)       ({ \
-               ssize_t nbytes __attribute__((unused)); \
-               nbytes = write(STDERR_FILENO, msg, strlen(msg)); })
-
-static inline unsigned long pkeyreg_get(void)
-{
-       return mfspr(SPRN_AMR);
-}
-
-static inline void pkeyreg_set(unsigned long amr)
-{
-       set_amr(amr);
-}
-
-static void pkey_set_rights(int pkey, unsigned long rights)
-{
-       unsigned long amr, shift;
-
-       shift = (NR_PKEYS - pkey - 1) * PKEY_BITS_PER_PKEY;
-       amr = pkeyreg_get();
-       amr &= ~(PKEY_BITS_MASK << shift);
-       amr |= (rights & PKEY_BITS_MASK) << shift;
-       pkeyreg_set(amr);
-}
-
-static int sys_pkey_mprotect(void *addr, size_t len, int prot, int pkey)
-{
-       return syscall(SYS_pkey_mprotect, addr, len, prot, pkey);
-}
-
-static int sys_pkey_alloc(unsigned long flags, unsigned long rights)
-{
-       return syscall(SYS_pkey_alloc, flags, rights);
-}
-
-static int sys_pkey_free(int pkey)
-{
-       return syscall(SYS_pkey_free, pkey);
-}
-
 static volatile sig_atomic_t fault_pkey, fault_code, fault_type;
 static volatile sig_atomic_t remaining_faults;
 static volatile unsigned int *fault_addr;
@@ -110,16 +40,7 @@ static void segv_handler(int signum, siginfo_t *sinfo, void *ctx)
 {
        int signal_pkey;
 
-       /*
-        * In older versions of libc, siginfo_t does not have si_pkey as
-        * a member.
-        */
-#ifdef si_pkey
-       signal_pkey = sinfo->si_pkey;
-#else
-       signal_pkey = *((int *)(((char *) sinfo) + SI_PKEY_OFFSET));
-#endif
-
+       signal_pkey = siginfo_pkey(sinfo);
        fault_code = sinfo->si_code;
 
        /* Check if this fault originated from the expected address */
@@ -178,23 +99,6 @@ static void segv_handler(int signum, siginfo_t *sinfo, void *ctx)
        remaining_faults--;
 }
 
-static int pkeys_unsupported(void)
-{
-       bool hash_mmu = false;
-       int pkey;
-
-       /* Protection keys are currently supported on Hash MMU only */
-       FAIL_IF(using_hash_mmu(&hash_mmu));
-       SKIP_IF(!hash_mmu);
-
-       /* Check if the system call is supported */
-       pkey = sys_pkey_alloc(0, 0);
-       SKIP_IF(pkey < 0);
-       sys_pkey_free(pkey);
-
-       return 0;
-}
-
 static int test(void)
 {
        struct sigaction segv_act, trap_act;