From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, "Mahmoud Mandour" <ma.mandourr@gmail.com>,
"Thomas Huth" <thuth@redhat.com>,
"Daniel Henrique Barboza" <danielhb413@gmail.com>,
"Alistair Francis" <alistair.francis@wdc.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Hao Wu" <wuhaotsh@google.com>, "Peter Xu" <peterx@redhat.com>,
"Warner Losh" <imp@bsdimp.com>,
"Pierrick Bouvier" <pierrick.bouvier@linaro.org>,
qemu-arm@nongnu.org, "Harsh Prateek Bora" <harshpb@linux.ibm.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Kyle Evans" <kevans@freebsd.org>,
"Laurent Vivier" <laurent@vivier.eu>,
"Riku Voipio" <riku.voipio@iki.fi>,
"Bin Meng" <bmeng.cn@gmail.com>,
qemu-rust@nongnu.org, "Laurent Vivier" <lvivier@redhat.com>,
"Liu Zhiwei" <zhiwei_liu@linux.alibaba.com>,
"Weiwei Li" <liwei1518@gmail.com>,
qemu-riscv@nongnu.org, "Fabiano Rosas" <farosas@suse.de>,
"Tyrone Ting" <kfting@nuvoton.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Nicholas Piggin" <npiggin@gmail.com>,
"Alexandre Iooss" <erdnaxe@crans.org>,
"Ilya Leoshkevich" <iii@linux.ibm.com>
Subject: [PATCH 13/18] user: Introduce host_interrupt_signal
Date: Mon, 3 Feb 2025 14:40:43 +0000 [thread overview]
Message-ID: <20250203144048.2131117-14-alex.bennee@linaro.org> (raw)
In-Reply-To: <20250203144048.2131117-1-alex.bennee@linaro.org>
From: Ilya Leoshkevich <iii@linux.ibm.com>
Attaching to the gdbstub of a running process requires stopping its
threads. For threads that run on a CPU, cpu_exit() is enough, but the
only way to grab attention of a thread that is stuck in a long-running
syscall is to interrupt it with a signal.
Reserve a host realtime signal for this, just like it's already done
for TARGET_SIGABRT on Linux. This may reduce the number of available
guest realtime signals by one, but this is acceptable, since there are
quite a lot of them, and it's unlikely that there are apps that need
them all.
Set signal_pending for the safe_sycall machinery to prevent invoking
the syscall. This is a lie, since we don't queue a guest signal, but
process_pending_signals() can handle the absence of pending signals.
The syscall returns with QEMU_ERESTARTSYS errno, which arranges for
the automatic restart. This is important, because it helps avoiding
disturbing poorly written guests.
Reviewed-by: Warner Losh <imp@bsdimp.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20250117001542.8290-5-iii@linux.ibm.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
include/user/signal.h | 2 ++
bsd-user/signal.c | 12 ++++++++++++
linux-user/signal.c | 25 ++++++++++++++++++++-----
3 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/include/user/signal.h b/include/user/signal.h
index 19b6b9e5dd..7fa33b05d9 100644
--- a/include/user/signal.h
+++ b/include/user/signal.h
@@ -20,4 +20,6 @@
*/
int target_to_host_signal(int sig);
+extern int host_interrupt_signal;
+
#endif
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 8c51f6ce65..ff2ccbbf60 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -51,6 +51,8 @@ static inline int sas_ss_flags(TaskState *ts, unsigned long sp)
on_sig_stack(ts, sp) ? SS_ONSTACK : 0;
}
+int host_interrupt_signal = SIGRTMAX;
+
/*
* The BSD ABIs use the same signal numbers across all the CPU architectures, so
* (unlike Linux) these functions are just the identity mapping. This might not
@@ -491,6 +493,12 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
uintptr_t pc = 0;
bool sync_sig = false;
+ if (host_sig == host_interrupt_signal) {
+ ts->signal_pending = 1;
+ cpu_exit(thread_cpu);
+ return;
+ }
+
/*
* Non-spoofed SIGSEGV and SIGBUS are synchronous, and need special
* handling wrt signal blocking and unwinding.
@@ -854,6 +862,9 @@ void signal_init(void)
for (i = 1; i <= TARGET_NSIG; i++) {
host_sig = target_to_host_signal(i);
+ if (host_sig == host_interrupt_signal) {
+ continue;
+ }
sigaction(host_sig, NULL, &oact);
if (oact.sa_sigaction == (void *)SIG_IGN) {
sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
@@ -872,6 +883,7 @@ void signal_init(void)
sigaction(host_sig, &act, NULL);
}
}
+ sigaction(host_interrupt_signal, &act, NULL);
}
static void handle_pending_signal(CPUArchState *env, int sig,
diff --git a/linux-user/signal.c b/linux-user/signal.c
index bffbef235c..81a98c6d02 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -517,6 +517,8 @@ static int core_dump_signal(int sig)
}
}
+int host_interrupt_signal;
+
static void signal_table_init(const char *rtsig_map)
{
int hsig, tsig, count;
@@ -580,10 +582,10 @@ static void signal_table_init(const char *rtsig_map)
* Attempts for configure "missing" signals via sigaction will be
* silently ignored.
*
- * Reserve one signal for internal usage (see below).
+ * Reserve two signals for internal usage (see below).
*/
- hsig = SIGRTMIN + 1;
+ hsig = SIGRTMIN + 2;
for (tsig = TARGET_SIGRTMIN;
hsig <= SIGRTMAX && tsig <= TARGET_NSIG;
hsig++, tsig++) {
@@ -604,12 +606,17 @@ static void signal_table_init(const char *rtsig_map)
host_to_target_signal_table[SIGABRT] = 0;
for (hsig = SIGRTMIN; hsig <= SIGRTMAX; hsig++) {
if (!host_to_target_signal_table[hsig]) {
- host_to_target_signal_table[hsig] = TARGET_SIGABRT;
- break;
+ if (host_interrupt_signal) {
+ host_to_target_signal_table[hsig] = TARGET_SIGABRT;
+ break;
+ } else {
+ host_interrupt_signal = hsig;
+ }
}
}
if (hsig > SIGRTMAX) {
- fprintf(stderr, "No rt signals left for SIGABRT mapping\n");
+ fprintf(stderr,
+ "No rt signals left for interrupt and SIGABRT mapping\n");
exit(EXIT_FAILURE);
}
@@ -689,6 +696,8 @@ void signal_init(const char *rtsig_map)
}
sigact_table[tsig - 1]._sa_handler = thand;
}
+
+ sigaction(host_interrupt_signal, &act, NULL);
}
/* Force a synchronously taken signal. The kernel force_sig() function
@@ -1036,6 +1045,12 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
bool sync_sig = false;
void *sigmask;
+ if (host_sig == host_interrupt_signal) {
+ ts->signal_pending = 1;
+ cpu_exit(thread_cpu);
+ return;
+ }
+
/*
* Non-spoofed SIGSEGV and SIGBUS are synchronous, and need special
* handling wrt signal blocking and unwinding. Non-spoofed SIGILL,
--
2.39.5
next prev parent reply other threads:[~2025-02-03 14:41 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-03 14:40 [PATCH 00/18] maintainer updates for feb25 (qtest, gdbstub, plugins) Alex Bennée
2025-02-03 14:40 ` [PATCH 01/18] tests/docker: replicate the check-rust-tools-nightly CI job Alex Bennée
2025-02-03 14:40 ` [PATCH 02/18] tests/qtest: don't attempt to clock_step while waiting for virtio ISR Alex Bennée
2025-02-03 14:40 ` [PATCH 03/18] tests/qtest: don't step clock at start of npcm7xx periodic IRQ test Alex Bennée
2025-02-03 14:40 ` [PATCH 04/18] tests/qtest: simplify qtest_process_inbuf Alex Bennée
2025-02-06 15:50 ` Peter Maydell
2025-02-03 14:40 ` [PATCH 05/18] tests/qtest: rename qtest_send_prefix and roll-up into qtest_send Alex Bennée
2025-02-03 14:40 ` [PATCH 06/18] tests/qtest: tighten up the checks on clock_step Alex Bennée
2025-02-06 15:52 ` Peter Maydell
2025-02-03 14:40 ` [PATCH 07/18] Revert "util/timer: avoid deadlock when shutting down" Alex Bennée
2025-02-06 15:53 ` Peter Maydell
2025-02-03 14:40 ` [PATCH 08/18] tests/qtest/migration: Add --full option Alex Bennée
2025-02-03 14:40 ` [PATCH 09/18] tests/qtest/migration: Pick smoke tests Alex Bennée
2025-02-03 14:40 ` [PATCH 10/18] gdbstub: Allow the %d placeholder in the socket path Alex Bennée
2025-02-03 14:40 ` [PATCH 11/18] gdbstub: Try unlinking the unix socket before binding Alex Bennée
2025-02-03 14:40 ` [PATCH 12/18] user: Introduce user/signal.h Alex Bennée
2025-02-03 14:40 ` Alex Bennée [this message]
2025-02-03 14:40 ` [PATCH 14/18] osdep: Introduce qemu_kill_thread() Alex Bennée
2025-02-03 14:40 ` [PATCH 15/18] gdbstub: Allow late attachment Alex Bennée
2025-02-03 14:40 ` [PATCH 16/18] docs/user: Document the %d placeholder and suspend=n QEMU_GDB features Alex Bennée
2025-02-03 14:40 ` [PATCH 17/18] tests/tcg: Add late gdbstub attach test Alex Bennée
2025-02-03 14:40 ` [PATCH 18/18] plugins: fix -Werror=maybe-uninitialized false-positive Alex Bennée
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=20250203144048.2131117-14-alex.bennee@linaro.org \
--to=alex.bennee@linaro.org \
--cc=alistair.francis@wdc.com \
--cc=bmeng.cn@gmail.com \
--cc=danielhb413@gmail.com \
--cc=erdnaxe@crans.org \
--cc=farosas@suse.de \
--cc=harshpb@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=imp@bsdimp.com \
--cc=kevans@freebsd.org \
--cc=kfting@nuvoton.com \
--cc=laurent@vivier.eu \
--cc=liwei1518@gmail.com \
--cc=lvivier@redhat.com \
--cc=ma.mandourr@gmail.com \
--cc=npiggin@gmail.com \
--cc=palmer@dabbelt.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=pierrick.bouvier@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=qemu-rust@nongnu.org \
--cc=riku.voipio@iki.fi \
--cc=thuth@redhat.com \
--cc=wuhaotsh@google.com \
--cc=zhiwei_liu@linux.alibaba.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).