Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'x86_urgent_for_v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:
"Two more urgent FPU fixes:

- prevent unprivileged userspace from reinitializing supervisor
states

- prepare init_fpstate, which is the buffer used when initializing
FPU state, properly in case the skip-writing-state-components
XSAVE* variants are used"

* tag 'x86_urgent_for_v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/fpu: Make init_fpstate correct with optimized XSAVE
x86/fpu: Preserve supervisor states in sanitize_restored_user_xstate()

+54 -43
+8 -22
arch/x86/include/asm/fpu/internal.h
··· 204 204 asm volatile("fxsaveq %[fx]" : [fx] "=m" (fpu->state.fxsave)); 205 205 } 206 206 207 + static inline void fxsave(struct fxregs_state *fx) 208 + { 209 + if (IS_ENABLED(CONFIG_X86_32)) 210 + asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx)); 211 + else 212 + asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx)); 213 + } 214 + 207 215 /* These macros all use (%edi)/(%rdi) as the single memory argument. */ 208 216 #define XSAVE ".byte " REX_PREFIX "0x0f,0xae,0x27" 209 217 #define XSAVEOPT ".byte " REX_PREFIX "0x0f,0xae,0x37" ··· 275 267 : \ 276 268 : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ 277 269 : "memory") 278 - 279 - /* 280 - * This function is called only during boot time when x86 caps are not set 281 - * up and alternative can not be used yet. 282 - */ 283 - static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate) 284 - { 285 - u64 mask = xfeatures_mask_all; 286 - u32 lmask = mask; 287 - u32 hmask = mask >> 32; 288 - int err; 289 - 290 - WARN_ON(system_state != SYSTEM_BOOTING); 291 - 292 - if (boot_cpu_has(X86_FEATURE_XSAVES)) 293 - XSTATE_OP(XSAVES, xstate, lmask, hmask, err); 294 - else 295 - XSTATE_OP(XSAVE, xstate, lmask, hmask, err); 296 - 297 - /* We should never fault when copying to a kernel buffer: */ 298 - WARN_ON_FPU(err); 299 - } 300 270 301 271 /* 302 272 * This function is called only during boot time when x86 caps are not set
+8 -18
arch/x86/kernel/fpu/signal.c
··· 221 221 222 222 if (use_xsave()) { 223 223 /* 224 - * Note: we don't need to zero the reserved bits in the 225 - * xstate_header here because we either didn't copy them at all, 226 - * or we checked earlier that they aren't set. 224 + * Clear all feature bits which are not set in 225 + * user_xfeatures and clear all extended features 226 + * for fx_only mode. 227 227 */ 228 + u64 mask = fx_only ? XFEATURE_MASK_FPSSE : user_xfeatures; 228 229 229 230 /* 230 - * 'user_xfeatures' might have bits clear which are 231 - * set in header->xfeatures. This represents features that 232 - * were in init state prior to a signal delivery, and need 233 - * to be reset back to the init state. Clear any user 234 - * feature bits which are set in the kernel buffer to get 235 - * them back to the init state. 236 - * 237 - * Supervisor state is unchanged by input from userspace. 238 - * Ensure supervisor state bits stay set and supervisor 239 - * state is not modified. 231 + * Supervisor state has to be preserved. The sigframe 232 + * restore can only modify user features, i.e. @mask 233 + * cannot contain them. 240 234 */ 241 - if (fx_only) 242 - header->xfeatures = XFEATURE_MASK_FPSSE; 243 - else 244 - header->xfeatures &= user_xfeatures | 245 - xfeatures_mask_supervisor(); 235 + header->xfeatures &= mask | xfeatures_mask_supervisor(); 246 236 } 247 237 248 238 if (use_fxsr()) {
+38 -3
arch/x86/kernel/fpu/xstate.c
··· 441 441 } 442 442 443 443 /* 444 + * All supported features have either init state all zeros or are 445 + * handled in setup_init_fpu() individually. This is an explicit 446 + * feature list and does not use XFEATURE_MASK*SUPPORTED to catch 447 + * newly added supported features at build time and make people 448 + * actually look at the init state for the new feature. 449 + */ 450 + #define XFEATURES_INIT_FPSTATE_HANDLED \ 451 + (XFEATURE_MASK_FP | \ 452 + XFEATURE_MASK_SSE | \ 453 + XFEATURE_MASK_YMM | \ 454 + XFEATURE_MASK_OPMASK | \ 455 + XFEATURE_MASK_ZMM_Hi256 | \ 456 + XFEATURE_MASK_Hi16_ZMM | \ 457 + XFEATURE_MASK_PKRU | \ 458 + XFEATURE_MASK_BNDREGS | \ 459 + XFEATURE_MASK_BNDCSR | \ 460 + XFEATURE_MASK_PASID) 461 + 462 + /* 444 463 * setup the xstate image representing the init state 445 464 */ 446 465 static void __init setup_init_fpu_buf(void) 447 466 { 448 467 static int on_boot_cpu __initdata = 1; 468 + 469 + BUILD_BUG_ON((XFEATURE_MASK_USER_SUPPORTED | 470 + XFEATURE_MASK_SUPERVISOR_SUPPORTED) != 471 + XFEATURES_INIT_FPSTATE_HANDLED); 449 472 450 473 WARN_ON_FPU(!on_boot_cpu); 451 474 on_boot_cpu = 0; ··· 489 466 copy_kernel_to_xregs_booting(&init_fpstate.xsave); 490 467 491 468 /* 492 - * Dump the init state again. This is to identify the init state 493 - * of any feature which is not represented by all zero's. 469 + * All components are now in init state. Read the state back so 470 + * that init_fpstate contains all non-zero init state. This only 471 + * works with XSAVE, but not with XSAVEOPT and XSAVES because 472 + * those use the init optimization which skips writing data for 473 + * components in init state. 474 + * 475 + * XSAVE could be used, but that would require to reshuffle the 476 + * data when XSAVES is available because XSAVES uses xstate 477 + * compaction. But doing so is a pointless exercise because most 478 + * components have an all zeros init state except for the legacy 479 + * ones (FP and SSE). Those can be saved with FXSAVE into the 480 + * legacy area. Adding new features requires to ensure that init 481 + * state is all zeroes or if not to add the necessary handling 482 + * here. 494 483 */ 495 - copy_xregs_to_kernel_booting(&init_fpstate.xsave); 484 + fxsave(&init_fpstate.fxsave); 496 485 } 497 486 498 487 static int xfeature_uncompacted_offset(int xfeature_nr)