diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index 9cb691d67ef4..40769c16de1b 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -480,7 +480,6 @@ static void test_fork(void) int main(void) { - const unsigned int ctxtsw_num_threads = 5, ctxtsw_iterations = 10; unsigned long features; long rc; @@ -506,11 +505,11 @@ int main(void) test_fork(); - test_context_switch(XFEATURE_XTILEDATA, ctxtsw_num_threads, ctxtsw_iterations); - - test_ptrace(XFEATURE_XTILEDATA); - - test_signal(XFEATURE_XTILEDATA); + /* + * Perform generic xstate tests for context switching, ptrace, + * and signal. + */ + test_xstate(XFEATURE_XTILEDATA); clearhandler(SIGILL); free_stashed_xsave(); diff --git a/tools/testing/selftests/x86/xstate.c b/tools/testing/selftests/x86/xstate.c index b5600f492632..fd8451e55f3f 100644 --- a/tools/testing/selftests/x86/xstate.c +++ b/tools/testing/selftests/x86/xstate.c @@ -6,7 +6,9 @@ #include #include +#include #include +#include #include #include @@ -189,15 +191,13 @@ static void affinitize_cpu0(void) ksft_exit_fail_msg("sched_setaffinity to CPU 0 failed\n"); } -void test_context_switch(uint32_t feature_num, uint32_t num_threads, uint32_t iterations) +static void test_context_switch(uint32_t num_threads, uint32_t iterations) { struct futex_info *finfo; /* Affinitize to one CPU to force context switches */ affinitize_cpu0(); - xstate = get_xstate_info(feature_num); - printf("[RUN]\t%s: check context switches, %d iterations, %d threads.\n", xstate.name, iterations, num_threads); @@ -299,13 +299,11 @@ static void ptracer_inject_xstate(pid_t target) free(xbuf2); } -void test_ptrace(uint32_t feature_num) +static void test_ptrace(void) { pid_t child; int status; - xstate = get_xstate_info(feature_num); - child = fork(); if (child < 0) { ksft_exit_fail_msg("fork() failed\n"); @@ -392,17 +390,14 @@ static void validate_sigfpstate(int sig, siginfo_t *si, void *ctx_void) copy_xstate(stashed_xbuf, xbuf); } -void test_signal(uint32_t feature_num) +static void test_signal(void) { bool valid_xstate; - xstate = get_xstate_info(feature_num); - /* * The signal handler will access this to verify xstate context * preservation. */ - stashed_xbuf = alloc_xbuf(); if (!stashed_xbuf) ksft_exit_fail_msg("unable to allocate XSAVE buffer\n"); @@ -433,3 +428,26 @@ void test_signal(uint32_t feature_num) clearhandler(SIGUSR1); free(stashed_xbuf); } + +void test_xstate(uint32_t feature_num) +{ + const unsigned int ctxtsw_num_threads = 5, ctxtsw_iterations = 10; + unsigned long features; + long rc; + + rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_SUPP, &features); + if (rc || !(features & (1 << feature_num))) { + ksft_print_msg("The kernel does not support feature number: %u\n", feature_num); + return; + } + + xstate = get_xstate_info(feature_num); + if (!xstate.size || !xstate.xbuf_offset) { + ksft_exit_fail_msg("invalid state size/offset (%d/%d)\n", + xstate.size, xstate.xbuf_offset); + } + + test_context_switch(ctxtsw_num_threads, ctxtsw_iterations); + test_ptrace(); + test_signal(); +} diff --git a/tools/testing/selftests/x86/xstate.h b/tools/testing/selftests/x86/xstate.h index 4d0ffe9609f8..42af36ec852f 100644 --- a/tools/testing/selftests/x86/xstate.h +++ b/tools/testing/selftests/x86/xstate.h @@ -189,8 +189,7 @@ static inline void set_rand_data(struct xstate_info *xstate, struct xsave_buffer *ptr = data; } -void test_context_switch(uint32_t feature_num, uint32_t num_threads, uint32_t iterations); -void test_ptrace(uint32_t feature_num); -void test_signal(uint32_t feature_num); +/* Testing kernel's context switching and ABI support for the xstate. */ +void test_xstate(uint32_t feature_num); #endif /* __SELFTESTS_X86_XSTATE_H */