From nobody Sat May 30 17:44:07 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1779370506; cv=none; d=zohomail.com; s=zohoarc; b=PKHKBtokkWdsZeFqC7y8lMU2g0RiRhUCoDwGGtKcJ7h3Yg2jjRvSeT87BV9IZlRUiKrCSKzeCwQBCmDUUfwJsVahR1zwQVsM8gfFp6tPUJL/5Rw1vdldwnSknwozWmEn1R8Y8ln62uFpgGYLG53QnK7CyoDpi2Ih9m0N2ooJDG0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779370506; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=a7EtJcaeszOWZCpp5YqQS4YLNVQ5b7sTn+HBpnI0Nag=; b=YCCGIi3n6MRHPVtSR+w8NtKFbSYZCnl92D9cWe1q3tcFooJ3+qV6T1NR/L2Aoir4sga9jnAEcK+yRF9jXArViyZWx2miM8r+Re3Z+pq4iI64q5gANUZ5nigFN6StFd5IJ0txIbiyqmVDi3V3fNXdiWFGeksOVgmjFZeUhafyVsg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1779370506762991.69611496861; Thu, 21 May 2026 06:35:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wQ3Y8-0002Ur-1L; Thu, 21 May 2026 09:34:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wQ3Xw-0002SH-K4 for qemu-devel@nongnu.org; Thu, 21 May 2026 09:34:49 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wQ3Xu-0005Sp-EF for qemu-devel@nongnu.org; Thu, 21 May 2026 09:34:43 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p508926a6.dip0.t-ipconnect.de [80.137.38.166]) by linux.microsoft.com (Postfix) with ESMTPSA id 3B44020B7167; Thu, 21 May 2026 06:34:29 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 3B44020B7167 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1779370471; bh=a7EtJcaeszOWZCpp5YqQS4YLNVQ5b7sTn+HBpnI0Nag=; h=From:To:Cc:Subject:Date:From; b=khakCAse/5dIOrBY71aQvaxvwYL5xzV3VCoWnroZmL0hoQUagSX88UkHTcD29284G HWtMI+1sxyFJhE6rTDB08EwkZGeXHWRK8HvnD3OZsfNiVIXZQmP9xW4ZVSc47K4TAI 51UQEAoAoiPrPlDPlrfTvI2Ak/UwRTG7+fpuJYdg= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Wei Liu , Anirudh Rayabharam , aastharawat@microsoft.com, =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Magnus Kulke , Aastha Rawat , magnuskulke@microsoft.com, Anirudh.Rayabharam@microsoft.com, liuwe@microsoft.com, doru.blanzeanu@microsoft.com, Paolo Bonzini Subject: [PATCH] accel/mshv: mitigate early boot vcpu exit race Date: Thu, 21 May 2026 15:34:33 +0200 Message-Id: <20260521133433.48463-1-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@linux.microsoft.com; helo=linux.microsoft.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1779370563383154100 Content-Type: text/plain; charset="utf-8" When using the mshv accelerator, there is a high likelihood in early boot for a QMP execute::quit command to return w/o the QEMU process terminating. The race is between SIG_IPI delivery and the vcpu thread's exec loop. qemu_cpu_kick() relies on SIG_IPI to make MSHV_RUN_VP return -EINTR so the vcpu thread can observe cpu->stop. During early boot, there are many PIO intercept exit produce MshvVmExitIgnore. That means the inner loop in mshv_cpu_exec() spins through RUN_VP ioctl -> handler -> RUN_VP ioctl, without being able to consult cpu->exit_request of cpu->stop. The qemu_cpu_kick_self() in sa_ipi_handler() was practically a no-op, since it calls cpus_kick_thread() which itsself issues a SIG_IPI, in the handler for that signal. Hence it has been removed a made a practial noop. Once we have a facility in MSHV to signal immediate_exit to the kernel it should be used in this handler. To mitigate we register a custom kick_vcpu_thread() impl for mshv, that will set cpu->exit_request before calling the generic kick_vcpu_thread() implement that will raise SIG_IPI. We then observe cpu->exit request in the mshv_cpu_exec() inner loop and break with EXCP_INTERRUPT when set. Signed-off-by: Magnus Kulke Reviewed-by: Doru Bl=C3=A2nzeanu --- accel/mshv/mshv-all.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 58af674bd9..a3593c67db 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -502,6 +502,18 @@ static int mshv_cpu_exec(CPUState *cpu) cpu_exec_start(cpu); =20 do { + /* + * We consider a pending exit_request before re-entering the guest. + * This condition is set by mshv_kick_vcpu_thread(), so we unset + * thread_kicked to allow future kicks to interrupt the guest. + */ + if (qatomic_load_acquire(&cpu->exit_request)) { + qatomic_set(&cpu->exit_request, false); + qatomic_set_mb(&cpu->thread_kicked, false); + ret =3D EXCP_INTERRUPT; + break; + } + if (cpu->accel->dirty) { ret =3D mshv_arch_put_registers(cpu); if (ret) { @@ -540,17 +552,17 @@ static int mshv_cpu_exec(CPUState *cpu) } =20 /* - * The signal handler is triggered when QEMU's main thread receives a SIG_= IPI - * (SIGUSR1). This signal causes the current CPU thread to be kicked, forc= ing a - * VM exit on the CPU. The VM exit generates an exit reason that breaks th= e loop - * (see mshv_cpu_exec). If the exit is due to a Ctrl+A+x command, the syst= em - * will shut down. For other cases, the system will continue running. + * SIG_IPI handler for the vCPU thread. It's a noop currently. A decision = to + * leave the guest is communicated via cpu->exit_request, which is set by + * mshv_kick_vcpu_thread() before it raises a SIG_IPI. + * + * Note: MSHV currently lacks an immediate_exit equivalent to KVM, there + * remains a theoretical race window between userspace check and ioctl ent= ry + * in the vcpu loop. Once MSHV supports immediate_exit semantics, we should + * invoke it here. */ static void sa_ipi_handler(int sig) { - /* TODO: call IOCTL to set_immediate_exit, once implemented. */ - - qemu_cpu_kick_self(); } =20 static void init_signal(CPUState *cpu) @@ -605,6 +617,19 @@ cleanup: return NULL; } =20 +/* + * mshv-custom kick implementation: + * + * We set cpu->exit_request before the SIG_IPI is delivered to the vcpu + * thread (as part of cpus_kick_thread()). It is consumed in the + * mshv_cpu_exec loop. + */ +static void mshv_kick_vcpu_thread(CPUState *cpu) +{ + qatomic_set_mb(&cpu->exit_request, true); + cpus_kick_thread(cpu); +} + static void mshv_start_vcpu_thread(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -719,6 +744,7 @@ static void mshv_accel_ops_class_init(ObjectClass *oc, = const void *data) AccelOpsClass *ops =3D ACCEL_OPS_CLASS(oc); =20 ops->create_vcpu_thread =3D mshv_start_vcpu_thread; + ops->kick_vcpu_thread =3D mshv_kick_vcpu_thread; ops->synchronize_post_init =3D mshv_cpu_synchronize_post_init; ops->synchronize_post_reset =3D mshv_cpu_synchronize_post_reset; ops->synchronize_state =3D mshv_cpu_synchronize; --=20 2.34.1