Skip to content

Commit

Permalink
powerpc: Keep thread.dscr and thread.dscr_inherit in sync
Browse files Browse the repository at this point in the history
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>
Cc: <stable@kernel.org> # 3.0+
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Anton Blanchard authored and Benjamin Herrenschmidt committed Sep 5, 2012
1 parent 1b6ca2a commit 00ca0de
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 2 deletions.
4 changes: 3 additions & 1 deletion arch/powerpc/kernel/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ static ssize_t show_dscr_default(struct device *dev,

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 device *dev,
Expand Down
3 changes: 2 additions & 1 deletion arch/powerpc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -972,8 +972,9 @@ static int emulate_instruction(struct pt_regs *regs)
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
Expand Down

0 comments on commit 00ca0de

Please sign in to comment.