aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure6
-rw-r--r--cpus.c31
2 files changed, 36 insertions, 1 deletions
diff --git a/configure b/configure
index 598e8e1ebb..a3f53456f4 100755
--- a/configure
+++ b/configure
@@ -2057,6 +2057,12 @@ EOF
if compile_prog "" "" ; then
signalfd=yes
+elif test "$kvm" = "yes" -a "$io_thread" != "yes"; then
+ echo
+ echo "ERROR: Host kernel lacks signalfd() support,"
+ echo "but KVM depends on it when the IO thread is disabled."
+ echo
+ exit 1
fi
# check if eventfd is supported
diff --git a/cpus.c b/cpus.c
index 84792f0a0e..38dd506b92 100644
--- a/cpus.c
+++ b/cpus.c
@@ -319,6 +319,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
exit(1);
}
} while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+
+#ifndef CONFIG_IOTHREAD
+ if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
+ qemu_notify_event();
+ }
+#endif
}
#else /* _WIN32 */
@@ -368,11 +374,15 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
sigemptyset(&set);
sigaddset(&set, SIG_IPI);
+ sigaddset(&set, SIGIO);
+ sigaddset(&set, SIGALRM);
pthread_sigmask(SIG_BLOCK, &set, NULL);
pthread_sigmask(SIG_BLOCK, NULL, &set);
sigdelset(&set, SIG_IPI);
sigdelset(&set, SIGBUS);
+ sigdelset(&set, SIGIO);
+ sigdelset(&set, SIGALRM);
r = kvm_set_signal_mask(env, &set);
if (r) {
fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
@@ -381,13 +391,32 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
#endif
}
+#ifndef _WIN32
+static sigset_t block_synchronous_signals(void)
+{
+ sigset_t set;
+
+ sigemptyset(&set);
+ if (kvm_enabled()) {
+ /*
+ * We need to process timer signals synchronously to avoid a race
+ * between exit_request check and KVM vcpu entry.
+ */
+ sigaddset(&set, SIGIO);
+ sigaddset(&set, SIGALRM);
+ }
+
+ return set;
+}
+#endif
+
int qemu_init_main_loop(void)
{
#ifndef _WIN32
sigset_t blocked_signals;
int ret;
- sigemptyset(&blocked_signals);
+ blocked_signals = block_synchronous_signals();
ret = qemu_signalfd_init(blocked_signals);
if (ret) {