Split some of the common code to be used by selftests/arm, into ptrace.h.

Signed-off-by: Dev Jain <dev.j...@arm.com>
---
 tools/testing/selftests/arm64/abi/ptrace.c | 121 ++----------------
 tools/testing/selftests/arm64/abi/ptrace.h | 135 +++++++++++++++++++++
 2 files changed, 145 insertions(+), 111 deletions(-)
 create mode 100644 tools/testing/selftests/arm64/abi/ptrace.h

diff --git a/tools/testing/selftests/arm64/abi/ptrace.c 
b/tools/testing/selftests/arm64/abi/ptrace.c
index c83f0441e9d0..9e8494d950fe 100644
--- a/tools/testing/selftests/arm64/abi/ptrace.c
+++ b/tools/testing/selftests/arm64/abi/ptrace.c
@@ -18,15 +18,22 @@
 #include <asm/sigcontext.h>
 #include <asm/ptrace.h>
 
+#include "ptrace.h"
 #include "../../kselftest.h"
 
 #define EXPECTED_TESTS 11
 
 #define MAX_TPIDRS 2
 
-static bool have_sme(void)
+static int do_child(void)
 {
-       return getauxval(AT_HWCAP2) & HWCAP2_SME;
+       if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
+               ksft_exit_fail_perror("PTRACE_TRACEME");
+
+       if (raise(SIGSTOP))
+               ksft_exit_fail_perror("raise(SIGSTOP)");
+
+       return EXIT_SUCCESS;
 }
 
 static void test_tpidr(pid_t child)
@@ -132,119 +139,11 @@ static void test_tpidr(pid_t child)
        }
 }
 
-static void test_hw_debug(pid_t child, int type, const char *type_name)
-{
-       struct user_hwdebug_state state;
-       struct iovec iov;
-       int slots, arch, ret;
-
-       iov.iov_len = sizeof(state);
-       iov.iov_base = &state;
-
-       /* Should be able to read the values */
-       ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
-       ksft_test_result(ret == 0, "read_%s\n", type_name);
-
-       if (ret == 0) {
-               /* Low 8 bits is the number of slots, next 4 bits the arch */
-               slots = state.dbg_info & 0xff;
-               arch = (state.dbg_info >> 8) & 0xf;
-
-               ksft_print_msg("%s version %d with %d slots\n", type_name,
-                              arch, slots);
-
-               /* Zero is not currently architecturally valid */
-               ksft_test_result(arch, "%s_arch_set\n", type_name);
-       } else {
-               ksft_test_result_skip("%s_arch_set\n", type_name);
-       }
-}
-
-static int do_child(void)
-{
-       if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
-               ksft_exit_fail_perror("PTRACE_TRACEME");
-
-       if (raise(SIGSTOP))
-               ksft_exit_fail_perror("raise(SIGSTOP)");
-
-       return EXIT_SUCCESS;
-}
-
-static int do_parent(pid_t child)
+static void run_tests(pid_t child)
 {
-       int ret = EXIT_FAILURE;
-       pid_t pid;
-       int status;
-       siginfo_t si;
-
-       /* Attach to the child */
-       while (1) {
-               int sig;
-
-               pid = wait(&status);
-               if (pid == -1) {
-                       perror("wait");
-                       goto error;
-               }
-
-               /*
-                * This should never happen but it's hard to flag in
-                * the framework.
-                */
-               if (pid != child)
-                       continue;
-
-               if (WIFEXITED(status) || WIFSIGNALED(status))
-                       ksft_exit_fail_msg("Child died unexpectedly\n");
-
-               if (!WIFSTOPPED(status))
-                       goto error;
-
-               sig = WSTOPSIG(status);
-
-               if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)) {
-                       if (errno == ESRCH)
-                               goto disappeared;
-
-                       if (errno == EINVAL) {
-                               sig = 0; /* bust group-stop */
-                               goto cont;
-                       }
-
-                       ksft_test_result_fail("PTRACE_GETSIGINFO: %s\n",
-                                             strerror(errno));
-                       goto error;
-               }
-
-               if (sig == SIGSTOP && si.si_code == SI_TKILL &&
-                   si.si_pid == pid)
-                       break;
-
-       cont:
-               if (ptrace(PTRACE_CONT, pid, NULL, sig)) {
-                       if (errno == ESRCH)
-                               goto disappeared;
-
-                       ksft_test_result_fail("PTRACE_CONT: %s\n",
-                                             strerror(errno));
-                       goto error;
-               }
-       }
-
-       ksft_print_msg("Parent is %d, child is %d\n", getpid(), child);
-
        test_tpidr(child);
        test_hw_debug(child, NT_ARM_HW_WATCH, "NT_ARM_HW_WATCH");
        test_hw_debug(child, NT_ARM_HW_BREAK, "NT_ARM_HW_BREAK");
-
-       ret = EXIT_SUCCESS;
-
-error:
-       kill(child, SIGKILL);
-
-disappeared:
-       return ret;
 }
 
 int main(void)
diff --git a/tools/testing/selftests/arm64/abi/ptrace.h 
b/tools/testing/selftests/arm64/abi/ptrace.h
new file mode 100644
index 000000000000..ae65c58cd3bf
--- /dev/null
+++ b/tools/testing/selftests/arm64/abi/ptrace.h
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 ARM Limited.
+ */
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <asm/sigcontext.h>
+#include <asm/ptrace.h>
+
+#include "../../kselftest.h"
+
+static void run_tests(pid_t child);
+
+static int do_child(void);
+
+#ifdef __aarch64__
+static bool have_sme(void)
+{
+       return getauxval(AT_HWCAP2) & HWCAP2_SME;
+}
+
+static void test_hw_debug(pid_t child, int type, const char *type_name)
+{
+       struct user_hwdebug_state state;
+       struct iovec iov;
+       int slots, arch, ret;
+
+       iov.iov_len = sizeof(state);
+       iov.iov_base = &state;
+
+       /* Should be able to read the values */
+       ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
+       ksft_test_result(ret == 0, "read_%s\n", type_name);
+
+       if (ret == 0) {
+               /* Low 8 bits is the number of slots, next 4 bits the arch */
+               slots = state.dbg_info & 0xff;
+               arch = (state.dbg_info >> 8) & 0xf;
+
+               ksft_print_msg("%s version %d with %d slots\n", type_name,
+                              arch, slots);
+
+               /* Zero is not currently architecturally valid */
+               ksft_test_result(arch, "%s_arch_set\n", type_name);
+       } else {
+               ksft_test_result_skip("%s_arch_set\n", type_name);
+       }
+}
+#endif
+
+static int do_parent(pid_t child)
+{
+       int ret = EXIT_FAILURE;
+       pid_t pid;
+       int status;
+       siginfo_t si;
+
+       /* Attach to the child */
+       while (1) {
+               int sig;
+
+               pid = wait(&status);
+               if (pid == -1) {
+                       perror("wait");
+                       goto error;
+               }
+
+               /*
+                * This should never happen but it's hard to flag in
+                * the framework.
+                */
+               if (pid != child)
+                       continue;
+
+               if (WIFEXITED(status) || WIFSIGNALED(status))
+                       ksft_exit_fail_msg("Child died unexpectedly\n");
+
+               if (!WIFSTOPPED(status))
+                       goto error;
+
+               sig = WSTOPSIG(status);
+
+               if (sig == SIGTRAP)
+                       ksft_print_msg("Child received SIGTRAP\n");
+
+               if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)) {
+                       if (errno == ESRCH)
+                               goto disappeared;
+
+                       if (errno == EINVAL)
+                               goto cont;
+
+                       ksft_test_result_fail("PTRACE_GETSIGINFO: %s\n",
+                                             strerror(errno));
+                       goto error;
+               }
+
+               if (sig == SIGSTOP && si.si_code == SI_TKILL &&
+                   si.si_pid == pid)
+                       break;
+
+cont:
+               /* bust group-stop */
+               if (ptrace(PTRACE_CONT, pid, NULL, 0)) {
+                       if (errno == ESRCH)
+                               goto disappeared;
+
+                       ksft_test_result_fail("PTRACE_CONT: %s\n",
+                                             strerror(errno));
+                       goto error;
+               }
+       }
+
+       ksft_print_msg("Parent is %d, child is %d\n", getpid(), child);
+
+       ret = EXIT_SUCCESS;
+       run_tests(child);
+
+error:
+       kill(child, SIGKILL);
+
+disappeared:
+       return ret;
+}
-- 
2.39.2


Reply via email to