Skip to content

Commit 95c5d3f

Browse files
chenhuacaigregkh
authored andcommitted
LoongArch: Ensure FP/SIMD registers in the core dump file is up to date
[ Upstream commit 656f9ae ] This is a port of commit 379eb01 ("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: [email protected] Signed-off-by: Huacai Chen <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent ccdfcb9 commit 95c5d3f

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

arch/loongarch/include/asm/fpu.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,30 @@ static inline void restore_fp(struct task_struct *tsk)
117117
_restore_fp(&tsk->thread.fpu);
118118
}
119119

120-
static inline union fpureg *get_fpu_regs(struct task_struct *tsk)
120+
static inline void save_fpu_regs(struct task_struct *tsk)
121121
{
122+
unsigned int euen;
123+
122124
if (tsk == current) {
123125
preempt_disable();
124-
if (is_fpu_owner())
126+
127+
euen = csr_read32(LOONGARCH_CSR_EUEN);
128+
129+
#ifdef CONFIG_CPU_HAS_LASX
130+
if (euen & CSR_EUEN_LASXEN)
131+
_save_lasx(&current->thread.fpu);
132+
else
133+
#endif
134+
#ifdef CONFIG_CPU_HAS_LSX
135+
if (euen & CSR_EUEN_LSXEN)
136+
_save_lsx(&current->thread.fpu);
137+
else
138+
#endif
139+
if (euen & CSR_EUEN_FPEN)
125140
_save_fp(&current->thread.fpu);
141+
126142
preempt_enable();
127143
}
128-
129-
return tsk->thread.fpu.fpr;
130144
}
131145

132146
#endif /* _ASM_FPU_H */

arch/loongarch/kernel/ptrace.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ static int fpr_get(struct task_struct *target,
147147
{
148148
int r;
149149

150+
save_fpu_regs(target);
151+
150152
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
151153
r = gfpr_get(target, &to);
152154
else

0 commit comments

Comments
 (0)