From 159c645c80c148d05c552bf7034e7a465bb90842 Mon Sep 17 00:00:00 2001 From: Wenqiang Wei Date: Tue, 18 Aug 2026 11:26:29 +0800 Subject: [PATCH] linux-user, fix: Preserve x87 state in signal frames The 32-bit signal path invoked destructive FSAVE before building the FXSAVE or XSAVE image. FSAVE initializes the x87 state, so sigreturn restored an empty stack instead of the interrupted state for Minke.MI. Organ CLR suspension. Capture the extended state before filling the legacy FSAVE area. This preserves both signal-frame formats while leaving the initialized x87 state for the handler, matching Linux x86 signal semantics. Tests: - Verify that an x87 value survives SIGUSR1 delivery and sigreturn Signed-off-by: Wenqiang Wei --- linux-user/i386/signal.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c index 0df6237e87..b55430aff6 100644 --- a/linux-user/i386/signal.c +++ b/linux-user/i386/signal.c @@ -471,15 +471,21 @@ cs->previous_exception_index = -1; __put_user(env->regs[R_ESP], &sc->esp_at_signal); __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss); - cpu_x86_fsave(env, fpstate_addr, 1); - fpstate->status = fpstate->sw; if (!(env->features[FEAT_1_EDX] & CPUID_FXSR)) { magic = 0xffff; } else { + /* + * cpu_x86_fsave() has FSAVE semantics and resets the x87 state. + * Capture the non-destructive extended state first, then let FSAVE + * fill the legacy area and initialize the state used by the handler. + * Sigreturn restores the interrupted state from the signal frame. + */ xsave_sigcontext(env, &fpstate->fxsave, fpstate_addr + TARGET_FPSTATE_FXSAVE_OFFSET); magic = 0; } + cpu_x86_fsave(env, fpstate_addr, 1); + fpstate->status = fpstate->sw; __put_user(magic, &fpstate->magic); #else __put_user(env->regs[R_EDI], &sc->rdi);