powerpc/e500: Save SPEFCSR in flush_spe_to_thread()
authoryu liu <yu.liu@freescale.com>
Tue, 14 Jun 2011 23:34:25 +0000 (18:34 -0500)
committerAvi Kivity <avi@redhat.com>
Tue, 12 Jul 2011 10:16:30 +0000 (13:16 +0300)
giveup_spe() saves the SPE state which is protected by MSR[SPE].
However, modifying SPEFSCR does not trap when MSR[SPE]=0.
And since SPEFSCR is already saved/restored in _switch(),
not all the callers want to save SPEFSCR again.
Thus, saving SPEFSCR should not belong to giveup_spe().

This patch moves SPEFSCR saving to flush_spe_to_thread(),
and cleans up the caller that needs to save SPEFSCR accordingly.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
Acked-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/process.c
arch/powerpc/kernel/traps.c

index 5ecf54cfa7d47d774c78c754e08e7713edb214cc..aede4f87b682191a43e92715882c166bef9b65d8 100644 (file)
@@ -792,8 +792,6 @@ _GLOBAL(giveup_spe)
        evmwumiaa evr6, evr6, evr6      /* evr6 <- ACC = 0 * 0 + ACC */
        li      r4,THREAD_ACC
        evstddx evr6, r4, r3            /* save off accumulator */
-       mfspr   r6,SPRN_SPEFSCR
-       stw     r6,THREAD_SPEFSCR(r3)   /* save spefscr register value */
        beq     1f
        lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
        lis     r3,MSR_SPE@h
index 91e52df3d81d19ec7a22bba96fee3ea2d12b4002..60ac2a9251dbeef47d4bcd73658753335bb87251 100644 (file)
@@ -213,6 +213,7 @@ void flush_spe_to_thread(struct task_struct *tsk)
 #ifdef CONFIG_SMP
                        BUG_ON(tsk != current);
 #endif
+                       tsk->thread.spefscr = mfspr(SPRN_SPEFSCR);
                        giveup_spe(tsk);
                }
                preempt_enable();
index 1a0141426cda8ba86bc64840197617f9cc099b89..f19d9777d3c1825d01b9f0dde217ade0ddd80344 100644 (file)
@@ -1387,10 +1387,7 @@ void SPEFloatingPointException(struct pt_regs *regs)
        int code = 0;
        int err;
 
-       preempt_disable();
-       if (regs->msr & MSR_SPE)
-               giveup_spe(current);
-       preempt_enable();
+       flush_spe_to_thread(current);
 
        spefscr = current->thread.spefscr;
        fpexc_mode = current->thread.fpexc_mode;