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

Matt Turner posted 1 patch 5 days, 1 hour ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260525152312.4120017-1-mattst88@gmail.com
Maintainers: Laurent Vivier <laurent@vivier.eu>, Helge Deller <deller@gmx.de>, Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
linux-user/ppc/signal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] linux-user/ppc: restore fp_status from FPSCR on sigreturn
Posted by Matt Turner 5 days, 1 hour ago
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
---
 linux-user/ppc/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git ./linux-user/ppc/signal.c ./linux-user/ppc/signal.c
index a9c10e0987..ab1afea30a 100644
--- ./linux-user/ppc/signal.c
+++ ./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)
-- 
2.53.0
Re: [PATCH] linux-user/ppc: restore fp_status from FPSCR on sigreturn
Posted by Richard Henderson 4 days, 15 hours ago
On 5/25/26 08:23, Matt Turner wrote:
> 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
> ---
>   linux-user/ppc/signal.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git ./linux-user/ppc/signal.c ./linux-user/ppc/signal.c
> index a9c10e0987..ab1afea30a 100644
> --- ./linux-user/ppc/signal.c
> +++ ./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)

I think the cast is wrong.  With that dropped,

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
Re: [PATCH] linux-user/ppc: restore fp_status from FPSCR on sigreturn
Posted by Matt Turner 4 days, 18 hours ago
On Mon, May 25, 2026 at 11:23 AM Matt Turner <mattst88@gmail.com> wrote:
>
> 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
> ---

Signed-off-by: Matt Turner <mattst88@gmail.com>