* [PULL v3 00/10] Linux user next patches
@ 2026-05-29 21:51 Helge Deller
2026-05-29 21:51 ` [PULL v3 01/10] linux-user/ppc: restore fp_status from FPSCR on sigreturn Helge Deller
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo
The following changes since commit 2db91528542672cf0db78b3f2cc0e22b36302b38:
Merge tag 'pull-vfio-20260527' of https://github.com/legoater/qemu into staging (2026-05-27 14:45:58 -0400)
are available in the Git repository at:
https://github.com/hdeller/qemu-hppa.git tags/linux-user-next-pull-request
for you to fetch changes up to 07e701716b43da1a86c1045871c1eb613cf5e53a:
linux-user: Move cpu_copy() to user-internals.h (2026-05-29 23:40:53 +0200)
----------------------------------------------------------------
linux user patches
A series of patches for linux-user, specifically many FPU fixes in signal
handling code for sh4, mips, ppc and s390x (from Matt Turner), a madvise()
improvement (from me), and qemu header cleanups (from Peter Maydell).
---
v3: Fix build failure due to unknown MADV_COLLAPSE constant in madivise() patch
v2: Dropped the "ARM cortex-m55 program loading fix" and the FPU alpha patch
----------------------------------------------------------------
Helge Deller (2):
linux-user: Implement finer grained madivse() syscall
linux-user: Fix typo in function documentation for pgb_addr_set()
Matt Turner (6):
linux-user/ppc: restore fp_status from FPSCR on sigreturn
linux-user/mips: save/restore FCSR across signal delivery
linux-user/sh4: preserve T/M/Q bits across signal delivery
linux-user/sh4: restore FP rounding mode on sigreturn
target/sh4: sync fp_status when gdb writes FPSCR
linux-user/s390x: restore fpu_status rounding mode from FPC on
sigreturn
Peter Maydell (2):
linux-user: Move init_main_thread() prototype to user-internals.h
linux-user: Move cpu_copy() to user-internals.h
linux-user/elfload.c | 2 +-
linux-user/mips/signal.c | 7 +++++++
linux-user/mmap.c | 34 +++++++++++++++++++++++++++++++++-
linux-user/ppc/signal.c | 2 +-
linux-user/qemu.h | 5 -----
linux-user/s390x/signal.c | 6 +++++-
linux-user/sh4/signal.c | 19 ++++++++++++++++---
linux-user/user-internals.h | 18 ++++++++++++++++++
target/mips/cpu.h | 3 +++
target/mips/fpu.c | 5 +++++
target/s390x/cpu.h | 1 +
target/s390x/tcg/fpu_helper.c | 20 ++++++++++++++------
target/sh4/cpu.h | 3 +++
target/sh4/gdbstub.c | 2 +-
target/sh4/op_helper.c | 7 ++++++-
tests/tcg/sh4/Makefile.target | 7 -------
16 files changed, 114 insertions(+), 27 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PULL v3 01/10] linux-user/ppc: restore fp_status from FPSCR on sigreturn
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 02/10] linux-user/mips: save/restore FCSR across signal delivery Helge Deller
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Matt Turner, qemu-stable
From: Matt Turner <mattst88@gmail.com>
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>
---
linux-user/ppc/signal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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)
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 02/10] linux-user/mips: save/restore FCSR across signal delivery
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
2026-05-29 21:51 ` [PULL v3 01/10] linux-user/ppc: restore fp_status from FPSCR on sigreturn Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 03/10] linux-user/sh4: preserve T/M/Q bits " Helge Deller
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Matt Turner, qemu-stable
From: Matt Turner <mattst88@gmail.com>
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>
---
linux-user/mips/signal.c | 7 +++++++
target/mips/cpu.h | 3 +++
target/mips/fpu.c | 5 +++++
3 files changed, 15 insertions(+)
diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
index d69a5d73dd..1b10012726 100644
--- a/linux-user/mips/signal.c
+++ b/linux-user/mips/signal.c
@@ -134,6 +134,7 @@ static inline void setup_sigcontext(CPUMIPSState *regs,
for (i = 0; i < 32; ++i) {
__put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
}
+ __put_user(regs->active_fpu.fcr31, &sc->sc_fpc_csr);
}
static inline void
@@ -165,6 +166,12 @@ restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
for (i = 0; i < 32; ++i) {
__get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
}
+ {
+ uint32_t fcr31;
+ __get_user(fcr31, &sc->sc_fpc_csr);
+ regs->active_fpu.fcr31 = fcr31 & regs->active_fpu.fcr31_rw_bitmask;
+ cpu_mips_restore_fp_status(regs);
+ }
}
/*
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 346713705a..392406aff8 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1384,6 +1384,9 @@ void cpu_mips_clock_init(MIPSCPU *cpu);
/* helper.c */
target_ulong exception_resume_pc(CPUMIPSState *env);
+/* fpu.c */
+void cpu_mips_restore_fp_status(CPUMIPSState *env);
+
/**
* mips_cpu_create_with_clock:
* @typename: a MIPS CPU type.
diff --git a/target/mips/fpu.c b/target/mips/fpu.c
index c7c487c1f9..8b661865ca 100644
--- a/target/mips/fpu.c
+++ b/target/mips/fpu.c
@@ -17,6 +17,11 @@ const FloatRoundMode ieee_rm[4] = {
float_round_down
};
+void cpu_mips_restore_fp_status(CPUMIPSState *env)
+{
+ restore_fp_status(env);
+}
+
const char fregnames[32][4] = {
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 03/10] linux-user/sh4: preserve T/M/Q bits across signal delivery
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
2026-05-29 21:51 ` [PULL v3 01/10] linux-user/ppc: restore fp_status from FPSCR on sigreturn Helge Deller
2026-05-29 21:51 ` [PULL v3 02/10] linux-user/mips: save/restore FCSR across signal delivery Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 04/10] linux-user/sh4: restore FP rounding mode on sigreturn Helge Deller
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Matt Turner, qemu-stable
From: Matt Turner <mattst88@gmail.com>
QEMU keeps the SH4 T, M and Q status-register bits outside env->sr, in
the dedicated env->sr_t, env->sr_m and env->sr_q fields; cpu_read_sr()
folds them back into the architectural SR value and cpu_write_sr()
splits them back out.
setup_sigcontext() saved the bare env->sr (so the T/M/Q bits were always
zero in the signal frame) and restore_sigcontext() wrote the value
straight back into env->sr without updating sr_t/sr_m/sr_q. As a result
the T bit was never preserved across signal delivery: on sigreturn the
interrupted code resumed with whatever T value the signal handler last
left behind. Any conditional branch (or addc/subc/rotcl/div1, etc.)
immediately following the interrupted instruction could then take the
wrong path.
This is the cause of the long-standing intermittent failures of the
tests/tcg/multiarch/signals.c test on sh4, which was marked BROKEN. With
a SIGRTMIN timer firing every millisecond across many threads, the race
was hit a few percent of the time and corrupted the guest heap, surfacing
as a SIGSEGV in memset, a malloc assertion, or an rseq registration abort.
Traced on a deterministic rr recording: a cmp/hi set T=0, the timer
signal interrupted the very next instruction (a bf), the handler left
T=1, and the resumed bf took glibc calloc's MORECORE_CLEARS branch,
using the old top-chunk size as the clear length for a freshly split
small chunk and running memset off the end of the heap.
Fix setup_sigcontext()/restore_sigcontext() to use cpu_read_sr() and
cpu_write_sr() so the T, M and Q bits round-trip correctly, and drop the
BROKEN annotation on the sh4 signals test.
Fixes: c3b5bc8ab3 ("SH4: Signal handling for the user space emulator, by Magnus Damm.")
Cc: qemu-stable@nongnu.org
Reviewed-by: Yoshinori Sato <yoshinori.sato@nifty.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/sh4/signal.c | 12 ++++++++++--
tests/tcg/sh4/Makefile.target | 7 -------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/linux-user/sh4/signal.c b/linux-user/sh4/signal.c
index d70be24c38..cc36425c49 100644
--- a/linux-user/sh4/signal.c
+++ b/linux-user/sh4/signal.c
@@ -131,8 +131,10 @@ static void setup_sigcontext(struct target_sigcontext *sc,
COPY(gregs[14]); COPY(gregs[15]);
COPY(gbr); COPY(mach);
COPY(macl); COPY(pr);
- COPY(sr); COPY(pc);
+ COPY(pc);
#undef COPY
+ /* The T, M and Q bits live outside env->sr; fold them back in. */
+ __put_user(cpu_read_sr(regs), &sc->sc_sr);
for (i=0; i<16; i++) {
__put_user(regs->fregs[i], &sc->sc_fpregs[i]);
@@ -159,8 +161,14 @@ static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc)
COPY(gregs[14]); COPY(gregs[15]);
COPY(gbr); COPY(mach);
COPY(macl); COPY(pr);
- COPY(sr); COPY(pc);
+ COPY(pc);
#undef COPY
+ /* The T, M and Q bits live outside env->sr; unfold them. */
+ {
+ uint32_t sr;
+ __get_user(sr, &sc->sc_sr);
+ cpu_write_sr(regs, sr);
+ }
for (i=0; i<16; i++) {
__get_user(regs->fregs[i], &sc->sc_fpregs[i]);
diff --git a/tests/tcg/sh4/Makefile.target b/tests/tcg/sh4/Makefile.target
index 7852fa62d8..b7a8737be0 100644
--- a/tests/tcg/sh4/Makefile.target
+++ b/tests/tcg/sh4/Makefile.target
@@ -3,13 +3,6 @@
# SuperH specific tweaks
#
-# This triggers failures for sh4-linux about 10% of the time.
-# Random SIGSEGV at unpredictable guest address, cause unknown.
-run-signals: signals
- $(call skip-test, $<, "BROKEN")
-run-plugin-signals-with-%:
- $(call skip-test, $<, "BROKEN")
-
VPATH += $(SRC_PATH)/tests/tcg/sh4
test-macl: CFLAGS += -O -g
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 04/10] linux-user/sh4: restore FP rounding mode on sigreturn
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
` (2 preceding siblings ...)
2026-05-29 21:51 ` [PULL v3 03/10] linux-user/sh4: preserve T/M/Q bits " Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 05/10] target/sh4: sync fp_status when gdb writes FPSCR Helge Deller
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Matt Turner, qemu-stable
From: Matt Turner <mattst88@gmail.com>
The SH4 FPSCR rounding-mode (RM) and denormal (DN) bits are not held
only in env->fpscr: they are also reflected into the derived
env->fp_status via set_float_rounding_mode()/set_flush_to_zero(). The
guest keeps the two in sync by routing every write to FPSCR through
helper_ld_fpscr().
restore_sigcontext() wrote the saved value straight into env->fpscr and
never touched env->fp_status, so on sigreturn the interrupted code
resumed with whatever FP rounding mode and flush-to-zero setting the
signal handler last installed. (regs->flags = 0 forces the FR/SZ/PR TB
flags to be recomputed, but fp_status is runtime float state, not a TB
flag, so it was left stale.) This is the FP analogue of the T/M/Q bit
problem just fixed for the integer status register.
Factor the FPSCR -> fp_status synchronisation out of helper_ld_fpscr()
into cpu_load_fpscr() and use it from restore_sigcontext() so the
rounding mode round-trips correctly across signal delivery.
Fixes: c3b5bc8ab3 ("SH4: Signal handling for the user space emulator, by Magnus Damm.")
Cc: qemu-stable@nongnu.org
Reviewed-by: Yoshinori Sato <yoshinori.sato@nifty.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/sh4/signal.c | 7 ++++++-
target/sh4/cpu.h | 3 +++
target/sh4/op_helper.c | 7 ++++++-
3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/linux-user/sh4/signal.c b/linux-user/sh4/signal.c
index cc36425c49..00290d6e40 100644
--- a/linux-user/sh4/signal.c
+++ b/linux-user/sh4/signal.c
@@ -173,7 +173,12 @@ static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc)
for (i=0; i<16; i++) {
__get_user(regs->fregs[i], &sc->sc_fpregs[i]);
}
- __get_user(regs->fpscr, &sc->sc_fpscr);
+ /* Resync the derived float_status state, not just env->fpscr. */
+ {
+ uint32_t fpscr;
+ __get_user(fpscr, &sc->sc_fpscr);
+ cpu_load_fpscr(regs, fpscr);
+ }
__get_user(regs->fpul, &sc->sc_fpul);
regs->tra = -1; /* disable syscall checks */
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 4b0f3f6d97..3302702376 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -379,4 +379,7 @@ static inline void cpu_write_sr(CPUSH4State *env, uint32_t sr)
env->sr = sr & ~((1u << SR_M) | (1u << SR_Q) | (1u << SR_T));
}
+/* Set FPSCR and the derived float_status rounding/flush-to-zero state. */
+void cpu_load_fpscr(CPUSH4State *env, uint32_t val);
+
#endif /* SH4_CPU_H */
diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c
index 669bc84cb6..cf0f80e4a5 100644
--- a/target/sh4/op_helper.c
+++ b/target/sh4/op_helper.c
@@ -204,7 +204,7 @@ void helper_macw(CPUSH4State *env, int32_t arg0, int32_t arg1)
}
}
-void helper_ld_fpscr(CPUSH4State *env, uint32_t val)
+void cpu_load_fpscr(CPUSH4State *env, uint32_t val)
{
env->fpscr = val & FPSCR_MASK;
if ((val & FPSCR_RM_MASK) == FPSCR_RM_ZERO) {
@@ -215,6 +215,11 @@ void helper_ld_fpscr(CPUSH4State *env, uint32_t val)
set_flush_to_zero((val & FPSCR_DN) != 0, &env->fp_status);
}
+void helper_ld_fpscr(CPUSH4State *env, uint32_t val)
+{
+ cpu_load_fpscr(env, val);
+}
+
static void update_fpscr(CPUSH4State *env, uintptr_t retaddr)
{
int xcpt, cause, enable;
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 05/10] target/sh4: sync fp_status when gdb writes FPSCR
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
` (3 preceding siblings ...)
2026-05-29 21:51 ` [PULL v3 04/10] linux-user/sh4: restore FP rounding mode on sigreturn Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 06/10] linux-user/s390x: restore fpu_status rounding mode from FPC on sigreturn Helge Deller
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Matt Turner, qemu-stable
From: Matt Turner <mattst88@gmail.com>
sh4_cpu_gdb_write_register() wrote the incoming FPSCR value straight
into env->fpscr, leaving the derived env->fp_status (rounding mode and
flush-to-zero) stale, so a gdb-initiated FPSCR change did not take
effect for subsequent FP operations. Use cpu_load_fpscr() instead, the
same way the adjacent case already uses cpu_write_sr() for SR.
Cc: qemu-stable@nongnu.org
Reviewed-by: Yoshinori Sato <yoshinori.sato@nifty.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
---
target/sh4/gdbstub.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/sh4/gdbstub.c b/target/sh4/gdbstub.c
index 4f36e800d2..bdc8c1d164 100644
--- a/target/sh4/gdbstub.c
+++ b/target/sh4/gdbstub.c
@@ -113,7 +113,7 @@ int superh_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
env->fpul = ldl_p(mem_buf);
break;
case 24:
- env->fpscr = ldl_p(mem_buf);
+ cpu_load_fpscr(env, ldl_p(mem_buf));
break;
case 25 ... 40:
if (env->fpscr & FPSCR_FR) {
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 06/10] linux-user/s390x: restore fpu_status rounding mode from FPC on sigreturn
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
` (4 preceding siblings ...)
2026-05-29 21:51 ` [PULL v3 05/10] target/sh4: sync fp_status when gdb writes FPSCR Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 07/10] linux-user: Implement finer grained madivse() syscall Helge Deller
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Matt Turner, qemu-stable
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
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 07/10] linux-user: Implement finer grained madivse() syscall
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
` (5 preceding siblings ...)
2026-05-29 21:51 ` [PULL v3 06/10] linux-user/s390x: restore fpu_status rounding mode from FPC on sigreturn Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 08/10] linux-user: Fix typo in function documentation for pgb_addr_set() Helge Deller
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo
Although most madvise() values are hints, some are important and are
checked by userspace, especially by security-relevant applications like
BoringSLL. So, return -EINVAL for those functions which we don't emulate.
Signed-off-by: Helge Deller <deller@gmx.de>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3489
---
linux-user/mmap.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index b4b7b3e5cc..55277f7c3e 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -1282,7 +1282,7 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
case TARGET_MADV_KEEPONFORK: /* parisc */
advice = MADV_KEEPONFORK;
break;
- /* we do not care about the other MADV_xxx values yet */
+ /* all other MADV_xxx values are the same across architectures */
}
/*
@@ -1307,6 +1307,19 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
*/
mmap_lock();
switch (advice) {
+ case MADV_NORMAL:
+ case MADV_RANDOM:
+ case MADV_SEQUENTIAL:
+ case MADV_WILLNEED:
+ case MADV_DOFORK:
+ case MADV_FREE:
+ case MADV_COLD:
+ case MADV_PAGEOUT:
+ ret = 0; /* OK */
+ break;
+ case MADV_REMOVE:
+ ret = -EOPNOTSUPP;
+ break;
case MADV_DONTDUMP:
page_set_flags(start, start + len - 1, PAGE_DONTDUMP, 0);
break;
@@ -1324,6 +1337,25 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
page_reset_target_data(start, start + len - 1);
}
}
+ break;
+ case MADV_DONTFORK:
+ case MADV_HWPOISON:
+ case MADV_MERGEABLE:
+ case MADV_UNMERGEABLE:
+ case MADV_HUGEPAGE:
+ case MADV_NOHUGEPAGE:
+ case MADV_POPULATE_READ:
+ case MADV_POPULATE_WRITE:
+#ifdef MADV_COLLAPSE
+ case MADV_COLLAPSE:
+#endif
+ case -1: /* BoringSSL uses -1 to check if the environment is broken */
+ ret = -EINVAL;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "Unhandled madvise(%d) call.\n", advice);
+ ret = -EINVAL; /* not yet known advise */
+ break;
}
mmap_unlock();
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 08/10] linux-user: Fix typo in function documentation for pgb_addr_set()
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
` (6 preceding siblings ...)
2026-05-29 21:51 ` [PULL v3 07/10] linux-user: Implement finer grained madivse() syscall Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 09/10] linux-user: Move init_main_thread() prototype to user-internals.h Helge Deller
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Peter Maydell, Alex Bennée
The third parameter is called guest_hiaddr.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/elfload.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0e757787d2..f7625c0952 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -848,7 +848,7 @@ static bool pgb_try_mmap_set(const PGBAddrs *ga, uintptr_t base, uintptr_t brk)
* pgb_addr_set:
* @ga: output set of guest addrs
* @guest_loaddr: guest image low address
- * @guest_loaddr: guest image high address
+ * @guest_hiaddr: guest image high address
* @identity: create for identity mapping
*
* Fill in @ga with the image, COMMPAGE and NULL page.
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 09/10] linux-user: Move init_main_thread() prototype to user-internals.h
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
` (7 preceding siblings ...)
2026-05-29 21:51 ` [PULL v3 08/10] linux-user: Fix typo in function documentation for pgb_addr_set() Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-05-29 21:51 ` [PULL v3 10/10] linux-user: Move cpu_copy() " Helge Deller
2026-06-01 14:00 ` [PULL v3 00/10] Linux user next patches Stefan Hajnoczi
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
The init_main_thread() prototype is needed only by code internal to
linux-user/, so it doesn't need to be in qemu.h (which is also pulled
in by various files outside linux-user/).
Move the prototype to user-internals.h, and give it a documentation
comment.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/qemu.h | 2 --
linux-user/user-internals.h | 15 +++++++++++++++
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 7f98fb2607..474489f046 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -371,6 +371,4 @@ void *lock_user_string(abi_ulong guest_addr);
/* Clone cpu state */
CPUArchState *cpu_copy(CPUArchState *env);
-void init_main_thread(CPUState *cs, struct image_info *info);
-
#endif /* QEMU_H */
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
index 21daf422b7..fbfd12237f 100644
--- a/linux-user/user-internals.h
+++ b/linux-user/user-internals.h
@@ -194,6 +194,21 @@ static inline void begin_parallel_context(CPUState *cs)
}
}
+/**
+ * init_main_thread: Set CPU state for main thread
+ * @cs: CPU context to set
+ * @info: information about the image being loaded
+ *
+ * This function must be provided by the per-target code. It should
+ * set the initial CPU state based on the information about the
+ * starting binary in @image_info. This will be at a minimum setting
+ * the initial guest program counter and stack pointer; it should
+ * also set up any other guest register values where the Linux ABI
+ * defines that they start set to some other value than what the
+ * guest CPU architecture gives you out of reset.
+ */
+void init_main_thread(CPUState *cs, struct image_info *info);
+
/*
* Include target-specific struct and function definitions;
* they may need access to the target-independent structures
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL v3 10/10] linux-user: Move cpu_copy() to user-internals.h
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
` (8 preceding siblings ...)
2026-05-29 21:51 ` [PULL v3 09/10] linux-user: Move init_main_thread() prototype to user-internals.h Helge Deller
@ 2026-05-29 21:51 ` Helge Deller
2026-06-01 14:00 ` [PULL v3 00/10] Linux user next patches Stefan Hajnoczi
10 siblings, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-05-29 21:51 UTC (permalink / raw)
To: qemu-devel
Cc: Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier, Richard Henderson,
Cornelia Huck, David Hildenbrand, qemu-s390x, Eric Farman,
Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo, Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
We only use cpu_copy() inside linux-user, so we don't need to have
the prototype in qemu.h available to code outside linux-user; move it
to user-internals.h.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/qemu.h | 3 ---
linux-user/user-internals.h | 3 +++
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 474489f046..07fe801628 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -368,7 +368,4 @@ void *lock_user_string(abi_ulong guest_addr);
#define unlock_user_struct(host_ptr, guest_addr, copy) \
unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
-/* Clone cpu state */
-CPUArchState *cpu_copy(CPUArchState *env);
-
#endif /* QEMU_H */
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
index fbfd12237f..0380d44fe9 100644
--- a/linux-user/user-internals.h
+++ b/linux-user/user-internals.h
@@ -209,6 +209,9 @@ static inline void begin_parallel_context(CPUState *cs)
*/
void init_main_thread(CPUState *cs, struct image_info *info);
+/* Clone cpu state */
+CPUArchState *cpu_copy(CPUArchState *env);
+
/*
* Include target-specific struct and function definitions;
* they may need access to the target-independent structures
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PULL v3 00/10] Linux user next patches
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
` (9 preceding siblings ...)
2026-05-29 21:51 ` [PULL v3 10/10] linux-user: Move cpu_copy() " Helge Deller
@ 2026-06-01 14:00 ` Stefan Hajnoczi
10 siblings, 0 replies; 12+ messages in thread
From: Stefan Hajnoczi @ 2026-06-01 14:00 UTC (permalink / raw)
To: Helge Deller
Cc: qemu-devel, Jiaxun Yang, Ilya Leoshkevich, Laurent Vivier,
Richard Henderson, Cornelia Huck, David Hildenbrand, qemu-s390x,
Eric Farman, Aurelien Jarno, Matthew Rosato, Helge Deller,
Philippe Mathieu-Daudé, Yoshinori Sato, Pierrick Bouvier,
Aleksandar Rikalo
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-06-01 14:01 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-29 21:51 [PULL v3 00/10] Linux user next patches Helge Deller
2026-05-29 21:51 ` [PULL v3 01/10] linux-user/ppc: restore fp_status from FPSCR on sigreturn Helge Deller
2026-05-29 21:51 ` [PULL v3 02/10] linux-user/mips: save/restore FCSR across signal delivery Helge Deller
2026-05-29 21:51 ` [PULL v3 03/10] linux-user/sh4: preserve T/M/Q bits " Helge Deller
2026-05-29 21:51 ` [PULL v3 04/10] linux-user/sh4: restore FP rounding mode on sigreturn Helge Deller
2026-05-29 21:51 ` [PULL v3 05/10] target/sh4: sync fp_status when gdb writes FPSCR Helge Deller
2026-05-29 21:51 ` [PULL v3 06/10] linux-user/s390x: restore fpu_status rounding mode from FPC on sigreturn Helge Deller
2026-05-29 21:51 ` [PULL v3 07/10] linux-user: Implement finer grained madivse() syscall Helge Deller
2026-05-29 21:51 ` [PULL v3 08/10] linux-user: Fix typo in function documentation for pgb_addr_set() Helge Deller
2026-05-29 21:51 ` [PULL v3 09/10] linux-user: Move init_main_thread() prototype to user-internals.h Helge Deller
2026-05-29 21:51 ` [PULL v3 10/10] linux-user: Move cpu_copy() " Helge Deller
2026-06-01 14:00 ` [PULL v3 00/10] Linux user next patches Stefan Hajnoczi
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.