From nobody Wed Dec 17 00:18:29 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1897CEE49A3 for ; Fri, 25 Aug 2023 11:44:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240472AbjHYLna (ORCPT ); Fri, 25 Aug 2023 07:43:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230330AbjHYLm5 (ORCPT ); Fri, 25 Aug 2023 07:42:57 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84DB91FD7; Fri, 25 Aug 2023 04:42:55 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 1A9CE64998; Fri, 25 Aug 2023 11:42:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E165DC433C8; Fri, 25 Aug 2023 11:42:51 +0000 (UTC) From: Huacai Chen To: Arnd Bergmann , Huacai Chen Cc: loongarch@lists.linux.dev, linux-arch@vger.kernel.org, Xuefeng Li , Guo Ren , Xuerui Wang , Jiaxun Yang , linux-kernel@vger.kernel.org, loongson-kernel@lists.loongnix.cn, Huacai Chen Subject: [PATCH] LoongArch: Ensure FP/SIMD registers in the core dump file is up to date Date: Fri, 25 Aug 2023 19:42:24 +0800 Message-Id: <20230825114224.3886577-1-chenhuacai@loongson.cn> X-Mailer: git-send-email 2.39.3 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Huacai Chen --- 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); } =20 -static inline union fpureg *get_fpu_regs(struct task_struct *tsk) +static inline void get_fpu_regs(struct task_struct *tsk) { + unsigned int euen; + if (tsk =3D=3D current) { preempt_disable(); - if (is_fpu_owner()) + + euen =3D 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; } =20 static inline int is_simd_owner(void) diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c index 2bb5ec55ae1e..209e3d29e0b2 100644 --- a/arch/loongarch/kernel/ptrace.c +++ b/arch/loongarch/kernel/ptrace.c @@ -148,6 +148,8 @@ static int fpr_get(struct task_struct *target, { int r; =20 + get_fpu_regs(target); + if (sizeof(target->thread.fpu.fpr[0]) =3D=3D sizeof(elf_fpreg_t)) r =3D gfpr_get(target, &to); else @@ -279,6 +281,8 @@ static int simd_get(struct task_struct *target, { const unsigned int wr_size =3D NUM_FPU_REGS * regset->size; =20 + get_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); --=20 2.39.3