extern struct task_struct *_switch(struct thread_struct *prev,
                                   struct thread_struct *next);
 #ifdef CONFIG_PPC_BOOK3S_64
-static inline void save_tar(struct thread_struct *prev)
+static inline void save_early_sprs(struct thread_struct *prev)
 {
        if (cpu_has_feature(CPU_FTR_ARCH_207S))
                prev->tar = mfspr(SPRN_TAR);
+       if (cpu_has_feature(CPU_FTR_DSCR))
+               prev->dscr = mfspr(SPRN_DSCR);
 }
 #else
-static inline void save_tar(struct thread_struct *prev) {}
+static inline void save_early_sprs(struct thread_struct *prev) {}
 #endif
 
 extern void enable_kernel_fp(void);
 
 
        WARN_ON(!irqs_disabled());
 
-       /* Back up the TAR across context switches.
+       /* Back up the TAR and DSCR across context switches.
         * Note that the TAR is not available for use in the kernel.  (To
         * provide this, the TAR should be backed up/restored on exception
         * entry/exit instead, and be in pt_regs.  FIXME, this should be in
         * pt_regs anyway (for debug).)
-        * Save the TAR here before we do treclaim/trecheckpoint as these
-        * will change the TAR.
+        * Save the TAR and DSCR here before we do treclaim/trecheckpoint as
+        * these will change them.
         */
-       save_tar(&prev->thread);
+       save_early_sprs(&prev->thread);
 
        __switch_to_tm(prev);
 
 
--- /dev/null
+/* Test context switching to see if the DSCR SPR is correctly preserved
+ * when within a transaction.
+ *
+ * Note: We assume that the DSCR has been left at the default value (0)
+ * for all CPUs.
+ *
+ * Method:
+ *
+ * Set a value into the DSCR.
+ *
+ * Start a transaction, and suspend it (*).
+ *
+ * Hard loop checking to see if the transaction has become doomed.
+ *
+ * Now that we *may* have been preempted, record the DSCR and TEXASR SPRS.
+ *
+ * If the abort was because of a context switch, check the DSCR value.
+ * Otherwise, try again.
+ *
+ * (*) If the transaction is not suspended we can't see the problem because
+ * the transaction abort handler will restore the DSCR to it's checkpointed
+ * value before we regain control.
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <asm/tm.h>
+
+#define TBEGIN          ".long 0x7C00051D ;"
+#define TEND            ".long 0x7C00055D ;"
+#define TCHECK          ".long 0x7C00059C ;"
+#define TSUSPEND        ".long 0x7C0005DD ;"
+#define TRESUME         ".long 0x7C2005DD ;"
+#define SPRN_TEXASR     0x82
+#define SPRN_DSCR       0x03
+
+int main(void) {
+       uint64_t rv, dscr1 = 1, dscr2, texasr;
+
+       printf("Check DSCR TM context switch: ");
+       fflush(stdout);
+       for (;;) {
+               rv = 1;
+               asm __volatile__ (
+                       /* set a known value into the DSCR */
+                       "ld      3, %[dscr1];"
+                       "mtspr   %[sprn_dscr], 3;"
+
+                       /* start and suspend a transaction */
+                       TBEGIN
+                       "beq     1f;"
+                       TSUSPEND
+
+                       /* hard loop until the transaction becomes doomed */
+                       "2: ;"
+                       TCHECK
+                       "bc      4, 0, 2b;"
+
+                       /* record DSCR and TEXASR */
+                       "mfspr   3, %[sprn_dscr];"
+                       "std     3, %[dscr2];"
+                       "mfspr   3, %[sprn_texasr];"
+                       "std     3, %[texasr];"
+
+                       TRESUME
+                       TEND
+                       "li      %[rv], 0;"
+                       "1: ;"
+                       : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr)
+                       : [dscr1]"m"(dscr1)
+                       , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR)
+                       : "memory", "r3"
+               );
+               assert(rv); /* make sure the transaction aborted */
+               if ((texasr >> 56) != TM_CAUSE_RESCHED) {
+                       putchar('.');
+                       fflush(stdout);
+                       continue;
+               }
+               if (dscr2 != dscr1) {
+                       printf(" FAIL\n");
+                       exit(EXIT_FAILURE);
+               } else {
+                       printf(" OK\n");
+                       exit(EXIT_SUCCESS);
+               }
+       }
+}