.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * xsave/xrstor support. |
---|
3 | 4 | * |
---|
.. | .. |
---|
7 | 8 | #include <linux/cpu.h> |
---|
8 | 9 | #include <linux/mman.h> |
---|
9 | 10 | #include <linux/pkeys.h> |
---|
| 11 | +#include <linux/seq_file.h> |
---|
| 12 | +#include <linux/proc_fs.h> |
---|
10 | 13 | |
---|
11 | 14 | #include <asm/fpu/api.h> |
---|
12 | 15 | #include <asm/fpu/internal.h> |
---|
.. | .. |
---|
34 | 37 | "AVX-512 ZMM_Hi256" , |
---|
35 | 38 | "Processor Trace (unused)" , |
---|
36 | 39 | "Protection Keys User registers", |
---|
| 40 | + "PASID state", |
---|
37 | 41 | "unknown xstate feature" , |
---|
38 | 42 | }; |
---|
39 | 43 | |
---|
.. | .. |
---|
48 | 52 | X86_FEATURE_AVX512F, |
---|
49 | 53 | X86_FEATURE_INTEL_PT, |
---|
50 | 54 | X86_FEATURE_PKU, |
---|
| 55 | + X86_FEATURE_ENQCMD, |
---|
51 | 56 | }; |
---|
52 | 57 | |
---|
53 | 58 | /* |
---|
54 | | - * Mask of xstate features supported by the CPU and the kernel: |
---|
| 59 | + * This represents the full set of bits that should ever be set in a kernel |
---|
| 60 | + * XSAVE buffer, both supervisor and user xstates. |
---|
55 | 61 | */ |
---|
56 | | -u64 xfeatures_mask __read_mostly; |
---|
| 62 | +u64 xfeatures_mask_all __read_mostly; |
---|
57 | 63 | |
---|
58 | 64 | static unsigned int xstate_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1}; |
---|
59 | 65 | static unsigned int xstate_sizes[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1}; |
---|
60 | | -static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8]; |
---|
| 66 | +static unsigned int xstate_comp_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1}; |
---|
| 67 | +static unsigned int xstate_supervisor_only_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1}; |
---|
61 | 68 | |
---|
62 | 69 | /* |
---|
63 | 70 | * The XSAVE area of kernel can be in standard or compacted format; |
---|
.. | .. |
---|
67 | 74 | unsigned int fpu_user_xstate_size; |
---|
68 | 75 | |
---|
69 | 76 | /* |
---|
70 | | - * Clear all of the X86_FEATURE_* bits that are unavailable |
---|
71 | | - * when the CPU has no XSAVE support. |
---|
72 | | - */ |
---|
73 | | -void fpu__xstate_clear_all_cpu_caps(void) |
---|
74 | | -{ |
---|
75 | | - setup_clear_cpu_cap(X86_FEATURE_XSAVE); |
---|
76 | | -} |
---|
77 | | - |
---|
78 | | -/* |
---|
79 | 77 | * Return whether the system supports a given xfeature. |
---|
80 | 78 | * |
---|
81 | 79 | * Also return the name of the (most advanced) feature that the caller requested: |
---|
82 | 80 | */ |
---|
83 | 81 | int cpu_has_xfeatures(u64 xfeatures_needed, const char **feature_name) |
---|
84 | 82 | { |
---|
85 | | - u64 xfeatures_missing = xfeatures_needed & ~xfeatures_mask; |
---|
| 83 | + u64 xfeatures_missing = xfeatures_needed & ~xfeatures_mask_all; |
---|
86 | 84 | |
---|
87 | 85 | if (unlikely(feature_name)) { |
---|
88 | 86 | long xfeature_idx, max_idx; |
---|
.. | .. |
---|
113 | 111 | } |
---|
114 | 112 | EXPORT_SYMBOL_GPL(cpu_has_xfeatures); |
---|
115 | 113 | |
---|
116 | | -static int xfeature_is_supervisor(int xfeature_nr) |
---|
| 114 | +static bool xfeature_is_supervisor(int xfeature_nr) |
---|
117 | 115 | { |
---|
118 | 116 | /* |
---|
119 | | - * We currently do not support supervisor states, but if |
---|
120 | | - * we did, we could find out like this. |
---|
121 | | - * |
---|
122 | | - * SDM says: If state component 'i' is a user state component, |
---|
123 | | - * ECX[0] return 0; if state component i is a supervisor |
---|
124 | | - * state component, ECX[0] returns 1. |
---|
| 117 | + * Extended State Enumeration Sub-leaves (EAX = 0DH, ECX = n, n > 1) |
---|
| 118 | + * returns ECX[0] set to (1) for a supervisor state, and cleared (0) |
---|
| 119 | + * for a user state. |
---|
125 | 120 | */ |
---|
126 | 121 | u32 eax, ebx, ecx, edx; |
---|
127 | 122 | |
---|
128 | 123 | cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx); |
---|
129 | | - return !!(ecx & 1); |
---|
130 | | -} |
---|
131 | | - |
---|
132 | | -static int xfeature_is_user(int xfeature_nr) |
---|
133 | | -{ |
---|
134 | | - return !xfeature_is_supervisor(xfeature_nr); |
---|
| 124 | + return ecx & 1; |
---|
135 | 125 | } |
---|
136 | 126 | |
---|
137 | 127 | /* |
---|
.. | .. |
---|
164 | 154 | * None of the feature bits are in init state. So nothing else |
---|
165 | 155 | * to do for us, as the memory layout is up to date. |
---|
166 | 156 | */ |
---|
167 | | - if ((xfeatures & xfeatures_mask) == xfeatures_mask) |
---|
| 157 | + if ((xfeatures & xfeatures_mask_all) == xfeatures_mask_all) |
---|
168 | 158 | return; |
---|
169 | 159 | |
---|
170 | 160 | /* |
---|
.. | .. |
---|
191 | 181 | * in a special way already: |
---|
192 | 182 | */ |
---|
193 | 183 | feature_bit = 0x2; |
---|
194 | | - xfeatures = (xfeatures_mask & ~xfeatures) >> 2; |
---|
| 184 | + xfeatures = (xfeatures_mask_user() & ~xfeatures) >> 2; |
---|
195 | 185 | |
---|
196 | 186 | /* |
---|
197 | 187 | * Update all the remaining memory layouts according to their |
---|
.. | .. |
---|
219 | 209 | */ |
---|
220 | 210 | void fpu__init_cpu_xstate(void) |
---|
221 | 211 | { |
---|
222 | | - if (!boot_cpu_has(X86_FEATURE_XSAVE) || !xfeatures_mask) |
---|
| 212 | + u64 unsup_bits; |
---|
| 213 | + |
---|
| 214 | + if (!boot_cpu_has(X86_FEATURE_XSAVE) || !xfeatures_mask_all) |
---|
223 | 215 | return; |
---|
224 | 216 | /* |
---|
225 | | - * Make it clear that XSAVES supervisor states are not yet |
---|
226 | | - * implemented should anyone expect it to work by changing |
---|
227 | | - * bits in XFEATURE_MASK_* macros and XCR0. |
---|
| 217 | + * Unsupported supervisor xstates should not be found in |
---|
| 218 | + * the xfeatures mask. |
---|
228 | 219 | */ |
---|
229 | | - WARN_ONCE((xfeatures_mask & XFEATURE_MASK_SUPERVISOR), |
---|
230 | | - "x86/fpu: XSAVES supervisor states are not yet implemented.\n"); |
---|
| 220 | + unsup_bits = xfeatures_mask_all & XFEATURE_MASK_SUPERVISOR_UNSUPPORTED; |
---|
| 221 | + WARN_ONCE(unsup_bits, "x86/fpu: Found unsupported supervisor xstates: 0x%llx\n", |
---|
| 222 | + unsup_bits); |
---|
231 | 223 | |
---|
232 | | - xfeatures_mask &= ~XFEATURE_MASK_SUPERVISOR; |
---|
| 224 | + xfeatures_mask_all &= ~XFEATURE_MASK_SUPERVISOR_UNSUPPORTED; |
---|
233 | 225 | |
---|
234 | 226 | cr4_set_bits(X86_CR4_OSXSAVE); |
---|
235 | | - xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask); |
---|
| 227 | + |
---|
| 228 | + /* |
---|
| 229 | + * XCR_XFEATURE_ENABLED_MASK (aka. XCR0) sets user features |
---|
| 230 | + * managed by XSAVE{C, OPT, S} and XRSTOR{S}. Only XSAVE user |
---|
| 231 | + * states can be set here. |
---|
| 232 | + */ |
---|
| 233 | + xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask_user()); |
---|
| 234 | + |
---|
| 235 | + /* |
---|
| 236 | + * MSR_IA32_XSS sets supervisor states managed by XSAVES. |
---|
| 237 | + */ |
---|
| 238 | + if (boot_cpu_has(X86_FEATURE_XSAVES)) { |
---|
| 239 | + wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() | |
---|
| 240 | + xfeatures_mask_dynamic()); |
---|
| 241 | + } |
---|
236 | 242 | } |
---|
237 | 243 | |
---|
238 | | -/* |
---|
239 | | - * Note that in the future we will likely need a pair of |
---|
240 | | - * functions here: one for user xstates and the other for |
---|
241 | | - * system xstates. For now, they are the same. |
---|
242 | | - */ |
---|
243 | | -static int xfeature_enabled(enum xfeature xfeature) |
---|
| 244 | +static bool xfeature_enabled(enum xfeature xfeature) |
---|
244 | 245 | { |
---|
245 | | - return !!(xfeatures_mask & (1UL << xfeature)); |
---|
| 246 | + return xfeatures_mask_all & BIT_ULL(xfeature); |
---|
246 | 247 | } |
---|
247 | 248 | |
---|
248 | 249 | /* |
---|
.. | .. |
---|
260 | 261 | * in the fixed offsets in the xsave area in either compacted form |
---|
261 | 262 | * or standard form. |
---|
262 | 263 | */ |
---|
263 | | - xstate_offsets[0] = 0; |
---|
264 | | - xstate_sizes[0] = offsetof(struct fxregs_state, xmm_space); |
---|
265 | | - xstate_offsets[1] = xstate_sizes[0]; |
---|
266 | | - xstate_sizes[1] = FIELD_SIZEOF(struct fxregs_state, xmm_space); |
---|
| 264 | + xstate_offsets[XFEATURE_FP] = 0; |
---|
| 265 | + xstate_sizes[XFEATURE_FP] = offsetof(struct fxregs_state, |
---|
| 266 | + xmm_space); |
---|
| 267 | + |
---|
| 268 | + xstate_offsets[XFEATURE_SSE] = xstate_sizes[XFEATURE_FP]; |
---|
| 269 | + xstate_sizes[XFEATURE_SSE] = sizeof_field(struct fxregs_state, |
---|
| 270 | + xmm_space); |
---|
267 | 271 | |
---|
268 | 272 | for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { |
---|
269 | 273 | if (!xfeature_enabled(i)) |
---|
.. | .. |
---|
271 | 275 | |
---|
272 | 276 | cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx); |
---|
273 | 277 | |
---|
274 | | - /* |
---|
275 | | - * If an xfeature is supervisor state, the offset |
---|
276 | | - * in EBX is invalid. We leave it to -1. |
---|
277 | | - */ |
---|
278 | | - if (xfeature_is_user(i)) |
---|
279 | | - xstate_offsets[i] = ebx; |
---|
280 | | - |
---|
281 | 278 | xstate_sizes[i] = eax; |
---|
| 279 | + |
---|
282 | 280 | /* |
---|
283 | | - * In our xstate size checks, we assume that the |
---|
284 | | - * highest-numbered xstate feature has the |
---|
285 | | - * highest offset in the buffer. Ensure it does. |
---|
| 281 | + * If an xfeature is supervisor state, the offset in EBX is |
---|
| 282 | + * invalid, leave it to -1. |
---|
| 283 | + */ |
---|
| 284 | + if (xfeature_is_supervisor(i)) |
---|
| 285 | + continue; |
---|
| 286 | + |
---|
| 287 | + xstate_offsets[i] = ebx; |
---|
| 288 | + |
---|
| 289 | + /* |
---|
| 290 | + * In our xstate size checks, we assume that the highest-numbered |
---|
| 291 | + * xstate feature has the highest offset in the buffer. Ensure |
---|
| 292 | + * it does. |
---|
286 | 293 | */ |
---|
287 | 294 | WARN_ONCE(last_good_offset > xstate_offsets[i], |
---|
288 | | - "x86/fpu: misordered xstate at %d\n", last_good_offset); |
---|
| 295 | + "x86/fpu: misordered xstate at %d\n", last_good_offset); |
---|
| 296 | + |
---|
289 | 297 | last_good_offset = xstate_offsets[i]; |
---|
290 | 298 | } |
---|
291 | 299 | } |
---|
.. | .. |
---|
312 | 320 | print_xstate_feature(XFEATURE_MASK_ZMM_Hi256); |
---|
313 | 321 | print_xstate_feature(XFEATURE_MASK_Hi16_ZMM); |
---|
314 | 322 | print_xstate_feature(XFEATURE_MASK_PKRU); |
---|
| 323 | + print_xstate_feature(XFEATURE_MASK_PASID); |
---|
315 | 324 | } |
---|
316 | 325 | |
---|
317 | 326 | /* |
---|
.. | .. |
---|
332 | 341 | u32 eax, ebx, ecx, edx; |
---|
333 | 342 | |
---|
334 | 343 | CHECK_XFEATURE(xfeature_nr); |
---|
| 344 | + |
---|
| 345 | + if (!xfeature_enabled(xfeature_nr)) { |
---|
| 346 | + WARN_ONCE(1, "Checking alignment of disabled xfeature %d\n", |
---|
| 347 | + xfeature_nr); |
---|
| 348 | + return 0; |
---|
| 349 | + } |
---|
| 350 | + |
---|
335 | 351 | cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx); |
---|
336 | 352 | /* |
---|
337 | 353 | * The value returned by ECX[1] indicates the alignment |
---|
.. | .. |
---|
344 | 360 | /* |
---|
345 | 361 | * This function sets up offsets and sizes of all extended states in |
---|
346 | 362 | * xsave area. This supports both standard format and compacted format |
---|
347 | | - * of the xsave aread. |
---|
| 363 | + * of the xsave area. |
---|
348 | 364 | */ |
---|
349 | | -static void __init setup_xstate_comp(void) |
---|
| 365 | +static void __init setup_xstate_comp_offsets(void) |
---|
350 | 366 | { |
---|
351 | | - unsigned int xstate_comp_sizes[sizeof(xfeatures_mask)*8]; |
---|
| 367 | + unsigned int next_offset; |
---|
352 | 368 | int i; |
---|
353 | 369 | |
---|
354 | 370 | /* |
---|
.. | .. |
---|
356 | 372 | * in the fixed offsets in the xsave area in either compacted form |
---|
357 | 373 | * or standard form. |
---|
358 | 374 | */ |
---|
359 | | - xstate_comp_offsets[0] = 0; |
---|
360 | | - xstate_comp_offsets[1] = offsetof(struct fxregs_state, xmm_space); |
---|
| 375 | + xstate_comp_offsets[XFEATURE_FP] = 0; |
---|
| 376 | + xstate_comp_offsets[XFEATURE_SSE] = offsetof(struct fxregs_state, |
---|
| 377 | + xmm_space); |
---|
361 | 378 | |
---|
362 | 379 | if (!boot_cpu_has(X86_FEATURE_XSAVES)) { |
---|
363 | 380 | for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { |
---|
364 | | - if (xfeature_enabled(i)) { |
---|
| 381 | + if (xfeature_enabled(i)) |
---|
365 | 382 | xstate_comp_offsets[i] = xstate_offsets[i]; |
---|
366 | | - xstate_comp_sizes[i] = xstate_sizes[i]; |
---|
367 | | - } |
---|
368 | 383 | } |
---|
369 | 384 | return; |
---|
370 | 385 | } |
---|
371 | 386 | |
---|
372 | | - xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] = |
---|
373 | | - FXSAVE_SIZE + XSAVE_HDR_SIZE; |
---|
| 387 | + next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE; |
---|
374 | 388 | |
---|
375 | 389 | for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { |
---|
376 | | - if (xfeature_enabled(i)) |
---|
377 | | - xstate_comp_sizes[i] = xstate_sizes[i]; |
---|
378 | | - else |
---|
379 | | - xstate_comp_sizes[i] = 0; |
---|
| 390 | + if (!xfeature_enabled(i)) |
---|
| 391 | + continue; |
---|
380 | 392 | |
---|
381 | | - if (i > FIRST_EXTENDED_XFEATURE) { |
---|
382 | | - xstate_comp_offsets[i] = xstate_comp_offsets[i-1] |
---|
383 | | - + xstate_comp_sizes[i-1]; |
---|
| 393 | + if (xfeature_is_aligned(i)) |
---|
| 394 | + next_offset = ALIGN(next_offset, 64); |
---|
384 | 395 | |
---|
385 | | - if (xfeature_is_aligned(i)) |
---|
386 | | - xstate_comp_offsets[i] = |
---|
387 | | - ALIGN(xstate_comp_offsets[i], 64); |
---|
388 | | - } |
---|
| 396 | + xstate_comp_offsets[i] = next_offset; |
---|
| 397 | + next_offset += xstate_sizes[i]; |
---|
| 398 | + } |
---|
| 399 | +} |
---|
| 400 | + |
---|
| 401 | +/* |
---|
| 402 | + * Setup offsets of a supervisor-state-only XSAVES buffer: |
---|
| 403 | + * |
---|
| 404 | + * The offsets stored in xstate_comp_offsets[] only work for one specific |
---|
| 405 | + * value of the Requested Feature BitMap (RFBM). In cases where a different |
---|
| 406 | + * RFBM value is used, a different set of offsets is required. This set of |
---|
| 407 | + * offsets is for when RFBM=xfeatures_mask_supervisor(). |
---|
| 408 | + */ |
---|
| 409 | +static void __init setup_supervisor_only_offsets(void) |
---|
| 410 | +{ |
---|
| 411 | + unsigned int next_offset; |
---|
| 412 | + int i; |
---|
| 413 | + |
---|
| 414 | + next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE; |
---|
| 415 | + |
---|
| 416 | + for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { |
---|
| 417 | + if (!xfeature_enabled(i) || !xfeature_is_supervisor(i)) |
---|
| 418 | + continue; |
---|
| 419 | + |
---|
| 420 | + if (xfeature_is_aligned(i)) |
---|
| 421 | + next_offset = ALIGN(next_offset, 64); |
---|
| 422 | + |
---|
| 423 | + xstate_supervisor_only_offsets[i] = next_offset; |
---|
| 424 | + next_offset += xstate_sizes[i]; |
---|
389 | 425 | } |
---|
390 | 426 | } |
---|
391 | 427 | |
---|
.. | .. |
---|
420 | 456 | XFEATURE_MASK_Hi16_ZMM | \ |
---|
421 | 457 | XFEATURE_MASK_PKRU | \ |
---|
422 | 458 | XFEATURE_MASK_BNDREGS | \ |
---|
423 | | - XFEATURE_MASK_BNDCSR) |
---|
| 459 | + XFEATURE_MASK_BNDCSR | \ |
---|
| 460 | + XFEATURE_MASK_PASID) |
---|
424 | 461 | |
---|
425 | 462 | /* |
---|
426 | 463 | * setup the xstate image representing the init state |
---|
.. | .. |
---|
429 | 466 | { |
---|
430 | 467 | static int on_boot_cpu __initdata = 1; |
---|
431 | 468 | |
---|
432 | | - BUILD_BUG_ON(XCNTXT_MASK != XFEATURES_INIT_FPSTATE_HANDLED); |
---|
| 469 | + BUILD_BUG_ON((XFEATURE_MASK_USER_SUPPORTED | |
---|
| 470 | + XFEATURE_MASK_SUPERVISOR_SUPPORTED) != |
---|
| 471 | + XFEATURES_INIT_FPSTATE_HANDLED); |
---|
433 | 472 | |
---|
434 | 473 | WARN_ON_FPU(!on_boot_cpu); |
---|
435 | 474 | on_boot_cpu = 0; |
---|
.. | .. |
---|
441 | 480 | print_xstate_features(); |
---|
442 | 481 | |
---|
443 | 482 | if (boot_cpu_has(X86_FEATURE_XSAVES)) |
---|
444 | | - init_fpstate.xsave.header.xcomp_bv = (u64)1 << 63 | xfeatures_mask; |
---|
| 483 | + init_fpstate.xsave.header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT | |
---|
| 484 | + xfeatures_mask_all; |
---|
445 | 485 | |
---|
446 | 486 | /* |
---|
447 | 487 | * Init all the features state with header.xfeatures being 0x0 |
---|
.. | .. |
---|
476 | 516 | * format. Checking a supervisor state's uncompacted offset is |
---|
477 | 517 | * an error. |
---|
478 | 518 | */ |
---|
479 | | - if (XFEATURE_MASK_SUPERVISOR & (1 << xfeature_nr)) { |
---|
| 519 | + if (XFEATURE_MASK_SUPERVISOR_ALL & BIT_ULL(xfeature_nr)) { |
---|
480 | 520 | WARN_ONCE(1, "No fixed offset for xstate %d\n", xfeature_nr); |
---|
481 | 521 | return -1; |
---|
482 | 522 | } |
---|
.. | .. |
---|
486 | 526 | return ebx; |
---|
487 | 527 | } |
---|
488 | 528 | |
---|
489 | | -static int xfeature_size(int xfeature_nr) |
---|
| 529 | +int xfeature_size(int xfeature_nr) |
---|
490 | 530 | { |
---|
491 | 531 | u32 eax, ebx, ecx, edx; |
---|
492 | 532 | |
---|
.. | .. |
---|
510 | 550 | } |
---|
511 | 551 | |
---|
512 | 552 | /* Validate an xstate header supplied by userspace (ptrace or sigreturn) */ |
---|
513 | | -int validate_xstate_header(const struct xstate_header *hdr) |
---|
| 553 | +int validate_user_xstate_header(const struct xstate_header *hdr) |
---|
514 | 554 | { |
---|
515 | 555 | /* No unknown or supervisor features may be set */ |
---|
516 | | - if (hdr->xfeatures & (~xfeatures_mask | XFEATURE_MASK_SUPERVISOR)) |
---|
| 556 | + if (hdr->xfeatures & ~xfeatures_mask_user()) |
---|
517 | 557 | return -EINVAL; |
---|
518 | 558 | |
---|
519 | 559 | /* Userspace must use the uncompacted format */ |
---|
.. | .. |
---|
590 | 630 | XCHECK_SZ(sz, nr, XFEATURE_ZMM_Hi256, struct avx_512_zmm_uppers_state); |
---|
591 | 631 | XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM, struct avx_512_hi16_state); |
---|
592 | 632 | XCHECK_SZ(sz, nr, XFEATURE_PKRU, struct pkru_state); |
---|
| 633 | + XCHECK_SZ(sz, nr, XFEATURE_PASID, struct ia32_pasid_state); |
---|
593 | 634 | |
---|
594 | 635 | /* |
---|
595 | 636 | * Make *SURE* to add any feature numbers in below if |
---|
.. | .. |
---|
598 | 639 | */ |
---|
599 | 640 | if ((nr < XFEATURE_YMM) || |
---|
600 | 641 | (nr >= XFEATURE_MAX) || |
---|
601 | | - (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR)) { |
---|
| 642 | + (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR) || |
---|
| 643 | + ((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_LBR))) { |
---|
602 | 644 | WARN_ONCE(1, "no structure for xstate: %d\n", nr); |
---|
603 | 645 | XSTATE_WARN_ON(1); |
---|
604 | 646 | } |
---|
.. | .. |
---|
608 | 650 | * This essentially double-checks what the cpu told us about |
---|
609 | 651 | * how large the XSAVE buffer needs to be. We are recalculating |
---|
610 | 652 | * it to be safe. |
---|
| 653 | + * |
---|
| 654 | + * Dynamic XSAVE features allocate their own buffers and are not |
---|
| 655 | + * covered by these checks. Only the size of the buffer for task->fpu |
---|
| 656 | + * is checked here. |
---|
611 | 657 | */ |
---|
612 | 658 | static void do_extra_xstate_size_checks(void) |
---|
613 | 659 | { |
---|
.. | .. |
---|
648 | 694 | |
---|
649 | 695 | |
---|
650 | 696 | /* |
---|
651 | | - * Get total size of enabled xstates in XCR0/xfeatures_mask. |
---|
| 697 | + * Get total size of enabled xstates in XCR0 | IA32_XSS. |
---|
652 | 698 | * |
---|
653 | 699 | * Note the SDM's wording here. "sub-function 0" only enumerates |
---|
654 | 700 | * the size of the *user* states. If we use it to size a buffer |
---|
655 | 701 | * that we use 'XSAVES' on, we could potentially overflow the |
---|
656 | 702 | * buffer because 'XSAVES' saves system states too. |
---|
657 | | - * |
---|
658 | | - * Note that we do not currently set any bits on IA32_XSS so |
---|
659 | | - * 'XCR0 | IA32_XSS == XCR0' for now. |
---|
660 | 703 | */ |
---|
661 | 704 | static unsigned int __init get_xsaves_size(void) |
---|
662 | 705 | { |
---|
.. | .. |
---|
671 | 714 | */ |
---|
672 | 715 | cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx); |
---|
673 | 716 | return ebx; |
---|
| 717 | +} |
---|
| 718 | + |
---|
| 719 | +/* |
---|
| 720 | + * Get the total size of the enabled xstates without the dynamic supervisor |
---|
| 721 | + * features. |
---|
| 722 | + */ |
---|
| 723 | +static unsigned int __init get_xsaves_size_no_dynamic(void) |
---|
| 724 | +{ |
---|
| 725 | + u64 mask = xfeatures_mask_dynamic(); |
---|
| 726 | + unsigned int size; |
---|
| 727 | + |
---|
| 728 | + if (!mask) |
---|
| 729 | + return get_xsaves_size(); |
---|
| 730 | + |
---|
| 731 | + /* Disable dynamic features. */ |
---|
| 732 | + wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor()); |
---|
| 733 | + |
---|
| 734 | + /* |
---|
| 735 | + * Ask the hardware what size is required of the buffer. |
---|
| 736 | + * This is the size required for the task->fpu buffer. |
---|
| 737 | + */ |
---|
| 738 | + size = get_xsaves_size(); |
---|
| 739 | + |
---|
| 740 | + /* Re-enable dynamic features so XSAVES will work on them again. */ |
---|
| 741 | + wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() | mask); |
---|
| 742 | + |
---|
| 743 | + return size; |
---|
674 | 744 | } |
---|
675 | 745 | |
---|
676 | 746 | static unsigned int __init get_xsave_size(void) |
---|
.. | .. |
---|
701 | 771 | return false; |
---|
702 | 772 | } |
---|
703 | 773 | |
---|
704 | | -static int init_xstate_size(void) |
---|
| 774 | +static int __init init_xstate_size(void) |
---|
705 | 775 | { |
---|
706 | 776 | /* Recompute the context size for enabled features: */ |
---|
707 | 777 | unsigned int possible_xstate_size; |
---|
.. | .. |
---|
710 | 780 | xsave_size = get_xsave_size(); |
---|
711 | 781 | |
---|
712 | 782 | if (boot_cpu_has(X86_FEATURE_XSAVES)) |
---|
713 | | - possible_xstate_size = get_xsaves_size(); |
---|
| 783 | + possible_xstate_size = get_xsaves_size_no_dynamic(); |
---|
714 | 784 | else |
---|
715 | 785 | possible_xstate_size = xsave_size; |
---|
716 | 786 | |
---|
.. | .. |
---|
738 | 808 | */ |
---|
739 | 809 | static void fpu__init_disable_system_xstate(void) |
---|
740 | 810 | { |
---|
741 | | - xfeatures_mask = 0; |
---|
| 811 | + xfeatures_mask_all = 0; |
---|
742 | 812 | cr4_clear_bits(X86_CR4_OSXSAVE); |
---|
743 | | - fpu__xstate_clear_all_cpu_caps(); |
---|
| 813 | + setup_clear_cpu_cap(X86_FEATURE_XSAVE); |
---|
744 | 814 | } |
---|
745 | 815 | |
---|
746 | 816 | /* |
---|
.. | .. |
---|
773 | 843 | return; |
---|
774 | 844 | } |
---|
775 | 845 | |
---|
| 846 | + /* |
---|
| 847 | + * Find user xstates supported by the processor. |
---|
| 848 | + */ |
---|
776 | 849 | cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx); |
---|
777 | | - xfeatures_mask = eax + ((u64)edx << 32); |
---|
| 850 | + xfeatures_mask_all = eax + ((u64)edx << 32); |
---|
778 | 851 | |
---|
779 | | - if ((xfeatures_mask & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) { |
---|
| 852 | + /* |
---|
| 853 | + * Find supervisor xstates supported by the processor. |
---|
| 854 | + */ |
---|
| 855 | + cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx); |
---|
| 856 | + xfeatures_mask_all |= ecx + ((u64)edx << 32); |
---|
| 857 | + |
---|
| 858 | + if ((xfeatures_mask_user() & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) { |
---|
780 | 859 | /* |
---|
781 | 860 | * This indicates that something really unexpected happened |
---|
782 | 861 | * with the enumeration. Disable XSAVE and try to continue |
---|
783 | 862 | * booting without it. This is too early to BUG(). |
---|
784 | 863 | */ |
---|
785 | | - pr_err("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n", xfeatures_mask); |
---|
| 864 | + pr_err("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n", |
---|
| 865 | + xfeatures_mask_all); |
---|
786 | 866 | goto out_disable; |
---|
787 | 867 | } |
---|
788 | 868 | |
---|
.. | .. |
---|
791 | 871 | */ |
---|
792 | 872 | for (i = 0; i < ARRAY_SIZE(xsave_cpuid_features); i++) { |
---|
793 | 873 | if (!boot_cpu_has(xsave_cpuid_features[i])) |
---|
794 | | - xfeatures_mask &= ~BIT(i); |
---|
| 874 | + xfeatures_mask_all &= ~BIT_ULL(i); |
---|
795 | 875 | } |
---|
796 | 876 | |
---|
797 | | - xfeatures_mask &= fpu__get_supported_xfeatures_mask(); |
---|
| 877 | + xfeatures_mask_all &= fpu__get_supported_xfeatures_mask(); |
---|
798 | 878 | |
---|
799 | 879 | /* Enable xstate instructions to be able to continue with initialization: */ |
---|
800 | 880 | fpu__init_cpu_xstate(); |
---|
.. | .. |
---|
806 | 886 | * Update info used for ptrace frames; use standard-format size and no |
---|
807 | 887 | * supervisor xstates: |
---|
808 | 888 | */ |
---|
809 | | - update_regset_xstate_info(fpu_user_xstate_size, xfeatures_mask & ~XFEATURE_MASK_SUPERVISOR); |
---|
| 889 | + update_regset_xstate_info(fpu_user_xstate_size, xfeatures_mask_user()); |
---|
810 | 890 | |
---|
811 | 891 | fpu__init_prepare_fx_sw_frame(); |
---|
812 | 892 | setup_init_fpu_buf(); |
---|
813 | | - setup_xstate_comp(); |
---|
| 893 | + setup_xstate_comp_offsets(); |
---|
| 894 | + setup_supervisor_only_offsets(); |
---|
| 895 | + |
---|
| 896 | + /* |
---|
| 897 | + * CPU capabilities initialization runs before FPU init. So |
---|
| 898 | + * X86_FEATURE_OSXSAVE is not set. Now that XSAVE is completely |
---|
| 899 | + * functional, set the feature bit so depending code works. |
---|
| 900 | + */ |
---|
| 901 | + setup_force_cpu_cap(X86_FEATURE_OSXSAVE); |
---|
| 902 | + |
---|
814 | 903 | print_xstate_offset_size(); |
---|
815 | 904 | |
---|
816 | 905 | pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n", |
---|
817 | | - xfeatures_mask, |
---|
| 906 | + xfeatures_mask_all, |
---|
818 | 907 | fpu_kernel_xstate_size, |
---|
819 | 908 | boot_cpu_has(X86_FEATURE_XSAVES) ? "compacted" : "standard"); |
---|
820 | 909 | return; |
---|
.. | .. |
---|
833 | 922 | * Restore XCR0 on xsave capable CPUs: |
---|
834 | 923 | */ |
---|
835 | 924 | if (boot_cpu_has(X86_FEATURE_XSAVE)) |
---|
836 | | - xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask); |
---|
| 925 | + xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask_user()); |
---|
| 926 | + |
---|
| 927 | + /* |
---|
| 928 | + * Restore IA32_XSS. The same CPUID bit enumerates support |
---|
| 929 | + * of XSAVES and MSR_IA32_XSS. |
---|
| 930 | + */ |
---|
| 931 | + if (boot_cpu_has(X86_FEATURE_XSAVES)) { |
---|
| 932 | + wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() | |
---|
| 933 | + xfeatures_mask_dynamic()); |
---|
| 934 | + } |
---|
837 | 935 | } |
---|
838 | 936 | |
---|
839 | 937 | /* |
---|
840 | | - * Given an xstate feature mask, calculate where in the xsave |
---|
| 938 | + * Given an xstate feature nr, calculate where in the xsave |
---|
841 | 939 | * buffer the state is. Callers should ensure that the buffer |
---|
842 | 940 | * is valid. |
---|
843 | | - * |
---|
844 | | - * Note: does not work for compacted buffers. |
---|
845 | 941 | */ |
---|
846 | | -void *__raw_xsave_addr(struct xregs_state *xsave, int xstate_feature_mask) |
---|
| 942 | +static void *__raw_xsave_addr(struct xregs_state *xsave, int xfeature_nr) |
---|
847 | 943 | { |
---|
848 | | - int feature_nr = fls64(xstate_feature_mask) - 1; |
---|
849 | | - |
---|
850 | | - if (!xfeature_enabled(feature_nr)) { |
---|
| 944 | + if (!xfeature_enabled(xfeature_nr)) { |
---|
851 | 945 | WARN_ON_FPU(1); |
---|
852 | 946 | return NULL; |
---|
853 | 947 | } |
---|
854 | 948 | |
---|
855 | | - return (void *)xsave + xstate_comp_offsets[feature_nr]; |
---|
| 949 | + return (void *)xsave + xstate_comp_offsets[xfeature_nr]; |
---|
856 | 950 | } |
---|
857 | 951 | /* |
---|
858 | 952 | * Given the xsave area and a state inside, this function returns the |
---|
.. | .. |
---|
866 | 960 | * |
---|
867 | 961 | * Inputs: |
---|
868 | 962 | * xstate: the thread's storage area for all FPU data |
---|
869 | | - * xstate_feature: state which is defined in xsave.h (e.g. |
---|
870 | | - * XFEATURE_MASK_FP, XFEATURE_MASK_SSE, etc...) |
---|
| 963 | + * xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP, |
---|
| 964 | + * XFEATURE_SSE, etc...) |
---|
871 | 965 | * Output: |
---|
872 | 966 | * address of the state in the xsave area, or NULL if the |
---|
873 | 967 | * field is not present in the xsave buffer. |
---|
874 | 968 | */ |
---|
875 | | -void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature) |
---|
| 969 | +void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr) |
---|
876 | 970 | { |
---|
877 | 971 | /* |
---|
878 | 972 | * Do we even *have* xsave state? |
---|
.. | .. |
---|
882 | 976 | |
---|
883 | 977 | /* |
---|
884 | 978 | * We should not ever be requesting features that we |
---|
885 | | - * have not enabled. Remember that pcntxt_mask is |
---|
886 | | - * what we write to the XCR0 register. |
---|
| 979 | + * have not enabled. |
---|
887 | 980 | */ |
---|
888 | | - WARN_ONCE(!(xfeatures_mask & xstate_feature), |
---|
| 981 | + WARN_ONCE(!(xfeatures_mask_all & BIT_ULL(xfeature_nr)), |
---|
889 | 982 | "get of unsupported state"); |
---|
890 | 983 | /* |
---|
891 | 984 | * This assumes the last 'xsave*' instruction to |
---|
892 | | - * have requested that 'xstate_feature' be saved. |
---|
| 985 | + * have requested that 'xfeature_nr' be saved. |
---|
893 | 986 | * If it did not, we might be seeing and old value |
---|
894 | 987 | * of the field in the buffer. |
---|
895 | 988 | * |
---|
.. | .. |
---|
898 | 991 | * or because the "init optimization" caused it |
---|
899 | 992 | * to not be saved. |
---|
900 | 993 | */ |
---|
901 | | - if (!(xsave->header.xfeatures & xstate_feature)) |
---|
| 994 | + if (!(xsave->header.xfeatures & BIT_ULL(xfeature_nr))) |
---|
902 | 995 | return NULL; |
---|
903 | 996 | |
---|
904 | | - return __raw_xsave_addr(xsave, xstate_feature); |
---|
| 997 | + return __raw_xsave_addr(xsave, xfeature_nr); |
---|
905 | 998 | } |
---|
906 | 999 | EXPORT_SYMBOL_GPL(get_xsave_addr); |
---|
907 | 1000 | |
---|
.. | .. |
---|
916 | 1009 | * Note that this only works on the current task. |
---|
917 | 1010 | * |
---|
918 | 1011 | * Inputs: |
---|
919 | | - * @xsave_state: state which is defined in xsave.h (e.g. XFEATURE_MASK_FP, |
---|
920 | | - * XFEATURE_MASK_SSE, etc...) |
---|
| 1012 | + * @xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP, |
---|
| 1013 | + * XFEATURE_SSE, etc...) |
---|
921 | 1014 | * Output: |
---|
922 | 1015 | * address of the state in the xsave area or NULL if the state |
---|
923 | 1016 | * is not present or is in its 'init state'. |
---|
924 | 1017 | */ |
---|
925 | | -const void *get_xsave_field_ptr(int xsave_state) |
---|
| 1018 | +const void *get_xsave_field_ptr(int xfeature_nr) |
---|
926 | 1019 | { |
---|
927 | 1020 | struct fpu *fpu = ¤t->thread.fpu; |
---|
928 | 1021 | |
---|
929 | | - if (!fpu->initialized) |
---|
930 | | - return NULL; |
---|
931 | 1022 | /* |
---|
932 | 1023 | * fpu__save() takes the CPU's xstate registers |
---|
933 | 1024 | * and saves them off to the 'fpu memory buffer. |
---|
934 | 1025 | */ |
---|
935 | 1026 | fpu__save(fpu); |
---|
936 | 1027 | |
---|
937 | | - return get_xsave_addr(&fpu->state.xsave, xsave_state); |
---|
| 1028 | + return get_xsave_addr(&fpu->state.xsave, xfeature_nr); |
---|
938 | 1029 | } |
---|
939 | 1030 | |
---|
940 | 1031 | #ifdef CONFIG_ARCH_HAS_PKEYS |
---|
.. | .. |
---|
1001 | 1092 | return true; |
---|
1002 | 1093 | } |
---|
1003 | 1094 | |
---|
1004 | | -static void fill_gap(unsigned to, void **kbuf, unsigned *pos, unsigned *count) |
---|
| 1095 | +static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, |
---|
| 1096 | + void *init_xstate, unsigned int size) |
---|
1005 | 1097 | { |
---|
1006 | | - if (*pos < to) { |
---|
1007 | | - unsigned size = to - *pos; |
---|
1008 | | - |
---|
1009 | | - if (size > *count) |
---|
1010 | | - size = *count; |
---|
1011 | | - memcpy(*kbuf, (void *)&init_fpstate.xsave + *pos, size); |
---|
1012 | | - *kbuf += size; |
---|
1013 | | - *pos += size; |
---|
1014 | | - *count -= size; |
---|
1015 | | - } |
---|
1016 | | -} |
---|
1017 | | - |
---|
1018 | | -static void copy_part(unsigned offset, unsigned size, void *from, |
---|
1019 | | - void **kbuf, unsigned *pos, unsigned *count) |
---|
1020 | | -{ |
---|
1021 | | - fill_gap(offset, kbuf, pos, count); |
---|
1022 | | - if (size > *count) |
---|
1023 | | - size = *count; |
---|
1024 | | - if (size) { |
---|
1025 | | - memcpy(*kbuf, from, size); |
---|
1026 | | - *kbuf += size; |
---|
1027 | | - *pos += size; |
---|
1028 | | - *count -= size; |
---|
1029 | | - } |
---|
| 1098 | + membuf_write(to, from_xstate ? xstate : init_xstate, size); |
---|
1030 | 1099 | } |
---|
1031 | 1100 | |
---|
1032 | 1101 | /* |
---|
.. | .. |
---|
1036 | 1105 | * It supports partial copy but pos always starts from zero. This is called |
---|
1037 | 1106 | * from xstateregs_get() and there we check the CPU has XSAVES. |
---|
1038 | 1107 | */ |
---|
1039 | | -int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) |
---|
| 1108 | +void copy_xstate_to_kernel(struct membuf to, struct xregs_state *xsave) |
---|
1040 | 1109 | { |
---|
| 1110 | + const unsigned int off_mxcsr = offsetof(struct fxregs_state, mxcsr); |
---|
| 1111 | + struct xregs_state *xinit = &init_fpstate.xsave; |
---|
1041 | 1112 | struct xstate_header header; |
---|
1042 | | - const unsigned off_mxcsr = offsetof(struct fxregs_state, mxcsr); |
---|
1043 | | - unsigned count = size_total; |
---|
| 1113 | + unsigned int zerofrom; |
---|
1044 | 1114 | int i; |
---|
1045 | 1115 | |
---|
1046 | 1116 | /* |
---|
1047 | | - * Currently copy_regset_to_user() starts from pos 0: |
---|
1048 | | - */ |
---|
1049 | | - if (unlikely(offset_start != 0)) |
---|
1050 | | - return -EFAULT; |
---|
1051 | | - |
---|
1052 | | - /* |
---|
1053 | 1117 | * The destination is a ptrace buffer; we put in only user xstates: |
---|
1054 | 1118 | */ |
---|
1055 | 1119 | memset(&header, 0, sizeof(header)); |
---|
1056 | 1120 | header.xfeatures = xsave->header.xfeatures; |
---|
1057 | | - header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; |
---|
| 1121 | + header.xfeatures &= xfeatures_mask_user(); |
---|
1058 | 1122 | |
---|
1059 | | - if (header.xfeatures & XFEATURE_MASK_FP) |
---|
1060 | | - copy_part(0, off_mxcsr, |
---|
1061 | | - &xsave->i387, &kbuf, &offset_start, &count); |
---|
1062 | | - if (header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM)) |
---|
1063 | | - copy_part(off_mxcsr, MXCSR_AND_FLAGS_SIZE, |
---|
1064 | | - &xsave->i387.mxcsr, &kbuf, &offset_start, &count); |
---|
1065 | | - if (header.xfeatures & XFEATURE_MASK_FP) |
---|
1066 | | - copy_part(offsetof(struct fxregs_state, st_space), 128, |
---|
1067 | | - &xsave->i387.st_space, &kbuf, &offset_start, &count); |
---|
1068 | | - if (header.xfeatures & XFEATURE_MASK_SSE) |
---|
1069 | | - copy_part(xstate_offsets[XFEATURE_SSE], 256, |
---|
1070 | | - &xsave->i387.xmm_space, &kbuf, &offset_start, &count); |
---|
1071 | | - /* |
---|
1072 | | - * Fill xsave->i387.sw_reserved value for ptrace frame: |
---|
1073 | | - */ |
---|
1074 | | - copy_part(offsetof(struct fxregs_state, sw_reserved), 48, |
---|
1075 | | - xstate_fx_sw_bytes, &kbuf, &offset_start, &count); |
---|
1076 | | - /* |
---|
1077 | | - * Copy xregs_state->header: |
---|
1078 | | - */ |
---|
1079 | | - copy_part(offsetof(struct xregs_state, header), sizeof(header), |
---|
1080 | | - &header, &kbuf, &offset_start, &count); |
---|
| 1123 | + /* Copy FP state up to MXCSR */ |
---|
| 1124 | + copy_feature(header.xfeatures & XFEATURE_MASK_FP, &to, &xsave->i387, |
---|
| 1125 | + &xinit->i387, off_mxcsr); |
---|
| 1126 | + |
---|
| 1127 | + /* Copy MXCSR when SSE or YMM are set in the feature mask */ |
---|
| 1128 | + copy_feature(header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM), |
---|
| 1129 | + &to, &xsave->i387.mxcsr, &xinit->i387.mxcsr, |
---|
| 1130 | + MXCSR_AND_FLAGS_SIZE); |
---|
| 1131 | + |
---|
| 1132 | + /* Copy the remaining FP state */ |
---|
| 1133 | + copy_feature(header.xfeatures & XFEATURE_MASK_FP, |
---|
| 1134 | + &to, &xsave->i387.st_space, &xinit->i387.st_space, |
---|
| 1135 | + sizeof(xsave->i387.st_space)); |
---|
| 1136 | + |
---|
| 1137 | + /* Copy the SSE state - shared with YMM, but independently managed */ |
---|
| 1138 | + copy_feature(header.xfeatures & XFEATURE_MASK_SSE, |
---|
| 1139 | + &to, &xsave->i387.xmm_space, &xinit->i387.xmm_space, |
---|
| 1140 | + sizeof(xsave->i387.xmm_space)); |
---|
| 1141 | + |
---|
| 1142 | + /* Zero the padding area */ |
---|
| 1143 | + membuf_zero(&to, sizeof(xsave->i387.padding)); |
---|
| 1144 | + |
---|
| 1145 | + /* Copy xsave->i387.sw_reserved */ |
---|
| 1146 | + membuf_write(&to, xstate_fx_sw_bytes, sizeof(xsave->i387.sw_reserved)); |
---|
| 1147 | + |
---|
| 1148 | + /* Copy the user space relevant state of @xsave->header */ |
---|
| 1149 | + membuf_write(&to, &header, sizeof(header)); |
---|
| 1150 | + |
---|
| 1151 | + zerofrom = offsetof(struct xregs_state, extended_state_area); |
---|
1081 | 1152 | |
---|
1082 | 1153 | for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { |
---|
1083 | 1154 | /* |
---|
1084 | | - * Copy only in-use xstates: |
---|
| 1155 | + * The ptrace buffer is in non-compacted XSAVE format. |
---|
| 1156 | + * In non-compacted format disabled features still occupy |
---|
| 1157 | + * state space, but there is no state to copy from in the |
---|
| 1158 | + * compacted init_fpstate. The gap tracking will zero this |
---|
| 1159 | + * later. |
---|
1085 | 1160 | */ |
---|
1086 | | - if ((header.xfeatures >> i) & 1) { |
---|
1087 | | - void *src = __raw_xsave_addr(xsave, 1 << i); |
---|
| 1161 | + if (!(xfeatures_mask_user() & BIT_ULL(i))) |
---|
| 1162 | + continue; |
---|
1088 | 1163 | |
---|
1089 | | - copy_part(xstate_offsets[i], xstate_sizes[i], |
---|
1090 | | - src, &kbuf, &offset_start, &count); |
---|
1091 | | - } |
---|
1092 | | - |
---|
1093 | | - } |
---|
1094 | | - fill_gap(size_total, &kbuf, &offset_start, &count); |
---|
1095 | | - |
---|
1096 | | - return 0; |
---|
1097 | | -} |
---|
1098 | | - |
---|
1099 | | -static inline int |
---|
1100 | | -__copy_xstate_to_user(void __user *ubuf, const void *data, unsigned int offset, unsigned int size, unsigned int size_total) |
---|
1101 | | -{ |
---|
1102 | | - if (!size) |
---|
1103 | | - return 0; |
---|
1104 | | - |
---|
1105 | | - if (offset < size_total) { |
---|
1106 | | - unsigned int copy = min(size, size_total - offset); |
---|
1107 | | - |
---|
1108 | | - if (__copy_to_user(ubuf + offset, data, copy)) |
---|
1109 | | - return -EFAULT; |
---|
1110 | | - } |
---|
1111 | | - return 0; |
---|
1112 | | -} |
---|
1113 | | - |
---|
1114 | | -/* |
---|
1115 | | - * Convert from kernel XSAVES compacted format to standard format and copy |
---|
1116 | | - * to a user-space buffer. It supports partial copy but pos always starts from |
---|
1117 | | - * zero. This is called from xstateregs_get() and there we check the CPU |
---|
1118 | | - * has XSAVES. |
---|
1119 | | - */ |
---|
1120 | | -int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) |
---|
1121 | | -{ |
---|
1122 | | - unsigned int offset, size; |
---|
1123 | | - int ret, i; |
---|
1124 | | - struct xstate_header header; |
---|
1125 | | - |
---|
1126 | | - /* |
---|
1127 | | - * Currently copy_regset_to_user() starts from pos 0: |
---|
1128 | | - */ |
---|
1129 | | - if (unlikely(offset_start != 0)) |
---|
1130 | | - return -EFAULT; |
---|
1131 | | - |
---|
1132 | | - /* |
---|
1133 | | - * The destination is a ptrace buffer; we put in only user xstates: |
---|
1134 | | - */ |
---|
1135 | | - memset(&header, 0, sizeof(header)); |
---|
1136 | | - header.xfeatures = xsave->header.xfeatures; |
---|
1137 | | - header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; |
---|
1138 | | - |
---|
1139 | | - /* |
---|
1140 | | - * Copy xregs_state->header: |
---|
1141 | | - */ |
---|
1142 | | - offset = offsetof(struct xregs_state, header); |
---|
1143 | | - size = sizeof(header); |
---|
1144 | | - |
---|
1145 | | - ret = __copy_xstate_to_user(ubuf, &header, offset, size, size_total); |
---|
1146 | | - if (ret) |
---|
1147 | | - return ret; |
---|
1148 | | - |
---|
1149 | | - for (i = 0; i < XFEATURE_MAX; i++) { |
---|
1150 | 1164 | /* |
---|
1151 | | - * Copy only in-use xstates: |
---|
| 1165 | + * If there was a feature or alignment gap, zero the space |
---|
| 1166 | + * in the destination buffer. |
---|
1152 | 1167 | */ |
---|
1153 | | - if ((header.xfeatures >> i) & 1) { |
---|
1154 | | - void *src = __raw_xsave_addr(xsave, 1 << i); |
---|
| 1168 | + if (zerofrom < xstate_offsets[i]) |
---|
| 1169 | + membuf_zero(&to, xstate_offsets[i] - zerofrom); |
---|
1155 | 1170 | |
---|
1156 | | - offset = xstate_offsets[i]; |
---|
1157 | | - size = xstate_sizes[i]; |
---|
| 1171 | + copy_feature(header.xfeatures & BIT_ULL(i), &to, |
---|
| 1172 | + __raw_xsave_addr(xsave, i), |
---|
| 1173 | + __raw_xsave_addr(xinit, i), |
---|
| 1174 | + xstate_sizes[i]); |
---|
1158 | 1175 | |
---|
1159 | | - /* The next component has to fit fully into the output buffer: */ |
---|
1160 | | - if (offset + size > size_total) |
---|
1161 | | - break; |
---|
1162 | | - |
---|
1163 | | - ret = __copy_xstate_to_user(ubuf, src, offset, size, size_total); |
---|
1164 | | - if (ret) |
---|
1165 | | - return ret; |
---|
1166 | | - } |
---|
1167 | | - |
---|
| 1176 | + /* |
---|
| 1177 | + * Keep track of the last copied state in the non-compacted |
---|
| 1178 | + * target buffer for gap zeroing. |
---|
| 1179 | + */ |
---|
| 1180 | + zerofrom = xstate_offsets[i] + xstate_sizes[i]; |
---|
1168 | 1181 | } |
---|
1169 | 1182 | |
---|
1170 | | - if (xfeatures_mxcsr_quirk(header.xfeatures)) { |
---|
1171 | | - offset = offsetof(struct fxregs_state, mxcsr); |
---|
1172 | | - size = MXCSR_AND_FLAGS_SIZE; |
---|
1173 | | - __copy_xstate_to_user(ubuf, &xsave->i387.mxcsr, offset, size, size_total); |
---|
1174 | | - } |
---|
1175 | | - |
---|
1176 | | - /* |
---|
1177 | | - * Fill xsave->i387.sw_reserved value for ptrace frame: |
---|
1178 | | - */ |
---|
1179 | | - offset = offsetof(struct fxregs_state, sw_reserved); |
---|
1180 | | - size = sizeof(xstate_fx_sw_bytes); |
---|
1181 | | - |
---|
1182 | | - ret = __copy_xstate_to_user(ubuf, xstate_fx_sw_bytes, offset, size, size_total); |
---|
1183 | | - if (ret) |
---|
1184 | | - return ret; |
---|
1185 | | - |
---|
1186 | | - return 0; |
---|
| 1183 | + if (to.left) |
---|
| 1184 | + membuf_zero(&to, to.left); |
---|
1187 | 1185 | } |
---|
1188 | 1186 | |
---|
1189 | 1187 | /* |
---|
.. | .. |
---|
1201 | 1199 | |
---|
1202 | 1200 | memcpy(&hdr, kbuf + offset, size); |
---|
1203 | 1201 | |
---|
1204 | | - if (validate_xstate_header(&hdr)) |
---|
| 1202 | + if (validate_user_xstate_header(&hdr)) |
---|
1205 | 1203 | return -EINVAL; |
---|
1206 | 1204 | |
---|
1207 | 1205 | for (i = 0; i < XFEATURE_MAX; i++) { |
---|
1208 | 1206 | u64 mask = ((u64)1 << i); |
---|
1209 | 1207 | |
---|
1210 | 1208 | if (hdr.xfeatures & mask) { |
---|
1211 | | - void *dst = __raw_xsave_addr(xsave, 1 << i); |
---|
| 1209 | + void *dst = __raw_xsave_addr(xsave, i); |
---|
1212 | 1210 | |
---|
1213 | 1211 | offset = xstate_offsets[i]; |
---|
1214 | 1212 | size = xstate_sizes[i]; |
---|
.. | .. |
---|
1227 | 1225 | * The state that came in from userspace was user-state only. |
---|
1228 | 1226 | * Mask all the user states out of 'xfeatures': |
---|
1229 | 1227 | */ |
---|
1230 | | - xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR; |
---|
| 1228 | + xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR_ALL; |
---|
1231 | 1229 | |
---|
1232 | 1230 | /* |
---|
1233 | 1231 | * Add back in the features that came in from userspace: |
---|
.. | .. |
---|
1255 | 1253 | if (__copy_from_user(&hdr, ubuf + offset, size)) |
---|
1256 | 1254 | return -EFAULT; |
---|
1257 | 1255 | |
---|
1258 | | - if (validate_xstate_header(&hdr)) |
---|
| 1256 | + if (validate_user_xstate_header(&hdr)) |
---|
1259 | 1257 | return -EINVAL; |
---|
1260 | 1258 | |
---|
1261 | 1259 | for (i = 0; i < XFEATURE_MAX; i++) { |
---|
1262 | 1260 | u64 mask = ((u64)1 << i); |
---|
1263 | 1261 | |
---|
1264 | 1262 | if (hdr.xfeatures & mask) { |
---|
1265 | | - void *dst = __raw_xsave_addr(xsave, 1 << i); |
---|
| 1263 | + void *dst = __raw_xsave_addr(xsave, i); |
---|
1266 | 1264 | |
---|
1267 | 1265 | offset = xstate_offsets[i]; |
---|
1268 | 1266 | size = xstate_sizes[i]; |
---|
.. | .. |
---|
1283 | 1281 | * The state that came in from userspace was user-state only. |
---|
1284 | 1282 | * Mask all the user states out of 'xfeatures': |
---|
1285 | 1283 | */ |
---|
1286 | | - xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR; |
---|
| 1284 | + xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR_ALL; |
---|
1287 | 1285 | |
---|
1288 | 1286 | /* |
---|
1289 | 1287 | * Add back in the features that came in from userspace: |
---|
.. | .. |
---|
1292 | 1290 | |
---|
1293 | 1291 | return 0; |
---|
1294 | 1292 | } |
---|
| 1293 | + |
---|
| 1294 | +/* |
---|
| 1295 | + * Save only supervisor states to the kernel buffer. This blows away all |
---|
| 1296 | + * old states, and is intended to be used only in __fpu__restore_sig(), where |
---|
| 1297 | + * user states are restored from the user buffer. |
---|
| 1298 | + */ |
---|
| 1299 | +void copy_supervisor_to_kernel(struct xregs_state *xstate) |
---|
| 1300 | +{ |
---|
| 1301 | + struct xstate_header *header; |
---|
| 1302 | + u64 max_bit, min_bit; |
---|
| 1303 | + u32 lmask, hmask; |
---|
| 1304 | + int err, i; |
---|
| 1305 | + |
---|
| 1306 | + if (WARN_ON(!boot_cpu_has(X86_FEATURE_XSAVES))) |
---|
| 1307 | + return; |
---|
| 1308 | + |
---|
| 1309 | + if (!xfeatures_mask_supervisor()) |
---|
| 1310 | + return; |
---|
| 1311 | + |
---|
| 1312 | + max_bit = __fls(xfeatures_mask_supervisor()); |
---|
| 1313 | + min_bit = __ffs(xfeatures_mask_supervisor()); |
---|
| 1314 | + |
---|
| 1315 | + lmask = xfeatures_mask_supervisor(); |
---|
| 1316 | + hmask = xfeatures_mask_supervisor() >> 32; |
---|
| 1317 | + XSTATE_OP(XSAVES, xstate, lmask, hmask, err); |
---|
| 1318 | + |
---|
| 1319 | + /* We should never fault when copying to a kernel buffer: */ |
---|
| 1320 | + if (WARN_ON_FPU(err)) |
---|
| 1321 | + return; |
---|
| 1322 | + |
---|
| 1323 | + /* |
---|
| 1324 | + * At this point, the buffer has only supervisor states and must be |
---|
| 1325 | + * converted back to normal kernel format. |
---|
| 1326 | + */ |
---|
| 1327 | + header = &xstate->header; |
---|
| 1328 | + header->xcomp_bv |= xfeatures_mask_all; |
---|
| 1329 | + |
---|
| 1330 | + /* |
---|
| 1331 | + * This only moves states up in the buffer. Start with |
---|
| 1332 | + * the last state and move backwards so that states are |
---|
| 1333 | + * not overwritten until after they are moved. Note: |
---|
| 1334 | + * memmove() allows overlapping src/dst buffers. |
---|
| 1335 | + */ |
---|
| 1336 | + for (i = max_bit; i >= min_bit; i--) { |
---|
| 1337 | + u8 *xbuf = (u8 *)xstate; |
---|
| 1338 | + |
---|
| 1339 | + if (!((header->xfeatures >> i) & 1)) |
---|
| 1340 | + continue; |
---|
| 1341 | + |
---|
| 1342 | + /* Move xfeature 'i' into its normal location */ |
---|
| 1343 | + memmove(xbuf + xstate_comp_offsets[i], |
---|
| 1344 | + xbuf + xstate_supervisor_only_offsets[i], |
---|
| 1345 | + xstate_sizes[i]); |
---|
| 1346 | + } |
---|
| 1347 | +} |
---|
| 1348 | + |
---|
| 1349 | +/** |
---|
| 1350 | + * copy_dynamic_supervisor_to_kernel() - Save dynamic supervisor states to |
---|
| 1351 | + * an xsave area |
---|
| 1352 | + * @xstate: A pointer to an xsave area |
---|
| 1353 | + * @mask: Represent the dynamic supervisor features saved into the xsave area |
---|
| 1354 | + * |
---|
| 1355 | + * Only the dynamic supervisor states sets in the mask are saved into the xsave |
---|
| 1356 | + * area (See the comment in XFEATURE_MASK_DYNAMIC for the details of dynamic |
---|
| 1357 | + * supervisor feature). Besides the dynamic supervisor states, the legacy |
---|
| 1358 | + * region and XSAVE header are also saved into the xsave area. The supervisor |
---|
| 1359 | + * features in the XFEATURE_MASK_SUPERVISOR_SUPPORTED and |
---|
| 1360 | + * XFEATURE_MASK_SUPERVISOR_UNSUPPORTED are not saved. |
---|
| 1361 | + * |
---|
| 1362 | + * The xsave area must be 64-bytes aligned. |
---|
| 1363 | + */ |
---|
| 1364 | +void copy_dynamic_supervisor_to_kernel(struct xregs_state *xstate, u64 mask) |
---|
| 1365 | +{ |
---|
| 1366 | + u64 dynamic_mask = xfeatures_mask_dynamic() & mask; |
---|
| 1367 | + u32 lmask, hmask; |
---|
| 1368 | + int err; |
---|
| 1369 | + |
---|
| 1370 | + if (WARN_ON_FPU(!boot_cpu_has(X86_FEATURE_XSAVES))) |
---|
| 1371 | + return; |
---|
| 1372 | + |
---|
| 1373 | + if (WARN_ON_FPU(!dynamic_mask)) |
---|
| 1374 | + return; |
---|
| 1375 | + |
---|
| 1376 | + lmask = dynamic_mask; |
---|
| 1377 | + hmask = dynamic_mask >> 32; |
---|
| 1378 | + |
---|
| 1379 | + XSTATE_OP(XSAVES, xstate, lmask, hmask, err); |
---|
| 1380 | + |
---|
| 1381 | + /* Should never fault when copying to a kernel buffer */ |
---|
| 1382 | + WARN_ON_FPU(err); |
---|
| 1383 | +} |
---|
| 1384 | + |
---|
| 1385 | +/** |
---|
| 1386 | + * copy_kernel_to_dynamic_supervisor() - Restore dynamic supervisor states from |
---|
| 1387 | + * an xsave area |
---|
| 1388 | + * @xstate: A pointer to an xsave area |
---|
| 1389 | + * @mask: Represent the dynamic supervisor features restored from the xsave area |
---|
| 1390 | + * |
---|
| 1391 | + * Only the dynamic supervisor states sets in the mask are restored from the |
---|
| 1392 | + * xsave area (See the comment in XFEATURE_MASK_DYNAMIC for the details of |
---|
| 1393 | + * dynamic supervisor feature). Besides the dynamic supervisor states, the |
---|
| 1394 | + * legacy region and XSAVE header are also restored from the xsave area. The |
---|
| 1395 | + * supervisor features in the XFEATURE_MASK_SUPERVISOR_SUPPORTED and |
---|
| 1396 | + * XFEATURE_MASK_SUPERVISOR_UNSUPPORTED are not restored. |
---|
| 1397 | + * |
---|
| 1398 | + * The xsave area must be 64-bytes aligned. |
---|
| 1399 | + */ |
---|
| 1400 | +void copy_kernel_to_dynamic_supervisor(struct xregs_state *xstate, u64 mask) |
---|
| 1401 | +{ |
---|
| 1402 | + u64 dynamic_mask = xfeatures_mask_dynamic() & mask; |
---|
| 1403 | + u32 lmask, hmask; |
---|
| 1404 | + int err; |
---|
| 1405 | + |
---|
| 1406 | + if (WARN_ON_FPU(!boot_cpu_has(X86_FEATURE_XSAVES))) |
---|
| 1407 | + return; |
---|
| 1408 | + |
---|
| 1409 | + if (WARN_ON_FPU(!dynamic_mask)) |
---|
| 1410 | + return; |
---|
| 1411 | + |
---|
| 1412 | + lmask = dynamic_mask; |
---|
| 1413 | + hmask = dynamic_mask >> 32; |
---|
| 1414 | + |
---|
| 1415 | + XSTATE_OP(XRSTORS, xstate, lmask, hmask, err); |
---|
| 1416 | + |
---|
| 1417 | + /* Should never fault when copying from a kernel buffer */ |
---|
| 1418 | + WARN_ON_FPU(err); |
---|
| 1419 | +} |
---|
| 1420 | + |
---|
| 1421 | +#ifdef CONFIG_PROC_PID_ARCH_STATUS |
---|
| 1422 | +/* |
---|
| 1423 | + * Report the amount of time elapsed in millisecond since last AVX512 |
---|
| 1424 | + * use in the task. |
---|
| 1425 | + */ |
---|
| 1426 | +static void avx512_status(struct seq_file *m, struct task_struct *task) |
---|
| 1427 | +{ |
---|
| 1428 | + unsigned long timestamp = READ_ONCE(task->thread.fpu.avx512_timestamp); |
---|
| 1429 | + long delta; |
---|
| 1430 | + |
---|
| 1431 | + if (!timestamp) { |
---|
| 1432 | + /* |
---|
| 1433 | + * Report -1 if no AVX512 usage |
---|
| 1434 | + */ |
---|
| 1435 | + delta = -1; |
---|
| 1436 | + } else { |
---|
| 1437 | + delta = (long)(jiffies - timestamp); |
---|
| 1438 | + /* |
---|
| 1439 | + * Cap to LONG_MAX if time difference > LONG_MAX |
---|
| 1440 | + */ |
---|
| 1441 | + if (delta < 0) |
---|
| 1442 | + delta = LONG_MAX; |
---|
| 1443 | + delta = jiffies_to_msecs(delta); |
---|
| 1444 | + } |
---|
| 1445 | + |
---|
| 1446 | + seq_put_decimal_ll(m, "AVX512_elapsed_ms:\t", delta); |
---|
| 1447 | + seq_putc(m, '\n'); |
---|
| 1448 | +} |
---|
| 1449 | + |
---|
| 1450 | +/* |
---|
| 1451 | + * Report architecture specific information |
---|
| 1452 | + */ |
---|
| 1453 | +int proc_pid_arch_status(struct seq_file *m, struct pid_namespace *ns, |
---|
| 1454 | + struct pid *pid, struct task_struct *task) |
---|
| 1455 | +{ |
---|
| 1456 | + /* |
---|
| 1457 | + * Report AVX512 state if the processor and build option supported. |
---|
| 1458 | + */ |
---|
| 1459 | + if (cpu_feature_enabled(X86_FEATURE_AVX512F)) |
---|
| 1460 | + avx512_status(m, task); |
---|
| 1461 | + |
---|
| 1462 | + return 0; |
---|
| 1463 | +} |
---|
| 1464 | +#endif /* CONFIG_PROC_PID_ARCH_STATUS */ |
---|