• Ingo Molnar's avatar
    x86/fpu: Synchronize the naming of drop_fpu() and fpu_reset_state() · 50338615
    Ingo Molnar authored
    drop_fpu() and fpu_reset_state() are similar in functionality
    and in scope, yet this is not apparent from their names.
    
    drop_fpu() deactivates FPU contents (both the fpregs and the fpstate),
    but leaves register contents intact in the eager-FPU case, mostly as an
    optimization. It disables fpregs in the lazy FPU case. The drop_fpu()
    method can be used to destroy FPU state in an optimized way, when we
    know that a new state will be loaded before user-space might see
    any remains of the old FPU state:
    
         - such as in sys_exit()'s exit_thread() where we know this task
           won't execute any user-space instructions anymore and the
           next context switch cleans up the FPU. The old FPU state
           might still be around in the eagerfpu case but won't be
           saved.
    
         - in __restore_xstate_sig(), where we use drop_fpu() before
           copying a new state into the fpstate and activating that one.
           No user-pace instructions can execute between those steps.
    
         - in sys_execve()'s fpu__clear(): there we use drop_fpu() in
           the !eagerfpu case, where it's equivalent to a full reinit.
    
    fpu_reset_state() is a stronger version of drop_fpu(): both in
    the eagerfpu and the lazy-FPU case it guarantees that fpregs
    are reinitialized to init state. This method is used in cases
    where we need a full reset:
    
         - handle_signal() uses fpu_reset_state() to reset the FPU state
           to init before executing a user-space signal handler. While we
           have already saved the original FPU state at this point, and
           always restore the original state, the signal handling code
           still has to do this reinit, because signals may interrupt
           any user-space instruction, and the FPU might be in various
           intermediate states (such as an unbalanced x87 stack) that is
           not immediately usable for general C signal handler code.
    
         - __restore_xstate_sig() uses fpu_reset_state() when the signal
           frame has no FP context. Since the signal handler may have
           modified the FPU state, it gets reset back to init state.
    
         - in another branch __restore_xstate_sig() uses fpu_reset_state()
           to handle a restoration error: when restore_user_xstate() fails
           to restore FPU state and we might have inconsistent FPU data,
           fpu_reset_state() is used to reset it back to a known good
           state.
    
         - __kernel_fpu_end() uses fpu_reset_state() in an error branch.
           This is in a 'must not trigger' error branch, so on bug-free
           kernels this never triggers.
    
         - fpu__restore() uses fpu_reset_state() in an error path
           as well: if the fpstate was set up with invalid FPU state
           (via ptrace or via a signal handler), then it's reset back
           to init state.
    
         - likewise, the scheduler's switch_fpu_finish() uses it in a
           restoration error path too.
    
    Move both drop_fpu() and fpu_reset_state() to the fpu__*() namespace
    and harmonize their naming with their function:
    
        fpu__drop()
        fpu__reset()
    
    This clearly shows that both methods operate on the full state of the
    FPU, just like fpu__restore().
    
    Also add comments to explain what each function does.
    
    Cc: Andy Lutomirski <luto@amacapital.net>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Dave Hansen <dave.hansen@linux.intel.com>
    Cc: Fenghua Yu <fenghua.yu@intel.com>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    50338615
core.c 17.3 KB