From: Helge Deller <deller@kernel.org>
To: qemu-devel@nongnu.org
Cc: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>,
Max Filippov <jcmvbkbc@gmail.com>, Helge Deller <deller@gmx.de>,
Yoshinori Sato <yoshinori.sato@nifty.com>,
Laurent Vivier <laurent@vivier.eu>,
Matt Turner <mattst88@gmail.com>,
Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Subject: [PULL 6/8] linux-user/sparc: call block_signals() before set_sigmask() in setcontext
Date: Mon, 8 Jun 2026 21:42:54 +0200 [thread overview]
Message-ID: <20260608194256.13794-7-deller@kernel.org> (raw)
In-Reply-To: <20260608194256.13794-1-deller@kernel.org>
From: Matt Turner <mattst88@gmail.com>
sparc64_set_context() emulates the kernel's `ta 0x6f` trap by calling
set_sigmask() to install the mask supplied via the user's ucontext_t.
The contract of set_sigmask() (see its comment in linux-user/signal.c)
is that the caller must have first called block_signals(), which sets
TaskState::signal_pending.
Without block_signals(), if a guest signal is pending-and-blocked at
the time setcontext is invoked and the new mask unblocks it,
signal_pending stays 0 and the post-trap process_pending_signals()
call in linux-user/sparc/cpu_loop.c never enters its while loop, so
the now-deliverable signal is left undelivered indefinitely.
This affects programs that use getcontext/setcontext to swap signal
masks, including libunwind's unw_resume() out of a signal handler:
without this fix, the test program below loops forever printing
"calling setcontext" instead of delivering the pending SIGUSR2.
#define _GNU_SOURCE
#include <ucontext.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
static int got;
static void h(int s) { got = 1; }
int main(void) {
signal(SIGUSR2, h);
sigset_t m; sigemptyset(&m); sigaddset(&m, SIGUSR2);
sigprocmask(SIG_BLOCK, &m, NULL);
kill(getpid(), SIGUSR2);
ucontext_t uc;
getcontext(&uc);
if (got) return 0;
uc.uc_sigmask.__val[0] = 0;
setcontext(&uc);
return 1;
}
The 32-bit sparc do_sigreturn / do_rt_sigreturn paths already get
block_signals() from the rt_sigreturn syscall wrapper in
linux-user/syscall.c, so only sparc64_set_context (invoked directly
from cpu_loop) needs the addition.
Signed-off-by: Matt Turner <mattst88@gmail.com>
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/sparc/signal.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
index fda5508c48..ba692c3123 100644
--- a/linux-user/sparc/signal.c
+++ b/linux-user/sparc/signal.c
@@ -619,6 +619,15 @@ void sparc64_set_context(CPUSPARCState *env)
}
}
target_to_host_sigset_internal(&set, &target_set);
+ /*
+ * set_sigmask() requires the caller to have first called
+ * block_signals() so that process_pending_signals() is guaranteed
+ * to run after the mask change. Without this, a guest signal that
+ * is pending-and-blocked at setcontext time is left undelivered
+ * even after its mask bit is cleared, because signal_pending stays
+ * 0 and the post-trap process_pending_signals() loop never enters.
+ */
+ block_signals();
set_sigmask(&set);
}
env->pc = pc;
--
2.54.0
next prev parent reply other threads:[~2026-06-08 19:44 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 19:42 [PULL 0/8] Linux user patches Helge Deller
2026-06-08 19:42 ` [PULL 1/8] linux-user: implement fsmount(2) series of syscalls Helge Deller
2026-06-08 19:42 ` [PULL 2/8] linux-user/strace: add fsmount " Helge Deller
2026-06-08 19:42 ` [PULL 3/8] linux-user/alpha: add coredump support Helge Deller
2026-06-08 19:42 ` [PULL 4/8] linux-user/sparc: " Helge Deller
2026-06-08 19:42 ` [PULL 5/8] linux-user/sparc: restore L/I registers from RSA in sparc64_set_context Helge Deller
2026-06-08 19:42 ` Helge Deller [this message]
2026-06-08 19:42 ` [PULL 7/8] linux-user/sparc: flush register windows before core dump Helge Deller
2026-06-08 19:42 ` [PULL 8/8] target/sh4: decode_gusa: recognize add#imm with prior mov Rm, Rn Helge Deller
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=20260608194256.13794-7-deller@kernel.org \
--to=deller@kernel.org \
--cc=deller@gmx.de \
--cc=jcmvbkbc@gmail.com \
--cc=laurent@vivier.eu \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=mattst88@gmail.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.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.