Add capability to track a DEXCR value per thread. Nothing actually changes these values yet, but they are correctly tracked, propagated, and used to set the hardware register.
Signed-off-by: Benjamin Gray <bg...@linux.ibm.com> --- arch/powerpc/include/asm/processor.h | 12 ++++++++++++ arch/powerpc/kernel/process.c | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index b2c51d337e60..28a72023f9bd 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -260,6 +260,9 @@ struct thread_struct { unsigned long sier2; unsigned long sier3; unsigned long hashkeyr; + unsigned int dexcr; /* Temporary value saved during thread switch */ + unsigned int dexcr_enabled; /* Bitmask of aspects enabled by this thread */ + unsigned int dexcr_inherit; /* Bitmask of aspects to inherit across exec */ #endif }; @@ -448,6 +451,15 @@ int exit_vmx_usercopy(void); int enter_vmx_ops(void); void *exit_vmx_ops(void *dest); +static inline unsigned long get_thread_dexcr(struct thread_struct const *thread) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + return thread->dexcr_enabled; +#else + return 0; +#endif +} + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PROCESSOR_H */ diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index b68898ac07e1..c05d58b7c6b3 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1185,6 +1185,9 @@ static inline void save_sprs(struct thread_struct *t) if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE)) t->hashkeyr = mfspr(SPRN_HASHKEYR); + + if (cpu_has_feature(CPU_FTR_ARCH_31)) + t->dexcr = mfspr(SPRN_DEXCR); #endif } @@ -1267,6 +1270,10 @@ static inline void restore_sprs(struct thread_struct *old_thread, if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && old_thread->hashkeyr != new_thread->hashkeyr) mtspr(SPRN_HASHKEYR, new_thread->hashkeyr); + + if (cpu_has_feature(CPU_FTR_ARCH_31) && + old_thread->dexcr != get_thread_dexcr(new_thread)) + mtspr(SPRN_DEXCR, get_thread_dexcr(new_thread)); #endif } @@ -1634,6 +1641,11 @@ void arch_setup_new_exec(void) current->thread.regs->amr = default_amr; current->thread.regs->iamr = default_iamr; #endif + +#ifdef CONFIG_PPC_BOOK3S_64 + current->thread.dexcr_enabled &= current->thread.dexcr_inherit; + current->thread.dexcr_enabled |= ~current->thread.dexcr_inherit & DEXCR_INIT; +#endif } #ifdef CONFIG_PPC64 @@ -1878,6 +1890,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) #ifdef CONFIG_PPC_BOOK3S_64 if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE)) p->thread.hashkeyr = current->thread.hashkeyr; + + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + p->thread.dexcr_enabled = current->thread.dexcr_enabled; + p->thread.dexcr_inherit = current->thread.dexcr_inherit; + } #endif return 0; } @@ -2000,6 +2017,13 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) current->thread.hashkeyr = get_random_long(); mtspr(SPRN_HASHKEYR, current->thread.hashkeyr); } + + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + current->thread.dexcr = 0; + current->thread.dexcr_enabled = DEXCR_INIT; + current->thread.dexcr_inherit = 0; + mtspr(SPRN_DEXCR, get_thread_dexcr(¤t->thread)); + } #endif /* CONFIG_PPC_BOOK3S_64 */ } EXPORT_SYMBOL(start_thread); -- 2.41.0