1 // SPDX-License-Identifier: GPL-2.0
12 #include <x86intrin.h>
17 #include <sys/ptrace.h>
18 #include <sys/syscall.h>
22 #include "../kselftest.h" /* For __cpuid_count() */
25 # error This test is 64-bit only
28 #define XSAVE_HDR_OFFSET 512
29 #define XSAVE_HDR_SIZE 64
34 char legacy[XSAVE_HDR_OFFSET];
35 char header[XSAVE_HDR_SIZE];
42 static inline uint64_t xgetbv(uint32_t index)
46 asm volatile("xgetbv;"
47 : "=a" (eax), "=d" (edx)
49 return eax + ((uint64_t)edx << 32);
52 static inline void xsave(struct xsave_buffer *xbuf, uint64_t rfbm)
54 uint32_t rfbm_lo = rfbm;
55 uint32_t rfbm_hi = rfbm >> 32;
57 asm volatile("xsave (%%rdi)"
58 : : "D" (xbuf), "a" (rfbm_lo), "d" (rfbm_hi)
62 static inline void xrstor(struct xsave_buffer *xbuf, uint64_t rfbm)
64 uint32_t rfbm_lo = rfbm;
65 uint32_t rfbm_hi = rfbm >> 32;
67 asm volatile("xrstor (%%rdi)"
68 : : "D" (xbuf), "a" (rfbm_lo), "d" (rfbm_hi));
71 /* err() exits and will not return */
72 #define fatal_error(msg, ...) err(1, "[FAIL]\t" msg, ##__VA_ARGS__)
74 static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
79 memset(&sa, 0, sizeof(sa));
80 sa.sa_sigaction = handler;
81 sa.sa_flags = SA_SIGINFO | flags;
82 sigemptyset(&sa.sa_mask);
83 if (sigaction(sig, &sa, 0))
84 fatal_error("sigaction");
87 static void clearhandler(int sig)
91 memset(&sa, 0, sizeof(sa));
92 sa.sa_handler = SIG_DFL;
93 sigemptyset(&sa.sa_mask);
94 if (sigaction(sig, &sa, 0))
95 fatal_error("sigaction");
98 #define XFEATURE_XTILECFG 17
99 #define XFEATURE_XTILEDATA 18
100 #define XFEATURE_MASK_XTILECFG (1 << XFEATURE_XTILECFG)
101 #define XFEATURE_MASK_XTILEDATA (1 << XFEATURE_XTILEDATA)
102 #define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILECFG | XFEATURE_MASK_XTILEDATA)
104 #define CPUID_LEAF1_ECX_XSAVE_MASK (1 << 26)
105 #define CPUID_LEAF1_ECX_OSXSAVE_MASK (1 << 27)
106 static inline void check_cpuid_xsave(void)
108 uint32_t eax, ebx, ecx, edx;
111 * CPUID.1:ECX.XSAVE[bit 26] enumerates general
112 * support for the XSAVE feature set, including
115 __cpuid_count(1, 0, eax, ebx, ecx, edx);
116 if (!(ecx & CPUID_LEAF1_ECX_XSAVE_MASK))
117 fatal_error("cpuid: no CPU xsave support");
118 if (!(ecx & CPUID_LEAF1_ECX_OSXSAVE_MASK))
119 fatal_error("cpuid: no OS xsave support");
122 static uint32_t xbuf_size;
125 uint32_t xbuf_offset;
129 #define CPUID_LEAF_XSTATE 0xd
130 #define CPUID_SUBLEAF_XSTATE_USER 0x0
131 #define TILE_CPUID 0x1d
132 #define TILE_PALETTE_ID 0x1
134 static void check_cpuid_xtiledata(void)
136 uint32_t eax, ebx, ecx, edx;
138 __cpuid_count(CPUID_LEAF_XSTATE, CPUID_SUBLEAF_XSTATE_USER,
142 * EBX enumerates the size (in bytes) required by the XSAVE
143 * instruction for an XSAVE area containing all the user state
144 * components corresponding to bits currently set in XCR0.
146 * Stash that off so it can be used to allocate buffers later.
150 __cpuid_count(CPUID_LEAF_XSTATE, XFEATURE_XTILEDATA,
153 * eax: XTILEDATA state component size
154 * ebx: XTILEDATA state component offset in user buffer
157 fatal_error("xstate cpuid: invalid tile data size/offset: %d/%d",
160 xtiledata.size = eax;
161 xtiledata.xbuf_offset = ebx;
164 /* The helpers for managing XSAVE buffer and tile states: */
166 struct xsave_buffer *alloc_xbuf(void)
168 struct xsave_buffer *xbuf;
170 /* XSAVE buffer should be 64B-aligned. */
171 xbuf = aligned_alloc(64, xbuf_size);
173 fatal_error("aligned_alloc()");
177 static inline void clear_xstate_header(struct xsave_buffer *buffer)
179 memset(&buffer->header, 0, sizeof(buffer->header));
182 static inline uint64_t get_xstatebv(struct xsave_buffer *buffer)
184 /* XSTATE_BV is at the beginning of the header: */
185 return *(uint64_t *)&buffer->header;
188 static inline void set_xstatebv(struct xsave_buffer *buffer, uint64_t bv)
190 /* XSTATE_BV is at the beginning of the header: */
191 *(uint64_t *)(&buffer->header) = bv;
194 static void set_rand_tiledata(struct xsave_buffer *xbuf)
196 int *ptr = (int *)&xbuf->bytes[xtiledata.xbuf_offset];
201 * Ensure that 'data' is never 0. This ensures that
202 * the registers are never in their initial configuration
203 * and thus never tracked as being in the init state.
207 for (i = 0; i < xtiledata.size / sizeof(int); i++, ptr++)
211 struct xsave_buffer *stashed_xsave;
213 static void init_stashed_xsave(void)
215 stashed_xsave = alloc_xbuf();
217 fatal_error("failed to allocate stashed_xsave\n");
218 clear_xstate_header(stashed_xsave);
221 static void free_stashed_xsave(void)
226 /* See 'struct _fpx_sw_bytes' at sigcontext.h */
227 #define SW_BYTES_OFFSET 464
228 /* N.B. The struct's field name varies so read from the offset. */
229 #define SW_BYTES_BV_OFFSET (SW_BYTES_OFFSET + 8)
231 static inline struct _fpx_sw_bytes *get_fpx_sw_bytes(void *buffer)
233 return (struct _fpx_sw_bytes *)(buffer + SW_BYTES_OFFSET);
236 static inline uint64_t get_fpx_sw_bytes_features(void *buffer)
238 return *(uint64_t *)(buffer + SW_BYTES_BV_OFFSET);
241 /* Work around printf() being unsafe in signals: */
242 #define SIGNAL_BUF_LEN 1000
243 char signal_message_buffer[SIGNAL_BUF_LEN];
244 void sig_print(char *msg)
246 int left = SIGNAL_BUF_LEN - strlen(signal_message_buffer) - 1;
248 strncat(signal_message_buffer, msg, left);
251 static volatile bool noperm_signaled;
252 static int noperm_errs;
254 * Signal handler for when AMX is used but
255 * permission has not been obtained.
257 static void handle_noperm(int sig, siginfo_t *si, void *ctx_void)
259 ucontext_t *ctx = (ucontext_t *)ctx_void;
260 void *xbuf = ctx->uc_mcontext.fpregs;
261 struct _fpx_sw_bytes *sw_bytes;
264 /* Reset the signal message buffer: */
265 signal_message_buffer[0] = '\0';
266 sig_print("\tAt SIGILL handler,\n");
268 if (si->si_code != ILL_ILLOPC) {
270 sig_print("[FAIL]\tInvalid signal code.\n");
272 sig_print("[OK]\tValid signal code (ILL_ILLOPC).\n");
275 sw_bytes = get_fpx_sw_bytes(xbuf);
277 * Without permission, the signal XSAVE buffer should not
278 * have room for AMX register state (aka. xtiledata).
279 * Check that the size does not overlap with where xtiledata
282 * This also implies that no state components *PAST*
283 * XTILEDATA (features >=19) can be present in the buffer.
285 if (sw_bytes->xstate_size <= xtiledata.xbuf_offset) {
286 sig_print("[OK]\tValid xstate size\n");
289 sig_print("[FAIL]\tInvalid xstate size\n");
292 features = get_fpx_sw_bytes_features(xbuf);
294 * Without permission, the XTILEDATA feature
295 * bit should not be set.
297 if ((features & XFEATURE_MASK_XTILEDATA) == 0) {
298 sig_print("[OK]\tValid xstate mask\n");
301 sig_print("[FAIL]\tInvalid xstate mask\n");
304 noperm_signaled = true;
305 ctx->uc_mcontext.gregs[REG_RIP] += 3; /* Skip the faulting XRSTOR */
308 /* Return true if XRSTOR is successful; otherwise, false. */
309 static inline bool xrstor_safe(struct xsave_buffer *xbuf, uint64_t mask)
311 noperm_signaled = false;
314 /* Print any messages produced by the signal code: */
315 printf("%s", signal_message_buffer);
317 * Reset the buffer to make sure any future printing
318 * only outputs new messages:
320 signal_message_buffer[0] = '\0';
323 fatal_error("saw %d errors in noperm signal handler\n", noperm_errs);
325 return !noperm_signaled;
329 * Use XRSTOR to populate the XTILEDATA registers with
332 * Return true if successful; otherwise, false.
334 static inline bool load_rand_tiledata(struct xsave_buffer *xbuf)
336 clear_xstate_header(xbuf);
337 set_xstatebv(xbuf, XFEATURE_MASK_XTILEDATA);
338 set_rand_tiledata(xbuf);
339 return xrstor_safe(xbuf, XFEATURE_MASK_XTILEDATA);
342 /* Return XTILEDATA to its initial configuration. */
343 static inline void init_xtiledata(void)
345 clear_xstate_header(stashed_xsave);
346 xrstor_safe(stashed_xsave, XFEATURE_MASK_XTILEDATA);
349 enum expected_result { FAIL_EXPECTED, SUCCESS_EXPECTED };
351 /* arch_prctl() and sigaltstack() test */
353 #define ARCH_GET_XCOMP_PERM 0x1022
354 #define ARCH_REQ_XCOMP_PERM 0x1023
356 static void req_xtiledata_perm(void)
358 syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_PERM, XFEATURE_XTILEDATA);
361 static void validate_req_xcomp_perm(enum expected_result exp)
363 unsigned long bitmask, expected_bitmask;
366 rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_PERM, &bitmask);
368 fatal_error("prctl(ARCH_GET_XCOMP_PERM) error: %ld", rc);
369 } else if (!(bitmask & XFEATURE_MASK_XTILECFG)) {
370 fatal_error("ARCH_GET_XCOMP_PERM returns XFEATURE_XTILECFG off.");
373 rc = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_PERM, XFEATURE_XTILEDATA);
374 if (exp == FAIL_EXPECTED) {
376 printf("[OK]\tARCH_REQ_XCOMP_PERM saw expected failure..\n");
380 fatal_error("ARCH_REQ_XCOMP_PERM saw unexpected success.\n");
382 fatal_error("ARCH_REQ_XCOMP_PERM saw unexpected failure.\n");
385 expected_bitmask = bitmask | XFEATURE_MASK_XTILEDATA;
387 rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_PERM, &bitmask);
389 fatal_error("prctl(ARCH_GET_XCOMP_PERM) error: %ld", rc);
390 } else if (bitmask != expected_bitmask) {
391 fatal_error("ARCH_REQ_XCOMP_PERM set a wrong bitmask: %lx, expected: %lx.\n",
392 bitmask, expected_bitmask);
394 printf("\tARCH_REQ_XCOMP_PERM is successful.\n");
398 static void validate_xcomp_perm(enum expected_result exp)
400 bool load_success = load_rand_tiledata(stashed_xsave);
402 if (exp == FAIL_EXPECTED) {
405 printf("[FAIL]\tLoad tiledata succeeded.\n");
407 printf("[OK]\tLoad tiledata failed.\n");
409 } else if (exp == SUCCESS_EXPECTED) {
411 printf("[OK]\tLoad tiledata succeeded.\n");
414 printf("[FAIL]\tLoad tiledata failed.\n");
419 #ifndef AT_MINSIGSTKSZ
420 # define AT_MINSIGSTKSZ 51
423 static void *alloc_altstack(unsigned int size)
427 altstack = mmap(NULL, size, PROT_READ | PROT_WRITE,
428 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
430 if (altstack == MAP_FAILED)
431 fatal_error("mmap() for altstack");
436 static void setup_altstack(void *addr, unsigned long size, enum expected_result exp)
441 memset(&ss, 0, sizeof(ss));
445 rc = sigaltstack(&ss, NULL);
447 if (exp == FAIL_EXPECTED) {
449 printf("[OK]\tsigaltstack() failed.\n");
451 fatal_error("sigaltstack() succeeded unexpectedly.\n");
454 fatal_error("sigaltstack()");
458 static void test_dynamic_sigaltstack(void)
460 unsigned int small_size, enough_size;
461 unsigned long minsigstksz;
464 minsigstksz = getauxval(AT_MINSIGSTKSZ);
465 printf("\tAT_MINSIGSTKSZ = %lu\n", minsigstksz);
467 * getauxval() itself can return 0 for failure or
468 * success. But, in this case, AT_MINSIGSTKSZ
469 * will always return a >=0 value if implemented.
472 if (minsigstksz == 0) {
473 printf("no support for AT_MINSIGSTKSZ, skipping sigaltstack tests\n");
477 enough_size = minsigstksz * 2;
479 altstack = alloc_altstack(enough_size);
480 printf("\tAllocate memory for altstack (%u bytes).\n", enough_size);
483 * Try setup_altstack() with a size which can not fit
484 * XTILEDATA. ARCH_REQ_XCOMP_PERM should fail.
486 small_size = minsigstksz - xtiledata.size;
487 printf("\tAfter sigaltstack() with small size (%u bytes).\n", small_size);
488 setup_altstack(altstack, small_size, SUCCESS_EXPECTED);
489 validate_req_xcomp_perm(FAIL_EXPECTED);
492 * Try setup_altstack() with a size derived from
493 * AT_MINSIGSTKSZ. It should be more than large enough
494 * and thus ARCH_REQ_XCOMP_PERM should succeed.
496 printf("\tAfter sigaltstack() with enough size (%u bytes).\n", enough_size);
497 setup_altstack(altstack, enough_size, SUCCESS_EXPECTED);
498 validate_req_xcomp_perm(SUCCESS_EXPECTED);
501 * Try to coerce setup_altstack() to again accept a
502 * too-small altstack. This ensures that big-enough
503 * sigaltstacks can not shrink to a too-small value
504 * once XTILEDATA permission is established.
506 printf("\tThen, sigaltstack() with small size (%u bytes).\n", small_size);
507 setup_altstack(altstack, small_size, FAIL_EXPECTED);
510 static void test_dynamic_state(void)
512 pid_t parent, child, grandchild;
518 } else if (parent > 0) {
520 /* fork() succeeded. Now in the parent. */
523 if (!WIFEXITED(status) || WEXITSTATUS(status))
524 fatal_error("arch_prctl test parent exit");
527 /* fork() succeeded. Now in the child . */
529 printf("[RUN]\tCheck ARCH_REQ_XCOMP_PERM around process fork() and sigaltack() test.\n");
531 printf("\tFork a child.\n");
535 } else if (child > 0) {
539 if (!WIFEXITED(status) || WEXITSTATUS(status))
540 fatal_error("arch_prctl test child exit");
545 * The permission request should fail without an
546 * XTILEDATA-compatible signal stack
548 printf("\tTest XCOMP_PERM at child.\n");
549 validate_xcomp_perm(FAIL_EXPECTED);
552 * Set up an XTILEDATA-compatible signal stack and
553 * also obtain permission to populate XTILEDATA.
555 printf("\tTest dynamic sigaltstack at child:\n");
556 test_dynamic_sigaltstack();
558 /* Ensure that XTILEDATA can be populated. */
559 printf("\tTest XCOMP_PERM again at child.\n");
560 validate_xcomp_perm(SUCCESS_EXPECTED);
562 printf("\tFork a grandchild.\n");
564 if (grandchild < 0) {
567 } else if (!grandchild) {
568 /* fork() succeeded. Now in the (grand)child. */
569 printf("\tTest XCOMP_PERM at grandchild.\n");
572 * Ensure that the grandchild inherited
573 * permission and a compatible sigaltstack:
575 validate_xcomp_perm(SUCCESS_EXPECTED);
578 /* fork() succeeded. Now in the parent. */
581 if (!WIFEXITED(status) || WEXITSTATUS(status))
582 fatal_error("fork test grandchild");
588 static inline int __compare_tiledata_state(struct xsave_buffer *xbuf1, struct xsave_buffer *xbuf2)
590 return memcmp(&xbuf1->bytes[xtiledata.xbuf_offset],
591 &xbuf2->bytes[xtiledata.xbuf_offset],
596 * Save current register state and compare it to @xbuf1.'
598 * Returns false if @xbuf1 matches the registers.
599 * Returns true if @xbuf1 differs from the registers.
601 static inline bool __validate_tiledata_regs(struct xsave_buffer *xbuf1)
603 struct xsave_buffer *xbuf2;
606 xbuf2 = alloc_xbuf();
608 fatal_error("failed to allocate XSAVE buffer\n");
610 xsave(xbuf2, XFEATURE_MASK_XTILEDATA);
611 ret = __compare_tiledata_state(xbuf1, xbuf2);
620 static inline void validate_tiledata_regs_same(struct xsave_buffer *xbuf)
622 int ret = __validate_tiledata_regs(xbuf);
625 fatal_error("TILEDATA registers changed");
628 static inline void validate_tiledata_regs_changed(struct xsave_buffer *xbuf)
630 int ret = __validate_tiledata_regs(xbuf);
633 fatal_error("TILEDATA registers did not change");
636 /* tiledata inheritance test */
638 static void test_fork(void)
640 pid_t child, grandchild;
646 } else if (child > 0) {
647 /* fork() succeeded. Now in the parent. */
651 if (!WIFEXITED(status) || WEXITSTATUS(status))
652 fatal_error("fork test child");
655 /* fork() succeeded. Now in the child. */
656 printf("[RUN]\tCheck tile data inheritance.\n\tBefore fork(), load tiledata\n");
658 load_rand_tiledata(stashed_xsave);
661 if (grandchild < 0) {
664 } else if (grandchild > 0) {
665 /* fork() succeeded. Still in the first child. */
669 if (!WIFEXITED(status) || WEXITSTATUS(status))
670 fatal_error("fork test grand child");
673 /* fork() succeeded. Now in the (grand)child. */
676 * TILEDATA registers are not preserved across fork().
677 * Ensure that their value has changed:
679 validate_tiledata_regs_changed(stashed_xsave);
684 /* Context switching test */
686 static struct _ctxtswtest_cfg {
687 unsigned int iterations;
688 unsigned int num_threads;
694 pthread_mutex_t mutex;
695 struct futex_info *next;
698 static void *check_tiledata(void *info)
700 struct futex_info *finfo = (struct futex_info *)info;
701 struct xsave_buffer *xbuf;
706 fatal_error("unable to allocate XSAVE buffer");
709 * Load random data into 'xbuf' and then restore
710 * it to the tile registers themselves.
712 load_rand_tiledata(xbuf);
713 for (i = 0; i < ctxtswtest_config.iterations; i++) {
714 pthread_mutex_lock(&finfo->mutex);
717 * Ensure the register values have not
718 * diverged from those recorded in 'xbuf'.
720 validate_tiledata_regs_same(xbuf);
722 /* Load new, random values into xbuf and registers */
723 load_rand_tiledata(xbuf);
726 * The last thread's last unlock will be for
727 * thread 0's mutex. However, thread 0 will
728 * have already exited the loop and the mutex
729 * will already be unlocked.
731 * Because this is not an ERRORCHECK mutex,
732 * that inconsistency will be silently ignored.
734 pthread_mutex_unlock(&finfo->next->mutex);
739 * Return this thread's finfo, which is
740 * a unique value for this thread.
745 static int create_threads(int num, struct futex_info *finfo)
749 for (i = 0; i < num; i++) {
754 * Thread 'i' will wait on this mutex to
755 * be unlocked. Lock it immediately after
758 pthread_mutex_init(&finfo[i].mutex, NULL);
759 pthread_mutex_lock(&finfo[i].mutex);
761 next_nr = (i + 1) % num;
762 finfo[i].next = &finfo[next_nr];
764 if (pthread_create(&finfo[i].thread, NULL, check_tiledata, &finfo[i]))
765 fatal_error("pthread_create()");
770 static void affinitize_cpu0(void)
777 if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0)
778 fatal_error("sched_setaffinity to CPU 0");
781 static void test_context_switch(void)
783 struct futex_info *finfo;
786 /* Affinitize to one CPU to force context switches */
789 req_xtiledata_perm();
791 printf("[RUN]\tCheck tiledata context switches, %d iterations, %d threads.\n",
792 ctxtswtest_config.iterations,
793 ctxtswtest_config.num_threads);
796 finfo = malloc(sizeof(*finfo) * ctxtswtest_config.num_threads);
798 fatal_error("malloc()");
800 create_threads(ctxtswtest_config.num_threads, finfo);
803 * This thread wakes up thread 0
804 * Thread 0 will wake up 1
805 * Thread 1 will wake up 2
807 * the last thread will wake up 0
809 * ... this will repeat for the configured
810 * number of iterations.
812 pthread_mutex_unlock(&finfo[0].mutex);
814 /* Wait for all the threads to finish: */
815 for (i = 0; i < ctxtswtest_config.num_threads; i++) {
819 rc = pthread_join(finfo[i].thread, &thread_retval);
822 fatal_error("pthread_join() failed for thread %d err: %d\n",
825 if (thread_retval != &finfo[i])
826 fatal_error("unexpected thread retval for thread %d: %p\n",
831 printf("[OK]\tNo incorrect case was found.\n");
839 * Make sure the ptracee has the expanded kernel buffer on the first
840 * use. Then, initialize the state before performing the state
841 * injection from the ptracer.
843 static inline void ptracee_firstuse_tiledata(void)
845 load_rand_tiledata(stashed_xsave);
850 * Ptracer injects the randomized tile data state. It also reads
851 * before and after that, which will execute the kernel's state copy
852 * functions. So, the tester is advised to double-check any emitted
855 static void ptracer_inject_tiledata(pid_t target)
857 struct xsave_buffer *xbuf;
862 fatal_error("unable to allocate XSAVE buffer");
864 printf("\tRead the init'ed tiledata via ptrace().\n");
867 iov.iov_len = xbuf_size;
869 memset(stashed_xsave, 0, xbuf_size);
871 if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
872 fatal_error("PTRACE_GETREGSET");
874 if (!__compare_tiledata_state(stashed_xsave, xbuf))
875 printf("[OK]\tThe init'ed tiledata was read from ptracee.\n");
877 printf("[FAIL]\tThe init'ed tiledata was not read from ptracee.\n");
879 printf("\tInject tiledata via ptrace().\n");
881 load_rand_tiledata(xbuf);
883 memcpy(&stashed_xsave->bytes[xtiledata.xbuf_offset],
884 &xbuf->bytes[xtiledata.xbuf_offset],
887 if (ptrace(PTRACE_SETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
888 fatal_error("PTRACE_SETREGSET");
890 if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
891 fatal_error("PTRACE_GETREGSET");
893 if (!__compare_tiledata_state(stashed_xsave, xbuf))
894 printf("[OK]\tTiledata was correctly written to ptracee.\n");
896 printf("[FAIL]\tTiledata was not correctly written to ptracee.\n");
899 static void test_ptrace(void)
908 if (ptrace(PTRACE_TRACEME, 0, NULL, NULL))
909 err(1, "PTRACE_TRACEME");
911 ptracee_firstuse_tiledata();
919 } while (WSTOPSIG(status) != SIGTRAP);
921 ptracer_inject_tiledata(child);
923 ptrace(PTRACE_DETACH, child, NULL, NULL);
925 if (!WIFEXITED(status) || WEXITSTATUS(status))
926 err(1, "ptrace test");
931 /* Check hardware availability at first */
933 check_cpuid_xtiledata();
935 init_stashed_xsave();
936 sethandler(SIGILL, handle_noperm, 0);
938 test_dynamic_state();
940 /* Request permission for the following tests */
941 req_xtiledata_perm();
945 ctxtswtest_config.iterations = 10;
946 ctxtswtest_config.num_threads = 5;
947 test_context_switch();
951 clearhandler(SIGILL);
952 free_stashed_xsave();