|
6 | 6 | #include <pthread.h>
|
7 | 7 | #include <stdbool.h>
|
8 | 8 |
|
| 9 | +#include <asm/prctl.h> |
9 | 10 | #include <sys/ptrace.h>
|
| 11 | +#include <sys/syscall.h> |
10 | 12 | #include <sys/uio.h>
|
11 | 13 | #include <sys/wait.h>
|
12 | 14 |
|
@@ -189,15 +191,13 @@ static void affinitize_cpu0(void)
|
189 | 191 | ksft_exit_fail_msg("sched_setaffinity to CPU 0 failed\n");
|
190 | 192 | }
|
191 | 193 |
|
192 |
| -void test_context_switch(uint32_t feature_num, uint32_t num_threads, uint32_t iterations) |
| 194 | +static void test_context_switch(uint32_t num_threads, uint32_t iterations) |
193 | 195 | {
|
194 | 196 | struct futex_info *finfo;
|
195 | 197 |
|
196 | 198 | /* Affinitize to one CPU to force context switches */
|
197 | 199 | affinitize_cpu0();
|
198 | 200 |
|
199 |
| - xstate = get_xstate_info(feature_num); |
200 |
| - |
201 | 201 | printf("[RUN]\t%s: check context switches, %d iterations, %d threads.\n",
|
202 | 202 | xstate.name, iterations, num_threads);
|
203 | 203 |
|
@@ -299,13 +299,11 @@ static void ptracer_inject_xstate(pid_t target)
|
299 | 299 | free(xbuf2);
|
300 | 300 | }
|
301 | 301 |
|
302 |
| -void test_ptrace(uint32_t feature_num) |
| 302 | +static void test_ptrace(void) |
303 | 303 | {
|
304 | 304 | pid_t child;
|
305 | 305 | int status;
|
306 | 306 |
|
307 |
| - xstate = get_xstate_info(feature_num); |
308 |
| - |
309 | 307 | child = fork();
|
310 | 308 | if (child < 0) {
|
311 | 309 | ksft_exit_fail_msg("fork() failed\n");
|
@@ -392,17 +390,14 @@ static void validate_sigfpstate(int sig, siginfo_t *si, void *ctx_void)
|
392 | 390 | copy_xstate(stashed_xbuf, xbuf);
|
393 | 391 | }
|
394 | 392 |
|
395 |
| -void test_signal(uint32_t feature_num) |
| 393 | +static void test_signal(void) |
396 | 394 | {
|
397 | 395 | bool valid_xstate;
|
398 | 396 |
|
399 |
| - xstate = get_xstate_info(feature_num); |
400 |
| - |
401 | 397 | /*
|
402 | 398 | * The signal handler will access this to verify xstate context
|
403 | 399 | * preservation.
|
404 | 400 | */
|
405 |
| - |
406 | 401 | stashed_xbuf = alloc_xbuf();
|
407 | 402 | if (!stashed_xbuf)
|
408 | 403 | ksft_exit_fail_msg("unable to allocate XSAVE buffer\n");
|
@@ -433,3 +428,26 @@ void test_signal(uint32_t feature_num)
|
433 | 428 | clearhandler(SIGUSR1);
|
434 | 429 | free(stashed_xbuf);
|
435 | 430 | }
|
| 431 | + |
| 432 | +void test_xstate(uint32_t feature_num) |
| 433 | +{ |
| 434 | + const unsigned int ctxtsw_num_threads = 5, ctxtsw_iterations = 10; |
| 435 | + unsigned long features; |
| 436 | + long rc; |
| 437 | + |
| 438 | + rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_SUPP, &features); |
| 439 | + if (rc || !(features & (1 << feature_num))) { |
| 440 | + ksft_print_msg("The kernel does not support feature number: %u\n", feature_num); |
| 441 | + return; |
| 442 | + } |
| 443 | + |
| 444 | + xstate = get_xstate_info(feature_num); |
| 445 | + if (!xstate.size || !xstate.xbuf_offset) { |
| 446 | + ksft_exit_fail_msg("invalid state size/offset (%d/%d)\n", |
| 447 | + xstate.size, xstate.xbuf_offset); |
| 448 | + } |
| 449 | + |
| 450 | + test_context_switch(ctxtsw_num_threads, ctxtsw_iterations); |
| 451 | + test_ptrace(); |
| 452 | + test_signal(); |
| 453 | +} |
0 commit comments