Commit 3f50dd4666 for qemu.org

commit 3f50dd46664bdf94f10aca8b76dc4dcb9182a5ae
Author: Matt Turner <mattst88@gmail.com>
Date:   Mon May 25 11:23:12 2026 -0400

    linux-user/ppc: restore fp_status from FPSCR on sigreturn

    restore_user_regs() restores the PPC FPSCR with a direct assignment:

        env->fpscr = (uint32_t) fpscr;

    ppc_store_fpscr() exists precisely to write FPSCR and keep the derived
    env->fp_status in sync: it calls fpscr_set_rounding_mode() to update
    the softfloat rounding mode, and set_float_rebias_overflow/underflow()
    to reflect the FP_OE/FP_UE enable bits.  The direct assignment bypasses
    all of this.

    On sigreturn, interrupted code resumes with whatever rounding mode and
    overflow/underflow-rebias state the signal handler last installed in
    fp_status, rather than the state that was saved at signal delivery.

    Replace the direct assign with ppc_store_fpscr().  The FPSCR_MTFS_MASK
    applied inside ppc_store_fpscr() only excludes the computed FP_FEX and
    FP_VX bits, which it re-derives correctly from the exception and enable
    bits in the restored value.

    Fixes: bcd4933a23 ("linux-user: ppc signal handling")
    Cc: qemu-stable@nongnu.org
    Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
    Signed-off-by: Matt Turner <mattst88@gmail.com>
    Signed-off-by: Helge Deller <deller@gmx.de>

diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c
index a9c10e0987..ab1afea30a 100644
--- a/linux-user/ppc/signal.c
+++ b/linux-user/ppc/signal.c
@@ -420,7 +420,7 @@ static void restore_user_regs(CPUPPCState *env,
             __get_user(*fpr, &frame->mc_fregs[i]);
         }
         __get_user(fpscr, &frame->mc_fregs[32]);
-        env->fpscr = (uint32_t) fpscr;
+        ppc_store_fpscr(env, (uint32_t) fpscr);
     }

 #if !defined(TARGET_PPC64)