aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2016-06-08 22:31:08 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2016-06-21 01:30:50 -0400
commitb57bd2de8c6c9aa03f1b899edd6f5582cc8b5b08 (patch)
treed1842bca1241f401b1ccc538e00d5f2dd9215df5
parent103b7827d977ea34c982e6a9d2f960f731f7ee76 (diff)
powerpc: Improve FSCR init and context switching
This fixes a few issues with FSCR init and switching. In commit 152d523e6307 ("powerpc: Create context switch helpers save_sprs() and restore_sprs()") we moved the setting of the FSCR register from inside an CPU_FTR_ARCH_207S section to inside just a CPU_FTR_ARCH_DSCR section. Hence we are setting FSCR on POWER6/7 where the FSCR doesn't exist. This is harmless but we shouldn't do it. Also, we can simplify the FSCR context switch. We don't need to go through the calculation involving dscr_inherit. We can just restore what we saved last time. We also set an initial value in INIT_THREAD, so that pid 1 which is cloned from that gets a sane value. Based on patch by Jack Miller. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/asm/processor.h1
-rw-r--r--arch/powerpc/kernel/process.c12
-rw-r--r--arch/powerpc/kernel/traps.c3
3 files changed, 7 insertions, 9 deletions
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index c0c27bdbb069..f6b1a5f51d05 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -347,6 +347,7 @@ struct thread_struct {
347 .fs = KERNEL_DS, \ 347 .fs = KERNEL_DS, \
348 .fpexc_mode = 0, \ 348 .fpexc_mode = 0, \
349 .ppr = INIT_PPR, \ 349 .ppr = INIT_PPR, \
350 .fscr = FSCR_TAR | FSCR_EBB \
350} 351}
351#endif 352#endif
352 353
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index c5c3ae2ef3c1..6d0a831bc7d8 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1031,18 +1031,11 @@ static inline void restore_sprs(struct thread_struct *old_thread,
1031#ifdef CONFIG_PPC_BOOK3S_64 1031#ifdef CONFIG_PPC_BOOK3S_64
1032 if (cpu_has_feature(CPU_FTR_DSCR)) { 1032 if (cpu_has_feature(CPU_FTR_DSCR)) {
1033 u64 dscr = get_paca()->dscr_default; 1033 u64 dscr = get_paca()->dscr_default;
1034 u64 fscr = old_thread->fscr & ~FSCR_DSCR; 1034 if (new_thread->dscr_inherit)
1035
1036 if (new_thread->dscr_inherit) {
1037 dscr = new_thread->dscr; 1035 dscr = new_thread->dscr;
1038 fscr |= FSCR_DSCR;
1039 }
1040 1036
1041 if (old_thread->dscr != dscr) 1037 if (old_thread->dscr != dscr)
1042 mtspr(SPRN_DSCR, dscr); 1038 mtspr(SPRN_DSCR, dscr);
1043
1044 if (old_thread->fscr != fscr)
1045 mtspr(SPRN_FSCR, fscr);
1046 } 1039 }
1047 1040
1048 if (cpu_has_feature(CPU_FTR_ARCH_207S)) { 1041 if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
@@ -1053,6 +1046,9 @@ static inline void restore_sprs(struct thread_struct *old_thread,
1053 if (old_thread->ebbrr != new_thread->ebbrr) 1046 if (old_thread->ebbrr != new_thread->ebbrr)
1054 mtspr(SPRN_EBBRR, new_thread->ebbrr); 1047 mtspr(SPRN_EBBRR, new_thread->ebbrr);
1055 1048
1049 if (old_thread->fscr != new_thread->fscr)
1050 mtspr(SPRN_FSCR, new_thread->fscr);
1051
1056 if (old_thread->tar != new_thread->tar) 1052 if (old_thread->tar != new_thread->tar)
1057 mtspr(SPRN_TAR, new_thread->tar); 1053 mtspr(SPRN_TAR, new_thread->tar);
1058 } 1054 }
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 11d15e7270e0..d2518c3cbf04 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1419,7 +1419,8 @@ void facility_unavailable_exception(struct pt_regs *regs)
1419 rd = (instword >> 21) & 0x1f; 1419 rd = (instword >> 21) & 0x1f;
1420 current->thread.dscr = regs->gpr[rd]; 1420 current->thread.dscr = regs->gpr[rd];
1421 current->thread.dscr_inherit = 1; 1421 current->thread.dscr_inherit = 1;
1422 mtspr(SPRN_FSCR, value | FSCR_DSCR); 1422 current->thread.fscr |= FSCR_DSCR;
1423 mtspr(SPRN_FSCR, current->thread.fscr);
1423 } 1424 }
1424 1425
1425 /* Read from DSCR (mfspr RT, 0x03) */ 1426 /* Read from DSCR (mfspr RT, 0x03) */