mirror of
https://github.com/torvalds/linux.git
synced 2024-11-18 10:01:43 +00:00
powerpc: Improve FSCR init and context switching
This fixes a few issues with FSCR init and switching.
In commit 152d523e63
("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>
This commit is contained in:
parent
103b7827d9
commit
b57bd2de8c
@ -347,6 +347,7 @@ struct thread_struct {
|
||||
.fs = KERNEL_DS, \
|
||||
.fpexc_mode = 0, \
|
||||
.ppr = INIT_PPR, \
|
||||
.fscr = FSCR_TAR | FSCR_EBB \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1031,18 +1031,11 @@ static inline void restore_sprs(struct thread_struct *old_thread,
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
if (cpu_has_feature(CPU_FTR_DSCR)) {
|
||||
u64 dscr = get_paca()->dscr_default;
|
||||
u64 fscr = old_thread->fscr & ~FSCR_DSCR;
|
||||
|
||||
if (new_thread->dscr_inherit) {
|
||||
if (new_thread->dscr_inherit)
|
||||
dscr = new_thread->dscr;
|
||||
fscr |= FSCR_DSCR;
|
||||
}
|
||||
|
||||
if (old_thread->dscr != dscr)
|
||||
mtspr(SPRN_DSCR, dscr);
|
||||
|
||||
if (old_thread->fscr != fscr)
|
||||
mtspr(SPRN_FSCR, fscr);
|
||||
}
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
|
||||
@ -1053,6 +1046,9 @@ static inline void restore_sprs(struct thread_struct *old_thread,
|
||||
if (old_thread->ebbrr != new_thread->ebbrr)
|
||||
mtspr(SPRN_EBBRR, new_thread->ebbrr);
|
||||
|
||||
if (old_thread->fscr != new_thread->fscr)
|
||||
mtspr(SPRN_FSCR, new_thread->fscr);
|
||||
|
||||
if (old_thread->tar != new_thread->tar)
|
||||
mtspr(SPRN_TAR, new_thread->tar);
|
||||
}
|
||||
|
@ -1419,7 +1419,8 @@ void facility_unavailable_exception(struct pt_regs *regs)
|
||||
rd = (instword >> 21) & 0x1f;
|
||||
current->thread.dscr = regs->gpr[rd];
|
||||
current->thread.dscr_inherit = 1;
|
||||
mtspr(SPRN_FSCR, value | FSCR_DSCR);
|
||||
current->thread.fscr |= FSCR_DSCR;
|
||||
mtspr(SPRN_FSCR, current->thread.fscr);
|
||||
}
|
||||
|
||||
/* Read from DSCR (mfspr RT, 0x03) */
|
||||
|
Loading…
Reference in New Issue
Block a user