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 04/12] linux-user/sh4: preserve T/M/Q bits across signal delivery
Date: Tue, 26 May 2026 22:01:59 +0200 [thread overview]
Message-ID: <20260526200207.79738-5-deller@kernel.org> (raw)
In-Reply-To: <20260526200207.79738-1-deller@kernel.org>
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
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 ` Helge Deller [this message]
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 ` [PULL 07/12] linux-user/s390x: restore fpu_status rounding mode from FPC on sigreturn Helge Deller
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-5-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.