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