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

x86/fpu/core: Convert to fpstate

Convert the rest of the core code to the new register storage mechanism in
preparation for dynamically sized buffers.

No functional change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20211013145322.659456185@linutronix.de

authored by

Thomas Gleixner and committed by
Borislav Petkov
c20942ce 7e049e8b

+27 -25
+2 -2
arch/x86/include/asm/fpu/api.h
··· 50 50 } 51 51 52 52 /* 53 - * Use fpregs_lock() while editing CPU's FPU registers or fpu->state. 53 + * Use fpregs_lock() while editing CPU's FPU registers or fpu->fpstate. 54 54 * A context switch will (and softirq might) save CPU's FPU registers to 55 - * fpu->state and set TIF_NEED_FPU_LOAD leaving CPU's FPU registers in 55 + * fpu->fpstate.regs and set TIF_NEED_FPU_LOAD leaving CPU's FPU registers in 56 56 * a random state. 57 57 * 58 58 * local_bh_disable() protects against both preemption and soft interrupts
+23 -21
arch/x86/kernel/fpu/core.c
··· 89 89 EXPORT_SYMBOL(irq_fpu_usable); 90 90 91 91 /* 92 - * Save the FPU register state in fpu->state. The register state is 92 + * Save the FPU register state in fpu->fpstate->regs. The register state is 93 93 * preserved. 94 94 * 95 95 * Must be called with fpregs_lock() held. ··· 105 105 void save_fpregs_to_fpstate(struct fpu *fpu) 106 106 { 107 107 if (likely(use_xsave())) { 108 - os_xsave(&fpu->state.xsave); 108 + os_xsave(&fpu->fpstate->regs.xsave); 109 109 110 110 /* 111 111 * AVX512 state is tracked here because its use is 112 112 * known to slow the max clock speed of the core. 113 113 */ 114 - if (fpu->state.xsave.header.xfeatures & XFEATURE_MASK_AVX512) 114 + if (fpu->fpstate->regs.xsave.header.xfeatures & XFEATURE_MASK_AVX512) 115 115 fpu->avx512_timestamp = jiffies; 116 116 return; 117 117 } 118 118 119 119 if (likely(use_fxsr())) { 120 - fxsave(&fpu->state.fxsave); 120 + fxsave(&fpu->fpstate->regs.fxsave); 121 121 return; 122 122 } 123 123 ··· 125 125 * Legacy FPU register saving, FNSAVE always clears FPU registers, 126 126 * so we have to reload them from the memory state. 127 127 */ 128 - asm volatile("fnsave %[fp]; fwait" : [fp] "=m" (fpu->state.fsave)); 129 - frstor(&fpu->state.fsave); 128 + asm volatile("fnsave %[fp]; fwait" : [fp] "=m" (fpu->fpstate->regs.fsave)); 129 + frstor(&fpu->fpstate->regs.fsave); 130 130 } 131 131 132 132 void restore_fpregs_from_fpstate(struct fpstate *fpstate, u64 mask) ··· 167 167 168 168 if (save) { 169 169 if (test_thread_flag(TIF_NEED_FPU_LOAD)) { 170 - memcpy(&save->state, &current->thread.fpu.state, 170 + memcpy(&save->fpstate->regs, 171 + &current->thread.fpu.fpstate->regs, 171 172 fpu_kernel_xstate_size); 172 173 } else { 173 174 save_fpregs_to_fpstate(save); ··· 188 187 void fpu_copy_fpstate_to_kvm_uabi(struct fpu *fpu, void *buf, 189 188 unsigned int size, u32 pkru) 190 189 { 191 - union fpregs_state *kstate = &fpu->state; 190 + union fpregs_state *kstate = &fpu->fpstate->regs; 192 191 union fpregs_state *ustate = buf; 193 192 struct membuf mb = { .p = buf, .left = size }; 194 193 ··· 206 205 int fpu_copy_kvm_uabi_to_fpstate(struct fpu *fpu, const void *buf, u64 xcr0, 207 206 u32 *vpkru) 208 207 { 209 - union fpregs_state *kstate = &fpu->state; 208 + union fpregs_state *kstate = &fpu->fpstate->regs; 210 209 const union fpregs_state *ustate = buf; 211 210 struct pkru_state *xpkru; 212 211 int ret; ··· 379 378 */ 380 379 if (dst->flags & (PF_KTHREAD | PF_IO_WORKER)) { 381 380 /* Clear out the minimal state */ 382 - memcpy(&dst_fpu->state, &init_fpstate.regs, 381 + memcpy(&dst_fpu->fpstate->regs, &init_fpstate.regs, 383 382 init_fpstate_copy_size()); 384 383 return 0; 385 384 } ··· 390 389 * child's FPU context, without any memory-to-memory copying. 391 390 */ 392 391 fpregs_lock(); 393 - if (test_thread_flag(TIF_NEED_FPU_LOAD)) 394 - memcpy(&dst_fpu->state, &src_fpu->state, fpu_kernel_xstate_size); 395 - 396 - else 392 + if (test_thread_flag(TIF_NEED_FPU_LOAD)) { 393 + memcpy(&dst_fpu->fpstate->regs, &src_fpu->fpstate->regs, 394 + fpu_kernel_xstate_size); 395 + } else { 397 396 save_fpregs_to_fpstate(dst_fpu); 397 + } 398 398 fpregs_unlock(); 399 399 400 400 trace_x86_fpu_copy_src(src_fpu); ··· 468 466 * user space as PKRU is eagerly written in switch_to() and 469 467 * flush_thread(). 470 468 */ 471 - memcpy(&fpu->state, &init_fpstate.regs, init_fpstate_copy_size()); 469 + memcpy(&fpu->fpstate->regs, &init_fpstate.regs, init_fpstate_copy_size()); 472 470 set_thread_flag(TIF_NEED_FPU_LOAD); 473 471 fpregs_unlock(); 474 472 } ··· 495 493 */ 496 494 if (xfeatures_mask_supervisor() && 497 495 !fpregs_state_valid(fpu, smp_processor_id())) { 498 - os_xrstor(&fpu->state.xsave, xfeatures_mask_supervisor()); 496 + os_xrstor(&fpu->fpstate->regs.xsave, xfeatures_mask_supervisor()); 499 497 } 500 498 501 499 /* Reset user states in registers. */ ··· 576 574 * fully reproduce the context of the exception. 577 575 */ 578 576 if (boot_cpu_has(X86_FEATURE_FXSR)) { 579 - cwd = fpu->state.fxsave.cwd; 580 - swd = fpu->state.fxsave.swd; 577 + cwd = fpu->fpstate->regs.fxsave.cwd; 578 + swd = fpu->fpstate->regs.fxsave.swd; 581 579 } else { 582 - cwd = (unsigned short)fpu->state.fsave.cwd; 583 - swd = (unsigned short)fpu->state.fsave.swd; 580 + cwd = (unsigned short)fpu->fpstate->regs.fsave.cwd; 581 + swd = (unsigned short)fpu->fpstate->regs.fsave.swd; 584 582 } 585 583 586 584 err = swd & ~cwd; ··· 594 592 unsigned short mxcsr = MXCSR_DEFAULT; 595 593 596 594 if (boot_cpu_has(X86_FEATURE_XMM)) 597 - mxcsr = fpu->state.fxsave.mxcsr; 595 + mxcsr = fpu->fpstate->regs.fxsave.mxcsr; 598 596 599 597 err = ~(mxcsr >> 7) & mxcsr; 600 598 }
+1 -1
arch/x86/kernel/fpu/init.c
··· 38 38 /* Flush out any pending x87 state: */ 39 39 #ifdef CONFIG_MATH_EMULATION 40 40 if (!boot_cpu_has(X86_FEATURE_FPU)) 41 - fpstate_init_soft(&current->thread.fpu.state.soft); 41 + fpstate_init_soft(&current->thread.fpu.fpstate->regs.soft); 42 42 else 43 43 #endif 44 44 asm volatile ("fninit");
+1 -1
arch/x86/kernel/fpu/xstate.c
··· 1094 1094 void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, 1095 1095 enum xstate_copy_mode copy_mode) 1096 1096 { 1097 - __copy_xstate_to_uabi_buf(to, &tsk->thread.fpu.state.xsave, 1097 + __copy_xstate_to_uabi_buf(to, &tsk->thread.fpu.fpstate->regs.xsave, 1098 1098 tsk->thread.pkru, copy_mode); 1099 1099 } 1100 1100