* use altivec. Since VSCR only contains 32 bits saved in the least
         * significant bits of a vector, we "cheat" and stuff VRSAVE in the
         * most significant bits of that same vector. --BenH
+        * Note that the current VRSAVE value is in the SPR at this point.
         */
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               current->thread.vrsave = mfspr(SPRN_VRSAVE);
        if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
                return 1;
 #endif /* CONFIG_ALTIVEC */
         * significant bits of a vector, we "cheat" and stuff VRSAVE in the
         * most significant bits of that same vector. --BenH
         */
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               current->thread.vrsave = mfspr(SPRN_VRSAVE);
        if (__put_user(current->thread.vrsave,
                       (u32 __user *)&frame->mc_vregs[32]))
                return 1;
        /* Always get VRSAVE back */
        if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
                return 1;
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               mtspr(SPRN_VRSAVE, current->thread.vrsave);
 #endif /* CONFIG_ALTIVEC */
        if (copy_fpr_from_user(current, &sr->mc_fregs))
                return 1;
            __get_user(current->thread.transact_vrsave,
                       (u32 __user *)&tm_sr->mc_vregs[32]))
                return 1;
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               mtspr(SPRN_VRSAVE, current->thread.vrsave);
 #endif /* CONFIG_ALTIVEC */
 
        regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
 
        /* We always copy to/from vrsave, it's 0 if we don't have or don't
         * use altivec.
         */
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               current->thread.vrsave = mfspr(SPRN_VRSAVE);
        err |= __put_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
 #else /* CONFIG_ALTIVEC */
        err |= __put_user(0, &sc->v_regs);
        /* We always copy to/from vrsave, it's 0 if we don't have or don't
         * use altivec.
         */
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               current->thread.vrsave = mfspr(SPRN_VRSAVE);
        err |= __put_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
        if (msr & MSR_VEC)
                err |= __put_user(current->thread.transact_vrsave,
                err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
        else
                current->thread.vrsave = 0;
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               mtspr(SPRN_VRSAVE, current->thread.vrsave);
 #endif /* CONFIG_ALTIVEC */
        /* restore floating point */
        err |= copy_fpr_from_user(current, &sc->fp_regs);
                current->thread.vrsave = 0;
                current->thread.transact_vrsave = 0;
        }
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               mtspr(SPRN_VRSAVE, current->thread.vrsave);
 #endif /* CONFIG_ALTIVEC */
        /* restore floating point */
        err |= copy_fpr_from_user(current, &sc->fp_regs);
 
        mfvscr  vr0
        li      r6, THREAD_TRANSACT_VSCR
        stvx    vr0, r3, r6
+dont_backup_vec:
        mfspr   r0, SPRN_VRSAVE
        std     r0, THREAD_TRANSACT_VRSAVE(r3)
 
-dont_backup_vec:
        andi.   r0, r4, MSR_FP
        beq     dont_backup_fp
 
        lvx     vr0, r3, r5
        mtvscr  vr0
        REST_32VRS(0, r5, r3)                   /* r5 scratch, r3 THREAD ptr */
+dont_restore_vec:
        ld      r5, THREAD_VRSAVE(r3)
        mtspr   SPRN_VRSAVE, r5
 #endif
 
-dont_restore_vec:
        andi.   r0, r4, MSR_FP
        beq     dont_restore_fp