_switch() saves and restores ALTIVEC and SPE status.
For altivec this is redundant with what __switch_to() does with
save_sprs() and restore_sprs() and giveup_all() before
calling _switch().

Add support for SPI in save_sprs() and restore_sprs() and
remove things from _switch().

Signed-off-by: Christophe Leroy <christophe.le...@csgroup.eu>
---
 arch/powerpc/kernel/asm-offsets.c |  2 --
 arch/powerpc/kernel/entry_32.S    | 35 -------------------------------
 arch/powerpc/kernel/process.c     |  9 ++++++++
 3 files changed, 9 insertions(+), 37 deletions(-)

diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 28af4efb4587..5573da9a20d1 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -119,7 +119,6 @@ int main(void)
 #ifdef CONFIG_ALTIVEC
        OFFSET(THREAD_VRSTATE, thread_struct, vr_state.vr);
        OFFSET(THREAD_VRSAVEAREA, thread_struct, vr_save_area);
-       OFFSET(THREAD_VRSAVE, thread_struct, vrsave);
        OFFSET(THREAD_USED_VR, thread_struct, used_vr);
        OFFSET(VRSTATE_VSCR, thread_vr_state, vscr);
        OFFSET(THREAD_LOAD_VEC, thread_struct, load_vec);
@@ -150,7 +149,6 @@ int main(void)
 #ifdef CONFIG_SPE
        OFFSET(THREAD_EVR0, thread_struct, evr[0]);
        OFFSET(THREAD_ACC, thread_struct, acc);
-       OFFSET(THREAD_SPEFSCR, thread_struct, spefscr);
        OFFSET(THREAD_USED_SPE, thread_struct, used_spe);
 #endif /* CONFIG_SPE */
 #endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 9160285cb2f4..6c09ebb853ec 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -176,28 +176,6 @@ _GLOBAL(_switch)
        /* r3-r12 are caller saved -- Cort */
        SAVE_NVGPRS(r1)
        stw     r0,_NIP(r1)     /* Return to switch caller */
-       mfmsr   r11
-       li      r0,MSR_FP       /* Disable floating-point */
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
-       oris    r0,r0,MSR_VEC@h /* Disable altivec */
-       mfspr   r12,SPRN_VRSAVE /* save vrsave register value */
-       stw     r12,THREAD+THREAD_VRSAVE(r2)
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-BEGIN_FTR_SECTION
-       oris    r0,r0,MSR_SPE@h  /* Disable SPE */
-       mfspr   r12,SPRN_SPEFSCR /* save spefscr register value */
-       stw     r12,THREAD+THREAD_SPEFSCR(r2)
-END_FTR_SECTION_IFSET(CPU_FTR_SPE)
-#endif /* CONFIG_SPE */
-       and.    r0,r0,r11       /* FP or altivec or SPE enabled? */
-       beq+    1f
-       andc    r11,r11,r0
-       mtmsr   r11
-       isync
-1:     stw     r11,_MSR(r1)
        mfcr    r10
        stw     r10,_CCR(r1)
        stw     r1,KSP(r3)      /* Set old stack pointer */
@@ -218,19 +196,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPE)
        mr      r3,r2
        addi    r2,r4,-THREAD   /* Update current */
 
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
-       lwz     r0,THREAD+THREAD_VRSAVE(r2)
-       mtspr   SPRN_VRSAVE,r0          /* if G4, restore VRSAVE reg */
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-BEGIN_FTR_SECTION
-       lwz     r0,THREAD+THREAD_SPEFSCR(r2)
-       mtspr   SPRN_SPEFSCR,r0         /* restore SPEFSCR reg */
-END_FTR_SECTION_IFSET(CPU_FTR_SPE)
-#endif /* CONFIG_SPE */
-
        lwz     r0,_CCR(r1)
        mtcrf   0xFF,r0
        /* r3-r12 are destroyed -- Cort */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 89e34aa273e2..2bd30acc843c 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1129,6 +1129,10 @@ static inline void save_sprs(struct thread_struct *t)
        if (cpu_has_feature(CPU_FTR_ALTIVEC))
                t->vrsave = mfspr(SPRN_VRSAVE);
 #endif
+#ifdef CONFIG_SPE
+       if (cpu_has_feature(CPU_FTR_SPE))
+               t->spefscr = mfspr(SPRN_SPEFSCR);
+#endif
 #ifdef CONFIG_PPC_BOOK3S_64
        if (cpu_has_feature(CPU_FTR_DSCR))
                t->dscr = mfspr(SPRN_DSCR);
@@ -1159,6 +1163,11 @@ static inline void restore_sprs(struct thread_struct 
*old_thread,
            old_thread->vrsave != new_thread->vrsave)
                mtspr(SPRN_VRSAVE, new_thread->vrsave);
 #endif
+#ifdef CONFIG_SPE
+       if (cpu_has_feature(CPU_FTR_SPE) &&
+           old_thread->spefscr != new_thread->spefscr)
+               mtspr(SPRN_SPEFSCR, new_thread->spefscr);
+#endif
 #ifdef CONFIG_PPC_BOOK3S_64
        if (cpu_has_feature(CPU_FTR_DSCR)) {
                u64 dscr = get_paca()->dscr_default;
-- 
2.25.0

Reply via email to