powerpc: tm: Rename transct_(*) to ck(\1)_state
[cascardo/linux.git] / arch / powerpc / kernel / ptrace.c
index bf91658..b1ec62f 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/pgtable.h>
 #include <asm/switch_to.h>
 #include <asm/tm.h>
+#include <asm/asm-prototypes.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/syscalls.h>
@@ -402,13 +403,9 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
 }
 
 /*
- * When the transaction is active, 'transact_fp' holds the current running
- * value of all FPR registers and 'fp_state' holds the last checkpointed
- * value of all FPR registers for the current transaction. When transaction
- * is not active 'fp_state' holds the current running state of all the FPR
- * registers. So this function which returns the current running values of
- * all the FPR registers, needs to know whether any transaction is active
- * or not.
+ * Regardless of transactions, 'fp_state' holds the current running
+ * value of all FPR registers and 'ckfp_state' holds the last checkpointed
+ * value of all FPR registers for the current transaction.
  *
  * Userspace interface buffer layout:
  *
@@ -416,13 +413,6 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
  *     u64     fpr[32];
  *     u64     fpscr;
  * };
- *
- * There are two config options CONFIG_VSX and CONFIG_PPC_TRANSACTIONAL_MEM
- * which determines the final code in this function. All the combinations of
- * these two config options are possible except the one below as transactional
- * memory config pulls in CONFIG_VSX automatically.
- *
- *     !defined(CONFIG_VSX) && defined(CONFIG_PPC_TRANSACTIONAL_MEM)
  */
 static int fpr_get(struct task_struct *target, const struct user_regset *regset,
                   unsigned int pos, unsigned int count,
@@ -431,50 +421,29 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
 #ifdef CONFIG_VSX
        u64 buf[33];
        int i;
-#endif
-       flush_fp_to_thread(target);
 
-#if defined(CONFIG_VSX) && defined(CONFIG_PPC_TRANSACTIONAL_MEM)
-       /* copy to local buffer then write that out */
-       if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
-               flush_altivec_to_thread(target);
-               flush_tmregs_to_thread(target);
-               for (i = 0; i < 32 ; i++)
-                       buf[i] = target->thread.TS_TRANS_FPR(i);
-               buf[32] = target->thread.transact_fp.fpscr;
-       } else {
-               for (i = 0; i < 32 ; i++)
-                       buf[i] = target->thread.TS_FPR(i);
-               buf[32] = target->thread.fp_state.fpscr;
-       }
-       return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
-#endif
+       flush_fp_to_thread(target);
 
-#if defined(CONFIG_VSX) && !defined(CONFIG_PPC_TRANSACTIONAL_MEM)
        /* copy to local buffer then write that out */
        for (i = 0; i < 32 ; i++)
                buf[i] = target->thread.TS_FPR(i);
        buf[32] = target->thread.fp_state.fpscr;
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
-#endif
-
-#if !defined(CONFIG_VSX) && !defined(CONFIG_PPC_TRANSACTIONAL_MEM)
+#else
        BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
                     offsetof(struct thread_fp_state, fpr[32]));
 
+       flush_fp_to_thread(target);
+
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                   &target->thread.fp_state, 0, -1);
 #endif
 }
 
 /*
- * When the transaction is active, 'transact_fp' holds the current running
- * value of all FPR registers and 'fp_state' holds the last checkpointed
- * value of all FPR registers for the current transaction. When transaction
- * is not active 'fp_state' holds the current running state of all the FPR
- * registers. So this function which setss the current running values of
- * all the FPR registers, needs to know whether any transaction is active
- * or not.
+ * Regardless of transactions, 'fp_state' holds the current running
+ * value of all FPR registers and 'ckfp_state' holds the last checkpointed
+ * value of all FPR registers for the current transaction.
  *
  * Userspace interface buffer layout:
  *
@@ -483,12 +452,6 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
  *     u64     fpscr;
  * };
  *
- * There are two config options CONFIG_VSX and CONFIG_PPC_TRANSACTIONAL_MEM
- * which determines the final code in this function. All the combinations of
- * these two config options are possible except the one below as transactional
- * memory config pulls in CONFIG_VSX automatically.
- *
- *     !defined(CONFIG_VSX) && defined(CONFIG_PPC_TRANSACTIONAL_MEM)
  */
 static int fpr_set(struct task_struct *target, const struct user_regset *regset,
                   unsigned int pos, unsigned int count,
@@ -497,44 +460,24 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
 #ifdef CONFIG_VSX
        u64 buf[33];
        int i;
-#endif
+
        flush_fp_to_thread(target);
 
-#if defined(CONFIG_VSX) && defined(CONFIG_PPC_TRANSACTIONAL_MEM)
        /* copy to local buffer then write that out */
        i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
        if (i)
                return i;
 
-       if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
-               flush_altivec_to_thread(target);
-               flush_tmregs_to_thread(target);
-               for (i = 0; i < 32 ; i++)
-                       target->thread.TS_TRANS_FPR(i) = buf[i];
-               target->thread.transact_fp.fpscr = buf[32];
-       } else {
-               for (i = 0; i < 32 ; i++)
-                       target->thread.TS_FPR(i) = buf[i];
-               target->thread.fp_state.fpscr = buf[32];
-       }
-       return 0;
-#endif
-
-#if defined(CONFIG_VSX) && !defined(CONFIG_PPC_TRANSACTIONAL_MEM)
-       /* copy to local buffer then write that out */
-       i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
-       if (i)
-               return i;
        for (i = 0; i < 32 ; i++)
                target->thread.TS_FPR(i) = buf[i];
        target->thread.fp_state.fpscr = buf[32];
        return 0;
-#endif
-
-#if !defined(CONFIG_VSX) && !defined(CONFIG_PPC_TRANSACTIONAL_MEM)
+#else
        BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
                     offsetof(struct thread_fp_state, fpr[32]));
 
+       flush_fp_to_thread(target);
+
        return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                  &target->thread.fp_state, 0, -1);
 #endif
@@ -562,13 +505,10 @@ static int vr_active(struct task_struct *target,
 }
 
 /*
- * When the transaction is active, 'transact_vr' holds the current running
- * value of all the VMX registers and 'vr_state' holds the last checkpointed
- * value of all the VMX registers for the current transaction to fall back
- * on in case it aborts. When transaction is not active 'vr_state' holds
- * the current running state of all the VMX registers. So this function which
- * gets the current running values of all the VMX registers, needs to know
- * whether any transaction is active or not.
+ * Regardless of transactions, 'vr_state' holds the current running
+ * value of all the VMX registers and 'ckvr_state' holds the last
+ * checkpointed value of all the VMX registers for the current
+ * transaction to fall back on in case it aborts.
  *
  * Userspace interface buffer layout:
  *
@@ -582,7 +522,6 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
                  unsigned int pos, unsigned int count,
                  void *kbuf, void __user *ubuf)
 {
-       struct thread_vr_state *addr;
        int ret;
 
        flush_altivec_to_thread(target);
@@ -590,19 +529,8 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
        BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
                     offsetof(struct thread_vr_state, vr[32]));
 
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-       if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
-               flush_fp_to_thread(target);
-               flush_tmregs_to_thread(target);
-               addr = &target->thread.transact_vr;
-       } else {
-               addr = &target->thread.vr_state;
-       }
-#else
-       addr = &target->thread.vr_state;
-#endif
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 addr, 0,
+                                 &target->thread.vr_state, 0,
                                  33 * sizeof(vector128));
        if (!ret) {
                /*
@@ -614,14 +542,7 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
                } vrsave;
                memset(&vrsave, 0, sizeof(vrsave));
 
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-               if (MSR_TM_ACTIVE(target->thread.regs->msr))
-                       vrsave.word = target->thread.transact_vrsave;
-               else
-                       vrsave.word = target->thread.vrsave;
-#else
                vrsave.word = target->thread.vrsave;
-#endif
 
                ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
                                          33 * sizeof(vector128), -1);
@@ -631,13 +552,10 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
 }
 
 /*
- * When the transaction is active, 'transact_vr' holds the current running
- * value of all the VMX registers and 'vr_state' holds the last checkpointed
- * value of all the VMX registers for the current transaction to fall back
- * on in case it aborts. When transaction is not active 'vr_state' holds
- * the current running state of all the VMX registers. So this function which
- * sets the current running values of all the VMX registers, needs to know
- * whether any transaction is active or not.
+ * Regardless of transactions, 'vr_state' holds the current running
+ * value of all the VMX registers and 'ckvr_state' holds the last
+ * checkpointed value of all the VMX registers for the current
+ * transaction to fall back on in case it aborts.
  *
  * Userspace interface buffer layout:
  *
@@ -651,7 +569,6 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
                  unsigned int pos, unsigned int count,
                  const void *kbuf, const void __user *ubuf)
 {
-       struct thread_vr_state *addr;
        int ret;
 
        flush_altivec_to_thread(target);
@@ -659,19 +576,8 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
        BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
                     offsetof(struct thread_vr_state, vr[32]));
 
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-       if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
-               flush_fp_to_thread(target);
-               flush_tmregs_to_thread(target);
-               addr = &target->thread.transact_vr;
-       } else {
-               addr = &target->thread.vr_state;
-       }
-#else
-       addr = &target->thread.vr_state;
-#endif
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                addr, 0,
+                                &target->thread.vr_state, 0,
                                 33 * sizeof(vector128));
        if (!ret && count > 0) {
                /*
@@ -683,27 +589,12 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
                } vrsave;
                memset(&vrsave, 0, sizeof(vrsave));
 
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-               if (MSR_TM_ACTIVE(target->thread.regs->msr))
-                       vrsave.word = target->thread.transact_vrsave;
-               else
-                       vrsave.word = target->thread.vrsave;
-#else
                vrsave.word = target->thread.vrsave;
-#endif
+
                ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
                                         33 * sizeof(vector128), -1);
-               if (!ret) {
-
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-                       if (MSR_TM_ACTIVE(target->thread.regs->msr))
-                               target->thread.transact_vrsave = vrsave.word;
-                       else
-                               target->thread.vrsave = vrsave.word;
-#else
+               if (!ret)
                        target->thread.vrsave = vrsave.word;
-#endif
-               }
        }
 
        return ret;
@@ -725,13 +616,10 @@ static int vsr_active(struct task_struct *target,
 }
 
 /*
- * When the transaction is active, 'transact_fp' holds the current running
- * value of all FPR registers and 'fp_state' holds the last checkpointed
- * value of all FPR registers for the current transaction. When transaction
- * is not active 'fp_state' holds the current running state of all the FPR
- * registers. So this function which returns the current running values of
- * all the FPR registers, needs to know whether any transaction is active
- * or not.
+ * Regardless of transactions, 'fp_state' holds the current running
+ * value of all FPR registers and 'ckfp_state' holds the last
+ * checkpointed value of all FPR registers for the current
+ * transaction.
  *
  * Userspace interface buffer layout:
  *
@@ -746,27 +634,14 @@ static int vsr_get(struct task_struct *target, const struct user_regset *regset,
        u64 buf[32];
        int ret, i;
 
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
-#endif
        flush_vsx_to_thread(target);
 
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-       if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
-               for (i = 0; i < 32 ; i++)
-                       buf[i] = target->thread.
-                               transact_fp.fpr[i][TS_VSRLOWOFFSET];
-       } else {
-               for (i = 0; i < 32 ; i++)
-                       buf[i] = target->thread.
-                               fp_state.fpr[i][TS_VSRLOWOFFSET];
-       }
-#else
        for (i = 0; i < 32 ; i++)
                buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
-#endif
+
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                  buf, 0, 32 * sizeof(double));
 
@@ -774,12 +649,10 @@ static int vsr_get(struct task_struct *target, const struct user_regset *regset,
 }
 
 /*
- * When the transaction is active, 'transact_fp' holds the current running
- * value of all FPR registers and 'fp_state' holds the last checkpointed
- * value of all FPR registers for the current transaction. When transaction
- * is not active 'fp_state' holds the current running state of all the FPR
- * registers. So this function which sets the current running values of all
- * the FPR registers, needs to know whether any transaction is active or not.
+ * Regardless of transactions, 'fp_state' holds the current running
+ * value of all FPR registers and 'ckfp_state' holds the last
+ * checkpointed value of all FPR registers for the current
+ * transaction.
  *
  * Userspace interface buffer layout:
  *
@@ -794,31 +667,16 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
        u64 buf[32];
        int ret,i;
 
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
-#endif
        flush_vsx_to_thread(target);
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 buf, 0, 32 * sizeof(double));
-
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-       if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
-               for (i = 0; i < 32 ; i++)
-                       target->thread.transact_fp.
-                               fpr[i][TS_VSRLOWOFFSET] = buf[i];
-       } else {
+       if (!ret)
                for (i = 0; i < 32 ; i++)
-                       target->thread.fp_state.
-                               fpr[i][TS_VSRLOWOFFSET] = buf[i];
-       }
-#else
-       for (i = 0; i < 32 ; i++)
-               target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
-#endif
-
+                       target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
 
        return ret;
 }
@@ -944,9 +802,9 @@ static int tm_cgpr_get(struct task_struct *target,
        if (!MSR_TM_ACTIVE(target->thread.regs->msr))
                return -ENODATA;
 
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
 
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                  &target->thread.ckpt_regs,
@@ -1009,9 +867,9 @@ static int tm_cgpr_set(struct task_struct *target,
        if (!MSR_TM_ACTIVE(target->thread.regs->msr))
                return -ENODATA;
 
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 &target->thread.ckpt_regs,
@@ -1087,7 +945,7 @@ static int tm_cfpr_active(struct task_struct *target,
  *
  * This function gets in transaction checkpointed FPR registers.
  *
- * When the transaction is active 'fp_state' holds the checkpointed
+ * When the transaction is active 'ckfp_state' holds the checkpointed
  * values for the current transaction to fall back on if it aborts
  * in between. This function gets those checkpointed FPR registers.
  * The userspace interface buffer layout is as follows.
@@ -1111,14 +969,14 @@ static int tm_cfpr_get(struct task_struct *target,
        if (!MSR_TM_ACTIVE(target->thread.regs->msr))
                return -ENODATA;
 
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
 
        /* copy to local buffer then write that out */
        for (i = 0; i < 32 ; i++)
-               buf[i] = target->thread.TS_FPR(i);
-       buf[32] = target->thread.fp_state.fpscr;
+               buf[i] = target->thread.TS_CKFPR(i);
+       buf[32] = target->thread.ckfp_state.fpscr;
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
 }
 
@@ -1133,7 +991,7 @@ static int tm_cfpr_get(struct task_struct *target,
  *
  * This function sets in transaction checkpointed FPR registers.
  *
- * When the transaction is active 'fp_state' holds the checkpointed
+ * When the transaction is active 'ckfp_state' holds the checkpointed
  * FPR register values for the current transaction to fall back on
  * if it aborts in between. This function sets these checkpointed
  * FPR registers. The userspace interface buffer layout is as follows.
@@ -1157,17 +1015,17 @@ static int tm_cfpr_set(struct task_struct *target,
        if (!MSR_TM_ACTIVE(target->thread.regs->msr))
                return -ENODATA;
 
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
 
        /* copy to local buffer then write that out */
        i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
        if (i)
                return i;
        for (i = 0; i < 32 ; i++)
-               target->thread.TS_FPR(i) = buf[i];
-       target->thread.fp_state.fpscr = buf[32];
+               target->thread.TS_CKFPR(i) = buf[i];
+       target->thread.ckfp_state.fpscr = buf[32];
        return 0;
 }
 
@@ -1202,7 +1060,7 @@ static int tm_cvmx_active(struct task_struct *target,
  *
  * This function gets in transaction checkpointed VMX registers.
  *
- * When the transaction is active 'vr_state' and 'vr_save' hold
+ * When the transaction is active 'ckvr_state' and 'ckvrsave' hold
  * the checkpointed values for the current transaction to fall
  * back on if it aborts in between. The userspace interface buffer
  * layout is as follows.
@@ -1229,12 +1087,12 @@ static int tm_cvmx_get(struct task_struct *target,
                return -ENODATA;
 
        /* Flush the state */
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
 
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                       &target->thread.vr_state, 0,
+                                       &target->thread.ckvr_state, 0,
                                        33 * sizeof(vector128));
        if (!ret) {
                /*
@@ -1245,7 +1103,7 @@ static int tm_cvmx_get(struct task_struct *target,
                        u32 word;
                } vrsave;
                memset(&vrsave, 0, sizeof(vrsave));
-               vrsave.word = target->thread.vrsave;
+               vrsave.word = target->thread.ckvrsave;
                ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
                                                33 * sizeof(vector128), -1);
        }
@@ -1264,7 +1122,7 @@ static int tm_cvmx_get(struct task_struct *target,
  *
  * This function sets in transaction checkpointed VMX registers.
  *
- * When the transaction is active 'vr_state' and 'vr_save' hold
+ * When the transaction is active 'ckvr_state' and 'ckvrsave' hold
  * the checkpointed values for the current transaction to fall
  * back on if it aborts in between. The userspace interface buffer
  * layout is as follows.
@@ -1290,12 +1148,12 @@ static int tm_cvmx_set(struct task_struct *target,
        if (!MSR_TM_ACTIVE(target->thread.regs->msr))
                return -ENODATA;
 
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                       &target->thread.vr_state, 0,
+                                       &target->thread.ckvr_state, 0,
                                        33 * sizeof(vector128));
        if (!ret && count > 0) {
                /*
@@ -1306,11 +1164,11 @@ static int tm_cvmx_set(struct task_struct *target,
                        u32 word;
                } vrsave;
                memset(&vrsave, 0, sizeof(vrsave));
-               vrsave.word = target->thread.vrsave;
+               vrsave.word = target->thread.ckvrsave;
                ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
                                                33 * sizeof(vector128), -1);
                if (!ret)
-                       target->thread.vrsave = vrsave.word;
+                       target->thread.ckvrsave = vrsave.word;
        }
 
        return ret;
@@ -1348,7 +1206,7 @@ static int tm_cvsx_active(struct task_struct *target,
  *
  * This function gets in transaction checkpointed VSX registers.
  *
- * When the transaction is active 'fp_state' holds the checkpointed
+ * When the transaction is active 'ckfp_state' holds the checkpointed
  * values for the current transaction to fall back on if it aborts
  * in between. This function gets those checkpointed VSX registers.
  * The userspace interface buffer layout is as follows.
@@ -1372,13 +1230,13 @@ static int tm_cvsx_get(struct task_struct *target,
                return -ENODATA;
 
        /* Flush the state */
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
        flush_vsx_to_thread(target);
 
        for (i = 0; i < 32 ; i++)
-               buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
+               buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                  buf, 0, 32 * sizeof(double));
 
@@ -1396,7 +1254,7 @@ static int tm_cvsx_get(struct task_struct *target,
  *
  * This function sets in transaction checkpointed VSX registers.
  *
- * When the transaction is active 'fp_state' holds the checkpointed
+ * When the transaction is active 'ckfp_state' holds the checkpointed
  * VSX register values for the current transaction to fall back on
  * if it aborts in between. This function sets these checkpointed
  * FPR registers. The userspace interface buffer layout is as follows.
@@ -1420,15 +1278,16 @@ static int tm_cvsx_set(struct task_struct *target,
                return -ENODATA;
 
        /* Flush the state */
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
        flush_vsx_to_thread(target);
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 buf, 0, 32 * sizeof(double));
-       for (i = 0; i < 32 ; i++)
-               target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+       if (!ret)
+               for (i = 0; i < 32 ; i++)
+                       target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
 
        return ret;
 }
@@ -1484,9 +1343,9 @@ static int tm_spr_get(struct task_struct *target,
                return -ENODEV;
 
        /* Flush the states */
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
 
        /* TFHAR register */
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
@@ -1540,9 +1399,9 @@ static int tm_spr_set(struct task_struct *target,
                return -ENODEV;
 
        /* Flush the states */
+       flush_tmregs_to_thread(target);
        flush_fp_to_thread(target);
        flush_altivec_to_thread(target);
-       flush_tmregs_to_thread(target);
 
        /* TFHAR register */
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
@@ -2065,33 +1924,12 @@ static const struct user_regset_view user_ppc_native_view = {
 static int gpr32_get_common(struct task_struct *target,
                     const struct user_regset *regset,
                     unsigned int pos, unsigned int count,
-                           void *kbuf, void __user *ubuf, bool tm_active)
+                           void *kbuf, void __user *ubuf,
+                           unsigned long *regs)
 {
-       const unsigned long *regs = &target->thread.regs->gpr[0];
-       const unsigned long *ckpt_regs;
        compat_ulong_t *k = kbuf;
        compat_ulong_t __user *u = ubuf;
        compat_ulong_t reg;
-       int i;
-
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-       ckpt_regs = &target->thread.ckpt_regs.gpr[0];
-#endif
-       if (tm_active) {
-               regs = ckpt_regs;
-       } else {
-               if (target->thread.regs == NULL)
-                       return -EIO;
-
-               if (!FULL_REGS(target->thread.regs)) {
-                       /*
-                        * We have a partial register set.
-                        * Fill 14-31 with bogus values.
-                        */
-                       for (i = 14; i < 32; i++)
-                               target->thread.regs->gpr[i] = NV_REG_POISON;
-               }
-       }
 
        pos /= sizeof(reg);
        count /= sizeof(reg);
@@ -2133,29 +1971,13 @@ static int gpr32_get_common(struct task_struct *target,
 static int gpr32_set_common(struct task_struct *target,
                     const struct user_regset *regset,
                     unsigned int pos, unsigned int count,
-                    const void *kbuf, const void __user *ubuf, bool tm_active)
+                    const void *kbuf, const void __user *ubuf,
+                    unsigned long *regs)
 {
-       unsigned long *regs = &target->thread.regs->gpr[0];
-       unsigned long *ckpt_regs;
        const compat_ulong_t *k = kbuf;
        const compat_ulong_t __user *u = ubuf;
        compat_ulong_t reg;
 
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-       ckpt_regs = &target->thread.ckpt_regs.gpr[0];
-#endif
-
-       if (tm_active) {
-               regs = ckpt_regs;
-       } else {
-               regs = &target->thread.regs->gpr[0];
-
-               if (target->thread.regs == NULL)
-                       return -EIO;
-
-               CHECK_FULL_REGS(target->thread.regs);
-       }
-
        pos /= sizeof(reg);
        count /= sizeof(reg);
 
@@ -2220,7 +2042,8 @@ static int tm_cgpr32_get(struct task_struct *target,
                     unsigned int pos, unsigned int count,
                     void *kbuf, void __user *ubuf)
 {
-       return gpr32_get_common(target, regset, pos, count, kbuf, ubuf, 1);
+       return gpr32_get_common(target, regset, pos, count, kbuf, ubuf,
+                       &target->thread.ckpt_regs.gpr[0]);
 }
 
 static int tm_cgpr32_set(struct task_struct *target,
@@ -2228,7 +2051,8 @@ static int tm_cgpr32_set(struct task_struct *target,
                     unsigned int pos, unsigned int count,
                     const void *kbuf, const void __user *ubuf)
 {
-       return gpr32_set_common(target, regset, pos, count, kbuf, ubuf, 1);
+       return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
+                       &target->thread.ckpt_regs.gpr[0]);
 }
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
@@ -2237,7 +2061,21 @@ static int gpr32_get(struct task_struct *target,
                     unsigned int pos, unsigned int count,
                     void *kbuf, void __user *ubuf)
 {
-       return gpr32_get_common(target, regset, pos, count, kbuf, ubuf, 0);
+       int i;
+
+       if (target->thread.regs == NULL)
+               return -EIO;
+
+       if (!FULL_REGS(target->thread.regs)) {
+               /*
+                * We have a partial register set.
+                * Fill 14-31 with bogus values.
+                */
+               for (i = 14; i < 32; i++)
+                       target->thread.regs->gpr[i] = NV_REG_POISON;
+       }
+       return gpr32_get_common(target, regset, pos, count, kbuf, ubuf,
+                       &target->thread.regs->gpr[0]);
 }
 
 static int gpr32_set(struct task_struct *target,
@@ -2245,7 +2083,12 @@ static int gpr32_set(struct task_struct *target,
                     unsigned int pos, unsigned int count,
                     const void *kbuf, const void __user *ubuf)
 {
-       return gpr32_set_common(target, regset, pos, count, kbuf, ubuf, 0);
+       if (target->thread.regs == NULL)
+               return -EIO;
+
+       CHECK_FULL_REGS(target->thread.regs);
+       return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
+                       &target->thread.regs->gpr[0]);
 }
 
 /*