• Yu-cheng Yu's avatar
    x86/fpu/xstate: Restore supervisor states for signal return · 55e00fb6
    Yu-cheng Yu authored
    The signal return fast path directly restores user states from the user
    buffer. Once that succeeds, restore supervisor states (but only when
    they are not yet restored).
    
    For the slow path, save supervisor states to preserve them across context
    switches, and restore after the user states are restored.
    
    The previous version has the overhead of an XSAVES in both the fast and the
    slow paths.  It is addressed as the following:
    
    - In the fast path, only do an XRSTORS.
    - In the slow path, do a supervisor-state-only XSAVES, and relocate the
      buffer contents.
    
    Some thoughts in the implementation:
    
    - In the slow path, can any supervisor state become stale between
      save/restore?
    
      Answer: set_thread_flag(TIF_NEED_FPU_LOAD) protects the xstate buffer.
    
    - In the slow path, can any code reference a stale supervisor state
      register between save/restore?
    
      Answer: In the current lazy-restore scheme, any reference to xstate
      registers needs fpregs_lock()/fpregs_unlock() and __fpregs_load_activate().
    
    - Are there other options?
    
      One other option is eagerly restoring all supervisor states.
    
      Currently, CET user-mode states and ENQCMD's PASID do not need to be
      eagerly restored.  The upcoming CET kernel-mode states (24 bytes) need
      to be eagerly restored.  To me, eagerly restoring all supervisor states
      adds more overhead then benefit at this point.
    Signed-off-by: default avatarYu-cheng Yu <yu-cheng.yu@intel.com>
    Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
    Reviewed-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
    Link: https://lkml.kernel.org/r/20200512145444.15483-11-yu-cheng.yu@intel.com
    55e00fb6
signal.c 14.4 KB