summaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2026-07-20 11:12:20 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2026-07-20 11:12:20 -0400
commit1a269766d4df82853ebb345f5afe7aba4b31f130 (patch)
treef7862a35041fe6752075a4ab5f6c30a7449e8e56 /linux-user
parentb9e9a55f9950b78ef4c940d0599409c614f36766 (diff)
parentc0e370474b020e4740c85c246e26ec8af1d9d53d (diff)
downloadqemu-1a269766d4df82853ebb345f5afe7aba4b31f130.tar.gz
qemu-1a269766d4df82853ebb345f5afe7aba4b31f130.zip
Merge tag 'linux-user-for-v11.1-pull-request' of https://github.com/hdeller/qemu-hppa into staging
linux-user for v11.1 pull request One patch for the linux-user to fix the sparc target regarding signal handling. # -----BEGIN PGP SIGNATURE----- # # iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCal0ZRgAKCRD3ErUQojoP # X1K5AP0XoVwQ54p3sZgkQ81yHjH4Y4IUL/UKrAzDwLXQn05qbQEA3BpI+4JK03/N # bxXzomlXJbSXlggNTf2pKCwRwGu6/QA= # =odCr # -----END PGP SIGNATURE----- # gpg: Signature made Sun 19 Jul 2026 14:36:54 EDT # gpg: using EDDSA key BCE9123E1AD29F07C049BBDEF712B510A23A0F5F # gpg: Good signature from "Helge Deller <deller@gmx.de>" [unknown] # gpg: aka "Helge Deller <deller@kernel.org>" [unknown] # gpg: aka "Helge Deller <deller@debian.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 4544 8228 2CD9 10DB EF3D 25F8 3E5F 3D04 A7A2 4603 # Subkey fingerprint: BCE9 123E 1AD2 9F07 C049 BBDE F712 B510 A23A 0F5F * tag 'linux-user-for-v11.1-pull-request' of https://github.com/hdeller/qemu-hppa: linux-user/sparc: Take pending signals in sparc64_set_context() Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/sparc/cpu_loop.c10
-rw-r--r--linux-user/sparc/signal.c30
2 files changed, 31 insertions, 9 deletions
diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index 0aacda9448..eaf388c167 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -282,6 +282,16 @@ void cpu_loop (CPUSPARCState *env)
break;
case TT_TRAP + 0x6f:
flush_windows(env);
+ /*
+ * If we have a pending signal, sparc64_set_context() may
+ * return early without changing register state (like a
+ * syscall that returns -QEMU_ERESTARTSYS). We will then
+ * take the pending signal via process_pending_signals()
+ * below and eventually re-execute the trap. We don't need
+ * the function to return a different value for the
+ * "restart" case because this main loop code does the
+ * same thing in both cases.
+ */
sparc64_set_context(env);
break;
#endif
diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
index ba692c3123..4baf983ed8 100644
--- a/linux-user/sparc/signal.c
+++ b/linux-user/sparc/signal.c
@@ -594,6 +594,27 @@ void sparc64_set_context(CPUSPARCState *env)
unsigned int i;
unsigned char fenab;
+ if (env->regwptr[WREG_O1]) {
+ /*
+ * We're going to set the signal mask; we need to call
+ * block_signals() first, 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.
+ *
+ * If block_signals() returns true, this means we have a
+ * pending signal that we could take now; we return early so
+ * the cpu_loop takes that signal. Eventually the guest will
+ * re-execute the trap insn and we'll come back here to have
+ * another go at set_context. This is the same way that
+ * do_sigprocmask() handles setting the signal mask.
+ */
+ if (block_signals()) {
+ return;
+ }
+ }
ucp_addr = env->regwptr[WREG_O0];
if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) {
goto do_sigsegv;
@@ -619,15 +640,6 @@ 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;