This is a port of commit 379eb01c21795edb4c ("riscv: Ensure the value of FP registers in the core dump file is up to date").
The values of FP/SIMD registers in the core dump file come from the thread.fpu. However, kernel saves the FP/SIMD registers only before scheduling out the process. If no process switch happens during the exception handling, kernel will not have a chance to save the latest values of FP/SIMD registers. So it may cause their values in the core dump file incorrect. To solve this problem, force fpr_get()/simd_get() to save the FP/SIMD registers into the thread.fpu if the target task equals the current task.
Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen chenhuacai@loongson.cn --- V2: Rename get_fpu_regs() to save_fpu_regs().
arch/loongarch/include/asm/fpu.h | 22 ++++++++++++++++++---- arch/loongarch/kernel/ptrace.c | 4 ++++ 2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/arch/loongarch/include/asm/fpu.h b/arch/loongarch/include/asm/fpu.h index b541f6248837..08a45e9fd15c 100644 --- a/arch/loongarch/include/asm/fpu.h +++ b/arch/loongarch/include/asm/fpu.h @@ -173,16 +173,30 @@ static inline void restore_fp(struct task_struct *tsk) _restore_fp(&tsk->thread.fpu); }
-static inline union fpureg *get_fpu_regs(struct task_struct *tsk) +static inline void save_fpu_regs(struct task_struct *tsk) { + unsigned int euen; + if (tsk == current) { preempt_disable(); - if (is_fpu_owner()) + + euen = csr_read32(LOONGARCH_CSR_EUEN); + +#ifdef CONFIG_CPU_HAS_LASX + if (euen & CSR_EUEN_LASXEN) + _save_lasx(¤t->thread.fpu); + else +#endif +#ifdef CONFIG_CPU_HAS_LSX + if (euen & CSR_EUEN_LSXEN) + _save_lsx(¤t->thread.fpu); + else +#endif + if (euen & CSR_EUEN_FPEN) _save_fp(¤t->thread.fpu); + preempt_enable(); } - - return tsk->thread.fpu.fpr; }
static inline int is_simd_owner(void) diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c index a0767c3a0f0a..9a75dc43eb29 100644 --- a/arch/loongarch/kernel/ptrace.c +++ b/arch/loongarch/kernel/ptrace.c @@ -147,6 +147,8 @@ static int fpr_get(struct task_struct *target, { int r;
+ save_fpu_regs(target); + if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t)) r = gfpr_get(target, &to); else @@ -278,6 +280,8 @@ static int simd_get(struct task_struct *target, { const unsigned int wr_size = NUM_FPU_REGS * regset->size;
+ save_fpu_regs(target); + if (!tsk_used_math(target)) { /* The task hasn't used FP or LSX, fill with 0xff */ copy_pad_fprs(target, regset, &to, 0);
On Sat, Aug 26, 2023 at 10:23:41PM +0800, Huacai Chen wrote:
This is a port of commit 379eb01c21795edb4c ("riscv: Ensure the value of FP registers in the core dump file is up to date").
The values of FP/SIMD registers in the core dump file come from the thread.fpu. However, kernel saves the FP/SIMD registers only before scheduling out the process. If no process switch happens during the exception handling, kernel will not have a chance to save the latest values of FP/SIMD registers. So it may cause their values in the core dump file incorrect. To solve this problem, force fpr_get()/simd_get() to save the FP/SIMD registers into the thread.fpu if the target task equals the current task.
Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen chenhuacai@loongson.cn
V2: Rename get_fpu_regs() to save_fpu_regs().
What stable tree(s) is this for?
thanks,
greg k-h
On Sat, Aug 26, 2023 at 11:22 PM Greg KH gregkh@linuxfoundation.org wrote:
On Sat, Aug 26, 2023 at 10:23:41PM +0800, Huacai Chen wrote:
This is a port of commit 379eb01c21795edb4c ("riscv: Ensure the value of FP registers in the core dump file is up to date").
The values of FP/SIMD registers in the core dump file come from the thread.fpu. However, kernel saves the FP/SIMD registers only before scheduling out the process. If no process switch happens during the exception handling, kernel will not have a chance to save the latest values of FP/SIMD registers. So it may cause their values in the core dump file incorrect. To solve this problem, force fpr_get()/simd_get() to save the FP/SIMD registers into the thread.fpu if the target task equals the current task.
Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen chenhuacai@loongson.cn
V2: Rename get_fpu_regs() to save_fpu_regs().
What stable tree(s) is this for?
For 5.19+, but before 6.4 we should remove the call site in simd_get() because that function doesn't exist.
Huacai
thanks,
greg k-h
On Sat, Aug 26, 2023 at 11:35:31PM +0800, Huacai Chen wrote:
On Sat, Aug 26, 2023 at 11:22 PM Greg KH gregkh@linuxfoundation.org wrote:
On Sat, Aug 26, 2023 at 10:23:41PM +0800, Huacai Chen wrote:
This is a port of commit 379eb01c21795edb4c ("riscv: Ensure the value of FP registers in the core dump file is up to date").
The values of FP/SIMD registers in the core dump file come from the thread.fpu. However, kernel saves the FP/SIMD registers only before scheduling out the process. If no process switch happens during the exception handling, kernel will not have a chance to save the latest values of FP/SIMD registers. So it may cause their values in the core dump file incorrect. To solve this problem, force fpr_get()/simd_get() to save the FP/SIMD registers into the thread.fpu if the target task equals the current task.
Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen chenhuacai@loongson.cn
V2: Rename get_fpu_regs() to save_fpu_regs().
What stable tree(s) is this for?
For 5.19+, but before 6.4 we should remove the call site in simd_get() because that function doesn't exist.
But this commit is already in the following released kernels: 5.10.62 5.13.14 5.14 so how can it be backported?
totally confused,
greg k-h
On Sat, Aug 26, 2023 at 11:43 PM Greg KH gregkh@linuxfoundation.org wrote:
On Sat, Aug 26, 2023 at 11:35:31PM +0800, Huacai Chen wrote:
On Sat, Aug 26, 2023 at 11:22 PM Greg KH gregkh@linuxfoundation.org wrote:
On Sat, Aug 26, 2023 at 10:23:41PM +0800, Huacai Chen wrote:
This is a port of commit 379eb01c21795edb4c ("riscv: Ensure the value of FP registers in the core dump file is up to date").
The values of FP/SIMD registers in the core dump file come from the thread.fpu. However, kernel saves the FP/SIMD registers only before scheduling out the process. If no process switch happens during the exception handling, kernel will not have a chance to save the latest values of FP/SIMD registers. So it may cause their values in the core dump file incorrect. To solve this problem, force fpr_get()/simd_get() to save the FP/SIMD registers into the thread.fpu if the target task equals the current task.
Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen chenhuacai@loongson.cn
V2: Rename get_fpu_regs() to save_fpu_regs().
What stable tree(s) is this for?
For 5.19+, but before 6.4 we should remove the call site in simd_get() because that function doesn't exist.
But this commit is already in the following released kernels: 5.10.62 5.13.14 5.14
Do you means commit 379eb01c21795edb4c ("riscv: Ensure the value of FP registers in the core dump file is up to date")? That is a reference commit, not a Fixes tag. This patch is for LoongArch and LoongArch only exists after 5.19.
so how can it be backported?
totally confused,
greg k-h
On Sat, Aug 26, 2023 at 11:47:24PM +0800, Huacai Chen wrote:
On Sat, Aug 26, 2023 at 11:43 PM Greg KH gregkh@linuxfoundation.org wrote:
On Sat, Aug 26, 2023 at 11:35:31PM +0800, Huacai Chen wrote:
On Sat, Aug 26, 2023 at 11:22 PM Greg KH gregkh@linuxfoundation.org wrote:
On Sat, Aug 26, 2023 at 10:23:41PM +0800, Huacai Chen wrote:
This is a port of commit 379eb01c21795edb4c ("riscv: Ensure the value of FP registers in the core dump file is up to date").
The values of FP/SIMD registers in the core dump file come from the thread.fpu. However, kernel saves the FP/SIMD registers only before scheduling out the process. If no process switch happens during the exception handling, kernel will not have a chance to save the latest values of FP/SIMD registers. So it may cause their values in the core dump file incorrect. To solve this problem, force fpr_get()/simd_get() to save the FP/SIMD registers into the thread.fpu if the target task equals the current task.
Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen chenhuacai@loongson.cn
V2: Rename get_fpu_regs() to save_fpu_regs().
What stable tree(s) is this for?
For 5.19+, but before 6.4 we should remove the call site in simd_get() because that function doesn't exist.
But this commit is already in the following released kernels: 5.10.62 5.13.14 5.14
Do you means commit 379eb01c21795edb4c ("riscv: Ensure the value of FP registers in the core dump file is up to date")? That is a reference commit, not a Fixes tag. This patch is for LoongArch and LoongArch only exists after 5.19.
Ah, ok, that wasn't obvious sorry. I thought this was something you wanted backported to the stable kernel trees based on the comment in the first few lines of the change.
I'll leave this alone then, thanks!
greg k-h
linux-stable-mirror@lists.linaro.org