On Tue, Jun 25, 2024 at 05:54:05PM +0530, Dev Jain wrote: > --- /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 "../../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); This feels like it's pulling way too much stuff out into the header. I think some of this needs to be a C file that gets built for both architectures with some mechanism they can use to run tests, and a library of any shared tests. > + > + 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 >
Attachment:
signature.asc
Description: PGP signature