From nobody Sun Apr 28 20:08:56 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537957309841236.02725469372922; Wed, 26 Sep 2018 03:21:49 -0700 (PDT) Received: from localhost ([::1]:57525 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56wy-0003Wv-1Z for importer@patchew.org; Wed, 26 Sep 2018 06:21:44 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50505) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56fS-0003zR-RQ for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g56fR-0004QF-60 for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:38 -0400 Received: from smtp.nue.novell.com ([195.135.221.5]:56343) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g56fQ-0004Os-Rj for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:37 -0400 Received: from localhost.localdomain ([45.122.156.254]) by smtp.nue.novell.com with ESMTP (NOT encrypted); Wed, 26 Sep 2018 12:03:28 +0200 From: Fei Li To: qemu-devel@nongnu.org Date: Wed, 26 Sep 2018 18:02:40 +0800 Message-Id: <20180926100246.14010-2-fli@suse.com> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20180926100246.14010-1-fli@suse.com> References: <20180926100246.14010-1-fli@suse.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.135.221.5 Subject: [Qemu-devel] [PATCH RFC v4 1/7] Fix segmentation fault when qemu_signal_init fails X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: quintela@redhat.com, dgilbert@redhat.com, peterx@redhat.com, armbru@redhat.com, famz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Currently, when qemu_signal_init() fails it only returns a non-zero value but without propagating any Error. But its callers need a non-null err when runs error_report_err(err), or else 0->msg occurs. To avoid such segmentation fault, add a new Error parameter to make the call trace to propagate the err to the final caller. Signed-off-by: Fei Li Reviewed-by: Fam Zheng --- include/qemu/osdep.h | 2 +- util/compatfd.c | 9 ++++++--- util/main-loop.c | 9 ++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index a91068df0e..09ed85fcb8 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -421,7 +421,7 @@ struct qemu_signalfd_siginfo { additional fields in the future) */ }; =20 -int qemu_signalfd(const sigset_t *mask); +int qemu_signalfd(const sigset_t *mask, Error **errp); void sigaction_invoke(struct sigaction *action, struct qemu_signalfd_siginfo *info); #endif diff --git a/util/compatfd.c b/util/compatfd.c index 980bd33e52..d3ed890405 100644 --- a/util/compatfd.c +++ b/util/compatfd.c @@ -16,6 +16,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/thread.h" +#include "qapi/error.h" =20 #include =20 @@ -65,7 +66,7 @@ static void *sigwait_compat(void *opaque) } } =20 -static int qemu_signalfd_compat(const sigset_t *mask) +static int qemu_signalfd_compat(const sigset_t *mask, Error **errp) { struct sigfd_compat_info *info; QemuThread thread; @@ -73,11 +74,13 @@ static int qemu_signalfd_compat(const sigset_t *mask) =20 info =3D malloc(sizeof(*info)); if (info =3D=3D NULL) { + error_setg(errp, "Failed to allocate signalfd memory"); errno =3D ENOMEM; return -1; } =20 if (pipe(fds) =3D=3D -1) { + error_setg(errp, "Failed to create signalfd pipe"); free(info); return -1; } @@ -94,7 +97,7 @@ static int qemu_signalfd_compat(const sigset_t *mask) return fds[0]; } =20 -int qemu_signalfd(const sigset_t *mask) +int qemu_signalfd(const sigset_t *mask, Error **errp) { #if defined(CONFIG_SIGNALFD) int ret; @@ -106,5 +109,5 @@ int qemu_signalfd(const sigset_t *mask) } #endif =20 - return qemu_signalfd_compat(mask); + return qemu_signalfd_compat(mask, errp); } diff --git a/util/main-loop.c b/util/main-loop.c index affe0403c5..9671b6d226 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -71,7 +71,7 @@ static void sigfd_handler(void *opaque) } } =20 -static int qemu_signal_init(void) +static int qemu_signal_init(Error **errp) { int sigfd; sigset_t set; @@ -94,9 +94,8 @@ static int qemu_signal_init(void) pthread_sigmask(SIG_BLOCK, &set, NULL); =20 sigdelset(&set, SIG_IPI); - sigfd =3D qemu_signalfd(&set); + sigfd =3D qemu_signalfd(&set, errp); if (sigfd =3D=3D -1) { - fprintf(stderr, "failed to create signalfd\n"); return -errno; } =20 @@ -109,7 +108,7 @@ static int qemu_signal_init(void) =20 #else /* _WIN32 */ =20 -static int qemu_signal_init(void) +static int qemu_signal_init(Error **errp) { return 0; } @@ -148,7 +147,7 @@ int qemu_init_main_loop(Error **errp) =20 init_clocks(qemu_timer_notify_cb); =20 - ret =3D qemu_signal_init(); + ret =3D qemu_signal_init(errp); if (ret) { return ret; } --=20 2.13.7 From nobody Sun Apr 28 20:08:56 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537957220000730.7420424926896; Wed, 26 Sep 2018 03:20:20 -0700 (PDT) Received: from localhost ([::1]:57507 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56va-0002gx-Rj for importer@patchew.org; Wed, 26 Sep 2018 06:20:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50573) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56fb-0004Hb-BX for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g56fY-0004Wk-6i for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:47 -0400 Received: from smtp.nue.novell.com ([195.135.221.5]:46547) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g56fX-0004Vn-TD for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:44 -0400 Received: from localhost.localdomain ([45.122.156.254]) by smtp.nue.novell.com with ESMTP (NOT encrypted); Wed, 26 Sep 2018 12:03:36 +0200 From: Fei Li To: qemu-devel@nongnu.org Date: Wed, 26 Sep 2018 18:02:41 +0800 Message-Id: <20180926100246.14010-3-fli@suse.com> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20180926100246.14010-1-fli@suse.com> References: <20180926100246.14010-1-fli@suse.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.135.221.5 Subject: [Qemu-devel] [PATCH RFC v4 2/7] ui/vnc.c: polish vnc_init_func X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: quintela@redhat.com, dgilbert@redhat.com, peterx@redhat.com, armbru@redhat.com, famz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add a new Error parameter for vnc_display_init() to handle errors in its caller: vnc_init_func(), just like vnc_display_open() does. And let the call trace propagate the Error. Besides, make vnc_start_worker_thread() return a bool to indicate whether it succeeds instead of returning nothing. Signed-off-by: Fei Li Reviewed-by: Fam Zheng --- include/ui/console.h | 2 +- ui/vnc-jobs.c | 9 ++++++--- ui/vnc-jobs.h | 2 +- ui/vnc.c | 12 +++++++++--- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index fb969caf70..c17803c530 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -453,7 +453,7 @@ void qemu_display_early_init(DisplayOptions *opts); void qemu_display_init(DisplayState *ds, DisplayOptions *opts); =20 /* vnc.c */ -void vnc_display_init(const char *id); +void vnc_display_init(const char *id, Error **errp); void vnc_display_open(const char *id, Error **errp); void vnc_display_add_client(const char *id, int csock, bool skipauth); int vnc_display_password(const char *id, const char *password); diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index 929391f85d..8807d7217c 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -331,15 +331,18 @@ static bool vnc_worker_thread_running(void) return queue; /* Check global queue */ } =20 -void vnc_start_worker_thread(void) +bool vnc_start_worker_thread(Error **errp) { VncJobQueue *q; =20 - if (vnc_worker_thread_running()) - return ; + if (vnc_worker_thread_running()) { + goto out; + } =20 q =3D vnc_queue_init(); qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, q, QEMU_THREAD_DETACHED); queue =3D q; /* Set global queue */ +out: + return true; } diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h index 59f66bcc35..14640593db 100644 --- a/ui/vnc-jobs.h +++ b/ui/vnc-jobs.h @@ -37,7 +37,7 @@ void vnc_job_push(VncJob *job); void vnc_jobs_join(VncState *vs); =20 void vnc_jobs_consume_buffer(VncState *vs); -void vnc_start_worker_thread(void); +bool vnc_start_worker_thread(Error **errp); =20 /* Locks */ static inline int vnc_trylock_display(VncDisplay *vd) diff --git a/ui/vnc.c b/ui/vnc.c index 916a16d312..80662a84b4 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3205,7 +3205,7 @@ static const DisplayChangeListenerOps dcl_ops =3D { .dpy_cursor_define =3D vnc_dpy_cursor_define, }; =20 -void vnc_display_init(const char *id) +void vnc_display_init(const char *id, Error **errp) { VncDisplay *vd; =20 @@ -3235,7 +3235,9 @@ void vnc_display_init(const char *id) vd->connections_limit =3D 32; =20 qemu_mutex_init(&vd->mutex); - vnc_start_worker_thread(); + if (!vnc_start_worker_thread(errp)) { + return; + } =20 vd->dcl.ops =3D &dcl_ops; register_displaychangelistener(&vd->dcl); @@ -4078,7 +4080,11 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Erro= r **errp) char *id =3D (char *)qemu_opts_id(opts); =20 assert(id); - vnc_display_init(id); + vnc_display_init(id, &local_err); + if (local_err) { + error_reportf_err(local_err, "Failed to init VNC server: "); + exit(1); + } vnc_display_open(id, &local_err); if (local_err !=3D NULL) { error_reportf_err(local_err, "Failed to start VNC server: "); --=20 2.13.7 From nobody Sun Apr 28 20:08:56 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537956785834810.2275186217274; Wed, 26 Sep 2018 03:13:05 -0700 (PDT) Received: from localhost ([::1]:57465 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56oZ-00035Y-Vs for importer@patchew.org; Wed, 26 Sep 2018 06:13:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50610) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56fg-0004Mz-Tx for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g56ff-0004cW-8b for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:52 -0400 Received: from smtp.nue.novell.com ([195.135.221.5]:35367) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g56fe-0004ba-Rj for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:51 -0400 Received: from localhost.localdomain ([45.122.156.254]) by smtp.nue.novell.com with ESMTP (NOT encrypted); Wed, 26 Sep 2018 12:03:43 +0200 From: Fei Li To: qemu-devel@nongnu.org Date: Wed, 26 Sep 2018 18:02:42 +0800 Message-Id: <20180926100246.14010-4-fli@suse.com> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20180926100246.14010-1-fli@suse.com> References: <20180926100246.14010-1-fli@suse.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.135.221.5 Subject: [Qemu-devel] [PATCH RFC v4 3/7] qemu_init_vcpu: add a new Error parameter to propagate X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: quintela@redhat.com, dgilbert@redhat.com, peterx@redhat.com, armbru@redhat.com, famz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The caller of qemu_init_vcpu() already passed the **errp to handle errors. In view of this, add a new Error parameter to the following call trace to propagate the error and let the further caller check it. Besides, make qemu_init_vcpu() return a Boolean value to let its callers know whether it succeeds. Signed-off-by: Fei Li Reviewed-by: Fam Zheng --- accel/tcg/user-exec-stub.c | 2 +- cpus.c | 34 +++++++++++++++++++++------------- include/qom/cpu.h | 2 +- target/alpha/cpu.c | 4 +++- target/arm/cpu.c | 4 +++- target/cris/cpu.c | 4 +++- target/hppa/cpu.c | 4 +++- target/i386/cpu.c | 4 +++- target/lm32/cpu.c | 4 +++- target/m68k/cpu.c | 4 +++- target/microblaze/cpu.c | 4 +++- target/mips/cpu.c | 4 +++- target/moxie/cpu.c | 4 +++- target/nios2/cpu.c | 4 +++- target/openrisc/cpu.c | 4 +++- target/ppc/translate_init.inc.c | 4 +++- target/riscv/cpu.c | 4 +++- target/s390x/cpu.c | 4 +++- target/sh4/cpu.c | 4 +++- target/sparc/cpu.c | 4 +++- target/tilegx/cpu.c | 4 +++- target/tricore/cpu.c | 4 +++- target/unicore32/cpu.c | 4 +++- target/xtensa/cpu.c | 4 +++- 24 files changed, 86 insertions(+), 36 deletions(-) diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c index a32b4496af..38f6b928d4 100644 --- a/accel/tcg/user-exec-stub.c +++ b/accel/tcg/user-exec-stub.c @@ -10,7 +10,7 @@ void cpu_resume(CPUState *cpu) { } =20 -void qemu_init_vcpu(CPUState *cpu) +bool qemu_init_vcpu(CPUState *cpu, Error **errp) { } =20 diff --git a/cpus.c b/cpus.c index 719788320f..cb478039b6 100644 --- a/cpus.c +++ b/cpus.c @@ -1898,7 +1898,7 @@ void cpu_remove_sync(CPUState *cpu) /* For temporary buffers for forming a name */ #define VCPU_THREAD_NAME_SIZE 16 =20 -static void qemu_tcg_init_vcpu(CPUState *cpu) +static void qemu_tcg_init_vcpu(CPUState *cpu, Error **errp) { char thread_name[VCPU_THREAD_NAME_SIZE]; static QemuCond *single_tcg_halt_cond; @@ -1954,7 +1954,7 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) } } =20 -static void qemu_hax_start_vcpu(CPUState *cpu) +static void qemu_hax_start_vcpu(CPUState *cpu, Error **errp) { char thread_name[VCPU_THREAD_NAME_SIZE]; =20 @@ -1971,7 +1971,7 @@ static void qemu_hax_start_vcpu(CPUState *cpu) #endif } =20 -static void qemu_kvm_start_vcpu(CPUState *cpu) +static void qemu_kvm_start_vcpu(CPUState *cpu, Error **errp) { char thread_name[VCPU_THREAD_NAME_SIZE]; =20 @@ -1984,7 +1984,7 @@ static void qemu_kvm_start_vcpu(CPUState *cpu) cpu, QEMU_THREAD_JOINABLE); } =20 -static void qemu_hvf_start_vcpu(CPUState *cpu) +static void qemu_hvf_start_vcpu(CPUState *cpu, Error **errp) { char thread_name[VCPU_THREAD_NAME_SIZE]; =20 @@ -2002,7 +2002,7 @@ static void qemu_hvf_start_vcpu(CPUState *cpu) cpu, QEMU_THREAD_JOINABLE); } =20 -static void qemu_whpx_start_vcpu(CPUState *cpu) +static void qemu_whpx_start_vcpu(CPUState *cpu, Error **errp) { char thread_name[VCPU_THREAD_NAME_SIZE]; =20 @@ -2018,7 +2018,7 @@ static void qemu_whpx_start_vcpu(CPUState *cpu) #endif } =20 -static void qemu_dummy_start_vcpu(CPUState *cpu) +static void qemu_dummy_start_vcpu(CPUState *cpu, Error **errp) { char thread_name[VCPU_THREAD_NAME_SIZE]; =20 @@ -2031,11 +2031,12 @@ static void qemu_dummy_start_vcpu(CPUState *cpu) QEMU_THREAD_JOINABLE); } =20 -void qemu_init_vcpu(CPUState *cpu) +bool qemu_init_vcpu(CPUState *cpu, Error **errp) { cpu->nr_cores =3D smp_cores; cpu->nr_threads =3D smp_threads; cpu->stopped =3D true; + Error *local_err =3D NULL; =20 if (!cpu->as) { /* If the target cpu hasn't set up any address spaces itself, @@ -2046,22 +2047,29 @@ void qemu_init_vcpu(CPUState *cpu) } =20 if (kvm_enabled()) { - qemu_kvm_start_vcpu(cpu); + qemu_kvm_start_vcpu(cpu, &local_err); } else if (hax_enabled()) { - qemu_hax_start_vcpu(cpu); + qemu_hax_start_vcpu(cpu, &local_err); } else if (hvf_enabled()) { - qemu_hvf_start_vcpu(cpu); + qemu_hvf_start_vcpu(cpu, &local_err); } else if (tcg_enabled()) { - qemu_tcg_init_vcpu(cpu); + qemu_tcg_init_vcpu(cpu, &local_err); } else if (whpx_enabled()) { - qemu_whpx_start_vcpu(cpu); + qemu_whpx_start_vcpu(cpu, &local_err); } else { - qemu_dummy_start_vcpu(cpu); + qemu_dummy_start_vcpu(cpu, &local_err); + } + + if (local_err) { + error_propagate(errp, local_err); + return false; } =20 while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } + + return true; } =20 void cpu_stop_current(void) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index dc130cd307..4d85dda175 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -1012,7 +1012,7 @@ void end_exclusive(void); * * Initializes a vCPU. */ -void qemu_init_vcpu(CPUState *cpu); +bool qemu_init_vcpu(CPUState *cpu, Error **errp); =20 #define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ #define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index b08078e7fc..d531bd4f7e 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -66,7 +66,9 @@ static void alpha_cpu_realizefn(DeviceState *dev, Error *= *errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 acc->parent_realize(dev, errp); } diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 258ba6dcaa..d2ad17fbca 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1028,7 +1028,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error= **errp) } #endif =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } cpu_reset(cs); =20 acc->parent_realize(dev, errp); diff --git a/target/cris/cpu.c b/target/cris/cpu.c index a23aba2688..ec92d69781 100644 --- a/target/cris/cpu.c +++ b/target/cris/cpu.c @@ -140,7 +140,9 @@ static void cris_cpu_realizefn(DeviceState *dev, Error = **errp) } =20 cpu_reset(cs); - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 ccc->parent_realize(dev, errp); } diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 00bf444620..08f600ced9 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -98,7 +98,9 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **= errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } acc->parent_realize(dev, errp); =20 #ifndef CONFIG_USER_ONLY diff --git a/target/i386/cpu.c b/target/i386/cpu.c index f24295e6e4..fad65766a4 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5112,7 +5112,9 @@ static void x86_cpu_realizefn(DeviceState *dev, Error= **errp) } #endif =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 /* * Most Intel and certain AMD CPUs support hyperthreading. Even though= QEMU diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c index b7499cb627..d50b1e4a43 100644 --- a/target/lm32/cpu.c +++ b/target/lm32/cpu.c @@ -139,7 +139,9 @@ static void lm32_cpu_realizefn(DeviceState *dev, Error = **errp) =20 cpu_reset(cs); =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 lcc->parent_realize(dev, errp); } diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index 582e3a73b3..4ab53f2d58 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -231,7 +231,9 @@ static void m68k_cpu_realizefn(DeviceState *dev, Error = **errp) m68k_cpu_init_gdb(cpu); =20 cpu_reset(cs); - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 mcc->parent_realize(dev, errp); } diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c index 9b546a2c18..3906c864a3 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c @@ -161,7 +161,9 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **= errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 env->pvr.regs[0] =3D PVR0_USE_EXC_MASK \ | PVR0_USE_ICACHE_MASK \ diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 497706b669..62be84af76 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -136,7 +136,9 @@ static void mips_cpu_realizefn(DeviceState *dev, Error = **errp) cpu_mips_realize_env(&cpu->env); =20 cpu_reset(cs); - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 mcc->parent_realize(dev, errp); } diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c index 8d67eb6727..8581a6d922 100644 --- a/target/moxie/cpu.c +++ b/target/moxie/cpu.c @@ -66,7 +66,9 @@ static void moxie_cpu_realizefn(DeviceState *dev, Error *= *errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } cpu_reset(cs); =20 mcc->parent_realize(dev, errp); diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c index fbfaa2ce26..5c7b4b486e 100644 --- a/target/nios2/cpu.c +++ b/target/nios2/cpu.c @@ -94,7 +94,9 @@ static void nios2_cpu_realizefn(DeviceState *dev, Error *= *errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } cpu_reset(cs); =20 ncc->parent_realize(dev, errp); diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index fb7cb5c507..a6dcdb9df9 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -83,7 +83,9 @@ static void openrisc_cpu_realizefn(DeviceState *dev, Erro= r **errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } cpu_reset(cs); =20 occ->parent_realize(dev, errp); diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.in= c.c index 263e63cb03..a6dd2318a6 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9694,7 +9694,9 @@ static void ppc_cpu_realize(DeviceState *dev, Error *= *errp) 32, "power-vsx.xml", 0); } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + goto unrealize; + } =20 pcc->parent_realize(dev, errp); =20 diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index d630e8fd6c..ef56215e92 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -303,7 +303,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error *= *errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } cpu_reset(cs); =20 mcc->parent_realize(dev, errp); diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 8ed4823d6e..3a665c4df8 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -217,7 +217,9 @@ static void s390_cpu_realizefn(DeviceState *dev, Error = **errp) qemu_register_reset(s390_cpu_machine_reset_cb, cpu); #endif s390_cpu_gdb_init(cs); - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 /* * KVM requires the initial CPU reset ioctl to be executed on the targ= et diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index b9f393b7c7..d32ef2e1cb 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -196,7 +196,9 @@ static void superh_cpu_realizefn(DeviceState *dev, Erro= r **errp) } =20 cpu_reset(cs); - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 scc->parent_realize(dev, errp); } diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index 0f090ece54..9c22f6a7df 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -773,7 +773,9 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error= **errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 scc->parent_realize(dev, errp); } diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c index bfe9be59b5..234148fabd 100644 --- a/target/tilegx/cpu.c +++ b/target/tilegx/cpu.c @@ -92,7 +92,9 @@ static void tilegx_cpu_realizefn(DeviceState *dev, Error = **errp) } =20 cpu_reset(cs); - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 tcc->parent_realize(dev, errp); } diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c index 2edaef1aef..5482d6ea3f 100644 --- a/target/tricore/cpu.c +++ b/target/tricore/cpu.c @@ -96,7 +96,9 @@ static void tricore_cpu_realizefn(DeviceState *dev, Error= **errp) set_feature(env, TRICORE_FEATURE_13); } cpu_reset(cs); - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 tcc->parent_realize(dev, errp); } diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c index 68f978d80b..1f6a33b6f3 100644 --- a/target/unicore32/cpu.c +++ b/target/unicore32/cpu.c @@ -96,7 +96,9 @@ static void uc32_cpu_realizefn(DeviceState *dev, Error **= errp) return; } =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 ucc->parent_realize(dev, errp); } diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index 590813d4f7..177694454f 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -131,7 +131,9 @@ static void xtensa_cpu_realizefn(DeviceState *dev, Erro= r **errp) =20 cs->gdb_num_regs =3D xcc->config->gdb_regmap.num_regs; =20 - qemu_init_vcpu(cs); + if (!qemu_init_vcpu(cs, errp)) { + return; + } =20 xcc->parent_realize(dev, errp); } --=20 2.13.7 From nobody Sun Apr 28 20:08:56 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537956555754226.10521639850265; Wed, 26 Sep 2018 03:09:15 -0700 (PDT) Received: from localhost ([::1]:57439 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56ks-0008TM-Fg for importer@patchew.org; Wed, 26 Sep 2018 06:09:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50654) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56fo-0004TG-EN for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g56fn-0004jx-N6 for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:00 -0400 Received: from smtp.nue.novell.com ([195.135.221.5]:36798) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g56fn-0004i7-DD for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:03:59 -0400 Received: from localhost.localdomain ([45.122.156.254]) by smtp.nue.novell.com with ESMTP (NOT encrypted); Wed, 26 Sep 2018 12:03:50 +0200 From: Fei Li To: qemu-devel@nongnu.org Date: Wed, 26 Sep 2018 18:02:43 +0800 Message-Id: <20180926100246.14010-5-fli@suse.com> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20180926100246.14010-1-fli@suse.com> References: <20180926100246.14010-1-fli@suse.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.135.221.5 Subject: [Qemu-devel] [PATCH RFC v4 4/7] qemu_thread_join: fix segmentation fault X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: quintela@redhat.com, dgilbert@redhat.com, peterx@redhat.com, armbru@redhat.com, famz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" To avoid the segmentation fault in qemu_thread_join(), just directly return when the QemuThread *thread failed to be created in either qemu-thread-posix.c or qemu-thread-win32.c. Signed-off-by: Fei Li Reviewed-by: Fam Zheng --- util/qemu-thread-posix.c | 3 +++ util/qemu-thread-win32.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index dfa66ff2fb..289af4fab5 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -562,6 +562,9 @@ void *qemu_thread_join(QemuThread *thread) int err; void *ret; =20 + if (!thread->thread) { + return NULL; + } err =3D pthread_join(thread->thread, &ret); if (err) { error_exit(err, __func__); diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index 4a363ca675..1a27e1cf6f 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -366,7 +366,7 @@ void *qemu_thread_join(QemuThread *thread) HANDLE handle; =20 data =3D thread->data; - if (data->mode =3D=3D QEMU_THREAD_DETACHED) { + if (data =3D=3D NULL || data->mode =3D=3D QEMU_THREAD_DETACHED) { return NULL; } =20 --=20 2.13.7 From nobody Sun Apr 28 20:08:56 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 153795669305960.75963125962278; Wed, 26 Sep 2018 03:11:33 -0700 (PDT) Received: from localhost ([::1]:57457 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56n5-0001vU-TY for importer@patchew.org; Wed, 26 Sep 2018 06:11:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50700) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56fy-0004Xk-56 for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g56fu-0004yx-QP for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:10 -0400 Received: from smtp.nue.novell.com ([195.135.221.5]:55010) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g56fu-0004yD-EY for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:06 -0400 Received: from localhost.localdomain ([45.122.156.254]) by smtp.nue.novell.com with ESMTP (NOT encrypted); Wed, 26 Sep 2018 12:03:58 +0200 From: Fei Li To: qemu-devel@nongnu.org Date: Wed, 26 Sep 2018 18:02:44 +0800 Message-Id: <20180926100246.14010-6-fli@suse.com> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20180926100246.14010-1-fli@suse.com> References: <20180926100246.14010-1-fli@suse.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.135.221.5 Subject: [Qemu-devel] [PATCH RFC v4 5/7] migration: fix the multifd code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: quintela@redhat.com, dgilbert@redhat.com, peterx@redhat.com, armbru@redhat.com, famz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When multifd is used during migration, if there is an error before the destination receives all new channels, the destination does not exit but keeps waiting in our current code. However, a segmentaion fault will occur in the source when multifd_save_cleanup() is called again as the multifd_send_state has been freed earlier in the first error handling. This can happen when migrate_fd_connect() fails and multifd_fd_cleanup() is called, and then multifd_new_send_channel_ async() fails and multifd_save_cleanup() is called again. If the QIOChannel *c of multifd_recv_state->params[i] (p->c) is not initialized, there is no need to close the channel. Or else a segmentation fault will occur in multifd_recv_terminate_threads() when multifd_recv_initial_packet() fails. Signed-off-by: Fei Li --- migration/ram.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index f6fd8e5e09..1db080a696 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -904,6 +904,11 @@ static void multifd_send_terminate_threads(Error *err) } } =20 + /* in case multifd_send_state has been freed earlier */ + if (!multifd_send_state) { + return; + } + for (i =3D 0; i < migrate_multifd_channels(); i++) { MultiFDSendParams *p =3D &multifd_send_state->params[i]; =20 @@ -919,7 +924,7 @@ int multifd_save_cleanup(Error **errp) int i; int ret =3D 0; =20 - if (!migrate_use_multifd()) { + if (!migrate_use_multifd() || !multifd_send_state) { return 0; } multifd_send_terminate_threads(NULL); @@ -1128,7 +1133,7 @@ struct { uint64_t packet_num; } *multifd_recv_state; =20 -static void multifd_recv_terminate_threads(Error *err) +static void multifd_recv_terminate_threads(Error *err, bool channel) { int i; =20 @@ -1142,6 +1147,11 @@ static void multifd_recv_terminate_threads(Error *er= r) } } =20 + /* in case p->c is not initialized */ + if (!channel) { + return; + } + for (i =3D 0; i < migrate_multifd_channels(); i++) { MultiFDRecvParams *p =3D &multifd_recv_state->params[i]; =20 @@ -1163,7 +1173,7 @@ int multifd_load_cleanup(Error **errp) if (!migrate_use_multifd()) { return 0; } - multifd_recv_terminate_threads(NULL); + multifd_recv_terminate_threads(NULL, true); for (i =3D 0; i < migrate_multifd_channels(); i++) { MultiFDRecvParams *p =3D &multifd_recv_state->params[i]; =20 @@ -1266,7 +1276,7 @@ static void *multifd_recv_thread(void *opaque) } =20 if (local_err) { - multifd_recv_terminate_threads(local_err); + multifd_recv_terminate_threads(local_err, true); } qemu_mutex_lock(&p->mutex); p->running =3D false; @@ -1328,7 +1338,7 @@ bool multifd_recv_new_channel(QIOChannel *ioc) =20 id =3D multifd_recv_initial_packet(ioc, &local_err); if (id < 0) { - multifd_recv_terminate_threads(local_err); + multifd_recv_terminate_threads(local_err, false); return false; } =20 @@ -1336,7 +1346,7 @@ bool multifd_recv_new_channel(QIOChannel *ioc) if (p->c !=3D NULL) { error_setg(&local_err, "multifd: received id '%d' already setup'", id); - multifd_recv_terminate_threads(local_err); + multifd_recv_terminate_threads(local_err, true); return false; } p->c =3D ioc; --=20 2.13.7 From nobody Sun Apr 28 20:08:56 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537956912356357.6011139921634; Wed, 26 Sep 2018 03:15:12 -0700 (PDT) Received: from localhost ([::1]:57479 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56qd-0004ko-71 for importer@patchew.org; Wed, 26 Sep 2018 06:15:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50732) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56g4-0004cc-Ha for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g56g2-00055M-Kh for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:16 -0400 Received: from smtp.nue.novell.com ([195.135.221.5]:52502) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g56g2-000547-BG for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:14 -0400 Received: from localhost.localdomain ([45.122.156.254]) by smtp.nue.novell.com with ESMTP (NOT encrypted); Wed, 26 Sep 2018 12:04:05 +0200 From: Fei Li To: qemu-devel@nongnu.org Date: Wed, 26 Sep 2018 18:02:45 +0800 Message-Id: <20180926100246.14010-7-fli@suse.com> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20180926100246.14010-1-fli@suse.com> References: <20180926100246.14010-1-fli@suse.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.135.221.5 Subject: [Qemu-devel] [PATCH RFC v4 6/7] migration: fix error handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: quintela@redhat.com, dgilbert@redhat.com, peterx@redhat.com, armbru@redhat.com, famz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add error handling for qemu_ram_foreach_migratable_block() when it fails. Always call migrate_set_error() to set the error state without relying on whether multifd_save_cleanup() succeeds. As the passed &local_err is never used in multifd_save_cleanup(), remove it. Signed-off-by: Fei Li --- migration/migration.c | 5 +---- migration/postcopy-ram.c | 3 +++ migration/ram.c | 7 +++---- migration/ram.h | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/migration/migration.c b/migration/migration.c index 05d0a7296a..0dbaf3ff80 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1329,7 +1329,6 @@ static void migrate_fd_cleanup(void *opaque) qemu_savevm_state_cleanup(); =20 if (s->to_dst_file) { - Error *local_err =3D NULL; QEMUFile *tmp; =20 trace_migrate_fd_cleanup(); @@ -1340,9 +1339,7 @@ static void migrate_fd_cleanup(void *opaque) } qemu_mutex_lock_iothread(); =20 - if (multifd_save_cleanup(&local_err) !=3D 0) { - error_report_err(local_err); - } + multifd_save_cleanup(); qemu_mutex_lock(&s->qemu_file_lock); tmp =3D s->to_dst_file; s->to_dst_file =3D NULL; diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index 853d8b32ca..f96e0ae1f8 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -1116,6 +1116,9 @@ int postcopy_ram_enable_notify(MigrationIncomingState= *mis) =20 /* Mark so that we get notified of accesses to unwritten areas */ if (qemu_ram_foreach_migratable_block(ram_block_enable_notify, mis)) { + error_report("ram_block_enable_notify failed"); + close(mis->userfault_event_fd); + close(mis->userfault_fd); return -1; } =20 diff --git a/migration/ram.c b/migration/ram.c index 1db080a696..433f35664a 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -919,7 +919,7 @@ static void multifd_send_terminate_threads(Error *err) } } =20 -int multifd_save_cleanup(Error **errp) +int multifd_save_cleanup(void) { int i; int ret =3D 0; @@ -1073,9 +1073,8 @@ static void multifd_new_send_channel_async(QIOTask *t= ask, gpointer opaque) Error *local_err =3D NULL; =20 if (qio_task_propagate_error(task, &local_err)) { - if (multifd_save_cleanup(&local_err) !=3D 0) { - migrate_set_error(migrate_get_current(), local_err); - } + multifd_save_cleanup(); + migrate_set_error(migrate_get_current(), local_err); } else { p->c =3D QIO_CHANNEL(sioc); qio_channel_set_delay(p->c, false); diff --git a/migration/ram.h b/migration/ram.h index 457bf54b8c..1354f3a549 100644 --- a/migration/ram.h +++ b/migration/ram.h @@ -42,7 +42,7 @@ uint64_t ram_bytes_remaining(void); uint64_t ram_bytes_total(void); =20 int multifd_save_setup(void); -int multifd_save_cleanup(Error **errp); +int multifd_save_cleanup(void); int multifd_load_setup(void); int multifd_load_cleanup(Error **errp); bool multifd_recv_all_channels_created(void); --=20 2.13.7 From nobody Sun Apr 28 20:08:56 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537957380970926.9603195044402; Wed, 26 Sep 2018 03:23:00 -0700 (PDT) Received: from localhost ([::1]:57529 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56yB-0004KZ-5L for importer@patchew.org; Wed, 26 Sep 2018 06:22:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50818) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g56gN-0004sv-IT for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g56gB-0005Fo-P7 for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:35 -0400 Received: from smtp.nue.novell.com ([195.135.221.5]:35542) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g56g9-0005DL-B4 for qemu-devel@nongnu.org; Wed, 26 Sep 2018 06:04:21 -0400 Received: from localhost.localdomain ([45.122.156.254]) by smtp.nue.novell.com with ESMTP (NOT encrypted); Wed, 26 Sep 2018 12:04:13 +0200 From: Fei Li To: qemu-devel@nongnu.org Date: Wed, 26 Sep 2018 18:02:46 +0800 Message-Id: <20180926100246.14010-8-fli@suse.com> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20180926100246.14010-1-fli@suse.com> References: <20180926100246.14010-1-fli@suse.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.135.221.5 Subject: [Qemu-devel] [PATCH RFC v4 7/7] qemu_thread_create: propagate the error to callers to handle X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: quintela@redhat.com, dgilbert@redhat.com, peterx@redhat.com, armbru@redhat.com, famz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Make qemu_thread_create() return a Boolean to indicate if it succeeds rather than failing with an error. And add an Error parameter to hold the error message and let the callers handle it. Signed-off-by: Fei Li --- cpus.c | 45 +++++++++++++++++++++++++++-------------- dump.c | 6 ++++-- hw/misc/edu.c | 6 ++++-- hw/ppc/spapr_hcall.c | 10 +++++++-- hw/rdma/rdma_backend.c | 4 +++- hw/usb/ccid-card-emulated.c | 13 ++++++++---- include/qemu/thread.h | 4 ++-- io/task.c | 3 ++- iothread.c | 18 ++++++++++++----- migration/migration.c | 49 +++++++++++++++++++++++++++++++----------= ---- migration/postcopy-ram.c | 14 +++++++++++-- migration/ram.c | 39 +++++++++++++++++++++++++++--------- migration/savevm.c | 11 +++++++--- tests/atomic_add-bench.c | 3 ++- tests/iothread.c | 2 +- tests/qht-bench.c | 3 ++- tests/rcutorture.c | 3 ++- tests/test-aio.c | 2 +- tests/test-rcu-list.c | 3 ++- ui/vnc-jobs.c | 8 ++++++-- util/compatfd.c | 9 +++++++-- util/oslib-posix.c | 17 ++++++++++++---- util/qemu-thread-posix.c | 24 ++++++++++++++-------- util/qemu-thread-win32.c | 16 +++++++++++---- util/rcu.c | 3 ++- util/thread-pool.c | 4 +++- 26 files changed, 227 insertions(+), 92 deletions(-) diff --git a/cpus.c b/cpus.c index cb478039b6..d9ba3f5532 100644 --- a/cpus.c +++ b/cpus.c @@ -1928,15 +1928,20 @@ static void qemu_tcg_init_vcpu(CPUState *cpu, Error= **errp) snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", cpu->cpu_index); =20 - qemu_thread_create(cpu->thread, thread_name, qemu_tcg_cpu_thre= ad_fn, - cpu, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(cpu->thread, thread_name, + qemu_tcg_cpu_thread_fn, cpu, + QEMU_THREAD_JOINABLE, errp)) { + return; + } =20 } else { /* share a single thread for all cpus with TCG */ snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG"); - qemu_thread_create(cpu->thread, thread_name, - qemu_tcg_rr_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(cpu->thread, thread_name, + qemu_tcg_rr_cpu_thread_fn, cpu, + QEMU_THREAD_JOINABLE, errp)) { + return; + } =20 single_tcg_halt_cond =3D cpu->halt_cond; single_tcg_cpu_thread =3D cpu->thread; @@ -1964,8 +1969,10 @@ static void qemu_hax_start_vcpu(CPUState *cpu, Error= **errp) =20 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HAX", cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_hax_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(cpu->thread, thread_name, qemu_hax_cpu_thread_= fn, + cpu, QEMU_THREAD_JOINABLE, errp)) { + return; + } #ifdef _WIN32 cpu->hThread =3D qemu_thread_get_handle(cpu->thread); #endif @@ -1980,8 +1987,10 @@ static void qemu_kvm_start_vcpu(CPUState *cpu, Error= **errp) qemu_cond_init(cpu->halt_cond); snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM", cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_= fn, + cpu, QEMU_THREAD_JOINABLE, errp)) { + /* keep 'if' here in case there is further error handling logic */ + } } =20 static void qemu_hvf_start_vcpu(CPUState *cpu, Error **errp) @@ -1998,8 +2007,10 @@ static void qemu_hvf_start_vcpu(CPUState *cpu, Error= **errp) =20 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF", cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_hvf_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(cpu->thread, thread_name, qemu_hvf_cpu_thread_= fn, + cpu, QEMU_THREAD_JOINABLE, errp)) { + /* keep 'if' here in case there is further error handling logic */ + } } =20 static void qemu_whpx_start_vcpu(CPUState *cpu, Error **errp) @@ -2011,8 +2022,10 @@ static void qemu_whpx_start_vcpu(CPUState *cpu, Erro= r **errp) qemu_cond_init(cpu->halt_cond); snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/WHPX", cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_whpx_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(cpu->thread, thread_name, qemu_whpx_cpu_thread= _fn, + cpu, QEMU_THREAD_JOINABLE, errp)) { + return; + } #ifdef _WIN32 cpu->hThread =3D qemu_thread_get_handle(cpu->thread); #endif @@ -2027,8 +2040,10 @@ static void qemu_dummy_start_vcpu(CPUState *cpu, Err= or **errp) qemu_cond_init(cpu->halt_cond); snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY", cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_dummy_cpu_thread_fn,= cpu, - QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(cpu->thread, thread_name, qemu_dummy_cpu_threa= d_fn, + cpu, QEMU_THREAD_JOINABLE, errp)) { + /* keep 'if' here in case there is further error handling logic */ + } } =20 bool qemu_init_vcpu(CPUState *cpu, Error **errp) diff --git a/dump.c b/dump.c index 4ec94c5e25..1f003aff9a 100644 --- a/dump.c +++ b/dump.c @@ -2020,8 +2020,10 @@ void qmp_dump_guest_memory(bool paging, const char *= file, if (detach_p) { /* detached dump */ s->detached =3D true; - qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread, - s, QEMU_THREAD_DETACHED); + if (!qemu_thread_create(&s->dump_thread, "dump_thread", dump_threa= d, + s, QEMU_THREAD_DETACHED, errp)) { + /* keep 'if' here in case there is further error handling logi= c */ + } } else { /* sync dump */ dump_process(s, errp); diff --git a/hw/misc/edu.c b/hw/misc/edu.c index df26a4d046..2810192b1f 100644 --- a/hw/misc/edu.c +++ b/hw/misc/edu.c @@ -354,8 +354,10 @@ static void pci_edu_realize(PCIDevice *pdev, Error **e= rrp) =20 qemu_mutex_init(&edu->thr_mutex); qemu_cond_init(&edu->thr_cond); - qemu_thread_create(&edu->thread, "edu", edu_fact_thread, - edu, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(&edu->thread, "edu", edu_fact_thread, + edu, QEMU_THREAD_JOINABLE, errp)) { + return; + } =20 memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu, "edu-mmio", 1 * MiB); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index ae913d070f..7c16ade04a 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -478,6 +478,7 @@ static target_ulong h_resize_hpt_prepare(PowerPCCPU *cp= u, sPAPRPendingHPT *pending =3D spapr->pending_hpt; uint64_t current_ram_size; int rc; + Error *local_err =3D NULL; =20 if (spapr->resize_hpt =3D=3D SPAPR_RESIZE_HPT_DISABLED) { return H_AUTHORITY; @@ -538,8 +539,13 @@ static target_ulong h_resize_hpt_prepare(PowerPCCPU *c= pu, pending->shift =3D shift; pending->ret =3D H_HARDWARE; =20 - qemu_thread_create(&pending->thread, "sPAPR HPT prepare", - hpt_prepare_thread, pending, QEMU_THREAD_DETACHED); + if (!qemu_thread_create(&pending->thread, "sPAPR HPT prepare", + hpt_prepare_thread, pending, + QEMU_THREAD_DETACHED, &local_err)) { + error_reportf_err(local_err, "failed to create hpt_prepare_thread:= "); + g_free(pending); + return H_RESOURCE; + } =20 spapr->pending_hpt =3D pending; =20 diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c index d7a4bbd91f..53a2bd0d85 100644 --- a/hw/rdma/rdma_backend.c +++ b/hw/rdma/rdma_backend.c @@ -164,8 +164,10 @@ static void start_comp_thread(RdmaBackendDev *backend_= dev) snprintf(thread_name, sizeof(thread_name), "rdma_comp_%s", ibv_get_device_name(backend_dev->ib_dev)); backend_dev->comp_thread.run =3D true; + /* FIXME: let the further caller handle the error instead of abort() h= ere */ qemu_thread_create(&backend_dev->comp_thread.thread, thread_name, - comp_handler_thread, backend_dev, QEMU_THREAD_DETAC= HED); + comp_handler_thread, backend_dev, + QEMU_THREAD_DETACHED, &error_abort); } =20 void rdma_backend_register_comp_handler(void (*handler)(int status, diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c index 5c8b3c9907..09682b5d30 100644 --- a/hw/usb/ccid-card-emulated.c +++ b/hw/usb/ccid-card-emulated.c @@ -538,10 +538,15 @@ static void emulated_realize(CCIDCardState *base, Err= or **errp) error_setg(errp, "%s: failed to initialize vcard", TYPE_EMULATED_C= CID); return; } - qemu_thread_create(&card->event_thread_id, "ccid/event", event_thread, - card, QEMU_THREAD_JOINABLE); - qemu_thread_create(&card->apdu_thread_id, "ccid/apdu", handle_apdu_thr= ead, - card, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(&card->event_thread_id, "ccid/event", event_th= read, + card, QEMU_THREAD_JOINABLE, errp)) { + return; + } + if (!qemu_thread_create(&card->apdu_thread_id, "ccid/apdu", + handle_apdu_thread, card, + QEMU_THREAD_JOINABLE, errp)) { + /* keep 'if' here in case there is further error handling logic */ + } } =20 static void emulated_unrealize(CCIDCardState *base, Error **errp) diff --git a/include/qemu/thread.h b/include/qemu/thread.h index dacebcfff0..1fb84a07d2 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -135,9 +135,9 @@ void qemu_event_reset(QemuEvent *ev); void qemu_event_wait(QemuEvent *ev); void qemu_event_destroy(QemuEvent *ev); =20 -void qemu_thread_create(QemuThread *thread, const char *name, +bool qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void *), - void *arg, int mode); + void *arg, int mode, Error **errp); void *qemu_thread_join(QemuThread *thread); void qemu_thread_get_self(QemuThread *thread); bool qemu_thread_is_self(QemuThread *thread); diff --git a/io/task.c b/io/task.c index 2886a2c1bc..6d3a18ab80 100644 --- a/io/task.c +++ b/io/task.c @@ -149,7 +149,8 @@ void qio_task_run_in_thread(QIOTask *task, "io-task-worker", qio_task_thread_worker, data, - QEMU_THREAD_DETACHED); + QEMU_THREAD_DETACHED, + &error_abort); } =20 =20 diff --git a/iothread.c b/iothread.c index aff1281257..cdc6fadce4 100644 --- a/iothread.c +++ b/iothread.c @@ -161,9 +161,7 @@ static void iothread_complete(UserCreatable *obj, Error= **errp) &local_error); if (local_error) { error_propagate(errp, local_error); - aio_context_unref(iothread->ctx); - iothread->ctx =3D NULL; - return; + goto fail; } =20 qemu_mutex_init(&iothread->init_done_lock); @@ -175,8 +173,14 @@ static void iothread_complete(UserCreatable *obj, Erro= r **errp) */ name =3D object_get_canonical_path_component(OBJECT(obj)); thread_name =3D g_strdup_printf("IO %s", name); - qemu_thread_create(&iothread->thread, thread_name, iothread_run, - iothread, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(&iothread->thread, thread_name, iothread_run, + iothread, QEMU_THREAD_JOINABLE, errp)) { + g_free(thread_name); + g_free(name); + qemu_cond_destroy(&iothread->init_done_cond); + qemu_mutex_destroy(&iothread->init_done_lock); + goto fail; + } g_free(thread_name); g_free(name); =20 @@ -187,6 +191,10 @@ static void iothread_complete(UserCreatable *obj, Erro= r **errp) &iothread->init_done_lock); } qemu_mutex_unlock(&iothread->init_done_lock); + return; +fail: + aio_context_unref(iothread->ctx); + iothread->ctx =3D NULL; } =20 typedef struct { diff --git a/migration/migration.c b/migration/migration.c index 0dbaf3ff80..623e8fafae 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -388,6 +388,7 @@ static void process_incoming_migration_co(void *opaque) MigrationIncomingState *mis =3D migration_incoming_get_current(); PostcopyState ps; int ret; + Error *local_err =3D NULL; =20 assert(mis->from_src_file); mis->migration_incoming_co =3D qemu_coroutine_self(); @@ -420,8 +421,13 @@ static void process_incoming_migration_co(void *opaque) =20 /* we get COLO info, and know if we are in COLO mode */ if (!ret && migration_incoming_enable_colo()) { - qemu_thread_create(&mis->colo_incoming_thread, "COLO incoming", - colo_process_incoming_thread, mis, QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(&mis->colo_incoming_thread, "COLO incoming= ", + colo_process_incoming_thread, mis, + QEMU_THREAD_JOINABLE, &local_err)) { + error_reportf_err(local_err, "failed to create " + "colo_process_incoming_thread: "); + goto fail; + } mis->have_colo_incoming_thread =3D true; qemu_coroutine_yield(); =20 @@ -430,20 +436,22 @@ static void process_incoming_migration_co(void *opaqu= e) } =20 if (ret < 0) { - Error *local_err =3D NULL; - - migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, - MIGRATION_STATUS_FAILED); error_report("load of migration failed: %s", strerror(-ret)); - qemu_fclose(mis->from_src_file); - if (multifd_load_cleanup(&local_err) !=3D 0) { - error_report_err(local_err); - } - exit(EXIT_FAILURE); + goto fail; } mis->bh =3D qemu_bh_new(process_incoming_migration_bh, mis); qemu_bh_schedule(mis->bh); mis->migration_incoming_co =3D NULL; + return; +fail: + local_err =3D NULL; + migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, + MIGRATION_STATUS_FAILED); + qemu_fclose(mis->from_src_file); + if (multifd_load_cleanup(&local_err) !=3D 0) { + error_report_err(local_err); + } + exit(EXIT_FAILURE); } =20 static void migration_incoming_setup(QEMUFile *f) @@ -2285,6 +2293,7 @@ out: static int open_return_path_on_source(MigrationState *ms, bool create_thread) { + Error *local_err =3D NULL; =20 ms->rp_state.from_dst_file =3D qemu_file_get_return_path(ms->to_dst_fi= le); if (!ms->rp_state.from_dst_file) { @@ -2298,8 +2307,13 @@ static int open_return_path_on_source(MigrationState= *ms, return 0; } =20 - qemu_thread_create(&ms->rp_state.rp_thread, "return path", - source_return_path_thread, ms, QEMU_THREAD_JOINABLE= ); + if (!qemu_thread_create(&ms->rp_state.rp_thread, "return path", + source_return_path_thread, ms, + QEMU_THREAD_JOINABLE, &local_err)) { + error_reportf_err(local_err, + "failed to create source_return_path_thread: "); + return -1; + } =20 trace_open_return_path_on_source_continue(); =20 @@ -3124,8 +3138,13 @@ void migrate_fd_connect(MigrationState *s, Error *er= ror_in) migrate_fd_cleanup(s); return; } - qemu_thread_create(&s->thread, "live_migration", migration_thread, s, - QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(&s->thread, "live_migration", migration_thread, + s, QEMU_THREAD_JOINABLE, &error_in)) { + error_reportf_err(error_in, "failed to create migration_thread: "); + migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED); + migrate_fd_cleanup(s); + return; + } s->migration_thread_running =3D true; } =20 diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index f96e0ae1f8..c6d2ca0df9 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -1082,6 +1082,8 @@ retry: =20 int postcopy_ram_enable_notify(MigrationIncomingState *mis) { + Error *local_err =3D NULL; + /* Open the fd for the kernel to give us userfaults */ mis->userfault_fd =3D syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK= ); if (mis->userfault_fd =3D=3D -1) { @@ -1108,8 +1110,16 @@ int postcopy_ram_enable_notify(MigrationIncomingStat= e *mis) } =20 qemu_sem_init(&mis->fault_thread_sem, 0); - qemu_thread_create(&mis->fault_thread, "postcopy/fault", - postcopy_ram_fault_thread, mis, QEMU_THREAD_JOINABL= E); + if (!qemu_thread_create(&mis->fault_thread, "postcopy/fault", + postcopy_ram_fault_thread, mis, + QEMU_THREAD_JOINABLE, &local_err)) { + error_reportf_err(local_err, + "failed to create postcopy_ram_fault_thread: "); + close(mis->userfault_event_fd); + close(mis->userfault_fd); + qemu_sem_destroy(&mis->fault_thread_sem); + return -1; + } qemu_sem_wait(&mis->fault_thread_sem); qemu_sem_destroy(&mis->fault_thread_sem); mis->have_fault_thread =3D true; diff --git a/migration/ram.c b/migration/ram.c index 433f35664a..a9b2de7898 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -470,6 +470,7 @@ static void compress_threads_save_cleanup(void) static int compress_threads_save_setup(void) { int i, thread_count; + Error *local_err =3D NULL; =20 if (!migrate_use_compression()) { return 0; @@ -499,9 +500,12 @@ static int compress_threads_save_setup(void) comp_param[i].quit =3D false; qemu_mutex_init(&comp_param[i].mutex); qemu_cond_init(&comp_param[i].cond); - qemu_thread_create(compress_threads + i, "compress", - do_data_compress, comp_param + i, - QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(compress_threads + i, "compress", + do_data_compress, comp_param + i, + QEMU_THREAD_JOINABLE, &local_err)) { + error_reportf_err(local_err, "failed to create do_data_compres= s: "); + goto exit; + } } return 0; =20 @@ -1079,8 +1083,14 @@ static void multifd_new_send_channel_async(QIOTask *= task, gpointer opaque) p->c =3D QIO_CHANNEL(sioc); qio_channel_set_delay(p->c, false); p->running =3D true; - qemu_thread_create(&p->thread, p->name, multifd_send_thread, p, - QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(&p->thread, p->name, multifd_send_thread, = p, + QEMU_THREAD_JOINABLE, &local_err)) { + error_reportf_err(local_err, + "failed to create multifd_send_thread: "); + multifd_save_cleanup(); + migrate_set_error(migrate_get_current(), local_err); + return; + } =20 atomic_inc(&multifd_send_state->count); } @@ -1354,8 +1364,12 @@ bool multifd_recv_new_channel(QIOChannel *ioc) p->num_packets =3D 1; =20 p->running =3D true; - qemu_thread_create(&p->thread, p->name, multifd_recv_thread, p, - QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(&p->thread, p->name, multifd_recv_thread, + p, QEMU_THREAD_JOINABLE, &local_err)) { + error_reportf_err(local_err, "failed to create multifd_recv_thread= : "); + multifd_recv_terminate_threads(local_err, true); + return false; + } atomic_inc(&multifd_recv_state->count); return multifd_recv_state->count =3D=3D migrate_multifd_channels(); } @@ -3551,6 +3565,7 @@ static void compress_threads_load_cleanup(void) static int compress_threads_load_setup(QEMUFile *f) { int i, thread_count; + Error *local_err =3D NULL; =20 if (!migrate_use_compression()) { return 0; @@ -3572,9 +3587,13 @@ static int compress_threads_load_setup(QEMUFile *f) qemu_cond_init(&decomp_param[i].cond); decomp_param[i].done =3D true; decomp_param[i].quit =3D false; - qemu_thread_create(decompress_threads + i, "decompress", - do_data_decompress, decomp_param + i, - QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(decompress_threads + i, "decompress", + do_data_decompress, decomp_param + i, + QEMU_THREAD_JOINABLE, &local_err)) { + error_reportf_err(local_err, + "failed to create do_data_decompress: "); + goto exit; + } } return 0; exit: diff --git a/migration/savevm.c b/migration/savevm.c index 13e51f0e34..fc26a10e68 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1727,9 +1727,14 @@ static int loadvm_postcopy_handle_listen(MigrationIn= comingState *mis) mis->have_listen_thread =3D true; /* Start up the listening thread and wait for it to signal ready */ qemu_sem_init(&mis->listen_thread_sem, 0); - qemu_thread_create(&mis->listen_thread, "postcopy/listen", - postcopy_ram_listen_thread, NULL, - QEMU_THREAD_DETACHED); + if (!qemu_thread_create(&mis->listen_thread, "postcopy/listen", + postcopy_ram_listen_thread, NULL, + QEMU_THREAD_DETACHED, &local_err)) { + error_reportf_err(local_err, + "failed to create postcopy_ram_listen_thread: "); + qemu_sem_destroy(&mis->listen_thread_sem); + return -1; + } qemu_sem_wait(&mis->listen_thread_sem); qemu_sem_destroy(&mis->listen_thread_sem); =20 diff --git a/tests/atomic_add-bench.c b/tests/atomic_add-bench.c index 2f6c72f63a..338b9563e3 100644 --- a/tests/atomic_add-bench.c +++ b/tests/atomic_add-bench.c @@ -2,6 +2,7 @@ #include "qemu/thread.h" #include "qemu/host-utils.h" #include "qemu/processor.h" +#include "qapi/error.h" =20 struct thread_info { uint64_t r; @@ -110,7 +111,7 @@ static void create_threads(void) =20 info->r =3D (i + 1) ^ time(NULL); qemu_thread_create(&threads[i], NULL, thread_func, info, - QEMU_THREAD_JOINABLE); + QEMU_THREAD_JOINABLE, &error_abort); } } =20 diff --git a/tests/iothread.c b/tests/iothread.c index 777d9eea46..f4ad992e61 100644 --- a/tests/iothread.c +++ b/tests/iothread.c @@ -73,7 +73,7 @@ IOThread *iothread_new(void) qemu_mutex_init(&iothread->init_done_lock); qemu_cond_init(&iothread->init_done_cond); qemu_thread_create(&iothread->thread, NULL, iothread_run, - iothread, QEMU_THREAD_JOINABLE); + iothread, QEMU_THREAD_JOINABLE, &error_abort); =20 /* Wait for initialization to complete */ qemu_mutex_lock(&iothread->init_done_lock); diff --git a/tests/qht-bench.c b/tests/qht-bench.c index f492b3a20a..20a4101a17 100644 --- a/tests/qht-bench.c +++ b/tests/qht-bench.c @@ -9,6 +9,7 @@ #include "qemu/atomic.h" #include "qemu/qht.h" #include "qemu/rcu.h" +#include "qapi/error.h" #include "exec/tb-hash-xx.h" =20 struct thread_stats { @@ -239,7 +240,7 @@ th_create_n(QemuThread **threads, struct thread_info **= infos, const char *name, prepare_thread_info(&info[i], offset + i); info[i].func =3D func; qemu_thread_create(&th[i], name, thread_func, &info[i], - QEMU_THREAD_JOINABLE); + QEMU_THREAD_JOINABLE, &error_abort); } } =20 diff --git a/tests/rcutorture.c b/tests/rcutorture.c index 49311c82ea..0e799ff256 100644 --- a/tests/rcutorture.c +++ b/tests/rcutorture.c @@ -64,6 +64,7 @@ #include "qemu/atomic.h" #include "qemu/rcu.h" #include "qemu/thread.h" +#include "qapi/error.h" =20 long long n_reads =3D 0LL; long n_updates =3D 0L; @@ -90,7 +91,7 @@ static void create_thread(void *(*func)(void *)) exit(-1); } qemu_thread_create(&threads[n_threads], "test", func, &data[n_threads], - QEMU_THREAD_JOINABLE); + QEMU_THREAD_JOINABLE, &error_abort); n_threads++; } =20 diff --git a/tests/test-aio.c b/tests/test-aio.c index 86fb73b3d5..b3ac261724 100644 --- a/tests/test-aio.c +++ b/tests/test-aio.c @@ -154,7 +154,7 @@ static void test_acquire(void) =20 qemu_thread_create(&thread, "test_acquire_thread", test_acquire_thread, - &data, QEMU_THREAD_JOINABLE); + &data, QEMU_THREAD_JOINABLE, &error_abort); =20 /* Block in aio_poll(), let other thread kick us and acquire context */ aio_context_acquire(ctx); diff --git a/tests/test-rcu-list.c b/tests/test-rcu-list.c index 192bfbf02e..9ea35a3dad 100644 --- a/tests/test-rcu-list.c +++ b/tests/test-rcu-list.c @@ -25,6 +25,7 @@ #include "qemu/rcu.h" #include "qemu/thread.h" #include "qemu/rcu_queue.h" +#include "qapi/error.h" =20 /* * Test variables. @@ -68,7 +69,7 @@ static void create_thread(void *(*func)(void *)) exit(-1); } qemu_thread_create(&threads[n_threads], "test", func, &data[n_threads], - QEMU_THREAD_JOINABLE); + QEMU_THREAD_JOINABLE, &error_abort); n_threads++; } =20 diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index 8807d7217c..35a652d1fd 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -31,6 +31,7 @@ #include "vnc-jobs.h" #include "qemu/sockets.h" #include "qemu/main-loop.h" +#include "qapi/error.h" #include "block/aio.h" =20 /* @@ -340,8 +341,11 @@ bool vnc_start_worker_thread(Error **errp) } =20 q =3D vnc_queue_init(); - qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, q, - QEMU_THREAD_DETACHED); + if (!qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, + q, QEMU_THREAD_DETACHED, errp)) { + vnc_queue_clear(q); + return false; + } queue =3D q; /* Set global queue */ out: return true; diff --git a/util/compatfd.c b/util/compatfd.c index d3ed890405..1ab94d423b 100644 --- a/util/compatfd.c +++ b/util/compatfd.c @@ -91,8 +91,13 @@ static int qemu_signalfd_compat(const sigset_t *mask, Er= ror **errp) memcpy(&info->mask, mask, sizeof(*mask)); info->fd =3D fds[1]; =20 - qemu_thread_create(&thread, "signalfd_compat", sigwait_compat, info, - QEMU_THREAD_DETACHED); + if (!qemu_thread_create(&thread, "signalfd_compat", sigwait_compat, + info, QEMU_THREAD_DETACHED, errp)) { + close(fds[0]); + close(fds[1]); + free(info); + return -1; + } =20 return fds[0]; } diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 13b6f8d776..85d0504f5a 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -364,9 +364,12 @@ static bool touch_all_pages(char *area, size_t hpagesi= ze, size_t numpages, size_t size_per_thread; char *addr =3D area; int i =3D 0; + int started_thread =3D 0; + Error *local_err =3D NULL; =20 memset_thread_failed =3D false; memset_num_threads =3D get_memset_num_threads(smp_cpus); + started_thread =3D memset_num_threads; memset_thread =3D g_new0(MemsetThread, memset_num_threads); numpages_per_thread =3D (numpages / memset_num_threads); size_per_thread =3D (hpagesize * numpages_per_thread); @@ -375,13 +378,19 @@ static bool touch_all_pages(char *area, size_t hpages= ize, size_t numpages, memset_thread[i].numpages =3D (i =3D=3D (memset_num_threads - 1)) ? numpages : numpages_per_thread; memset_thread[i].hpagesize =3D hpagesize; - qemu_thread_create(&memset_thread[i].pgthread, "touch_pages", - do_touch_pages, &memset_thread[i], - QEMU_THREAD_JOINABLE); + if (!qemu_thread_create(&memset_thread[i].pgthread, "touch_pages", + do_touch_pages, &memset_thread[i], + QEMU_THREAD_JOINABLE, &local_err)) { + error_reportf_err(local_err, "failed to create do_touch_pages:= "); + memset_thread_failed =3D true; + started_thread =3D i; + goto out; + } addr +=3D size_per_thread; numpages -=3D numpages_per_thread; } - for (i =3D 0; i < memset_num_threads; i++) { +out: + for (i =3D 0; i < started_thread; i++) { qemu_thread_join(&memset_thread[i].pgthread); } g_free(memset_thread); diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 289af4fab5..8b044e2798 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -15,6 +15,7 @@ #include "qemu/atomic.h" #include "qemu/notify.h" #include "qemu-thread-common.h" +#include "qapi/error.h" =20 static bool name_threads; =20 @@ -504,9 +505,9 @@ static void *qemu_thread_start(void *args) return start_routine(arg); } =20 -void qemu_thread_create(QemuThread *thread, const char *name, - void *(*start_routine)(void*), - void *arg, int mode) +bool qemu_thread_create(QemuThread *thread, const char *name, + void *(*start_routine)(void *), + void *arg, int mode, Error **errp) { sigset_t set, oldset; int err; @@ -515,7 +516,9 @@ void qemu_thread_create(QemuThread *thread, const char = *name, =20 err =3D pthread_attr_init(&attr); if (err) { - error_exit(err, __func__); + error_setg(errp, "pthread_attr_init failed: %s", strerror(err)); + errno =3D err; + return false; } =20 if (mode =3D=3D QEMU_THREAD_DETACHED) { @@ -530,16 +533,21 @@ void qemu_thread_create(QemuThread *thread, const cha= r *name, qemu_thread_args->name =3D g_strdup(name); qemu_thread_args->start_routine =3D start_routine; qemu_thread_args->arg =3D arg; - err =3D pthread_create(&thread->thread, &attr, qemu_thread_start, qemu_thread_args); - - if (err) - error_exit(err, __func__); + if (err) { + error_setg(errp, "pthread_create failed: %s", strerror(err)); + errno =3D err; + pthread_attr_destroy(&attr); + g_free(qemu_thread_args->name); + g_free(qemu_thread_args); + return false; + } =20 pthread_sigmask(SIG_SETMASK, &oldset, NULL); =20 pthread_attr_destroy(&attr); + return true; } =20 void qemu_thread_get_self(QemuThread *thread) diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index 1a27e1cf6f..96e5d19ca3 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -20,6 +20,7 @@ #include "qemu/thread.h" #include "qemu/notify.h" #include "qemu-thread-common.h" +#include "qapi/error.h" #include =20 static bool name_threads; @@ -388,9 +389,9 @@ void *qemu_thread_join(QemuThread *thread) return ret; } =20 -void qemu_thread_create(QemuThread *thread, const char *name, - void *(*start_routine)(void *), - void *arg, int mode) +bool qemu_thread_create(QemuThread *thread, const char *name, + void *(*start_routine)(void *), + void *arg, int mode, Error **errp) { HANDLE hThread; struct QemuThreadData *data; @@ -409,10 +410,17 @@ void qemu_thread_create(QemuThread *thread, const cha= r *name, hThread =3D (HANDLE) _beginthreadex(NULL, 0, win32_start_routine, data, 0, &thread->tid); if (!hThread) { - error_exit(GetLastError(), __func__); + if (data->mode !=3D QEMU_THREAD_DETACHED) { + DeleteCriticalSection(&data->cs); + } + error_setg_win32(errp, GetLastError(), + "failed to create win32_start_routine"); + g_free(data); + return false; } CloseHandle(hThread); thread->data =3D data; + return true; } =20 void qemu_thread_get_self(QemuThread *thread) diff --git a/util/rcu.c b/util/rcu.c index 5676c22bd1..145dcdb0c6 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -32,6 +32,7 @@ #include "qemu/atomic.h" #include "qemu/thread.h" #include "qemu/main-loop.h" +#include "qapi/error.h" #if defined(CONFIG_MALLOC_TRIM) #include #endif @@ -325,7 +326,7 @@ static void rcu_init_complete(void) * must have been quiescent even after forking, just recreate it. */ qemu_thread_create(&thread, "call_rcu", call_rcu_thread, - NULL, QEMU_THREAD_DETACHED); + NULL, QEMU_THREAD_DETACHED, &error_abort); =20 rcu_register_thread(); } diff --git a/util/thread-pool.c b/util/thread-pool.c index 610646d131..ad0f980783 100644 --- a/util/thread-pool.c +++ b/util/thread-pool.c @@ -22,6 +22,7 @@ #include "trace.h" #include "block/thread-pool.h" #include "qemu/main-loop.h" +#include "qapi/error.h" =20 static void do_spawn_thread(ThreadPool *pool); =20 @@ -132,7 +133,8 @@ static void do_spawn_thread(ThreadPool *pool) pool->new_threads--; pool->pending_threads++; =20 - qemu_thread_create(&t, "worker", worker_thread, pool, QEMU_THREAD_DETA= CHED); + qemu_thread_create(&t, "worker", worker_thread, pool, + QEMU_THREAD_DETACHED, &error_abort); } =20 static void spawn_thread_bh_fn(void *opaque) --=20 2.13.7