• David S. Miller's avatar
    sparc64: Fix userspace FPU register corruptions. · 0ddb60b1
    David S. Miller authored
    [ Upstream commit 44922150 ]
    
    If we have a series of events from userpsace, with %fprs=FPRS_FEF,
    like follows:
    
    ETRAP
    	ETRAP
    		VIS_ENTRY(fprs=0x4)
    		VIS_EXIT
    		RTRAP (kernel FPU restore with fpu_saved=0x4)
    	RTRAP
    
    We will not restore the user registers that were clobbered by the FPU
    using kernel code in the inner-most trap.
    
    Traps allocate FPU save slots in the thread struct, and FPU using
    sequences save the "dirty" FPU registers only.
    
    This works at the initial trap level because all of the registers
    get recorded into the top-level FPU save area, and we'll return
    to userspace with the FPU disabled so that any FPU use by the user
    will take an FPU disabled trap wherein we'll load the registers
    back up properly.
    
    But this is not how trap returns from kernel to kernel operate.
    
    The simplest fix for this bug is to always save all FPU register state
    for anything other than the top-most FPU save area.
    
    Getting rid of the optimized inner-slot FPU saving code ends up
    making VISEntryHalf degenerate into plain VISEntry.
    
    Longer term we need to do something smarter to reinstate the partial
    save optimizations.  Perhaps the fundament error is having trap entry
    and exit allocate FPU save slots and restore register state.  Instead,
    the VISEntry et al. calls should be doing that work.
    
    This bug is about two decades old.
    Reported-by: default avatarJames Y Knight <jyknight@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    0ddb60b1
VISsave.S 1.74 KB