OSDN Git Service

Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 7 May 2019 17:24:10 +0000 (10:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 7 May 2019 17:24:10 +0000 (10:24 -0700)
Pull x86 FPU state handling updates from Borislav Petkov:
 "This contains work started by Rik van Riel and brought to fruition by
  Sebastian Andrzej Siewior with the main goal to optimize when to load
  FPU registers: only when returning to userspace and not on every
  context switch (while the task remains in the kernel).

  In addition, this optimization makes kernel_fpu_begin() cheaper by
  requiring registers saving only on the first invocation and skipping
  that in following ones.

  What is more, this series cleans up and streamlines many aspects of
  the already complex FPU code, hopefully making it more palatable for
  future improvements and simplifications.

  Finally, there's a __user annotations fix from Jann Horn"

* 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (29 commits)
  x86/fpu: Fault-in user stack if copy_fpstate_to_sigframe() fails
  x86/pkeys: Add PKRU value to init_fpstate
  x86/fpu: Restore regs in copy_fpstate_to_sigframe() in order to use the fastpath
  x86/fpu: Add a fastpath to copy_fpstate_to_sigframe()
  x86/fpu: Add a fastpath to __fpu__restore_sig()
  x86/fpu: Defer FPU state load until return to userspace
  x86/fpu: Merge the two code paths in __fpu__restore_sig()
  x86/fpu: Restore from kernel memory on the 64-bit path too
  x86/fpu: Inline copy_user_to_fpregs_zeroing()
  x86/fpu: Update xstate's PKRU value on write_pkru()
  x86/fpu: Prepare copy_fpstate_to_sigframe() for TIF_NEED_FPU_LOAD
  x86/fpu: Always store the registers in copy_fpstate_to_sigframe()
  x86/entry: Add TIF_NEED_FPU_LOAD
  x86/fpu: Eager switch PKRU state
  x86/pkeys: Don't check if PKRU is zero before writing it
  x86/fpu: Only write PKRU if it is different from current
  x86/pkeys: Provide *pkru() helpers
  x86/fpu: Use a feature number instead of mask in two more helpers
  x86/fpu: Make __raw_xsave_addr() use a feature number instead of mask
  x86/fpu: Add an __fpregs_load_activate() internal helper
  ...

1  2 
arch/x86/ia32/ia32_signal.c
arch/x86/include/asm/fpu/internal.h
arch/x86/include/asm/pgtable.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/signal.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c

Simple merge
@@@ -494,12 -555,24 +555,23 @@@ static inline void __fpregs_load_activa
   *  - switch_fpu_prepare() saves the old state.
   *    This is done within the context of the old process.
   *
-  *  - switch_fpu_finish() restores the new state as
-  *    necessary.
+  *  - switch_fpu_finish() sets TIF_NEED_FPU_LOAD; the floating point state
+  *    will get loaded on return to userspace, or when the kernel needs it.
+  *
+  * If TIF_NEED_FPU_LOAD is cleared then the CPU's FPU registers
+  * are saved in the current thread's FPU register state.
+  *
+  * If TIF_NEED_FPU_LOAD is set then CPU's FPU registers may not
+  * hold current()'s FPU registers. It is required to load the
+  * registers before returning to userland or using the content
+  * otherwise.
+  *
+  * The FPU context is only stored/restored for a user task and
+  * ->mm is used to distinguish between kernel and user threads.
   */
 -static inline void
 -switch_fpu_prepare(struct fpu *old_fpu, int cpu)
 +static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
  {
-       if (static_cpu_has(X86_FEATURE_FPU) && old_fpu->initialized) {
+       if (static_cpu_has(X86_FEATURE_FPU) && current->mm) {
                if (!copy_fpregs_to_fpstate(old_fpu))
                        old_fpu->last_cpu = -1;
                else
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge