--- /dev/null
+From 00ca0de02f80924dfff6b4f630e1dff3db005e35 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Mon, 3 Sep 2012 16:48:46 +0000
+Subject: powerpc: Keep thread.dscr and thread.dscr_inherit in sync
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 00ca0de02f80924dfff6b4f630e1dff3db005e35 upstream.
+
+When we update the DSCR either via emulation of mtspr(DSCR) or via
+a change to dscr_default in sysfs we don't update thread.dscr.
+We will eventually update it at context switch time but there is
+a period where thread.dscr is incorrect.
+
+If we fork at this point we will copy the old value of thread.dscr
+into the child. To avoid this, always keep thread.dscr in sync with
+reality.
+
+This issue was found with the following testcase:
+
+http://ozlabs.org/~anton/junkcode/dscr_inherit_test.c
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Haren Myneni <haren@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/sysfs.c | 4 +++-
+ arch/powerpc/kernel/traps.c | 3 ++-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/kernel/sysfs.c
++++ b/arch/powerpc/kernel/sysfs.c
+@@ -194,8 +194,10 @@ static ssize_t show_dscr_default(struct
+
+ static void update_dscr(void *dummy)
+ {
+- if (!current->thread.dscr_inherit)
++ if (!current->thread.dscr_inherit) {
++ current->thread.dscr = dscr_default;
+ mtspr(SPRN_DSCR, dscr_default);
++ }
+ }
+
+ static ssize_t __used store_dscr_default(struct sysdev_class *class,
+--- a/arch/powerpc/kernel/traps.c
++++ b/arch/powerpc/kernel/traps.c
+@@ -935,8 +935,9 @@ static int emulate_instruction(struct pt
+ cpu_has_feature(CPU_FTR_DSCR)) {
+ PPC_WARN_EMULATED(mtdscr, regs);
+ rd = (instword >> 21) & 0x1f;
+- mtspr(SPRN_DSCR, regs->gpr[rd]);
++ current->thread.dscr = regs->gpr[rd];
+ current->thread.dscr_inherit = 1;
++ mtspr(SPRN_DSCR, current->thread.dscr);
+ return 0;
+ }
+ #endif
--- /dev/null
+From 1b6ca2a6fe56e7697d57348646e07df08f43b1bb Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Mon, 3 Sep 2012 16:47:56 +0000
+Subject: powerpc: Update DSCR on all CPUs when writing sysfs dscr_default
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 1b6ca2a6fe56e7697d57348646e07df08f43b1bb upstream.
+
+Writing to dscr_default in sysfs doesn't actually change the DSCR -
+we rely on a context switch on each CPU to do the work. There is no
+guarantee we will get a context switch in a reasonable amount of time
+so fire off an IPI to force an immediate change.
+
+This issue was found with the following test case:
+
+http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Haren Myneni <haren@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/sysfs.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/powerpc/kernel/sysfs.c
++++ b/arch/powerpc/kernel/sysfs.c
+@@ -192,6 +192,12 @@ static ssize_t show_dscr_default(struct
+ return sprintf(buf, "%lx\n", dscr_default);
+ }
+
++static void update_dscr(void *dummy)
++{
++ if (!current->thread.dscr_inherit)
++ mtspr(SPRN_DSCR, dscr_default);
++}
++
+ static ssize_t __used store_dscr_default(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, const char *buf,
+ size_t count)
+@@ -204,6 +210,8 @@ static ssize_t __used store_dscr_default
+ return -EINVAL;
+ dscr_default = val;
+
++ on_each_cpu(update_dscr, NULL, 1);
++
+ return count;
+ }
+