Based off the x86 one. WireGuard really wants to be able to do SIMD in interrupts, so it can accelerate its in-bound path.
Signed-off-by: Shawn Landden <sh...@git.icu> --- arch/powerpc/include/asm/simd.h | 13 +++++++++++++ arch/powerpc/kernel/process.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 arch/powerpc/include/asm/simd.h diff --git a/arch/powerpc/include/asm/simd.h b/arch/powerpc/include/asm/simd.h new file mode 100644 index 000000000..2c02ad531 --- /dev/null +++ b/arch/powerpc/include/asm/simd.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +/* + * may_use_simd - whether it is allowable at this time to issue SIMD + * instructions or access the SIMD register file + * + * It's always ok in process context (ie "not interrupt") + * but it is sometimes ok even from an irq. + */ +static __must_check inline bool may_use_simd(void) +{ + return irq_simd_usable(); +} diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index dd9e0d538..e436d708a 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -345,6 +345,36 @@ static int restore_altivec(struct task_struct *tsk) } return 0; } + +/* + * Were we in user mode when we were + * interrupted? + * + * Doing kernel_altivec/vsx_begin/end() is ok if we are running + * in an interrupt context from user mode - we'll just + * save the FPU state as required. + */ +static bool interrupted_user_mode(void) +{ + struct pt_regs *regs = get_irq_regs(); + + return regs && user_mode(regs); +} + +/* + * Can we use SIMD in kernel mode with the + * whole "kernel_altivec/vsx_begin/end()" sequence? + * + * It's always ok in process context (ie "not interrupt") + * but it is sometimes ok even from an irq. + */ +bool irq_simd_usable(void) +{ + return !in_interrupt() || + interrupted_user_mode(); +} +EXPORT_SYMBOL(irq_simd_usable); + #else #define loadvec(thr) 0 static inline int restore_altivec(struct task_struct *tsk) { return 0; } -- 2.21.0.1020.gf2820cf01a