From nobody Sun Jul 12 00:42:32 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=1783678609; cv=none; d=zohomail.com; s=zohoarc; b=W92BGUujHyKTcdv9mWRh9/D1VxpDbrZwmogy2OXIAZEdJPUBCMKjVqNojPg0aTTpFS4nF8oihL+NfQ7EaehTsVlSI1MH+9tv6esvZcQrI8wI4hQNmOTZahnx8GkzSrz9YlxPSMkI1ws6RUcAvw3NE31kxHsAPWyrg3bE3noHMNs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678609; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=b2Bgk0lYWwE6rb1Xc2GSgwgap3hUpX+o2F3ekqBW8To=; b=hMyL5+H2cB+ygaaERpekSz4beHPZE+lHNF72RJWuNTORUkgeM1g6zpDON7THLyRMgIg2Voi+myzlwU6pwQRcrSLSLjcCTRXziciPddvZeNS9Tihy3aOU6gN6D47ZepT2CVi0aNyN0FfKFxgZqblNjDUqs5K2+SL0ySLKyuRqT90= 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 1783678609302200.40484145601624; Fri, 10 Jul 2026 03:16:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8Gp-0006lK-IL; Fri, 10 Jul 2026 06:15:47 -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 1wi8Go-0006kN-Fn for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:15:46 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8Gn-0006C9-1Q for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:15:46 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 6807C20B716F; Fri, 10 Jul 2026 03:15:35 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 6807C20B716F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678537; bh=b2Bgk0lYWwE6rb1Xc2GSgwgap3hUpX+o2F3ekqBW8To=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qgsV4nLY6JRgOW50fS28KBr4HpeEWz8AluoRL1rnnPdesNavYPP5sMm55Q/J8YcZp L30y9SLhPyUMqUF17FFIWP6NWni77221G9iuRexAgKXAU24kvr5gYKN0AuDpSh1N+S o66C68bO+EQnRuFYLkPzCi9Af9JZYhzu6Fjmfxtg= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 01/12] target/i386/mshv: disable AMX TILE features Date: Fri, 10 Jul 2026 12:15:23 +0200 Message-Id: <20260710101534.664604-2-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678610237158500 Content-Type: text/plain; charset="utf-8" For the time being we disable AMX TILE in partition processor features and CPUID b/c AMX TILE XSAVE state (XTILE_DATA) is 8KB, which exceeds the current fixed 4KB XSAVE buffer size. For now we filter it until buffer sizing is computed dynamically from CPUID. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 8 ++++++++ target/i386/mshv/mshv-cpu.c | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 72721d0f0d..5e8756ede2 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -203,6 +203,14 @@ static int create_partition(int mshv_fd, int *vm_fd) =20 /* enable all */ disabled_xsave_features.as_uint64 =3D 0; + /* + * AMX TILE XSAVE state (XTILE_DATA) is 8KB, which exceeds the + * current fixed 4KB XSAVE buffer size. + */ + disabled_xsave_features.amx_tile_support =3D 1; + disabled_xsave_features.amx_bf16_support =3D 1; + disabled_xsave_features.amx_int8_support =3D 1; + disabled_xsave_features.amx_fp16_support =3D 1; =20 /* * query host for supported processor features and disable unsupported diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 1c433c408c..8eca01a8fa 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -2156,6 +2156,22 @@ uint32_t mshv_get_supported_cpuid(uint32_t func, uin= t32_t idx, int reg) */ ret &=3D ~CPUID_7_0_ECX_LA57; } + if (func =3D=3D 0x07 && idx =3D=3D 0 && reg =3D=3D R_EDX) { + /* + * AMX TILE XSAVE state (XTILE_DATA) is 8KB, which exceeds the + * current fixed 4KB XSAVE buffer size. Filter until buffer + * sizing is computed dynamically from CPUID. + */ + ret &=3D ~CPUID_7_0_EDX_AMX_TILE; + ret &=3D ~CPUID_7_0_EDX_AMX_BF16; + ret &=3D ~CPUID_7_0_EDX_AMX_INT8; + } + if (func =3D=3D 0x07 && idx =3D=3D 1 && reg =3D=3D R_EAX) { + ret &=3D ~CPUID_7_1_EAX_AMX_FP16; + } + if (func =3D=3D 0x07 && idx =3D=3D 1 && reg =3D=3D R_EDX) { + ret &=3D ~CPUID_7_1_EDX_AMX_COMPLEX; + } =20 return ret; } --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678592; cv=none; d=zohomail.com; s=zohoarc; b=L4AoOA9T4WMBNJHS0As2cjBZKkWzI2hOxQrfrBZBaD0TuPlkqTLYuNrPQGDbPJEpYDNYzsXOFypPfTZMRctnrVOYDJ1pedpBkhC+nnJVAK8O7Pn0mfN2TcWOxnL3ugCBWEl5qDactMU9u11WhNMddQCuaAgSYWCFsoX9nXv4lS8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678592; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=SvCh2f7tNQwLONA2g+kuw9iXDvOndr+2Kwyn46oMOrY=; b=mXZZAprcye/DxjpvdJkDgSaEJlE3Uq4ix8o/BCGflckkIqREjM0MAB/5aZpdbRbhkOHr1UWVCOTQTyztOCsAMxxHXl53lYoQLuKz94JuwVOh15+ZItlRTIVuL/DZJGYGFDhkawQqgG4MnPMFNNqQE/M7ileIaHn6+SGMC+hnhEI= 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 178367859232828.43117787075414; Fri, 10 Jul 2026 03:16:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8Gt-0006ms-UD; Fri, 10 Jul 2026 06:15:52 -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 1wi8Gr-0006lm-Vq for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:15:50 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8Gq-0006G4-I1 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:15:49 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id BDBA720B7171; Fri, 10 Jul 2026 03:15:38 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com BDBA720B7171 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678541; bh=SvCh2f7tNQwLONA2g+kuw9iXDvOndr+2Kwyn46oMOrY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LuQ5YhH9QeNTfzuLFmoiqBCoLoMxqnLe99iDw621bvtVNiLI1c8ocN4NbRiovGW4O GVgJnAMS2o2MM24CmolglwHwoL0VXcL4EFh3/W1fRxuzOdC6uBWtKztrM6f2eESP7Z U4zf0dfNvxNSd4Zc4gAmnavrBl4tBrBQQoGE8Z5M= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 02/12] accel/mshv: introduce SaveVMHandler Date: Fri, 10 Jul 2026 12:15:24 +0200 Message-Id: <20260710101534.664604-3-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678594650158500 Content-Type: text/plain; charset="utf-8" This mechanism is used to handle more imperative partition-wide steps that have to be taken as part of a migration routine. Currently it's just a skeleton. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 5e8756ede2..b34fb34d05 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -39,6 +39,8 @@ #include "system/mshv.h" #include "system/mshv_int.h" #include "system/reset.h" +#include "migration/qemu-file-types.h" +#include "migration/register.h" #include "trace.h" #include #include @@ -544,6 +546,9 @@ static int mshv_init_vcpu(CPUState *cpu) return 0; } =20 +static SaveVMHandlers savevm_mshv =3D { +}; + static int mshv_init(AccelState *as, MachineState *ms) { MshvState *s; @@ -599,6 +604,8 @@ static int mshv_init(AccelState *as, MachineState *ms) 0, "mshv-memory"); memory_listener_register(&mshv_io_listener, &address_space_io); =20 + register_savevm_live("mshv", 0, 1, &savevm_mshv, s); + return 0; } =20 --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678646; cv=none; d=zohomail.com; s=zohoarc; b=bfB+4RpJuKtd4VCTcT1pbAyFa9BUe6l8as2+L1B8duL7DgGeIwpGQ/Od8zQE0I59oSLeK4z+JrmF8ZF4I3em110+Cygnzct781yf0e6Roftk8ViWcRM/XwsI5l8co1Eb8vHVg9Ijf11u4TLrnNiitKc7H9mQP513bNuyRcX73rI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678646; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=bUs7HPt9XlYcvGqXEMDKsjAZZdQrDSmsL1ZEYxoLPqU=; b=jvM7LUCcyruFmSIBzHc7vjTB9UoebowqUayoAkAMuM6F5NWxLf36SKcb75ChHGH3UBz8l0/pQwIuOf/zIJOJ/BXiwOM93FZdQqUvpDU3lLygtQy/qhpesaytenmxcRgjC1+f+0Ou8rI2m+s1hRq5S3rQDkzxxNHgcMYnh3pbGuI= 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 1783678646709209.87223237031606; Fri, 10 Jul 2026 03:17:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8Gy-0006nM-0T; Fri, 10 Jul 2026 06:15: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 1wi8Gw-0006nC-8g for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:15:54 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8Gu-0006GI-5K for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:15:53 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 5FFFE20B716E; Fri, 10 Jul 2026 03:15:42 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 5FFFE20B716E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678544; bh=bUs7HPt9XlYcvGqXEMDKsjAZZdQrDSmsL1ZEYxoLPqU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=snZpkhoGDgPiAkd6rGHp6qqTV4+zec+rRJE++PJlgS13E0HnrtChWuj3dH1XjsPWA gd71bcliS/pGzAUSh6WgTzDVnGBPYXsKIJH2UeZP1QyoYdtH/x015foGBNT5KPZjCB FzrrP4HNF3qCN+Lv0c4dCANqxKXHH2xW+YBdm56s= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 03/12] hw/i386/mshv: migrate REFERENCE_TIME Date: Fri, 10 Jul 2026 12:15:25 +0200 Message-Id: <20260710101534.664604-4-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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: 1783678648579158500 This is a partition-wide state for which we use a dedicated hw clock facility, similar to KVM. We have to freeze the time for a partition before we are allowed to set it. We register a state change handler for the clock device and a post-load handler for migration state. In the post-load handler we toggle a flag that will set the reference time state on next state to "running" on the partition. We can move the time freeze and reference-time ioctls/hvcalls to the clock module. Signed-off-by: Magnus Kulke --- MAINTAINERS | 1 + accel/mshv/mshv-all.c | 67 ++------------ accel/mshv/trace-events | 1 + hw/i386/meson.build | 1 + hw/i386/mshv/clock.c | 189 +++++++++++++++++++++++++++++++++++++++ hw/i386/mshv/meson.build | 4 + include/system/mshv.h | 3 + 7 files changed, 208 insertions(+), 58 deletions(-) create mode 100644 hw/i386/mshv/clock.c create mode 100644 hw/i386/mshv/meson.build diff --git a/MAINTAINERS b/MAINTAINERS index 6171cc7494..269876db3e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -613,6 +613,7 @@ R: Wei Liu R: Doru Bl=C3=A2nzeanu S: Supported F: target/i386/mshv/ +F: hw/i386/mshv/ =20 X86 Instruction Emulator M: Roman Bolshakov diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index b34fb34d05..7b3c13cf1e 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -60,54 +60,6 @@ static int init_mshv(int *mshv_fd) return 0; } =20 -/* freeze 1 to pause, 0 to resume */ -static int set_time_freeze(int vm_fd, int freeze) -{ - int ret; - struct hv_input_set_partition_property in =3D {0}; - in.property_code =3D HV_PARTITION_PROPERTY_TIME_FREEZE; - in.property_value =3D freeze; - - struct mshv_root_hvcall args =3D {0}; - args.code =3D HVCALL_SET_PARTITION_PROPERTY; - args.in_sz =3D sizeof(in); - args.in_ptr =3D (uint64_t)∈ - - ret =3D mshv_hvcall(vm_fd, &args); - if (ret < 0) { - error_report("Failed to set time freeze"); - return -1; - } - - return 0; -} - -static int pause_vm(int vm_fd) -{ - int ret; - - ret =3D set_time_freeze(vm_fd, 1); - if (ret < 0) { - error_report("Failed to pause partition: %s", strerror(errno)); - return -1; - } - - return 0; -} - -static int resume_vm(int vm_fd) -{ - int ret; - - ret =3D set_time_freeze(vm_fd, 0); - if (ret < 0) { - error_report("Failed to resume partition: %s", strerror(errno)); - return -1; - } - - return 0; -} - static int get_host_partition_property(int mshv_fd, uint32_t property_code, uint64_t *value) { @@ -330,9 +282,6 @@ static int create_vm(int mshv_fd, int *vm_fd) return -1; } =20 - /* Always create a frozen partition */ - pause_vm(*vm_fd); - return 0; } =20 @@ -578,13 +527,6 @@ static int mshv_init(AccelState *as, MachineState *ms) return -1; } =20 - ret =3D resume_vm(vm_fd); - if (ret < 0) { - close(mshv_fd); - close(vm_fd); - return -1; - } - s->vm =3D vm_fd; s->fd =3D mshv_fd; =20 @@ -606,6 +548,8 @@ static int mshv_init(AccelState *as, MachineState *ms) =20 register_savevm_live("mshv", 0, 1, &savevm_mshv, s); =20 + mshv_clock_init(); + return 0; } =20 @@ -643,6 +587,13 @@ static int mshv_cpu_exec(CPUState *cpu) cpu->vcpu_dirty =3D false; } =20 + /* Corresponding store-release is in cpu_exit. */ + if (qatomic_load_acquire(&cpu->exit_request)) { + trace_mshv_interrupt_exit_request(cpu->cpu_index); + ret =3D EXCP_INTERRUPT; + break; + } + ret =3D mshv_run_vcpu(mshv_state->vm, cpu, &mshv_msg, &exit_reason= ); if (ret < 0) { error_report("Failed to run on vcpu %d", cpu->cpu_index); diff --git a/accel/mshv/trace-events b/accel/mshv/trace-events index a4dffeb24a..859e8bfb0f 100644 --- a/accel/mshv/trace-events +++ b/accel/mshv/trace-events @@ -4,6 +4,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later =20 mshv_start_vcpu_thread(const char* thread, uint32_t cpu) "thread=3D%s cpu_= index=3D%d" +mshv_interrupt_exit_request(uint32_t cpu) "cpu_index=3D%d" =20 mshv_set_memory(bool add, uint64_t gpa, uint64_t size, uint64_t user_addr,= bool readonly, int ret) "add=3D%d gpa=3D0x%" PRIx64 " size=3D0x%" PRIx64 "= user=3D0x%" PRIx64 " readonly=3D%d result=3D%d" mshv_mem_ioeventfd_add(uint64_t addr, uint32_t size, uint32_t data) "addr= =3D0x%" PRIx64 " size=3D%d data=3D0x%x" diff --git a/hw/i386/meson.build b/hw/i386/meson.build index b611fbb5a7..f4d3122863 100644 --- a/hw/i386/meson.build +++ b/hw/i386/meson.build @@ -39,6 +39,7 @@ i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c', = 'tdvf-hob.c')) =20 subdir('kvm') subdir('xen') +subdir('mshv') =20 i386_ss.add_all(xenpv_ss) =20 diff --git a/hw/i386/mshv/clock.c b/hw/i386/mshv/clock.c new file mode 100644 index 0000000000..02c586503a --- /dev/null +++ b/hw/i386/mshv/clock.c @@ -0,0 +1,189 @@ +/* + * MSHV partition reference clock + * + * Copyright Microsoft, Corp. 2026 + * + * Authors: Magnus Kulke + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "migration/vmstate.h" +#include "system/runstate.h" +#include "hw/hyperv/hvhdk.h" +#include "hw/hyperv/hvhdk_mini.h" +#include "hw/hyperv/hvgdk.h" +#include "hw/hyperv/hvgdk_mini.h" +#include "linux/mshv.h" +#include "system/mshv.h" +#include "system/mshv_int.h" + +/* + * Partition reference clock (HV_PARTITION_PROPERTY_REFERENCE_TIME), captu= red + * when the VM is stopped and re-applied when it resumes. + * + * Mirrors hw/i386/kvm/clock.c. + */ +typedef struct MshvClockState { + uint64_t ref_time; + bool ref_time_pending; +} MshvClockState; + +static MshvClockState mshv_clock; + +static int mshv_get_reference_time(int vm_fd, uint64_t *ref_time) +{ + struct hv_input_get_partition_property in =3D { 0 }; + struct hv_output_get_partition_property out =3D { 0 }; + struct mshv_root_hvcall args =3D { 0 }; + int ret; + + in.property_code =3D HV_PARTITION_PROPERTY_REFERENCE_TIME; + + args.code =3D HVCALL_GET_PARTITION_PROPERTY; + args.in_sz =3D sizeof(in); + args.in_ptr =3D (uint64_t)∈ + args.out_sz =3D sizeof(out); + args.out_ptr =3D (uint64_t)&out; + + ret =3D mshv_hvcall(vm_fd, &args); + if (ret < 0) { + error_report("Failed to get reference time"); + return -1; + } + + *ref_time =3D out.property_value; + return 0; +} + +static int mshv_set_reference_time(int vm_fd, uint64_t ref_time) +{ + struct hv_input_set_partition_property in =3D { 0 }; + struct mshv_root_hvcall args =3D { 0 }; + int ret; + + in.property_code =3D HV_PARTITION_PROPERTY_REFERENCE_TIME; + in.property_value =3D ref_time; + + args.code =3D HVCALL_SET_PARTITION_PROPERTY; + args.in_sz =3D sizeof(in); + args.in_ptr =3D (uint64_t)∈ + + ret =3D mshv_hvcall(vm_fd, &args); + if (ret < 0) { + error_report("Failed to set reference time"); + return -1; + } + + return 0; +} + +/* + * Freeze (freeze=3D1) or unfreeze (freeze=3D0) time for a partition. This= will not + * pause/eject vCPU execution. It is assumed that the caller already has s= topped + * the partition's vCPUs. + * + * NB: a partition's reference clock can only be written while the time is + * frozen. + */ +static int mshv_set_time_freeze(int vm_fd, int freeze) +{ + struct hv_input_set_partition_property in =3D { 0 }; + struct mshv_root_hvcall args =3D { 0 }; + int ret; + + in.property_code =3D HV_PARTITION_PROPERTY_TIME_FREEZE; + in.property_value =3D freeze; + + args.code =3D HVCALL_SET_PARTITION_PROPERTY; + args.in_sz =3D sizeof(in); + args.in_ptr =3D (uint64_t)∈ + + ret =3D mshv_hvcall(vm_fd, &args); + if (ret < 0) { + error_report("Failed to set time freeze"); + return -1; + } + + return 0; +} + +static void mshv_clock_vm_state_change(void *opaque, bool running, + RunState state) +{ + MshvClockState *s =3D opaque; + int vm_fd =3D mshv_state->vm; + int ret; + + if (running) { + /* Skip if we have nothing to restore, e.g. on initial boot. */ + if (!s->ref_time_pending) { + return; + } + + ret =3D mshv_set_time_freeze(vm_fd, 1); + if (ret < 0) { + error_report("Failed to freeze partition time on resume"); + abort(); + } + + /* INVARIANT: reference time can only be written if time is frozen= . */ + ret =3D mshv_set_reference_time(vm_fd, s->ref_time); + if (ret < 0) { + error_report("Failed to restore reference time on resume"); + abort(); + } + + if (mshv_set_time_freeze(vm_fd, 0) < 0) { + error_report("Failed to unfreeze partition time on resume"); + abort(); + } + + s->ref_time_pending =3D false; + } else { + /* Skip if we already have a to-be-set ref time */ + if (s->ref_time_pending) { + return; + } + + ret =3D mshv_get_reference_time(vm_fd, &s->ref_time); + if (ret < 0) { + error_report("Failed to capture reference time on stop"); + abort(); + } + + s->ref_time_pending =3D true; + } +} + +/* + * The incoming reference time should be applied on the next resume before + * vCPUs start executing. + */ +static int mshv_clock_post_load(void *opaque, int version_id) +{ + MshvClockState *s =3D opaque; + + s->ref_time_pending =3D true; + + return 0; +} + +static const VMStateDescription vmstate_mshv_clock =3D { + .name =3D "mshv-clock", + .version_id =3D 1, + .minimum_version_id =3D 1, + .post_load =3D mshv_clock_post_load, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT64(ref_time, MshvClockState), + VMSTATE_END_OF_LIST() + }, +}; + +void mshv_clock_init(void) +{ + vmstate_register(NULL, 0, &vmstate_mshv_clock, &mshv_clock); + qemu_add_vm_change_state_handler(mshv_clock_vm_state_change, &mshv_clo= ck); +} diff --git a/hw/i386/mshv/meson.build b/hw/i386/mshv/meson.build new file mode 100644 index 0000000000..0e556851b6 --- /dev/null +++ b/hw/i386/mshv/meson.build @@ -0,0 +1,4 @@ +i386_mshv_ss =3D ss.source_set() +i386_mshv_ss.add(files('clock.c')) + +i386_ss.add_all(when: 'CONFIG_MSHV', if_true: i386_mshv_ss) diff --git a/include/system/mshv.h b/include/system/mshv.h index 46fe3fcebc..a6f815b822 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -55,6 +55,9 @@ DECLARE_INSTANCE_CHECKER(MshvState, MSHV_STATE, =20 extern MshvState *mshv_state; =20 +/* clock (partition reference time) */ +void mshv_clock_init(void); + /* interrupt */ int mshv_request_interrupt(MshvState *mshv_state, uint32_t interrupt_type,= uint32_t vector, uint32_t vp_index, bool logical_destination_mod= e, --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678592; cv=none; d=zohomail.com; s=zohoarc; b=jdHfesq+21VF726b5/BN4r6BHDEyonoYxPrrZQkVElC5UKmZ06RP0PVIpn3iBaLOyqtAtCrS+KOsh0fFF5XmQZ2vWHLE+aoc13RD/1oktnwU5edQl5r+7Uq9NeY8yPt5MnaHjn1eBMjmZVWwFfIZUoZp+CX06gqAxLR6xTKzyFk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678592; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Jn8tM3gPqJHIZqmfAJS0m6WTLE5cquacWSQOkwm6lnU=; b=awo32N0vCMEA4EtA7orqx9YRLml/VClFNHDz4ebo70vmjA2GwlRVkLOzG3n3BaCVlFEcRDftbh7/InHXHvyJAGZE+MrE/Rm0aAbCGHtVW/iPkOiQg9OeYdSGv/3bq01ceK8VGwa8ObQ37kOFGBkT2cy/SG3kZwP9shvrDG6Jn0Y= 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 1783678591996789.1672369750688; Fri, 10 Jul 2026 03:16:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8H0-0006o4-Af; Fri, 10 Jul 2026 06:15:58 -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 1wi8Gz-0006nb-1h for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:15:57 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8Gx-0006HL-JJ for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:15:56 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 1166D20B716F; Fri, 10 Jul 2026 03:15:45 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 1166D20B716F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678548; bh=Jn8tM3gPqJHIZqmfAJS0m6WTLE5cquacWSQOkwm6lnU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DEJeoAuZhu7Ko6udy9jxkmlDqaexPi4mZgnuIu4DRU55zpnMD4IK8XEfOwOZNYPdV nf/LnMWJkSSHEO6hl97rmUsIRDqGauN1nHHHR08Fr/EsNKLDarY4+bgloiMUpInJdE qYCP3TI+AGJ1In7moVF3fEeudpgE/E8K0Zr8J/bQ= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 04/12] accel/mshv: install dummy handler for SIG_IPI Date: Fri, 10 Jul 2026 12:15:26 +0200 Message-Id: <20260710101534.664604-5-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678594657158500 Content-Type: text/plain; charset="utf-8" This is similar to HVF's implementation. We want to interrupt the blocking vcpu run. The self-kick was effectively a no-op for mshv. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 7b3c13cf1e..f9511ca050 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -621,17 +621,13 @@ 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. + * We need a dummy handler to make SIG_IPI a deliverable signal. The kernel + * handler will be woken up by the caught signal and instruct the hypervis= or + * to suspend execution (the concrete mechanism differs between schedulers) + * and return to userspace. */ -static void sa_ipi_handler(int sig) +static void dummy_handler(int sig) { - /* TODO: call IOCTL to set_immediate_exit, once implemented. */ - - qemu_cpu_kick_self(); } =20 static void init_signal(CPUState *cpu) @@ -641,7 +637,7 @@ static void init_signal(CPUState *cpu) sigset_t set; =20 memset(&sigact, 0, sizeof(sigact)); - sigact.sa_handler =3D sa_ipi_handler; + sigact.sa_handler =3D dummy_handler; sigaction(SIG_IPI, &sigact, NULL); =20 pthread_sigmask(SIG_BLOCK, NULL, &set); --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678594; cv=none; d=zohomail.com; s=zohoarc; b=jYokzbCO3wkhAZWKrpEQGzKOrzszxqkvGmkk3mWSeI2zTb2dU9jCIvSfcJz9uuPqOXTgwzRtPE7LL8ejhNKVuI+A4F9c2E6o35aM4sYeg64n68/LiO4mamRDndn7hWttVgXsKLAJtXFLvNLb7PMNtDapJv0epc7qnDsGad0wgz4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678594; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=s7V0NCZqj0OjLLDBBnnXZ+1izDUcY4K/I3lL9/ymNcg=; b=GRqWvBp0alz7sNVKuDtBKMuo9HJH6a7VuNKPib+3J7a/HHodz0uDP5iGryk8T6nxFkYveUfwEnvy8tD6Y0e0owU3dSd/LsK7Q2KUde8KUD9RMUJpByiFiVcEH4G70Fw6X7TC5Xa4r2S0Hmh9TxQHggRMDAV4QQ44xLB5iuFy5jE= 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 1783678594305866.1388132428305; Fri, 10 Jul 2026 03:16:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8H7-0006oR-Nu; Fri, 10 Jul 2026 06:16:06 -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 1wi8H4-0006o5-KT for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:02 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8H1-0006LG-JJ for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:02 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 43A9820B716E; Fri, 10 Jul 2026 03:15:49 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 43A9820B716E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678552; bh=s7V0NCZqj0OjLLDBBnnXZ+1izDUcY4K/I3lL9/ymNcg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rJpaMfPB6SjtSxTIeFi/R6Wx7LD9XrDwWo5icV+HpSHVQK8DoOxI4OAT4CY/STctD ynbslsxLblmSQTPqZnmmb+P43Swvz0sfozm7dKzpxSQuheJvsGI5SRTrSopkB2KUkh 4i8rk2vRx7s8CTifWC8bMW+X53xUXodk+7NW9Z7c= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 05/12] target/i386/mshv: migrate LAPIC state Date: Fri, 10 Jul 2026 12:15:27 +0200 Message-Id: <20260710101534.664604-6-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678596234158500 Content-Type: text/plain; charset="utf-8" This change implements loading and storing the hyperv lapic state as part of the load/store routines for a vcpu. The HyperV LAPIC is similar to the the split-irqchip in KVM. MSHV currently keeps PIC/IOAPIC emulation in userspace, while LAPIC interrupt injection is handled through hypercalls. We introduced dedicated apic infra in hw/i386/mshv to handle the migration and move lapic related functions from target/i386/mshv there. References have been the WHPX's whpx-apic implemenation and the mshv-ioctls crate's get_/set_lapic() impl for the mapping between MSHV/QEMU lapic state. We are mapping the lapic state that we receive from the hypervisor to fields in APICCommonState. Common fields are used where feasible, with an mshv-specific MshvAPICState object that carries mshv-specific fields. We have introduced a guard in pic_irq_request() that will early exit for the mshv accelerator, because mshv cannot take part in the userland path for legacy PIC interrupt injection. The TSC_DEADLINE MSR is also migrated as part of LAPIC migration. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 1 + hw/i386/meson.build | 2 +- hw/i386/mshv/apic.c | 395 +++++++++++++++++++++++++++++++++ hw/i386/mshv/meson.build | 1 + hw/i386/x86-cpu.c | 6 + include/hw/hyperv/hvgdk_mini.h | 2 + include/hw/i386/apic-msidef.h | 1 + include/system/mshv.h | 2 + include/system/mshv_int.h | 8 +- target/i386/cpu-apic.c | 3 + target/i386/mshv/mshv-cpu.c | 151 ++++--------- target/i386/mshv/msr.c | 2 + 12 files changed, 460 insertions(+), 114 deletions(-) create mode 100644 hw/i386/mshv/apic.c diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index f9511ca050..1516475f34 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -813,6 +813,7 @@ static void mshv_accel_ops_class_init(ObjectClass *oc, = const void *data) ops->synchronize_state =3D mshv_cpu_synchronize; ops->synchronize_pre_loadvm =3D mshv_cpu_synchronize_pre_loadvm; ops->cpus_are_resettable =3D mshv_cpus_are_resettable; + ops->cpu_thread_is_idle =3D mshv_vcpu_thread_is_idle; ops->handle_interrupt =3D generic_handle_interrupt; } =20 diff --git a/hw/i386/meson.build b/hw/i386/meson.build index f4d3122863..39ac8c9edc 100644 --- a/hw/i386/meson.build +++ b/hw/i386/meson.build @@ -38,8 +38,8 @@ i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('p= c_sysfw_ovmf.c'), i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c', 'tdvf-hob.c')) =20 subdir('kvm') -subdir('xen') subdir('mshv') +subdir('xen') =20 i386_ss.add_all(xenpv_ss) =20 diff --git a/hw/i386/mshv/apic.c b/hw/i386/mshv/apic.c new file mode 100644 index 0000000000..9188a93b2f --- /dev/null +++ b/hw/i386/mshv/apic.c @@ -0,0 +1,395 @@ +/* + * MSHV in-kernel APIC support + * + * Copyright Microsoft, Corp. 2026 + * + * Authors: Magnus Kulke + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/module.h" +#include "qemu/memalign.h" +#include "qemu/error-report.h" +#include "hw/i386/apic_internal.h" +#include "hw/i386/apic-msidef.h" +#include "hw/pci/msi.h" +#include "migration/vmstate.h" +#include "qemu/typedefs.h" +#include "system/hw_accel.h" +#include "system/mshv.h" +#include "system/mshv_int.h" + +typedef struct hv_local_interrupt_controller_state + hv_local_interrupt_controller_state; + +#define TYPE_MSHV_APIC "mshv-apic" +OBJECT_DECLARE_SIMPLE_TYPE(MshvAPICState, MSHV_APIC) + +struct MshvAPICState { + APICCommonState parent_obj; + + uint32_t apic_version; + uint32_t apic_lvt_cmci; + uint32_t apic_error_status; + uint32_t apic_counter_value; + uint32_t apic_remote_read; +}; + +static int get_lapic(int cpu_fd, + struct hv_local_interrupt_controller_state *state) +{ + int ret; + size_t size =3D 4096; + /* buffer aligned to 4k, as *state requires that */ + void *buffer =3D qemu_memalign(size, size); + struct mshv_get_set_vp_state mshv_state =3D { 0 }; + + mshv_state.buf_ptr =3D (uint64_t) buffer; + mshv_state.buf_sz =3D size; + mshv_state.type =3D MSHV_VP_STATE_LAPIC; + + ret =3D mshv_get_vp_state(cpu_fd, &mshv_state); + if (ret =3D=3D 0) { + memcpy(state, buffer, sizeof(*state)); + } + qemu_vfree(buffer); + if (ret < 0) { + error_report("failed to get lapic"); + return -1; + } + + return 0; +} + +static int set_lapic(int cpu_fd, + const struct hv_local_interrupt_controller_state *sta= te) +{ + int ret; + size_t size =3D 4096; + /* buffer aligned to 4k, as *state requires that */ + void *buffer =3D qemu_memalign(size, size); + struct mshv_get_set_vp_state mshv_state =3D { 0 }; + + if (!state) { + error_report("lapic state is NULL"); + return -1; + } + memcpy(buffer, state, sizeof(*state)); + + mshv_state.buf_ptr =3D (uint64_t) buffer; + mshv_state.buf_sz =3D size; + mshv_state.type =3D MSHV_VP_STATE_LAPIC; + + ret =3D mshv_set_vp_state(cpu_fd, &mshv_state); + qemu_vfree(buffer); + if (ret < 0) { + error_report("failed to set lapic: %s", strerror(errno)); + return -1; + } + + return 0; +} + +static void populate_apic_state(CPUState *cpu, + const hv_local_interrupt_controller_state = *hv) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + MshvAPICState *ms =3D MSHV_APIC(x86cpu->apic_state); + APICCommonState *s =3D &ms->parent_obj; + size_t i; + + /* + * x2APIC: + * - APIC ID is the full 32-bit initial_apic_id + * - LDR is read-only, architecturally derived from the ID + * - DFR does not exist in x2APIC mode + */ + if (is_x2apic_mode(s)) { + s->initial_apic_id =3D hv->apic_id; + } else { + s->id =3D hv->apic_id >> 24; + s->log_dest =3D hv->apic_ldr >> 24; + s->dest_mode =3D hv->apic_dfr >> 28; + } + ms->apic_version =3D hv->apic_version; + s->spurious_vec =3D hv->apic_spurious; + for (i =3D 0; i < 8; i++) { + s->isr[i] =3D hv->apic_isr[i]; + s->tmr[i] =3D hv->apic_tmr[i]; + s->irr[i] =3D hv->apic_irr[i]; + } + s->esr =3D hv->apic_esr; + s->icr[1] =3D hv->apic_icr_high; + s->icr[0] =3D hv->apic_icr_low; + + s->lvt[APIC_LVT_TIMER] =3D hv->apic_lvt_timer; + s->lvt[APIC_LVT_THERMAL] =3D hv->apic_lvt_thermal; + s->lvt[APIC_LVT_PERFORM] =3D hv->apic_lvt_perfmon; + s->lvt[APIC_LVT_LINT0] =3D hv->apic_lvt_lint0; + s->lvt[APIC_LVT_LINT1] =3D hv->apic_lvt_lint1; + s->lvt[APIC_LVT_ERROR] =3D hv->apic_lvt_error; + ms->apic_lvt_cmci =3D hv->apic_lvt_cmci; + + ms->apic_error_status =3D hv->apic_error_status; + s->initial_count =3D hv->apic_initial_count; + ms->apic_counter_value =3D hv->apic_counter_value; + s->divide_conf =3D hv->apic_divide_configuration; + ms->apic_remote_read =3D hv->apic_remote_read; +} + +static uint32_t set_apic_delivery_mode(uint32_t reg, uint32_t mode) +{ + return ((reg) & ~0x700) | ((mode) << 8); +} + +int mshv_init_lint(CPUState *cpu) +{ + uint32_t *lvt_lint0, *lvt_lint1; + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; + + ret =3D get_lapic(cpu_fd, &lapic_state); + if (ret < 0) { + return ret; + } + + lvt_lint0 =3D &lapic_state.apic_lvt_lint0; + *lvt_lint0 =3D set_apic_delivery_mode(*lvt_lint0, APIC_DM_EXTINT); + + lvt_lint1 =3D &lapic_state.apic_lvt_lint1; + *lvt_lint1 =3D set_apic_delivery_mode(*lvt_lint1, APIC_DM_NMI); + + /* TODO: should we skip setting lapic if the values are the same? */ + + ret =3D set_lapic(cpu_fd, &lapic_state); + if (ret < 0) { + return -1; + } + + populate_apic_state(cpu, &lapic_state); + + return 0; +} + +static void populate_hv_lapic_state(hv_local_interrupt_controller_state *h= v, + const CPUState *cpu) +{ + uint32_t x2apic_id; + X86CPU *x86cpu =3D X86_CPU(cpu); + MshvAPICState *ms =3D MSHV_APIC(x86cpu->apic_state); + APICCommonState *s =3D &ms->parent_obj; + size_t i; + + /* + * x2APIC: + * - APIC ID is the full 32-bit initial_apic_id + * - LDR is read-only, architecturally derived from the ID + * - DFR does not exist in x2APIC mode + */ + if (is_x2apic_mode(s)) { + x2apic_id =3D s->initial_apic_id; + + hv->apic_id =3D x2apic_id; + hv->apic_ldr =3D ((x2apic_id >> 4) << 16) | (1 << (x2apic_id & 0xf= )); + hv->apic_dfr =3D 0; + } else { + hv->apic_id =3D s->id << 24; + hv->apic_ldr =3D s->log_dest << 24; + hv->apic_dfr =3D s->dest_mode << 28 | 0x0fffffff; + } + hv->apic_version =3D ms->apic_version; + hv->apic_spurious =3D s->spurious_vec; + for (i =3D 0; i < 8; i++) { + hv->apic_isr[i] =3D s->isr[i]; + hv->apic_tmr[i] =3D s->tmr[i]; + hv->apic_irr[i] =3D s->irr[i]; + } + hv->apic_esr =3D s->esr; + hv->apic_icr_high =3D s->icr[1]; + hv->apic_icr_low =3D s->icr[0]; + + hv->apic_lvt_timer =3D s->lvt[APIC_LVT_TIMER]; + hv->apic_lvt_thermal =3D s->lvt[APIC_LVT_THERMAL]; + hv->apic_lvt_perfmon =3D s->lvt[APIC_LVT_PERFORM]; + hv->apic_lvt_lint0 =3D s->lvt[APIC_LVT_LINT0]; + hv->apic_lvt_lint1 =3D s->lvt[APIC_LVT_LINT1]; + hv->apic_lvt_error =3D s->lvt[APIC_LVT_ERROR]; + hv->apic_lvt_cmci =3D ms->apic_lvt_cmci; + + hv->apic_error_status =3D ms->apic_error_status; + hv->apic_initial_count =3D s->initial_count; + hv->apic_counter_value =3D ms->apic_counter_value; + hv->apic_divide_configuration =3D s->divide_conf; + hv->apic_remote_read =3D ms->apic_remote_read; +} + +int mshv_set_lapic(const CPUState *cpu) +{ + int cpu_fd =3D mshv_vcpufd(cpu); + struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; + + populate_hv_lapic_state(&lapic_state, cpu); + + return set_lapic(cpu_fd, &lapic_state); +} + +int mshv_get_lapic(CPUState *cpu) +{ + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; + + ret =3D get_lapic(cpu_fd, &lapic_state); + if (ret < 0) { + return -1; + } + + populate_apic_state(cpu, &lapic_state); + + return 0; +} + +static int mshv_apic_set_base(APICCommonState *s, uint64_t val) +{ + s->apicbase =3D val; + + return 0; +} + +static void mshv_apic_set_tpr(APICCommonState *s, uint8_t val) +{ + s->tpr =3D (val & APIC_PR_SUB_CLASS) << APIC_PR_CLASS_SHIFT; +} + +static uint8_t mshv_apic_get_tpr(APICCommonState *s) +{ + return s->tpr >> APIC_PR_CLASS_SHIFT; +} + +static void mshv_apic_external_nmi(APICCommonState *s) +{ +} + +static void mshv_apic_vapic_base_update(APICCommonState *s) +{ +} + +static void mshv_send_msi(MSIMessage *msi) +{ + uint64_t addr; + uint32_t data, dest; + uint8_t vector, dest_mode, trigger_mode, delivery; + + addr =3D msi->address; + data =3D msi->data; + dest =3D (addr & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SH= IFT | + (addr >> 32); + vector =3D (data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIF= T; + dest_mode =3D (addr >> MSI_ADDR_DEST_MODE_SHIFT) & 0x1; + trigger_mode =3D (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1; + delivery =3D (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & + MSI_DATA_DELIVERY_MODE_MASK; + + mshv_request_interrupt(mshv_state, delivery, vector, dest, dest_mode, + trigger_mode); +} + +static uint64_t mshv_apic_mem_read(void *opaque, hwaddr addr, + unsigned size) +{ + return UINT64_MAX; +} + +static void mshv_apic_mem_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + MSIMessage msg =3D { .address =3D addr, .data =3D data }; + + mshv_send_msi(&msg); +} + +static const MemoryRegionOps mshv_apic_io_ops =3D { + .read =3D mshv_apic_mem_read, + .write =3D mshv_apic_mem_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, +}; + +static void mshv_apic_reset(APICCommonState *s) +{ + s->wait_for_sipi =3D 0; +} + +static const VMStateDescription vmstate_mshv_apic =3D { + .name =3D "mshv-apic", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(apic_version, MshvAPICState), + VMSTATE_UINT32(apic_lvt_cmci, MshvAPICState), + VMSTATE_UINT32(apic_error_status, MshvAPICState), + VMSTATE_UINT32(apic_counter_value, MshvAPICState), + VMSTATE_UINT32(apic_remote_read, MshvAPICState), + VMSTATE_END_OF_LIST() + } +}; + +static void mshv_apic_realize(DeviceState *dev, Error **errp) +{ + APICCommonState *s =3D APIC_COMMON(dev); + MshvAPICState *ms =3D MSHV_APIC(dev); + + memory_region_init_io(&s->io_memory, OBJECT(s), &mshv_apic_io_ops, s, + "mshv-apic-msi", APIC_SPACE_SIZE); + + msi_nonbroken =3D true; + + /* + * We register this state explicity, rather than going via dc->vmsd. + * The auto-wiring would register the state with + * instance_id =3D=3D VMSTATE_INSTANCE_ID_ANY, which for the APIC does= n't + * work, b/c the ID carries semantic meaning for restoring the state + * on the destination (which vcpu it belongs to). + */ + vmstate_register_with_alias_id(NULL, + s->initial_apic_id, &vmstate_mshv_apic,= ms, + -1, 0, NULL); +} + +static void mshv_apic_unrealize(DeviceState *dev) +{ + MshvAPICState *ms =3D MSHV_APIC(dev); + + vmstate_unregister(NULL, &vmstate_mshv_apic, ms); +} + +static void mshv_apic_class_init(ObjectClass *klass, const void *data) +{ + APICCommonClass *k =3D APIC_COMMON_CLASS(klass); + + k->realize =3D mshv_apic_realize; + k->unrealize =3D mshv_apic_unrealize; + k->reset =3D mshv_apic_reset; + k->set_base =3D mshv_apic_set_base; + k->set_tpr =3D mshv_apic_set_tpr; + k->get_tpr =3D mshv_apic_get_tpr; + k->external_nmi =3D mshv_apic_external_nmi; + k->vapic_base_update =3D mshv_apic_vapic_base_update; + k->send_msi =3D mshv_send_msi; +} + +static const TypeInfo mshv_apic_info =3D { + .name =3D TYPE_MSHV_APIC, + .parent =3D TYPE_APIC_COMMON, + .instance_size =3D sizeof(MshvAPICState), + .class_init =3D mshv_apic_class_init, +}; + +static void mshv_apic_register_types(void) +{ + type_register_static(&mshv_apic_info); +} + +type_init(mshv_apic_register_types) diff --git a/hw/i386/mshv/meson.build b/hw/i386/mshv/meson.build index 0e556851b6..c631ee1302 100644 --- a/hw/i386/mshv/meson.build +++ b/hw/i386/mshv/meson.build @@ -1,4 +1,5 @@ i386_mshv_ss =3D ss.source_set() i386_mshv_ss.add(files('clock.c')) +i386_mshv_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c')) =20 i386_ss.add_all(when: 'CONFIG_MSHV', if_true: i386_mshv_ss) diff --git a/hw/i386/x86-cpu.c b/hw/i386/x86-cpu.c index 95e08e3c2a..fba313376c 100644 --- a/hw/i386/x86-cpu.c +++ b/hw/i386/x86-cpu.c @@ -22,6 +22,7 @@ */ #include "qemu/osdep.h" #include "system/whpx.h" +#include "system/mshv.h" #include "system/cpu-timers.h" #include "trace.h" =20 @@ -44,6 +45,11 @@ static void pic_irq_request(void *opaque, int irq, int l= evel) X86CPU *cpu =3D X86_CPU(cs); =20 trace_x86_pic_interrupt(irq, level); + + if (mshv_irqchip_in_kernel()) { + return; + } + if (cpu_is_apic_enabled(cpu->apic_state) && !kvm_irqchip_in_kernel() && !whpx_irqchip_in_kernel()) { CPU_FOREACH(cs) { diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h index f8838a31bb..0602a7c6cc 100644 --- a/include/hw/hyperv/hvgdk_mini.h +++ b/include/hw/hyperv/hvgdk_mini.h @@ -168,6 +168,7 @@ typedef enum hv_register_name { /* Available */ =20 HV_X64_REGISTER_SPEC_CTRL =3D 0x00080084, + HV_X64_REGISTER_TSC_DEADLINE =3D 0x00080095, HV_X64_REGISTER_TSC_ADJUST =3D 0x00080096, =20 /* CET / Shadow Stack */ @@ -930,6 +931,7 @@ struct hv_cpuid { #define IA32_MSR_DEBUG_CTL 0x1D9 #define IA32_MSR_SPEC_CTRL 0x00000048 #define IA32_MSR_TSC_ADJUST 0x0000003b +#define IA32_MSR_TSC_DEADLINE 0x000006e0 =20 #define IA32_MSR_MISC_ENABLE 0x000001a0 =20 diff --git a/include/hw/i386/apic-msidef.h b/include/hw/i386/apic-msidef.h index 420b41167d..6b860b5807 100644 --- a/include/hw/i386/apic-msidef.h +++ b/include/hw/i386/apic-msidef.h @@ -13,6 +13,7 @@ #define MSI_DATA_VECTOR_MASK 0x000000ff =20 #define MSI_DATA_DELIVERY_MODE_SHIFT 8 +#define MSI_DATA_DELIVERY_MODE_MASK 7 #define MSI_DATA_LEVEL_SHIFT 14 #define MSI_DATA_TRIGGER_SHIFT 15 =20 diff --git a/include/system/mshv.h b/include/system/mshv.h index a6f815b822..f98ddff9b5 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -41,9 +41,11 @@ extern bool mshv_allowed; #define mshv_enabled() (mshv_allowed) #define mshv_msi_via_irqfd_enabled() mshv_enabled() +#define mshv_irqchip_in_kernel() mshv_enabled() #else /* CONFIG_MSHV_IS_POSSIBLE */ #define mshv_enabled() false #define mshv_msi_via_irqfd_enabled() mshv_enabled() +#define mshv_irqchip_in_kernel() mshv_enabled() #endif =20 #define TYPE_MSHV_ACCEL ACCEL_CLASS_NAME("mshv") diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index b91c4d661a..c2f13c0194 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -105,10 +105,16 @@ void mshv_arch_amend_proc_features( void mshv_arch_disable_partition_proc_features( union hv_partition_processor_features *disabled_features); int mshv_arch_post_init_vm(int vm_fd); - +int mshv_get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state); +int mshv_set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *stat= e); typedef struct mshv_root_hvcall mshv_root_hvcall; int mshv_hvcall(int fd, const mshv_root_hvcall *args); =20 +/* apic */ +int mshv_init_lint(CPUState *cpu); +int mshv_set_lapic(const CPUState *cpu); +int mshv_get_lapic(CPUState *cpu); + /* memory */ typedef struct MshvMemoryRegion { uint64_t guest_phys_addr; diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c index 04b7257ad1..b4cf048a7c 100644 --- a/target/i386/cpu-apic.c +++ b/target/i386/cpu-apic.c @@ -14,6 +14,7 @@ #include "system/hw_accel.h" #include "system/kvm.h" #include "system/xen.h" +#include "system/mshv.h" #include "system/address-spaces.h" #include "hw/core/qdev-properties.h" #include "hw/i386/apic_internal.h" @@ -34,6 +35,8 @@ APICCommonClass *apic_get_class(Error **errp) apic_type =3D "xen-apic"; } else if (whpx_irqchip_in_kernel()) { apic_type =3D "whpx-apic"; + } else if (mshv_enabled()) { + apic_type =3D "mshv-apic"; } =20 return APIC_COMMON_CLASS(object_class_by_name(apic_type)); diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 8eca01a8fa..333ee35e72 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -21,7 +21,6 @@ #include "hw/hyperv/hvgdk.h" #include "hw/hyperv/hvgdk_mini.h" #include "hw/hyperv/hvhdk_mini.h" -#include "hw/i386/apic_internal.h" =20 #include "cpu.h" #include "host-cpu.h" @@ -955,6 +954,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D mshv_get_lapic(cpu); + if (ret < 0) { + return ret; + } + ret =3D mshv_get_msrs(cpu); if (ret < 0) { return ret; @@ -1377,116 +1381,6 @@ static int set_xc_reg(const CPUState *cpu) return 0; } =20 -static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state) -{ - int ret; - - ret =3D ioctl(cpu_fd, MSHV_GET_VP_STATE, state); - if (ret < 0) { - error_report("failed to get partition state: %s", strerror(errno)); - return -1; - } - - return 0; -} - -static int get_lapic(const CPUState *cpu, - struct hv_local_interrupt_controller_state *state) -{ - int ret; - size_t size =3D 4096; - /* buffer aligned to 4k, as *state requires that */ - void *buffer =3D qemu_memalign(size, size); - struct mshv_get_set_vp_state mshv_state =3D { 0 }; - int cpu_fd =3D mshv_vcpufd(cpu); - - mshv_state.buf_ptr =3D (uint64_t) buffer; - mshv_state.buf_sz =3D size; - mshv_state.type =3D MSHV_VP_STATE_LAPIC; - - ret =3D get_vp_state(cpu_fd, &mshv_state); - if (ret =3D=3D 0) { - memcpy(state, buffer, sizeof(*state)); - } - qemu_vfree(buffer); - if (ret < 0) { - error_report("failed to get lapic"); - return -1; - } - - return 0; -} - -static uint32_t set_apic_delivery_mode(uint32_t reg, uint32_t mode) -{ - return ((reg) & ~0x700) | ((mode) << 8); -} - -static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *st= ate) -{ - int ret; - - ret =3D ioctl(cpu_fd, MSHV_SET_VP_STATE, state); - if (ret < 0) { - error_report("failed to set partition state: %s", strerror(errno)); - return -1; - } - - return 0; -} - -static int set_lapic(const CPUState *cpu, - const struct hv_local_interrupt_controller_state *sta= te) -{ - int ret; - size_t size =3D 4096; - /* buffer aligned to 4k, as *state requires that */ - void *buffer =3D qemu_memalign(size, size); - struct mshv_get_set_vp_state mshv_state =3D { 0 }; - int cpu_fd =3D mshv_vcpufd(cpu); - - if (!state) { - error_report("lapic state is NULL"); - return -1; - } - memcpy(buffer, state, sizeof(*state)); - - mshv_state.buf_ptr =3D (uint64_t) buffer; - mshv_state.buf_sz =3D size; - mshv_state.type =3D MSHV_VP_STATE_LAPIC; - - ret =3D set_vp_state(cpu_fd, &mshv_state); - qemu_vfree(buffer); - if (ret < 0) { - error_report("failed to set lapic: %s", strerror(errno)); - return -1; - } - - return 0; -} - -static int init_lint(const CPUState *cpu) -{ - int ret; - uint32_t *lvt_lint0, *lvt_lint1; - - struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; - ret =3D get_lapic(cpu, &lapic_state); - if (ret < 0) { - return ret; - } - - lvt_lint0 =3D &lapic_state.apic_lvt_lint0; - *lvt_lint0 =3D set_apic_delivery_mode(*lvt_lint0, APIC_DM_EXTINT); - - lvt_lint1 =3D &lapic_state.apic_lvt_lint1; - *lvt_lint1 =3D set_apic_delivery_mode(*lvt_lint1, APIC_DM_NMI); - - /* TODO: should we skip setting lapic if the values are the same? */ - - return set_lapic(cpu, &lapic_state); -} - int mshv_arch_store_vcpu_state(const CPUState *cpu) { int ret; @@ -1511,6 +1405,12 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 + /* INVARIANT: special regs (APIC_BASE) must be restored before LAPIC */ + ret =3D mshv_set_lapic(cpu); + if (ret < 0) { + return ret; + } + ret =3D mshv_set_msrs(cpu); if (ret < 0) { return ret; @@ -2099,7 +1999,7 @@ void mshv_arch_init_vcpu(CPUState *cpu) ret =3D mshv_init_msrs(cpu); assert(ret =3D=3D 0); =20 - ret =3D init_lint(cpu); + ret =3D mshv_init_lint(cpu); assert(ret =3D=3D 0); } =20 @@ -2246,6 +2146,33 @@ static void mshv_cpu_xsave_init(void) } } =20 +int mshv_set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *stat= e) +{ + int ret; + + ret =3D ioctl(cpu_fd, MSHV_SET_VP_STATE, state); + if (ret < 0) { + error_report("failed to set partition state: %s", strerror(errno)); + return -1; + } + + return 0; +} + + +int mshv_get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state) +{ + int ret; + + ret =3D ioctl(cpu_fd, MSHV_GET_VP_STATE, state); + if (ret < 0) { + error_report("failed to get partition state: %s", strerror(errno)); + return -1; + } + + return 0; +} + static void mshv_cpu_instance_init(CPUState *cs) { X86CPU *cpu =3D X86_CPU(cs); diff --git a/target/i386/mshv/msr.c b/target/i386/mshv/msr.c index 8c220a9942..a5f639c3ca 100644 --- a/target/i386/mshv/msr.c +++ b/target/i386/mshv/msr.c @@ -60,6 +60,8 @@ static const MshvMsrEnvMap msr_env_map[] =3D { offsetof(CPUX86State, tsc_aux) }, { IA32_MSR_TSC_ADJUST, HV_X64_REGISTER_TSC_ADJUST, offsetof(CPUX86State, tsc_adjust) }, + { IA32_MSR_TSC_DEADLINE, HV_X64_REGISTER_TSC_DEADLINE, + offsetof(CPUX86State, tsc_deadline) }, =20 /* Hyper-V per-partition MSRs */ { HV_X64_MSR_HYPERCALL, HV_X64_REGISTER_HYPERCALL, --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678624; cv=none; d=zohomail.com; s=zohoarc; b=lYYQDMeSDUuspEV3MbE8mVQmbZuHjZiZNry5Z1FP2CXaRrmPK1Gc0u6K89phh67BDU+dxnoP55N14muH+OnhhfYqSDIsnK12cvpUcAkKZfUJa5Z60uob0+fOpM445PoME97+3F/hXb/Ysyt0cGa3oAoNM8/zBF/ca8OLyagU55w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678624; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=w6tG+jgCurIBEAAB+cRFIwgQuMTvkHoTE5+daMRnPnE=; b=NvaiBCSPzqnCV/1W4L+HP9/2aySt+DR6oanDomo9YEBbjvdNAJZLo/MRbJ36xm6KZKn3LZn/tDWBqWJAoub5B0VuQIKxq+xjtXNZYWYvSgfxa5Q0Q+Cw3G32QNMF6GdrwoVBaIaq8gGenS26mRYPHwo3+NKiw28h0Yr3Xc9eXkg= 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 1783678624519528.3645069985; Fri, 10 Jul 2026 03:17:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HB-0006oX-2h; Fri, 10 Jul 2026 06:16:09 -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 1wi8H7-0006oK-BK for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:05 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8H4-0006Nj-TR for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:04 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 8F1C420B716F; Fri, 10 Jul 2026 03:15:53 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8F1C420B716F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678556; bh=w6tG+jgCurIBEAAB+cRFIwgQuMTvkHoTE5+daMRnPnE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NzRUIe5IwYBH0wOkxenC3/dxA5ZnbHwvsBYK6U1sQIq+taZeIDK/zouzbiU4qliIw sdPQsQ2JHvEqXPMPeDU8PHJXwyj5aAkXED0Jea9gsSo0Xdm6WEWDBGq4teHt+wSrqb giVr2PCLNzeedg1lXudAasA+kDI/+MU74iOX0LF8= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 06/12] target/i386/mshv: migrate Synic SINT MSRs Date: Fri, 10 Jul 2026 12:15:28 +0200 Message-Id: <20260710101534.664604-7-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678626806158500 Content-Type: text/plain; charset="utf-8" Migrate HyperV SynIC SINT MSRs. We can only read/write those if SCONTROL is enabled in the guest, hence we have to split the SINT MSR out and make reading/writing them dependent on that MSR. Signed-off-by: Magnus Kulke --- target/i386/mshv/msr.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/target/i386/mshv/msr.c b/target/i386/mshv/msr.c index a5f639c3ca..5288e32b6d 100644 --- a/target/i386/mshv/msr.c +++ b/target/i386/mshv/msr.c @@ -331,6 +331,8 @@ int mshv_get_msrs(CPUState *cpu) struct hv_register_assoc assocs[MSHV_MSR_TOTAL_COUNT]; size_t i, j; uint32_t name; + X86CPU *x86cpu =3D X86_CPU(cpu); + bool synic_enabled; =20 set_hv_name_in_assocs(assocs, n_assocs); =20 @@ -357,6 +359,27 @@ int mshv_get_msrs(CPUState *cpu) =20 store_in_env(cpu, assocs, n_assocs); =20 + /* Read SINT MSRs only if SynIC is enabled */ + synic_enabled =3D x86cpu->env.msr_hv_synic_control & 1; + if (synic_enabled) { + QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT); + + for (i =3D 0; i < HV_SINT_COUNT; i++) { + assocs[i].name =3D HV_REGISTER_SINT0 + i; + } + + ret =3D mshv_get_generic_regs(cpu, assocs, HV_SINT_COUNT); + if (ret < 0) { + error_report("Failed to get SynIC SINT MSRs"); + return -errno; + } + + for (i =3D 0; i < HV_SINT_COUNT; i++) { + uint64_t hv_sint_value =3D assocs[i].value.reg64; + x86cpu->env.msr_hv_synic_sint[i] =3D hv_sint_value; + } + } + return 0; } =20 @@ -391,6 +414,8 @@ int mshv_set_msrs(const CPUState *cpu) struct hv_register_assoc assocs[MSHV_MSR_TOTAL_COUNT]; int ret; size_t i, j; + X86CPU *x86cpu =3D X86_CPU(cpu); + bool synic_enabled =3D x86cpu->env.msr_hv_synic_control & 1; =20 load_from_env(cpu, assocs, n_assocs); =20 @@ -423,5 +448,21 @@ int mshv_set_msrs(const CPUState *cpu) return -errno; } =20 + /* SINT MSRs can only be written if SCONTROL has been set, so we split= */ + if (synic_enabled) { + QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT); + + for (i =3D 0; i < HV_SINT_COUNT; i++) { + assocs[i].name =3D HV_REGISTER_SINT0 + i; + assocs[i].value.reg64 =3D x86cpu->env.msr_hv_synic_sint[i]; + } + + ret =3D mshv_set_generic_regs(cpu, assocs, HV_SINT_COUNT); + if (ret < 0) { + error_report("Failed to set SynIC SINT MSRs"); + return -errno; + } + } + return 0; } --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678634; cv=none; d=zohomail.com; s=zohoarc; b=aDhNOJi8b8cHueNvLOpko29g0PSemNk0ugUMCCaCQ737j4wCUE9k7+FWKwrQ08g7tXmgcJLOp7aor1JtiKM4qVdt253PyR1jKYDjs91LXUTCSLkgu2mhshEGqGhaR2bzXDzt7SQ0dzcVENYgKTtAH0XtkiB2LSZJXQM6iACye2Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678634; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=oIozB7AIxpfKGg6EYggLAAGQdKP0CsEE2Db8ZhzfJ9k=; b=KYVjaeW7RnQezzkXMSdV+BVI7IotKScuMG5k24LiK3m8KY9KmPx1svABly4MCpdlP1STEEE8Q9yk5ag54SdHzgRw2Yjnw5259X4lydh7q7AZirOpLsva5jOvClARMCCMRUnKUsp+Q+g5t5HlHC8dJE924Q7nXbpq1XdkfuDDSVo= 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 1783678634472860.8094792532265; Fri, 10 Jul 2026 03:17:14 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HE-0006pN-Vm; Fri, 10 Jul 2026 06:16:13 -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 1wi8HB-0006og-2s for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:09 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8H8-0006Ny-Vm for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:08 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id D683220B716E; Fri, 10 Jul 2026 03:15:56 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D683220B716E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678559; bh=oIozB7AIxpfKGg6EYggLAAGQdKP0CsEE2Db8ZhzfJ9k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ExF3FtmU33kO4sx2f3/sdaJxSlFXlv+n0Glh+DHcxw6+1D13xt+gHe7OgZ6E4YXCv yvFT4PKHoR09MX11lEVo0zmLm9USOZUvk4g/xDKwWN3j8VlPnufHRj8MOj8xBWYsP6 kNfMDR+vZYdABCeHaelLvqjPn24Z4deOSbb75T0Q= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 07/12] target/i386/mshv: migrate SIMP and SIEFP state Date: Fri, 10 Jul 2026 12:15:29 +0200 Message-Id: <20260710101534.664604-8-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678636384158500 Content-Type: text/plain; charset="utf-8" This part SynIC state is retrieved from the hypervisor via aligned state pages: - Add new synic source file - Centralize the synic_enabled() check - r/w pages from the hyper via aligned pages - only handle pages when synic is enabled - add buffers for migration to VM state Signed-off-by: Magnus Kulke --- include/system/mshv_int.h | 7 ++ target/i386/cpu.h | 5 ++ target/i386/machine.c | 26 ++++++ target/i386/mshv/meson.build | 1 + target/i386/mshv/mshv-cpu.c | 64 +++++++++++++++ target/i386/mshv/msr.c | 7 +- target/i386/mshv/synic.c | 155 +++++++++++++++++++++++++++++++++++ 7 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 target/i386/mshv/synic.c diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index c2f13c0194..bc023d3535 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -138,4 +138,11 @@ int mshv_init_msrs(const CPUState *cpu); int mshv_get_msrs(CPUState *cpu); int mshv_set_msrs(const CPUState *cpu); =20 +/* synic */ +int mshv_get_simp(int cpu_fd, uint8_t *page); +int mshv_set_simp(int cpu_fd, const uint8_t *page); +int mshv_get_siefp(int cpu_fd, uint8_t *page); +int mshv_set_siefp(int cpu_fd, const uint8_t *page); +bool mshv_synic_enabled(const CPUState *cpu); + #endif diff --git a/target/i386/cpu.h b/target/i386/cpu.h index e6a197602d..9270ae95d0 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -33,6 +33,7 @@ #include "qemu/cpu-float.h" #include "qemu/timer.h" #include "standard-headers/asm-x86/kvm_para.h" +#include "hw/hyperv/hvgdk_mini.h" =20 #define XEN_NR_VIRQS 24 =20 @@ -2299,6 +2300,10 @@ typedef struct CPUArchState { #if defined(CONFIG_HVF) || defined(CONFIG_MSHV) || defined(CONFIG_WHPX) void *emu_mmio_buf; #endif +#if defined(CONFIG_MSHV) + uint8_t hv_simp_page[HV_HYP_PAGE_SIZE]; + uint8_t hv_siefp_page[HV_HYP_PAGE_SIZE]; +#endif =20 uint64_t mcg_cap; uint64_t mcg_ctl; diff --git a/target/i386/machine.c b/target/i386/machine.c index df0e0c178e..023a397ab8 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -951,6 +951,29 @@ static const VMStateDescription vmstate_msr_hyperv_ree= nlightenment =3D { } }; =20 +#ifdef CONFIG_MSHV +static bool mshv_synic_vp_state_needed(void *opaque) +{ + X86CPU *cpu =3D opaque; + CPUX86State *env =3D &cpu->env; + + /* Only migrate SIMP/SIEFP if SynIC is enabled */ + return env->msr_hv_synic_control & 1; +} + +static const VMStateDescription vmstate_mshv_synic_vp_state =3D { + .name =3D "cpu/mshv_synic_vp_state", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D mshv_synic_vp_state_needed, + .fields =3D (const VMStateField[]) { + VMSTATE_BUFFER(env.hv_simp_page, X86CPU), + VMSTATE_BUFFER(env.hv_siefp_page, X86CPU), + VMSTATE_END_OF_LIST() + } +}; +#endif + static bool avx512_needed(void *opaque) { X86CPU *cpu =3D opaque; @@ -1915,6 +1938,9 @@ const VMStateDescription vmstate_x86_cpu =3D { &vmstate_cet, #ifdef TARGET_X86_64 &vmstate_apx, +#endif +#ifdef CONFIG_MSHV + &vmstate_mshv_synic_vp_state, #endif NULL } diff --git a/target/i386/mshv/meson.build b/target/i386/mshv/meson.build index 6091c21887..31ff4cc995 100644 --- a/target/i386/mshv/meson.build +++ b/target/i386/mshv/meson.build @@ -3,6 +3,7 @@ i386_mshv_ss =3D ss.source_set() i386_mshv_ss.add(files( 'mshv-cpu.c', 'msr.c', + 'synic.c', )) =20 i386_system_ss.add_all(when: 'CONFIG_MSHV', if_true: i386_mshv_ss) diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 333ee35e72..57244bc667 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -111,6 +111,33 @@ static enum hv_register_name FPU_REGISTER_NAMES[26] = =3D { =20 static int set_special_regs(const CPUState *cpu); =20 +static int get_synic_state(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + + /* SIMP/SIEFP can only be read when SynIC is enabled */ + if (!mshv_synic_enabled(cpu)) { + return 0; + } + + ret =3D mshv_get_simp(cpu_fd, env->hv_simp_page); + if (ret < 0) { + error_report("failed to get simp state"); + return -1; + } + + ret =3D mshv_get_siefp(cpu_fd, env->hv_siefp_page); + if (ret < 0) { + error_report("failed to get siefp state"); + return -1; + } + + return 0; +} + static int get_xsave_state(CPUState *cpu) { X86CPU *x86cpu =3D X86_CPU(cpu); @@ -969,6 +996,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D get_synic_state(cpu); + if (ret < 0) { + return ret; + } + ret =3D get_vcpu_events(cpu); if (ret < 0) { return ret; @@ -1381,6 +1413,33 @@ static int set_xc_reg(const CPUState *cpu) return 0; } =20 +static int set_synic_state(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + + /* SIMP/SIEFP can only be written when SynIC is enabled */ + if (!mshv_synic_enabled(cpu)) { + return 0; + } + + ret =3D mshv_set_simp(cpu_fd, env->hv_simp_page); + if (ret < 0) { + error_report("failed to set simp state"); + return -1; + } + + ret =3D mshv_set_siefp(cpu_fd, env->hv_siefp_page); + if (ret < 0) { + error_report("failed to set siefp state"); + return -1; + } + + return 0; +} + int mshv_arch_store_vcpu_state(const CPUState *cpu) { int ret; @@ -1421,6 +1480,11 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 + ret =3D set_synic_state(cpu); + if (ret < 0) { + return ret; + } + ret =3D set_vcpu_events(cpu); if (ret < 0) { return ret; diff --git a/target/i386/mshv/msr.c b/target/i386/mshv/msr.c index 5288e32b6d..d3788d7715 100644 --- a/target/i386/mshv/msr.c +++ b/target/i386/mshv/msr.c @@ -332,7 +332,6 @@ int mshv_get_msrs(CPUState *cpu) size_t i, j; uint32_t name; X86CPU *x86cpu =3D X86_CPU(cpu); - bool synic_enabled; =20 set_hv_name_in_assocs(assocs, n_assocs); =20 @@ -360,8 +359,7 @@ int mshv_get_msrs(CPUState *cpu) store_in_env(cpu, assocs, n_assocs); =20 /* Read SINT MSRs only if SynIC is enabled */ - synic_enabled =3D x86cpu->env.msr_hv_synic_control & 1; - if (synic_enabled) { + if (mshv_synic_enabled(cpu)) { QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT); =20 for (i =3D 0; i < HV_SINT_COUNT; i++) { @@ -415,7 +413,6 @@ int mshv_set_msrs(const CPUState *cpu) int ret; size_t i, j; X86CPU *x86cpu =3D X86_CPU(cpu); - bool synic_enabled =3D x86cpu->env.msr_hv_synic_control & 1; =20 load_from_env(cpu, assocs, n_assocs); =20 @@ -449,7 +446,7 @@ int mshv_set_msrs(const CPUState *cpu) } =20 /* SINT MSRs can only be written if SCONTROL has been set, so we split= */ - if (synic_enabled) { + if (mshv_synic_enabled(cpu)) { QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT); =20 for (i =3D 0; i < HV_SINT_COUNT; i++) { diff --git a/target/i386/mshv/synic.c b/target/i386/mshv/synic.c new file mode 100644 index 0000000000..8f9fee6ed7 --- /dev/null +++ b/target/i386/mshv/synic.c @@ -0,0 +1,155 @@ +/* + * QEMU MSHV SynIC support + * + * Copyright Microsoft, Corp. 2026 + * + * Authors: Magnus Kulke + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/memalign.h" +#include "qemu/error-report.h" + +#include "system/mshv.h" +#include "system/mshv_int.h" + +#include "linux/mshv.h" +#include "hw/hyperv/hvgdk_mini.h" +#include "cpu.h" + +#include + +bool mshv_synic_enabled(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + + return x86cpu->env.msr_hv_synic_control & 1; +} + +static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state) +{ + int ret; + + ret =3D ioctl(cpu_fd, MSHV_GET_VP_STATE, state); + if (ret < 0) { + error_report("failed to get vp state: %s", strerror(errno)); + return -1; + } + + return 0; +} + +static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *st= ate) +{ + int ret; + + ret =3D ioctl(cpu_fd, MSHV_SET_VP_STATE, state); + if (ret < 0) { + error_report("failed to set vp state: %s", strerror(errno)); + return -1; + } + + return 0; +} + +int mshv_get_simp(int cpu_fd, uint8_t *page) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SIMP; + + ret =3D get_vp_state(cpu_fd, &args); + + if (ret < 0) { + qemu_vfree(buffer); + error_report("failed to get simp"); + return -1; + } + + memcpy(page, buffer, HV_HYP_PAGE_SIZE); + qemu_vfree(buffer); + + return 0; +} + +int mshv_set_simp(int cpu_fd, const uint8_t *page) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SIMP; + + assert(page); + memcpy(buffer, page, HV_HYP_PAGE_SIZE); + + ret =3D set_vp_state(cpu_fd, &args); + qemu_vfree(buffer); + + if (ret < 0) { + error_report("failed to set simp"); + return -1; + } + + return 0; +} + +int mshv_get_siefp(int cpu_fd, uint8_t *page) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SIEFP, + + ret =3D get_vp_state(cpu_fd, &args); + + if (ret < 0) { + qemu_vfree(buffer); + error_report("failed to get siefp"); + return -1; + } + + memcpy(page, buffer, HV_HYP_PAGE_SIZE); + qemu_vfree(buffer); + + return 0; +} + +int mshv_set_siefp(int cpu_fd, const uint8_t *page) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SIEFP, + + assert(page); + memcpy(buffer, page, HV_HYP_PAGE_SIZE); + + ret =3D set_vp_state(cpu_fd, &args); + qemu_vfree(buffer); + + if (ret < 0) { + error_report("failed to set simp"); + return -1; + } + + return 0; +} --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678593; cv=none; d=zohomail.com; s=zohoarc; b=T9cZCbTFguEMQBsPP3Q+OF09ExKwmIbv+09H59VwWKc09EhiTvTOrAHbP5/2owKxKoBTN229U7dZhV27dqkDQ/4OWk9FWUlBNUCHfnEV5z+JgJmrlPZYG2vndFvEgxcOPdH08YKVWhZ/0+LCLeV/pxiFrB0T3INjxsq3/lzcMYo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678593; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=MLYd/clY4DaUkQwiV2AlNE84dmZItUqtEVca75uY3SI=; b=UN64C0ghyeVxZNeaTFSZmKPsPmGEbKuR23dT4xDNbKPDu16RrAVvxN+qABhdw5s6hGC85XMkemKVl51YKxj/6dQAPt1Aa9y31hsysGV04D918JobqYBTBDAmk62SJaBCDI91HY1TeXdXSRhllcoQ987W0Pokal9OkBbnn+arYeA= 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 1783678593032154.62455760488047; Fri, 10 Jul 2026 03:16:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HG-0006q3-G2; Fri, 10 Jul 2026 06:16:14 -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 1wi8HD-0006pE-Eq for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:12 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HB-0006OD-Rd for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:11 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 80B1A20B716F; Fri, 10 Jul 2026 03:16:00 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 80B1A20B716F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678563; bh=MLYd/clY4DaUkQwiV2AlNE84dmZItUqtEVca75uY3SI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HxkCaUzIaCET+X5UDWcNsjxKfn6YFBED8qqEjc7o0mpw3PeY0DmCSs5AH63wJJV0U 3w1mUk0nn3I5i7zjnerSWYFyZubmqRVGxoJSukf25GILGWz6gruMi7EomVOWefpepX kbysbEVyyBX8vr+5L/0XJv15AmHH8tfO2G6I0W2I= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 08/12] target/i386/mshv: migrate STIMER state Date: Fri, 10 Jul 2026 12:15:30 +0200 Message-Id: <20260710101534.664604-9-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678594721158500 Content-Type: text/plain; charset="utf-8" This part of Synic state is retrieved via a mem-aligned page. We declare the required space (size reference: rust-vmm/mshv) as a buffer on the VM state struct for inclusion in a migration. Other than other SynIC features, STIMER doesn't depend on SCONTROL being set. Signed-off-by: Magnus Kulke --- include/system/mshv_int.h | 2 ++ target/i386/cpu.h | 5 ++++ target/i386/machine.c | 20 +++++++++++++++ target/i386/mshv/mshv-cpu.c | 12 +++++++++ target/i386/mshv/synic.c | 51 +++++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+) diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index bc023d3535..063852115e 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -144,5 +144,7 @@ int mshv_set_simp(int cpu_fd, const uint8_t *page); int mshv_get_siefp(int cpu_fd, uint8_t *page); int mshv_set_siefp(int cpu_fd, const uint8_t *page); bool mshv_synic_enabled(const CPUState *cpu); +int mshv_get_synthetic_timers(int cpu_fd, uint8_t *state); +int mshv_set_synthetic_timers(int cpu_fd, const uint8_t *state); =20 #endif diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 9270ae95d0..6c9e674e81 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -45,6 +45,10 @@ #define ELF_MACHINE_UNAME "i686" #endif =20 +#ifdef CONFIG_MSHV +#define MSHV_STIMERS_STATE_SIZE 200 +#endif + enum { R_EAX =3D 0, R_ECX =3D 1, @@ -2303,6 +2307,7 @@ typedef struct CPUArchState { #if defined(CONFIG_MSHV) uint8_t hv_simp_page[HV_HYP_PAGE_SIZE]; uint8_t hv_siefp_page[HV_HYP_PAGE_SIZE]; + uint8_t hv_synthetic_timers_state[MSHV_STIMERS_STATE_SIZE]; #endif =20 uint64_t mcg_cap; diff --git a/target/i386/machine.c b/target/i386/machine.c index 023a397ab8..8d69d7e25e 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -10,6 +10,7 @@ #include "exec/watchpoint.h" #include "system/kvm.h" #include "system/kvm_xen.h" +#include "system/mshv.h" #include "system/tcg.h" =20 #include "qemu/error-report.h" @@ -952,6 +953,24 @@ static const VMStateDescription vmstate_msr_hyperv_ree= nlightenment =3D { }; =20 #ifdef CONFIG_MSHV + +static bool mshv_synthetic_timers_needed(void *opaque) +{ + /* Always migrate synthetic timers */ + return mshv_enabled(); +} + +static const VMStateDescription vmstate_mshv_synthetic_timers =3D { + .name =3D "cpu/mshv_synthetic_timers", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D mshv_synthetic_timers_needed, + .fields =3D (const VMStateField[]) { + VMSTATE_BUFFER(env.hv_synthetic_timers_state, X86CPU), + VMSTATE_END_OF_LIST() + } +}; + static bool mshv_synic_vp_state_needed(void *opaque) { X86CPU *cpu =3D opaque; @@ -1941,6 +1960,7 @@ const VMStateDescription vmstate_x86_cpu =3D { #endif #ifdef CONFIG_MSHV &vmstate_mshv_synic_vp_state, + &vmstate_mshv_synthetic_timers, #endif NULL } diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 57244bc667..ce6cfccc0a 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -118,6 +118,12 @@ static int get_synic_state(CPUState *cpu) int cpu_fd =3D mshv_vcpufd(cpu); int ret; =20 + ret =3D mshv_get_synthetic_timers(cpu_fd, env->hv_synthetic_timers_sta= te); + if (ret < 0) { + error_report("failed to get synthetic timers"); + return -1; + } + /* SIMP/SIEFP can only be read when SynIC is enabled */ if (!mshv_synic_enabled(cpu)) { return 0; @@ -1420,6 +1426,12 @@ static int set_synic_state(const CPUState *cpu) int cpu_fd =3D mshv_vcpufd(cpu); int ret; =20 + ret =3D mshv_set_synthetic_timers(cpu_fd, env->hv_synthetic_timers_sta= te); + if (ret < 0) { + error_report("failed to set synthetic timers state"); + return -1; + } + /* SIMP/SIEFP can only be written when SynIC is enabled */ if (!mshv_synic_enabled(cpu)) { return 0; diff --git a/target/i386/mshv/synic.c b/target/i386/mshv/synic.c index 8f9fee6ed7..4c629adc3a 100644 --- a/target/i386/mshv/synic.c +++ b/target/i386/mshv/synic.c @@ -54,6 +54,57 @@ static int set_vp_state(int cpu_fd, const struct mshv_ge= t_set_vp_state *state) return 0; } =20 +int mshv_get_synthetic_timers(int cpu_fd, uint8_t *state) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SYNTHETIC_TIMERS; + + ret =3D get_vp_state(cpu_fd, &args); + + if (ret < 0) { + qemu_vfree(buffer); + error_report("failed to get synthetic timers"); + return -1; + } + + memcpy(state, buffer, MSHV_STIMERS_STATE_SIZE); + qemu_vfree(buffer); + + return 0; +} + +int mshv_set_synthetic_timers(int cpu_fd, const uint8_t *state) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + memset(buffer, 0, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SYNTHETIC_TIMERS; + + assert(state); + memcpy(buffer, state, MSHV_STIMERS_STATE_SIZE); + + ret =3D set_vp_state(cpu_fd, &args); + qemu_vfree(buffer); + + if (ret < 0) { + error_report("failed to set synthetic timers"); + return -1; + } + + return 0; +} + int mshv_get_simp(int cpu_fd, uint8_t *page) { int ret; --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678641; cv=none; d=zohomail.com; s=zohoarc; b=Wu12pqjwyLJ4TwJ/yr8WGKH6+ZY2MrAm6xo+9Qn9W5VMktdmPu2wcd6UV0WhiuOeaYKoBGO8UcAKh8oR+sUa2zkV5Vc8fWM1KfpCn+sOFToeW1ot5lSQC59brX4uewbEWKwRDJr/X75Jm6DITiGkJFFEv/g7iFbL0ts33tpJXZI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678641; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=0cyuOH/4x+tG3A9xq6l+SkYJj1/PgPLHcLRVlDU7mhc=; b=hUSPJLMGZI5lTJSOZkbsAZH5b+xSJKGIP8Pq9sVLQ1S28iphDO/uJkv4uElEy58juBxxeQdl9OQlsMHqjZG5xO4Fp83ua0SaLKO/ZminL/uyTAHRn7BggjXWqcvoqBn8sOELF164MZiCuduXWSzz+iAP/kIkdFnNK7UUXWCnt78= 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 1783678641607994.9392359908816; Fri, 10 Jul 2026 03:17:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HI-0006qk-Ki; Fri, 10 Jul 2026 06:16:16 -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 1wi8HG-0006q8-Pv for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:14 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HF-0006OU-AI for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:14 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id D8FFE20B716E; Fri, 10 Jul 2026 03:16:03 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D8FFE20B716E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678566; bh=0cyuOH/4x+tG3A9xq6l+SkYJj1/PgPLHcLRVlDU7mhc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l3k3/edGLUqJqBPAH4efrlyBurRvRlVdEoZNsXbs4H8buLqbsdgDCOB0103lH76t1 bkQyp6WlKqZAOiDFMUYz6VAbXKvSfAfTPLQm7QQqIevi6Odsyg8WpeeXqY7ptCyJtR S4uS00wV88vrhtqUctcy1MWE6reSrVBe5WaBD91s= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 09/12] accel/mshv: write synthetic MSRs after migration Date: Fri, 10 Jul 2026 12:15:31 +0200 Message-Id: <20260710101534.664604-10-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678642453158500 Content-Type: text/plain; charset="utf-8" Write partition-wide synthetic MSRs. This ensures the hypercall page and SynIC facilities are set up before vCPUs attempt to use it. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 15 +++++++++++++++ include/hw/hyperv/hvgdk_mini.h | 3 +++ include/system/mshv_int.h | 1 + target/i386/mshv/mshv-cpu.c | 15 +++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 1516475f34..1ca1d4b54f 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -60,6 +60,20 @@ static int init_mshv(int *mshv_fd) return 0; } =20 +static int mshv_load_cleanup(void *opaque) +{ + int ret; + + ret =3D mshv_arch_set_partition_msrs(first_cpu); + if (ret < 0) { + error_report("Failed to set partition MSRs: %s", strerror(-ret)); + return -1; + } + + return 0; +} + + static int get_host_partition_property(int mshv_fd, uint32_t property_code, uint64_t *value) { @@ -496,6 +510,7 @@ static int mshv_init_vcpu(CPUState *cpu) } =20 static SaveVMHandlers savevm_mshv =3D { + .load_cleanup =3D mshv_load_cleanup, }; =20 static int mshv_init(AccelState *as, MachineState *ms) diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h index 0602a7c6cc..a5527d49cf 100644 --- a/include/hw/hyperv/hvgdk_mini.h +++ b/include/hw/hyperv/hvgdk_mini.h @@ -23,6 +23,9 @@ #define HV_X64_MSR_APIC_FREQUENCY 0x40000023 =20 typedef enum hv_register_name { + /* VP Management Registers */ + HV_REGISTER_INTERNAL_ACTIVITY_STATE =3D 0x00000004, + /* Pending Interruption Register */ HV_REGISTER_PENDING_INTERRUPTION =3D 0x00010002, HV_REGISTER_INTERRUPT_STATE =3D 0x00010003, diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 063852115e..cbfcb8611b 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -98,6 +98,7 @@ int mshv_get_generic_regs(CPUState *cpu, hv_register_asso= c *assocs, size_t n_regs); int mshv_arch_store_vcpu_state(const CPUState *cpu); int mshv_arch_load_vcpu_state(CPUState *cpu); +int mshv_arch_set_partition_msrs(const CPUState *cpu); void mshv_arch_init_vcpu(CPUState *cpu); void mshv_arch_destroy_vcpu(CPUState *cpu); void mshv_arch_amend_proc_features( diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index ce6cfccc0a..1485f6a1ef 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -1505,6 +1505,21 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return 0; } =20 +int mshv_arch_set_partition_msrs(const CPUState *cpu) +{ + CPUX86State *env =3D &X86_CPU(cpu)->env; + struct hv_register_assoc assocs[] =3D { + { .name =3D HV_REGISTER_GUEST_OS_ID, + .value.reg64 =3D env->msr_hv_guest_os_id }, + { .name =3D HV_REGISTER_REFERENCE_TSC, + .value.reg64 =3D env->msr_hv_tsc }, + { .name =3D HV_X64_REGISTER_HYPERCALL, + .value.reg64 =3D env->msr_hv_hypercall }, + }; + + return mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs)); +} + void mshv_arch_amend_proc_features( union hv_partition_synthetic_processor_features *features) { --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678619; cv=none; d=zohomail.com; s=zohoarc; b=iT3O3Uodk7rNabcsnYnL9jElJHsqqwoRdt1h76DkF0LwULVdWuEBgmmHKcAJIyOs+h+v2clayBEmCuuEEkKJlVl4K1lHjDfq2hnXF+77QQla8Q27DCgt/mx/ox9KtAGyIwJicY4/HjkFY0PXdNEqe55sKK3Jwcc/8laQScAmPS8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678619; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wikja4dri6pV3M1kMk3uCBESlMw6FF0jmj8W9SLIBf8=; b=XlsFbrHH4E+7Z9Ndh8D3OQgCcEEajXneh/rwXNdBVDbXo4NWtJ2+teSg7JEwonrsgvX0Euv+4/MyoanPMHg4iixaICO6LeXqt8JMiIGJCaVEvNiacn/pGi+fg7OoBzJd3MTkU+a38zz4beWy47JxqiLAZWFRrxWC1Corz84sHVE= 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 1783678619340363.31117766336274; Fri, 10 Jul 2026 03:16:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HL-0006r7-Vr; Fri, 10 Jul 2026 06:16:20 -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 1wi8HK-0006qw-4O for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:18 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HI-0006Oe-Be for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:17 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 1929F20B716F; Fri, 10 Jul 2026 03:16:06 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 1929F20B716F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678569; bh=wikja4dri6pV3M1kMk3uCBESlMw6FF0jmj8W9SLIBf8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qCHqLZvgOfMdVpURdrwg5Ae/ppPemYuWb8GHy2yr3jEstrZ4krwC2qVp8nMq5CCc8 V1E0ZLwg7BJ4S+Fs+wBqc1GBXRpbzPVYR4e55hLH5EXOXXOAla/M1vQMVxKGpKGPPy BElf9jNXU+SJKW5Gnd4iwrNezqyWP/SuPn789tzQ= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 10/12] target/i386/mshv: migrate MP_STATE Date: Fri, 10 Jul 2026 12:15:32 +0200 Message-Id: <20260710101534.664604-11-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678620405158500 Content-Type: text/plain; charset="utf-8" MSHV's "internal activity state" roughly maps to QEMU's env->mp_state and cpu->halted states that describe state of APs in a guest. We don't invoke set_mp_state as part of store_vcpu_state() b/c we would put all BSP + APs in a RUNNABLE (0) state immediately, breaking SMP boot Instead we store the mp state as part of the load_cleanup() routine after a migration. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 10 +++++ include/system/mshv_int.h | 1 + target/i386/mshv/mshv-cpu.c | 80 +++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 1ca1d4b54f..5921ce693e 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -62,6 +62,7 @@ static int init_mshv(int *mshv_fd) =20 static int mshv_load_cleanup(void *opaque) { + CPUState *cpu; int ret; =20 ret =3D mshv_arch_set_partition_msrs(first_cpu); @@ -70,6 +71,15 @@ static int mshv_load_cleanup(void *opaque) return -1; } =20 + CPU_FOREACH(cpu) { + ret =3D mshv_arch_set_mp_state(cpu); + if (ret < 0) { + error_report("Failed to set mp state for vCPU %d: %s", + cpu->cpu_index, strerror(-ret)); + return -1; + } + } + return 0; } =20 diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index cbfcb8611b..3dffe3c5fb 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -99,6 +99,7 @@ int mshv_get_generic_regs(CPUState *cpu, hv_register_asso= c *assocs, int mshv_arch_store_vcpu_state(const CPUState *cpu); int mshv_arch_load_vcpu_state(CPUState *cpu); int mshv_arch_set_partition_msrs(const CPUState *cpu); +int mshv_arch_set_mp_state(const CPUState *cpu); void mshv_arch_init_vcpu(CPUState *cpu); void mshv_arch_destroy_vcpu(CPUState *cpu); void mshv_arch_amend_proc_features( diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 1485f6a1ef..bff1ac9d17 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -35,6 +35,11 @@ =20 #include =20 +#define MSHV_MP_STATE_RUNNABLE 0 +#define MSHV_MP_STATE_UNINITIALIZED 1 +#define MSHV_MP_STATE_INIT_RECEIVED 2 +#define MSHV_MP_STATE_HALTED 3 + #define MAX_REGISTER_COUNT (MAX_CONST(ARRAY_SIZE(STANDARD_REGISTER_NAMES),= \ MAX_CONST(ARRAY_SIZE(SPECIAL_REGISTER_NAMES), \ ARRAY_SIZE(FPU_REGISTER_NAMES)))) @@ -950,6 +955,76 @@ static int set_vcpu_events(const CPUState *cpu) return 0; } =20 +static int get_mp_state(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + struct hv_register_assoc assoc =3D { + .name =3D HV_REGISTER_INTERNAL_ACTIVITY_STATE, + }; + union hv_internal_activity_register activity; + int ret; + + ret =3D mshv_get_generic_regs(cpu, &assoc, 1); + if (ret < 0) { + error_report("failed to get internal activity state"); + return -1; + } + + activity.as_uint64 =3D assoc.value.reg64; + + /* + * map MSHV activity state to KVM mp_state values, which are used as t= he + * shared representation in env->mp_state and serialized by vmstate_x8= 6_cpu. + */ + + if (activity.startup_suspend) { + env->mp_state =3D MSHV_MP_STATE_UNINITIALIZED; + } else if (activity.halt_suspend) { + env->mp_state =3D MSHV_MP_STATE_HALTED; + } else { + env->mp_state =3D MSHV_MP_STATE_RUNNABLE; + } + + cpu->halted =3D (env->mp_state =3D=3D MSHV_MP_STATE_HALTED); + + return 0; +} + +int mshv_arch_set_mp_state(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + union hv_internal_activity_register activity =3D { 0 }; + struct hv_register_assoc assoc =3D { + .name =3D HV_REGISTER_INTERNAL_ACTIVITY_STATE, + }; + int ret; + + switch (env->mp_state) { + case MSHV_MP_STATE_HALTED: + activity.halt_suspend =3D 1; + break; + case MSHV_MP_STATE_UNINITIALIZED: + case MSHV_MP_STATE_INIT_RECEIVED: + activity.startup_suspend =3D 1; + break; + case MSHV_MP_STATE_RUNNABLE: + default: + break; + } + + assoc.value.reg64 =3D activity.as_uint64; + + ret =3D mshv_set_generic_regs(cpu, &assoc, 1); + if (ret < 0) { + error_report("failed to set internal activity state"); + return -1; + } + + return 0; +} + static int update_hflags(CPUState *cpu) { X86CPU *x86cpu =3D X86_CPU(cpu); @@ -1012,6 +1087,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D get_mp_state(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678607; cv=none; d=zohomail.com; s=zohoarc; b=i3rkBWjgYJDxSZhgJj2QworkV1JlFxnjdHPyJvGrbuGkVykfpNn4trGmpUbeT8+uG7Jb+6xcx6ymngl5uYZdTPQZDlKJom4fp1H3xIXdhCaV2ldJmhAAjAQ1VJvIMrqpcp19yq1uXxyoG5c3A+2OVXzKeD3FDp7LI17memWGUvI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678607; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ap1AGdm2urEO2qR8Nc2JiIOZF+4iUaECLj3pRkt9gko=; b=ajoNuTB5z4oWUvFnEfbvmYI/qPFvfNy9PjITtMUJeHcL0HaJUbC1l7GTCAWv3gtZci2IaFlKVvdvtPpjLRtQVUg2YnfGkynup4mlkpc+Uve0b9SzHCT+5Uz94TVeGZspd8suu5rLqdxlxD3VWyjOv7rWW7I6MoZo82tuO//OpzQ= 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 1783678607509775.2763227053048; Fri, 10 Jul 2026 03:16:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HN-0006rV-Us; Fri, 10 Jul 2026 06:16:21 -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 1wi8HN-0006rN-6y for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:21 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HL-0006Oo-QX for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:20 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 60E4820B7170; Fri, 10 Jul 2026 03:16:10 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 60E4820B7170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678572; bh=Ap1AGdm2urEO2qR8Nc2JiIOZF+4iUaECLj3pRkt9gko=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sU3YP/Vo4H0EUNT3rRSdU7r0qOVqQKc4fdjWaA7eBL3WyqUFFgBk5CDKItNp1zKPy K4X1W4xNjDy7CUU1zEo7U7cSnviq2FLmAmaH0J6Hl3s/jrd8c5IRiEwAafeNNk4ixS LflCWZnylJEtjxrPzFyPkOt3P5lj6+O9S1fNzvqw= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 11/12] target/i386/mshv: toggle fpu/xsave migration Date: Fri, 10 Jul 2026 12:15:33 +0200 Message-Id: <20260710101534.664604-12-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678608304158500 Content-Type: text/plain; charset="utf-8" MSHV exposes overlapping legacy FP/SSE state through two paths: explicit Hyper-V FPU/XMM + registers and VP XSAVE state. There can be subtle inconsistencies across migrations when XSAVE is written after FPU state. Signed-off-by: Magnus Kulke --- target/i386/mshv/mshv-cpu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index bff1ac9d17..f528dd2b9a 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -1057,7 +1057,7 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 - ret =3D get_fpu(cpu); + ret =3D get_xsave_state(cpu); if (ret < 0) { return ret; } @@ -1072,7 +1072,7 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 - ret =3D get_xsave_state(cpu); + ret =3D get_fpu(cpu); if (ret < 0) { return ret; } @@ -1551,7 +1551,7 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 - ret =3D set_fpu(cpu); + ret =3D set_xsave_state(cpu); if (ret < 0) { return ret; } @@ -1567,7 +1567,8 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 - ret =3D set_xsave_state(cpu); + /* INVARIANT: legacy FPU state must be restored after XSAVE */ + ret =3D set_fpu(cpu); if (ret < 0) { return ret; } --=20 2.34.1 From nobody Sun Jul 12 00:42:32 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=1783678614; cv=none; d=zohomail.com; s=zohoarc; b=RQX9zrqfT5hemQRW3X33GJf6VFBHWkgsA23zU+wimhKQM0qAlrhuUz3ZiJCKVIlC+KlXWdeE+YyJI44JW0cw4Z1VuP7vlKvOduf1Dt+M+bCR1NO/Sp+HJ9aX3dlNLZThFCzOoLRmrrgKTcKVGaMguxdKFa2KaJvPLlnl9bZV2aQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783678614; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=VWQQm8vY6vkKwijEQUIN0sG/z6alwTBab0Y7LEX90Ek=; b=gCrmtb393QgeXANmt6RGd789ySfmbV8wREfYJQ/kiMBcZkbMlaQPRvXDbsrRC50vPaMKQT3OyJ3Qeo6fezfc03U1ImuKS7/F6aNlJgsMDx/0zbgyi1PbaMtHgcM4TXhRGUomUMZwpENB+D1MJz03dCXcY1fkeR06g7lFmgFcoS4= 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 1783678614949411.68630630216285; Fri, 10 Jul 2026 03:16:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HS-0006sI-AO; Fri, 10 Jul 2026 06:16:26 -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 1wi8HQ-0006s3-G2 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:24 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wi8HP-0006Oz-6X for qemu-devel@nongnu.org; Fri, 10 Jul 2026 06:16:24 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (p3e9c0c70.dip0.t-ipconnect.de [62.156.12.112]) by linux.microsoft.com (Postfix) with ESMTPSA id 935A120B716E; Fri, 10 Jul 2026 03:16:13 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 935A120B716E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1783678576; bh=VWQQm8vY6vkKwijEQUIN0sG/z6alwTBab0Y7LEX90Ek=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DXrghXxGGn8OX7QKTG6AYHX5EqgGyS4zlYGH8iCco6+cK75UdCfjdsSuRgj2PItQw Zq08mRKuwy5nM5enjm9hpCldW/jzpxZ+Ya40sqYHkg/HOow8+Sa7Eelkp2QtX/jiwI ESEYwQF+Bf/4AbVSUc67+BSk6ozC/UCWnEMa1vHQ= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Magnus Kulke , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= , Wei Liu Subject: [PATCH 12/12] hw/i386/mshv: drop initial msi vector 0 Date: Fri, 10 Jul 2026 12:15:34 +0200 Message-Id: <20260710101534.664604-13-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> 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: 1783678616389158501 Content-Type: text/plain; charset="utf-8" This has been a warning before that was always raised if the machine has a hpet. hpet_reset() will eventually result in mshv_send_msi called w/ vector 0, which we can safely drop. Signed-off-by: Magnus Kulke --- hw/i386/mshv/apic.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/i386/mshv/apic.c b/hw/i386/mshv/apic.c index 9188a93b2f..ad326030bf 100644 --- a/hw/i386/mshv/apic.c +++ b/hw/i386/mshv/apic.c @@ -293,6 +293,16 @@ static void mshv_send_msi(MSIMessage *msi) delivery =3D (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & MSI_DATA_DELIVERY_MODE_MASK; =20 + /* + * Vector 0 is not a valid interrupt vector (0-15 are reserved for CPU + * exceptions). This can trigger during machine reset, if hpet_reset() + * forces the PIT to pulse GSI 2 before IOAPIC's own reset has masked = its + * redirection entries. + */ + if (vector =3D=3D 0) { + return; + } + mshv_request_interrupt(mshv_state, delivery, vector, dest, dest_mode, trigger_mode); } --=20 2.34.1