linux-user/mips: save/restore FCSR across signal delivery
QEMU keeps the MIPS FPU control/status register (FCSR, fcr31) in env->active_fpu.fcr31. The rounding mode, flush-to-zero (FS), and NaN-2008 mode bits in fcr31 are reflected into the derived env->active_fpu.fp_status via set_float_rounding_mode() and friends; every architectural write to FCSR goes through helper_ctc1() which calls restore_fp_status() to keep the two in sync. Both target_sigcontext variants (O32 and N32/N64) have an sc_fpc_csr field that holds FCSR, but setup_sigcontext() never wrote it and restore_sigcontext() never read it. As a result: - The signal frame always delivered sc_fpc_csr == 0 to the handler, so sigaction(SA_SIGINFO) handlers that inspect the interrupted context see the wrong FCSR. - On sigreturn, active_fpu.fcr31 retained whatever value the signal handler last installed (if any), and active_fpu.fp_status was never resynced. Interrupted code resumed with the wrong rounding mode, FS flag, and NaN-2008 semantics. Fix setup_sigcontext() to save fcr31 into sc_fpc_csr. Fix restore_sigcontext() to read it back (masked to fcr31_rw_bitmask as the kernel does) and call cpu_mips_restore_fp_status() to resync fp_status from the restored fcr31. Add cpu_mips_restore_fp_status() in target/mips/fpu.c (which already defines ieee_rm and includes fpu_helper.h), and declare it in cpu.h. Fixes: 084d0497a0 ("mips-linux-user: Save and restore fpu and dsp from sigcontext") Cc: qemu-stable@nongnu.org Signed-off-by: Matt Turner <mattst88@gmail.com> Signed-off-by: Helge Deller <deller@gmx.de>