[RFC PATCH 2/6] powerpc/dexcr: Add thread specific DEXCR configuration
Benjamin Gray
bgray at linux.ibm.com
Mon Oct 9 16:54:02 AEDT 2023
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 <bgray at 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
More information about the Linuxppc-dev
mailing list