diff options
| author | Stefan Hajnoczi <stefanha@redhat.com> | 2026-07-20 11:12:20 -0400 |
|---|---|---|
| committer | Stefan Hajnoczi <stefanha@redhat.com> | 2026-07-20 11:12:20 -0400 |
| commit | 1a269766d4df82853ebb345f5afe7aba4b31f130 (patch) | |
| tree | f7862a35041fe6752075a4ab5f6c30a7449e8e56 /linux-user | |
| parent | b9e9a55f9950b78ef4c940d0599409c614f36766 (diff) | |
| parent | c0e370474b020e4740c85c246e26ec8af1d9d53d (diff) | |
| download | qemu-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.c | 10 | ||||
| -rw-r--r-- | linux-user/sparc/signal.c | 30 |
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; |
