summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/powerpc
diff options
context:
space:
mode:
authorSandipan Das <sandipan@linux.ibm.com>2020-07-27 09:30:35 +0530
committerMichael Ellerman <mpe@ellerman.id.au>2020-07-29 21:02:10 +1000
commit128d3d0210076232b7d54c361082c8ee17e4b669 (patch)
treecfe19bd8b429a00be10024a91e2d28e3f61f8bd7 /tools/testing/selftests/powerpc
parent107c55005fbd5243ee31fb13b6f166cde9e3ade1 (diff)
selftests/powerpc: Move pkey helpers to headers
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
Diffstat (limited to 'tools/testing/selftests/powerpc')
-rw-r--r--tools/testing/selftests/powerpc/include/pkeys.h108
-rw-r--r--tools/testing/selftests/powerpc/include/utils.h4
-rw-r--r--tools/testing/selftests/powerpc/mm/pkey_exec_prot.c100
3 files changed, 114 insertions, 98 deletions
diff --git a/tools/testing/selftests/powerpc/include/pkeys.h b/tools/testing/selftests/powerpc/include/pkeys.h
new file mode 100644
index 000000000000..9b53a97e664e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/include/pkeys.h
@@ -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 */
diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h
index 9dbe607cc5ec..7f259f36e23b 100644
--- a/tools/testing/selftests/powerpc/include/utils.h
+++ b/tools/testing/selftests/powerpc/include/utils.h
@@ -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
diff --git a/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c b/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
index 7c7c93425c5e..1253ad6afba2 100644
--- a/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
+++ b/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
@@ -14,83 +14,13 @@
#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;