History

powerpc: Keep thread.dscr and thread.dscr_inherit in sync

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

Anton Blanchard committed 14 years ago

Commit 00ca0de1 parent 1b6ca2a2 files · +5 −2Browse files

Unified · Split

2 files
  1. arch/powerpc/kernel/sysfs.c +3 −1
  2. arch/powerpc/kernel/traps.c +2 −1
arch/powerpc/kernel/sysfs.c+3−1
@@ -196,8 +196,10 @@ static ssize_t show_dscr_default(struct device *dev, · 195 unmodified lines
196 196
197static void update_dscr(void *dummy)197static void update_dscr(void *dummy)
198{198{
199 if (!current->thread.dscr_inherit)199 if (!current->thread.dscr_inherit) {
200 current->thread.dscr = dscr_default;
200 mtspr(SPRN_DSCR, dscr_default);201 mtspr(SPRN_DSCR, dscr_default);
202 }
201}203}
202 204
203static ssize_t __used store_dscr_default(struct device *dev,205static ssize_t __used store_dscr_default(struct device *dev,
arch/powerpc/kernel/traps.c+2−1
@@ -972,8 +972,9 @@ static int emulate_instruction(struct pt_regs *regs) · 971 unmodified lines
972 cpu_has_feature(CPU_FTR_DSCR)) {972 cpu_has_feature(CPU_FTR_DSCR)) {
973 PPC_WARN_EMULATED(mtdscr, regs);973 PPC_WARN_EMULATED(mtdscr, regs);
974 rd = (instword >> 21) & 0x1f;974 rd = (instword >> 21) & 0x1f;
975 mtspr(SPRN_DSCR, regs->gpr[rd]);975 current->thread.dscr = regs->gpr[rd];
976 current->thread.dscr_inherit = 1;976 current->thread.dscr_inherit = 1;
977 mtspr(SPRN_DSCR, current->thread.dscr);
977 return 0;978 return 0;
978 }979 }
979#endif980#endif