• Suresh Siddha's avatar
    x86, fpu: Unify signal handling code paths for x86 and x86_64 kernels · 72a671ce
    Suresh Siddha authored
    Currently for x86 and x86_32 binaries, fpstate in the user sigframe is copied
    to/from the fpstate in the task struct.
    
    And in the case of signal delivery for x86_64 binaries, if the fpstate is live
    in the CPU registers, then the live state is copied directly to the user
    sigframe. Otherwise  fpstate in the task struct is copied to the user sigframe.
    During restore, fpstate in the user sigframe is restored directly to the live
    CPU registers.
    
    Historically, different code paths led to different bugs. For example,
    x86_64 code path was not preemption safe till recently. Also there is lot
    of code duplication for support of new features like xsave etc.
    
    Unify signal handling code paths for x86 and x86_64 kernels.
    
    New strategy is as follows:
    
    Signal delivery: Both for 32/64-bit frames, align the core math frame area to
    64bytes as needed by xsave (this where the main fpu/extended state gets copied
    to and excludes the legacy compatibility fsave header for the 32-bit [f]xsave
    frames). If the state is live, copy the register state directly to the user
    frame. If not live, copy the state in the thread struct to the user frame. And
    for 32-bit [f]xsave frames, construct the fsave header separately before
    the actual [f]xsave area.
    
    Signal return: As the 32-bit frames with [f]xstate has an additional
    'fsave' header, copy everything back from the user sigframe to the
    fpstate in the task structure and reconstruct the fxstate from the 'fsave'
    header (Also user passed pointers may not be correctly aligned for
    any attempt to directly restore any partial state). At the next fpstate usage,
    everything will be restored to the live CPU registers.
    For all the 64-bit frames and the 32-bit fsave frame, restore the state from
    the user sigframe directly to the live CPU registers. 64-bit signals always
    restored the math frame directly, so we can expect the math frame pointer
    to be correctly aligned. For 32-bit fsave frames, there are no alignment
    requirements, so we can restore the state directly.
    
    "lat_sig catch" microbenchmark numbers (for x86, x86_64, x86_32 binaries) are
    with in the noise range with this change.
    Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
    Link: http://lkml.kernel.org/r/1343171129-2747-4-git-send-email-suresh.b.siddha@intel.com
    [ Merged in compilation fix ]
    Link: http://lkml.kernel.org/r/1344544736.8326.17.camel@sbsiddha-desk.sc.intel.comSigned-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
    72a671ce
xsave.c 14.4 KB