From: Helge Deller <deller@kernel.org>
To: qemu-devel@nongnu.org
Cc: "Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
qemu-s390x@nongnu.org,
"Richard Henderson" <richard.henderson@linaro.org>,
"Eric Farman" <farman@linux.ibm.com>,
"Matthew Rosato" <mjrosato@linux.ibm.com>,
"Helge Deller" <deller@gmx.de>,
"Aleksandar Rikalo" <arikalo@gmail.com>,
"David Hildenbrand" <david@kernel.org>,
"Laurent Vivier" <laurent@vivier.eu>,
"Cornelia Huck" <cohuck@redhat.com>,
"Jiaxun Yang" <jiaxun.yang@flygoat.com>,
"Yoshinori Sato" <yoshinori.sato@nifty.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Ilya Leoshkevich" <iii@linux.ibm.com>,
"Aurelien Jarno" <aurelien@aurel32.net>
Subject: [PULL 07/12] linux-user/s390x: restore fpu_status rounding mode from FPC on sigreturn
Date: Tue, 26 May 2026 22:02:02 +0200 [thread overview]
Message-ID: <20260526200207.79738-8-deller@kernel.org> (raw)
In-Reply-To: <20260526200207.79738-1-deller@kernel.org>
From: Matt Turner <mattst88@gmail.com>
QEMU keeps the s390x floating-point control register (FPC) in env->fpc.
The rounding mode bits [2:0] of FPC are reflected into the derived
env->fpu_status via set_float_rounding_mode(); every architectural
write to FPC goes through HELPER(sfpc) which keeps the two in sync.
restore_sigregs() restored FPC with a direct assignment:
__get_user(env->fpc, &sc->fpregs.fpc);
This wrote env->fpc correctly but never updated env->fpu_status, so on
sigreturn the interrupted code resumed with whatever rounding mode the
signal handler last installed in fpu_status.
Factor the two-step "write fpc + sync fpu_status" logic out of
HELPER(sfpc) into cpu_s390x_load_fpc(), declare it in cpu.h, and call
it from restore_sigregs() in place of the direct assignment.
cpu_s390x_load_fpc() partially reuses the sanity check from
HELPER(sfpc): if the FPC value has an invalid rounding mode or reserved
bits set, it falls back to 0, matching the kernel's fpu_lfpc_safe()
behavior where a corrupt signal frame value causes a specification
exception and 0 is used instead.
HELPER(sfpc) now calls cpu_s390x_load_fpc() after its full
specification-exception check, including the FEAT_FLOATING_POINT_EXT
test that is not needed for the signal restore path.
Fixes: 2941e0fa05 ("linux-user/s390x: Save/restore fpc when handling a signal")
Cc: qemu-stable@nongnu.org
Signed-off-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/s390x/signal.c | 6 +++++-
target/s390x/cpu.h | 1 +
target/s390x/tcg/fpu_helper.c | 20 ++++++++++++++------
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c
index 96d1c8d11c..28ad80bde4 100644
--- a/linux-user/s390x/signal.c
+++ b/linux-user/s390x/signal.c
@@ -332,7 +332,11 @@ static void restore_sigregs(CPUS390XState *env, target_sigregs *sc)
for (i = 0; i < 16; i++) {
__get_user(env->aregs[i], &sc->regs.acrs[i]);
}
- __get_user(env->fpc, &sc->fpregs.fpc);
+ {
+ uint32_t fpc;
+ __get_user(fpc, &sc->fpregs.fpc);
+ cpu_s390x_load_fpc(env, fpc);
+ }
for (i = 0; i < 16; i++) {
__get_user(*get_freg(env, i), &sc->fpregs.fprs[i]);
}
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 3acbe83f0f..f55b79ef8a 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -895,6 +895,7 @@ void s390_init_sigp(void);
/* helper.c */
void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr);
uint64_t s390_cpu_get_psw_mask(CPUS390XState *env);
+void cpu_s390x_load_fpc(CPUS390XState *env, uint32_t fpc);
/* outside of target/s390x/ */
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
diff --git a/target/s390x/tcg/fpu_helper.c b/target/s390x/tcg/fpu_helper.c
index 6ca0b7162b..107025e675 100644
--- a/target/s390x/tcg/fpu_helper.c
+++ b/target/s390x/tcg/fpu_helper.c
@@ -1087,6 +1087,19 @@ static const int fpc_to_rnd[8] = {
float_round_to_odd,
};
+void cpu_s390x_load_fpc(CPUS390XState *env, uint32_t fpc)
+{
+ /*
+ * Mimic kernel fpu_lfpc_safe(): a corrupt signal frame value that would
+ * trigger a specification exception instead results in FPC being set to 0.
+ */
+ if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u) {
+ fpc = 0;
+ }
+ env->fpc = fpc;
+ set_float_rounding_mode(fpc_to_rnd[fpc & 0x7], &env->fpu_status);
+}
+
/* set fpc */
void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
{
@@ -1094,12 +1107,7 @@ void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
(!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
}
-
- /* Install everything in the main FPC. */
- env->fpc = fpc;
-
- /* Install the rounding mode in the shadow fpu_status. */
- set_float_rounding_mode(fpc_to_rnd[fpc & 0x7], &env->fpu_status);
+ cpu_s390x_load_fpc(env, fpc);
}
/* set fpc and signal */
--
2.54.0
next prev parent reply other threads:[~2026-05-26 20:04 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-26 20:01 [PULL 00/12] Linux user next patches Helge Deller
2026-05-26 20:01 ` [PULL 01/12] linux-user/ppc: restore fp_status from FPSCR on sigreturn Helge Deller
2026-05-26 20:01 ` [PULL 02/12] linux-user/mips: save/restore FCSR across signal delivery Helge Deller
2026-05-26 20:01 ` [PULL 03/12] linux-user/alpha: add coredump support Helge Deller
2026-05-27 16:26 ` Richard Henderson
2026-05-26 20:01 ` [PULL 04/12] linux-user/sh4: preserve T/M/Q bits across signal delivery Helge Deller
2026-05-26 20:02 ` [PULL 05/12] linux-user/sh4: restore FP rounding mode on sigreturn Helge Deller
2026-05-26 20:02 ` [PULL 06/12] target/sh4: sync fp_status when gdb writes FPSCR Helge Deller
2026-05-26 20:02 ` Helge Deller [this message]
2026-05-26 20:02 ` [PULL 08/12] linux-user: Implement finer grained madivse() syscall Helge Deller
2026-05-26 20:02 ` [PULL 09/12] linux-user: Fix typo in function documentation for pgb_addr_set() Helge Deller
2026-05-26 20:02 ` [PULL 10/12] linux-user: Fix loading static ARM cortex-m55 binaries Helge Deller
2026-05-26 20:02 ` [PULL 11/12] linux-user: Move init_main_thread() prototype to user-internals.h Helge Deller
2026-05-26 20:02 ` [PULL 12/12] linux-user: Move cpu_copy() " Helge Deller
2026-05-27 11:41 ` [PULL 00/12] Linux user next patches Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260526200207.79738-8-deller@kernel.org \
--to=deller@kernel.org \
--cc=arikalo@gmail.com \
--cc=aurelien@aurel32.net \
--cc=cohuck@redhat.com \
--cc=david@kernel.org \
--cc=deller@gmx.de \
--cc=farman@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=jiaxun.yang@flygoat.com \
--cc=laurent@vivier.eu \
--cc=mjrosato@linux.ibm.com \
--cc=philmd@linaro.org \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=yoshinori.sato@nifty.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.