1 // SPDX-License-Identifier: GPL-2.0 2 3 #define _GNU_SOURCE 4 5 #include <elf.h> 6 #include <pthread.h> 7 #include <stdbool.h> 8 9 #include <asm/prctl.h> 10 #include <sys/ptrace.h> 11 #include <sys/syscall.h> 12 #include <sys/uio.h> 13 #include <sys/wait.h> 14 15 #include "helpers.h" 16 #include "xstate.h" 17 18 /* 19 * The userspace xstate test suite is designed to be generic and operates 20 * with randomized xstate data. However, some states require special handling: 21 * 22 * - PKRU and XTILECFG need specific adjustments, such as modifying 23 * randomization behavior or using fixed values. 24 * - But, PKRU already has a dedicated test suite in /tools/selftests/mm. 25 * - Legacy states (FP and SSE) are excluded, as they are not considered 26 * part of extended states (xstates) and their usage is already deeply 27 * integrated into user-space libraries. 28 */ 29 #define XFEATURE_MASK_TEST_SUPPORTED \ 30 ((1 << XFEATURE_YMM) | \ 31 (1 << XFEATURE_OPMASK) | \ 32 (1 << XFEATURE_ZMM_Hi256) | \ 33 (1 << XFEATURE_Hi16_ZMM) | \ 34 (1 << XFEATURE_XTILEDATA)) 35 36 static inline uint64_t xgetbv(uint32_t index) 37 { 38 uint32_t eax, edx; 39 40 asm volatile("xgetbv" : "=a" (eax), "=d" (edx) : "c" (index)); 41 return eax + ((uint64_t)edx << 32); 42 } 43 44 static inline uint64_t get_xstatebv(struct xsave_buffer *xbuf) 45 { 46 return *(uint64_t *)(&xbuf->header); 47 } 48 49 static struct xstate_info xstate; 50 51 struct futex_info { 52 unsigned int iterations; 53 struct futex_info *next; 54 pthread_mutex_t mutex; 55 pthread_t thread; 56 bool valid; 57 int nr; 58 }; 59 60 static inline void load_rand_xstate(struct xstate_info *xstate, struct xsave_buffer *xbuf) 61 { 62 clear_xstate_header(xbuf); 63 set_xstatebv(xbuf, xstate->mask); 64 set_rand_data(xstate, xbuf); 65 xrstor(xbuf, xstate->mask); 66 } 67 68 static inline void load_init_xstate(struct xstate_info *xstate, struct xsave_buffer *xbuf) 69 { 70 clear_xstate_header(xbuf); 71 xrstor(xbuf, xstate->mask); 72 } 73 74 static inline void copy_xstate(struct xsave_buffer *xbuf_dst, struct xsave_buffer *xbuf_src) 75 { 76 memcpy(&xbuf_dst->bytes[xstate.xbuf_offset], 77 &xbuf_src->bytes[xstate.xbuf_offset], 78 xstate.size); 79 } 80 81 static inline bool validate_xstate_same(struct xsave_buffer *xbuf1, struct xsave_buffer *xbuf2) 82 { 83 int ret; 84 85 ret = memcmp(&xbuf1->bytes[xstate.xbuf_offset], 86 &xbuf2->bytes[xstate.xbuf_offset], 87 xstate.size); 88 return ret == 0; 89 } 90 91 static inline bool validate_xregs_same(struct xsave_buffer *xbuf1) 92 { 93 struct xsave_buffer *xbuf2; 94 bool ret; 95 96 xbuf2 = alloc_xbuf(); 97 if (!xbuf2) 98 ksft_exit_fail_msg("failed to allocate XSAVE buffer\n"); 99 100 xsave(xbuf2, xstate.mask); 101 ret = validate_xstate_same(xbuf1, xbuf2); 102 103 free(xbuf2); 104 return ret; 105 } 106 107 /* Context switching test */ 108 109 static void *check_xstate(void *info) 110 { 111 struct futex_info *finfo = (struct futex_info *)info; 112 struct xsave_buffer *xbuf; 113 int i; 114 115 xbuf = alloc_xbuf(); 116 if (!xbuf) 117 ksft_exit_fail_msg("unable to allocate XSAVE buffer\n"); 118 119 /* 120 * Load random data into 'xbuf' and then restore it to the xstate 121 * registers. 122 */ 123 load_rand_xstate(&xstate, xbuf); 124 finfo->valid = true; 125 126 for (i = 0; i < finfo->iterations; i++) { 127 pthread_mutex_lock(&finfo->mutex); 128 129 /* 130 * Ensure the register values have not diverged from the 131 * record. Then reload a new random value. If it failed 132 * ever before, skip it. 133 */ 134 if (finfo->valid) { 135 finfo->valid = validate_xregs_same(xbuf); 136 load_rand_xstate(&xstate, xbuf); 137 } 138 139 /* 140 * The last thread's last unlock will be for thread 0's 141 * mutex. However, thread 0 will have already exited the 142 * loop and the mutex will already be unlocked. 143 * 144 * Because this is not an ERRORCHECK mutex, that 145 * inconsistency will be silently ignored. 146 */ 147 pthread_mutex_unlock(&finfo->next->mutex); 148 } 149 150 free(xbuf); 151 return finfo; 152 } 153 154 static void create_threads(uint32_t num_threads, uint32_t iterations, struct futex_info *finfo) 155 { 156 int i; 157 158 for (i = 0; i < num_threads; i++) { 159 int next_nr; 160 161 finfo[i].nr = i; 162 finfo[i].iterations = iterations; 163 164 /* 165 * Thread 'i' will wait on this mutex to be unlocked. 166 * Lock it immediately after initialization: 167 */ 168 pthread_mutex_init(&finfo[i].mutex, NULL); 169 pthread_mutex_lock(&finfo[i].mutex); 170 171 next_nr = (i + 1) % num_threads; 172 finfo[i].next = &finfo[next_nr]; 173 174 if (pthread_create(&finfo[i].thread, NULL, check_xstate, &finfo[i])) 175 ksft_exit_fail_msg("pthread_create() failed\n"); 176 } 177 } 178 179 static bool checkout_threads(uint32_t num_threads, struct futex_info *finfo) 180 { 181 void *thread_retval; 182 bool valid = true; 183 int err, i; 184 185 for (i = 0; i < num_threads; i++) { 186 err = pthread_join(finfo[i].thread, &thread_retval); 187 if (err) 188 ksft_exit_fail_msg("pthread_join() failed for thread %d err: %d\n", i, err); 189 190 if (thread_retval != &finfo[i]) { 191 ksft_exit_fail_msg("unexpected thread retval for thread %d: %p\n", 192 i, thread_retval); 193 } 194 195 valid &= finfo[i].valid; 196 } 197 198 return valid; 199 } 200 201 static void affinitize_cpu0(void) 202 { 203 cpu_set_t cpuset; 204 205 CPU_ZERO(&cpuset); 206 CPU_SET(0, &cpuset); 207 208 if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) 209 ksft_exit_fail_msg("sched_setaffinity to CPU 0 failed\n"); 210 } 211 212 static void test_context_switch(uint32_t num_threads, uint32_t iterations) 213 { 214 struct futex_info *finfo; 215 216 /* Affinitize to one CPU to force context switches */ 217 affinitize_cpu0(); 218 219 printf("[RUN]\t%s: check context switches, %d iterations, %d threads.\n", 220 xstate.name, iterations, num_threads); 221 222 finfo = malloc(sizeof(*finfo) * num_threads); 223 if (!finfo) 224 ksft_exit_fail_msg("unable allocate memory\n"); 225 226 create_threads(num_threads, iterations, finfo); 227 228 /* 229 * This thread wakes up thread 0 230 * Thread 0 will wake up 1 231 * Thread 1 will wake up 2 232 * ... 233 * The last thread will wake up 0 234 * 235 * This will repeat for the configured 236 * number of iterations. 237 */ 238 pthread_mutex_unlock(&finfo[0].mutex); 239 240 /* Wait for all the threads to finish: */ 241 if (checkout_threads(num_threads, finfo)) 242 printf("[OK]\tNo incorrect case was found.\n"); 243 else 244 printf("[FAIL]\tFailed with context switching test.\n"); 245 246 free(finfo); 247 } 248 249 /* 250 * Ptrace test for the ABI format as described in arch/x86/include/asm/user.h 251 */ 252 253 /* 254 * Make sure the ptracee has the expanded kernel buffer on the first use. 255 * Then, initialize the state before performing the state injection from 256 * the ptracer. For non-dynamic states, this is benign. 257 */ 258 static inline void ptracee_touch_xstate(void) 259 { 260 struct xsave_buffer *xbuf; 261 262 xbuf = alloc_xbuf(); 263 264 load_rand_xstate(&xstate, xbuf); 265 load_init_xstate(&xstate, xbuf); 266 267 free(xbuf); 268 } 269 270 /* 271 * Ptracer injects the randomized xstate data. It also reads before and 272 * after that, which will execute the kernel's state copy functions. 273 */ 274 static void ptracer_inject_xstate(pid_t target) 275 { 276 uint32_t xbuf_size = get_xbuf_size(); 277 struct xsave_buffer *xbuf1, *xbuf2; 278 struct iovec iov; 279 280 /* 281 * Allocate buffers to keep data while ptracer can write the 282 * other buffer 283 */ 284 xbuf1 = alloc_xbuf(); 285 xbuf2 = alloc_xbuf(); 286 if (!xbuf1 || !xbuf2) 287 ksft_exit_fail_msg("unable to allocate XSAVE buffer\n"); 288 289 iov.iov_base = xbuf1; 290 iov.iov_len = xbuf_size; 291 292 if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) 293 ksft_exit_fail_msg("PTRACE_GETREGSET failed\n"); 294 295 printf("[RUN]\t%s: inject xstate via ptrace().\n", xstate.name); 296 297 load_rand_xstate(&xstate, xbuf1); 298 copy_xstate(xbuf2, xbuf1); 299 300 if (ptrace(PTRACE_SETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) 301 ksft_exit_fail_msg("PTRACE_SETREGSET failed\n"); 302 303 if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov)) 304 ksft_exit_fail_msg("PTRACE_GETREGSET failed\n"); 305 306 if (*(uint64_t *)get_fpx_sw_bytes(xbuf1) == xgetbv(0)) 307 printf("[OK]\t'xfeatures' in SW reserved area was correctly written\n"); 308 else 309 printf("[FAIL]\t'xfeatures' in SW reserved area was not correctly written\n"); 310 311 if (validate_xstate_same(xbuf2, xbuf1)) 312 printf("[OK]\txstate was correctly updated.\n"); 313 else 314 printf("[FAIL]\txstate was not correctly updated.\n"); 315 316 free(xbuf1); 317 free(xbuf2); 318 } 319 320 static void test_ptrace(void) 321 { 322 pid_t child; 323 int status; 324 325 child = fork(); 326 if (child < 0) { 327 ksft_exit_fail_msg("fork() failed\n"); 328 } else if (!child) { 329 if (ptrace(PTRACE_TRACEME, 0, NULL, NULL)) 330 ksft_exit_fail_msg("PTRACE_TRACEME failed\n"); 331 332 ptracee_touch_xstate(); 333 334 raise(SIGTRAP); 335 _exit(0); 336 } 337 338 do { 339 wait(&status); 340 } while (WSTOPSIG(status) != SIGTRAP); 341 342 ptracer_inject_xstate(child); 343 344 ptrace(PTRACE_DETACH, child, NULL, NULL); 345 wait(&status); 346 if (!WIFEXITED(status) || WEXITSTATUS(status)) 347 ksft_exit_fail_msg("ptracee exit error\n"); 348 } 349 350 /* 351 * Test signal delivery for the ABI compatibility. 352 * See the ABI format: arch/x86/include/uapi/asm/sigcontext.h 353 */ 354 355 /* 356 * Avoid using printf() in signal handlers as it is not 357 * async-signal-safe. 358 */ 359 #define SIGNAL_BUF_LEN 1000 360 static char signal_message_buffer[SIGNAL_BUF_LEN]; 361 static void sig_print(char *msg) 362 { 363 int left = SIGNAL_BUF_LEN - strlen(signal_message_buffer) - 1; 364 365 strncat(signal_message_buffer, msg, left); 366 } 367 368 static struct xsave_buffer *stashed_xbuf; 369 370 static void validate_sigfpstate(int sig, siginfo_t *si, void *ctx_void) 371 { 372 ucontext_t *ctx = (ucontext_t *)ctx_void; 373 void *xbuf = ctx->uc_mcontext.fpregs; 374 struct _fpx_sw_bytes *sw_bytes; 375 uint32_t magic2; 376 377 /* Reset the signal message buffer: */ 378 signal_message_buffer[0] = '\0'; 379 380 sw_bytes = get_fpx_sw_bytes(xbuf); 381 if (sw_bytes->magic1 == FP_XSTATE_MAGIC1) 382 sig_print("[OK]\t'magic1' is valid\n"); 383 else 384 sig_print("[FAIL]\t'magic1' is not valid\n"); 385 386 if (get_fpx_sw_bytes_features(xbuf) & xstate.mask) 387 sig_print("[OK]\t'xfeatures' in SW reserved area is valid\n"); 388 else 389 sig_print("[FAIL]\t'xfeatures' in SW reserved area is not valid\n"); 390 391 if (get_xstatebv(xbuf) & xstate.mask) 392 sig_print("[OK]\t'xfeatures' in XSAVE header is valid\n"); 393 else 394 sig_print("[FAIL]\t'xfeatures' in XSAVE header is not valid\n"); 395 396 if (validate_xstate_same(stashed_xbuf, xbuf)) 397 sig_print("[OK]\txstate delivery was successful\n"); 398 else 399 sig_print("[FAIL]\txstate delivery was not successful\n"); 400 401 magic2 = *(uint32_t *)(xbuf + sw_bytes->xstate_size); 402 if (magic2 == FP_XSTATE_MAGIC2) 403 sig_print("[OK]\t'magic2' is valid\n"); 404 else 405 sig_print("[FAIL]\t'magic2' is not valid\n"); 406 407 set_rand_data(&xstate, xbuf); 408 copy_xstate(stashed_xbuf, xbuf); 409 } 410 411 static void test_signal(void) 412 { 413 bool valid_xstate; 414 415 /* 416 * The signal handler will access this to verify xstate context 417 * preservation. 418 */ 419 stashed_xbuf = alloc_xbuf(); 420 if (!stashed_xbuf) 421 ksft_exit_fail_msg("unable to allocate XSAVE buffer\n"); 422 423 printf("[RUN]\t%s: load xstate and raise SIGUSR1\n", xstate.name); 424 425 sethandler(SIGUSR1, validate_sigfpstate, 0); 426 427 load_rand_xstate(&xstate, stashed_xbuf); 428 429 raise(SIGUSR1); 430 431 /* 432 * Immediately record the test result, deferring printf() to 433 * prevent unintended state contamination by that. 434 */ 435 valid_xstate = validate_xregs_same(stashed_xbuf); 436 printf("%s", signal_message_buffer); 437 438 printf("[RUN]\t%s: load new xstate from sighandler and check it after sigreturn\n", 439 xstate.name); 440 441 if (valid_xstate) 442 printf("[OK]\txstate was restored correctly\n"); 443 else 444 printf("[FAIL]\txstate restoration failed\n"); 445 446 clearhandler(SIGUSR1); 447 free(stashed_xbuf); 448 } 449 450 void test_xstate(uint32_t feature_num) 451 { 452 const unsigned int ctxtsw_num_threads = 5, ctxtsw_iterations = 10; 453 unsigned long features; 454 long rc; 455 456 if (!(XFEATURE_MASK_TEST_SUPPORTED & (1 << feature_num))) { 457 ksft_print_msg("The xstate test does not fully support the component %u, yet.\n", 458 feature_num); 459 return; 460 } 461 462 rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_SUPP, &features); 463 if (rc || !(features & (1 << feature_num))) { 464 ksft_print_msg("The kernel does not support feature number: %u\n", feature_num); 465 return; 466 } 467 468 xstate = get_xstate_info(feature_num); 469 if (!xstate.size || !xstate.xbuf_offset) { 470 ksft_exit_fail_msg("invalid state size/offset (%d/%d)\n", 471 xstate.size, xstate.xbuf_offset); 472 } 473 474 test_context_switch(ctxtsw_num_threads, ctxtsw_iterations); 475 test_ptrace(); 476 test_signal(); 477 } 478