From nobody Sat Nov 15 06:34:09 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753939924; cv=none; d=zohomail.com; s=zohoarc; b=gwI63UpUBN2+57mrLT2sz4WvBCavwIOccnRie6z2+7DUwGqIUr/f/qOh5htQjuFb0QVO2HXSa2wmGACIzfjXuZVc4jgqBBBvmKEuxfjJVlARy4i2WEt7Ee1xFx1bzh5TTg/vy6sADdkFJ2OIR3tkFUFOLW71q6apLP/9+gEoRjo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753939924; 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=pwja+ZpN/2feJPEJZL5LWngWJ+S9c3/1c73FYPVP0IQ=; b=fon1snPvvAe0xMLnEPLGFW7gsakKXQoomeIQ83NRrgbQPCdJyhyyj8xmZNnTBLSJBsiRwVXSEysQR38nr+oMRlBiobuuozSeb8jz9fUAvVM8iSoMEMgytuGbaMC2X1PfuwdxudYojbuZEOAz0QsfzA+ESgikJI60Dx+H4SwL/tI= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753939924643209.53016998683165; Wed, 30 Jul 2025 22:32:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLr5-0000xB-G0; Thu, 31 Jul 2025 01:29:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpn-0007PN-FH for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:07 -0400 Received: from p-east3-cluster7-host9-snip4-1.eps.apple.com ([57.103.84.212] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpl-0005kh-AR for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:07 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id 424B5180010F; Thu, 31 Jul 2025 05:27:59 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id 2ED141800131; Thu, 31 Jul 2025 05:27:57 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=pwja+ZpN/2feJPEJZL5LWngWJ+S9c3/1c73FYPVP0IQ=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=ExZOPRvace2Ee1vtCumTF6zo0KTDjqGABgQNm2QeNbyFdJDRG8bO5w/46RdQ9khjUxFs7IdnLv6KKQ6eWG4Jtqd5PyWqHo26Z7fIHug4KPrSFeoH8ZgpdgA0pxtIyzE+ofqcIS6A3xYUE50cQlO/OPN2trTHQqTAzHG+wo97odGN8tc1TbQsLv9fEBzNlvcu8HrYU/ssDY5UGj1yJ8pZLeh1RjTdLNULEHgNKFZhIVaIcbeiiZJI1QCsbIwqRrr9qJ9ScqEGaH+Q3mn1iQWfkasXpVAcacgCPKJreG77ZA+BLfVQoNIbJBw5BrDWCNWo9LBAZB87LCwwVxrwOikavg== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 1/9] whpx: Move around files before introducing AArch64 support Date: Thu, 31 Jul 2025 07:27:45 +0200 Message-Id: <20250731052753.93255-2-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfX/Gz2RU0tEMD1 pnHFeLSy+K1QBX1Ww3C1NXZFHaMUeuIjYwl2O0Skkz0aMBOn459QzWe31W+5XNWOdHz/61Acy6p s6sH1kDBe6xliINOBQQ2uYp7TGD/QDwbl0pVLpnafqeLAwfKmh6l5hBy8o/qajLdcrrmrBAdePo LVJ8D8p6X7Jq0RhLtqLeA9ASxplIO0jiz1V5J0Yfit39LKRjFR9PvQXGbd6jhWLc8nC+0o2Nip5 4QIkaKXB1CkfTAx9TUc7sLhtMVRSd0LO33qGXOcpzl05zKtFzTpEQihg4J2F/4tYJo4uD6xtU= X-Proofpoint-ORIG-GUID: bnQJHQ4VWV27sdcR_qxph6lggf3yL5Db X-Proofpoint-GUID: bnQJHQ4VWV27sdcR_qxph6lggf3yL5Db X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 phishscore=0 mlxscore=0 mlxlogscore=999 clxscore=1030 bulkscore=0 adultscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.84.212; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753939926762116600 Content-Type: text/plain; charset="utf-8" Switch to a design where we can share whpx code between x86 and AArch64 whe= n it makes sense to do so. Signed-off-by: Mohamed Mediouni Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- accel/meson.build | 1 + accel/whpx/meson.build | 6 ++++++ {target/i386 =3D> accel}/whpx/whpx-accel-ops.c | 8 ++++++-- {target/i386/whpx =3D> include/system}/whpx-accel-ops.h | 0 {target/i386/whpx =3D> include/system}/whpx-internal.h | 7 ++++++- target/i386/whpx/meson.build | 1 - target/i386/whpx/whpx-all.c | 4 ++-- 7 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 accel/whpx/meson.build rename {target/i386 =3D> accel}/whpx/whpx-accel-ops.c (96%) rename {target/i386/whpx =3D> include/system}/whpx-accel-ops.h (100%) rename {target/i386/whpx =3D> include/system}/whpx-internal.h (98%) diff --git a/accel/meson.build b/accel/meson.build index 25b0f100b5..de927a3b37 100644 --- a/accel/meson.build +++ b/accel/meson.build @@ -6,6 +6,7 @@ user_ss.add(files('accel-user.c')) subdir('tcg') if have_system subdir('hvf') + subdir('whpx') subdir('qtest') subdir('kvm') subdir('xen') diff --git a/accel/whpx/meson.build b/accel/whpx/meson.build new file mode 100644 index 0000000000..659efb13c9 --- /dev/null +++ b/accel/whpx/meson.build @@ -0,0 +1,6 @@ +whpx_ss =3D ss.source_set() +whpx_ss.add(files( + 'whpx-accel-ops.c', +)) + +specific_ss.add_all(when: 'CONFIG_WHPX', if_true: whpx_ss) \ No newline at end of file diff --git a/target/i386/whpx/whpx-accel-ops.c b/accel/whpx/whpx-accel-ops.c similarity index 96% rename from target/i386/whpx/whpx-accel-ops.c rename to accel/whpx/whpx-accel-ops.c index da58805b1a..364d99b660 100644 --- a/target/i386/whpx/whpx-accel-ops.c +++ b/accel/whpx/whpx-accel-ops.c @@ -16,8 +16,8 @@ #include "qemu/guest-random.h" =20 #include "system/whpx.h" -#include "whpx-internal.h" -#include "whpx-accel-ops.h" +#include "system/whpx-internal.h" +#include "system/whpx-accel-ops.h" =20 static void *whpx_cpu_thread_fn(void *arg) { @@ -80,7 +80,11 @@ static void whpx_kick_vcpu_thread(CPUState *cpu) =20 static bool whpx_vcpu_thread_is_idle(CPUState *cpu) { +#ifndef __aarch64__ return !whpx_apic_in_platform(); +#else + return 0; +#endif } =20 static void whpx_accel_ops_class_init(ObjectClass *oc, const void *data) diff --git a/target/i386/whpx/whpx-accel-ops.h b/include/system/whpx-accel-= ops.h similarity index 100% rename from target/i386/whpx/whpx-accel-ops.h rename to include/system/whpx-accel-ops.h diff --git a/target/i386/whpx/whpx-internal.h b/include/system/whpx-interna= l.h similarity index 98% rename from target/i386/whpx/whpx-internal.h rename to include/system/whpx-internal.h index 6633e9c4ca..af1e46a491 100644 --- a/target/i386/whpx/whpx-internal.h +++ b/include/system/whpx-internal.h @@ -3,8 +3,9 @@ =20 #include #include +#ifdef __x86_64__ #include - +#endif typedef enum WhpxBreakpointState { WHPX_BP_CLEARED =3D 0, WHPX_BP_SET_PENDING, @@ -97,12 +98,16 @@ void whpx_apic_get(DeviceState *s); =20 /* Define function typedef */ LIST_WINHVPLATFORM_FUNCTIONS(WHP_DEFINE_TYPE) +#ifdef __x86_64__ LIST_WINHVEMULATION_FUNCTIONS(WHP_DEFINE_TYPE) +#endif LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_DEFINE_TYPE) =20 struct WHPDispatch { LIST_WINHVPLATFORM_FUNCTIONS(WHP_DECLARE_MEMBER) +#ifdef __x86_64__ LIST_WINHVEMULATION_FUNCTIONS(WHP_DECLARE_MEMBER) +#endif LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_DECLARE_MEMBER) }; =20 diff --git a/target/i386/whpx/meson.build b/target/i386/whpx/meson.build index 9c54aaad39..c3aaaff9fd 100644 --- a/target/i386/whpx/meson.build +++ b/target/i386/whpx/meson.build @@ -1,5 +1,4 @@ i386_system_ss.add(when: 'CONFIG_WHPX', if_true: files( 'whpx-all.c', 'whpx-apic.c', - 'whpx-accel-ops.c', )) diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c index b72dcff3c8..5a431fc3c7 100644 --- a/target/i386/whpx/whpx-all.c +++ b/target/i386/whpx/whpx-all.c @@ -31,8 +31,8 @@ #include "accel/accel-cpu-target.h" #include =20 -#include "whpx-internal.h" -#include "whpx-accel-ops.h" +#include "system/whpx-internal.h" +#include "system/whpx-accel-ops.h" =20 #include #include --=20 2.39.5 (Apple Git-154) From nobody Sat Nov 15 06:34:09 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753940140; cv=none; d=zohomail.com; s=zohoarc; b=fxh0oVS4eX4wlqiFy8pi0OUUjm8I7TpgOIXqsgeOH9BAwFNsx+6pDn9cKnRNy7arvC0/l1Ye++wvR4d+Pqzwn+GeHHVlr1OxUmQ0hxALD5MNg3huFWpdAOCAkjtB1C4HLCUKeiE11IYpeu/huR8h4PEv7F4u5k3shbwmN2ctmGc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753940140; 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=riHutUUn8qaImwFQHvKTsBAQU3hUYk7RrgWFMBLFJPA=; b=YA6tXaImLIZerAPl0jRtIpAJhbiPSzNSLrSpX1dGE/QtutbzKSkvSB/eQmk+ZO405EQo7/naxJq4aXwlRv6rc2wxyAJrLL+vram99xyx697ECpGYyho0d8tZ7gW1PlqwFD4GvM4ybFYoYlHjNrwaACVPFActKAv/60+QM3uR+50= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753940140546100.5166172056638; Wed, 30 Jul 2025 22:35:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLr8-00015N-Pp; Thu, 31 Jul 2025 01:29:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpr-0007WG-0c for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:11 -0400 Received: from p-east3-cluster7-host12-snip4-3.eps.apple.com ([57.103.84.244] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpl-0005kx-Pc for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:10 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id 802EF180012A; Thu, 31 Jul 2025 05:28:00 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id 7FECB180011E; Thu, 31 Jul 2025 05:27:58 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=riHutUUn8qaImwFQHvKTsBAQU3hUYk7RrgWFMBLFJPA=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=eqUv7zodN9XzLGCoNUvvtlIMEsfQuwtTaqKUs2RbBOzfaHiUpbmD5kwsl5+186jaWRfct9q3MFfUGZh52/9l9z2KaQ9nuZvlT0essRJyJNxodC5KlKosU0cIT+Y2F4FTdj/LlN4v+9RyQ1rK89rLyS4HBtO9xdyKq75dERysCCYXa5F5FI69RedeNancX6YAWVbP1aXSGXl85uRWzPPFc+Mi+CUNWP0Quvq7KLcF4WLoOK79p3igQzA0yIqrVi3z0Dn+3vq1ZCbT7plY9rPynIw27387bibSUW6YcxCjSEXHhiATM5lf7DIA7ug8Od0Fap70zgQv5dTTcTCkAoH0Ww== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 2/9] whpx: reshuffle common code Date: Thu, 31 Jul 2025 07:27:46 +0200 Message-Id: <20250731052753.93255-3-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfXx106+C7mHQ32 HHDD3GYYVgD9y+YLcN07xOTYJWWkK7dn7PD6VS464uHJfjod23hO+mu0RSCL2Sa3Fr2TT8IVUED sAS3X5pPrWILjil4/bsOd3r35CkmmMZ+439o+3qZqiNd1LPNvY/JxI+ojDPcwBwfIrG9s/TjWEu Qk8QCCww2XMWD+7el1GTDf10Sy3jmPbouseMAF/r9kypR11QfMFgKBs2cpzHGTeS00Kz5OIETPM 0Ani1VebuQ67DTf3Dd3S752p9ZmSxg7alCblG5I4HMmNHU89oE56fR11VzkkeOTl3VHTKPLjc= X-Proofpoint-GUID: zCMafaiK5X_T9TbKC2eScUCQCyATMb0W X-Proofpoint-ORIG-GUID: zCMafaiK5X_T9TbKC2eScUCQCyATMb0W X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=0 adultscore=0 mlxlogscore=999 clxscore=1030 mlxscore=0 phishscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.84.244; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753940142763116600 Content-Type: text/plain; charset="utf-8" Some code can be shared between x86_64 and arm64 WHPX. Do so as much as rea= sonable. Signed-off-by: Mohamed Mediouni --- accel/whpx/meson.build | 1 + accel/whpx/whpx-common.c | 578 ++++++++++++++++++++++++++++++++ include/system/whpx-accel-ops.h | 4 +- include/system/whpx-all.h | 12 + include/system/whpx-common.h | 22 ++ include/system/whpx-internal.h | 4 +- target/i386/whpx/whpx-all.c | 520 +--------------------------- target/i386/whpx/whpx-apic.c | 2 +- 8 files changed, 622 insertions(+), 521 deletions(-) create mode 100644 accel/whpx/whpx-common.c create mode 100644 include/system/whpx-all.h create mode 100644 include/system/whpx-common.h diff --git a/accel/whpx/meson.build b/accel/whpx/meson.build index 659efb13c9..344b2b45d0 100644 --- a/accel/whpx/meson.build +++ b/accel/whpx/meson.build @@ -1,6 +1,7 @@ whpx_ss =3D ss.source_set() whpx_ss.add(files( 'whpx-accel-ops.c', + 'whpx-common.c' )) =20 specific_ss.add_all(when: 'CONFIG_WHPX', if_true: whpx_ss) \ No newline at end of file diff --git a/accel/whpx/whpx-common.c b/accel/whpx/whpx-common.c new file mode 100644 index 0000000000..0b23deb7c4 --- /dev/null +++ b/accel/whpx/whpx-common.c @@ -0,0 +1,578 @@ +/* + * QEMU Windows Hypervisor Platform accelerator (WHPX) + * + * Copyright Microsoft Corp. 2017 + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "system/address-spaces.h" +#include "system/ioport.h" +#include "gdbstub/helpers.h" +#include "qemu/accel.h" +#include "accel/accel-ops.h" +#include "system/whpx.h" +#include "system/cpus.h" +#include "system/runstate.h" +#include "qemu/main-loop.h" +#include "hw/boards.h" +#include "hw/intc/ioapic.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "qapi/qapi-types-common.h" +#include "qapi/qapi-visit-common.h" +#include "migration/blocker.h" +#include "accel/accel-cpu-target.h" +#include + +#include "system/whpx-internal.h" +#include "system/whpx-accel-ops.h" +#include "system/whpx-common.h" +#include "system/whpx-all.h" + +#include +#include + +bool whpx_allowed; +static bool whp_dispatch_initialized; +static HMODULE hWinHvPlatform; +#ifdef __x86_64__ +static HMODULE hWinHvEmulation; +#endif + +struct whpx_state whpx_global; +struct WHPDispatch whp_dispatch; + +/* Tries to find a breakpoint at the specified address. */ +struct whpx_breakpoint *whpx_lookup_breakpoint_by_addr(uint64_t address) +{ + struct whpx_state *whpx =3D &whpx_global; + int i; + + if (whpx->breakpoints.breakpoints) { + for (i =3D 0; i < whpx->breakpoints.breakpoints->used; i++) { + if (address =3D=3D whpx->breakpoints.breakpoints->data[i].addr= ess) { + return &whpx->breakpoints.breakpoints->data[i]; + } + } + } + + return NULL; +} + +/* + * This function is called when the a VCPU is about to start and no other + * VCPUs have been started so far. Since the VCPU start order could be + * arbitrary, it doesn't have to be VCPU#0. + * + * It is used to commit the breakpoints into memory, and configure WHPX + * to intercept debug exceptions. + * + * Note that whpx_set_exception_exit_bitmap() cannot be called if one or + * more VCPUs are already running, so this is the best place to do it. + */ +int whpx_first_vcpu_starting(CPUState *cpu) +{ + struct whpx_state *whpx =3D &whpx_global; + + g_assert(bql_locked()); + + if (!QTAILQ_EMPTY(&cpu->breakpoints) || + (whpx->breakpoints.breakpoints && + whpx->breakpoints.breakpoints->used)) { + CPUBreakpoint *bp; + int i =3D 0; + bool update_pending =3D false; + + QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) { + if (i >=3D whpx->breakpoints.original_address_count || + bp->pc !=3D whpx->breakpoints.original_addresses[i]) { + update_pending =3D true; + } + + i++; + } + + if (i !=3D whpx->breakpoints.original_address_count) { + update_pending =3D true; + } + + if (update_pending) { + /* + * The CPU breakpoints have changed since the last call to + * whpx_translate_cpu_breakpoints(). WHPX breakpoints must + * now be recomputed. + */ +#ifdef __x86_64__ + whpx_translate_cpu_breakpoints(&whpx->breakpoints, cpu, i); +#endif + } +#ifdef __x86_64__ + /* Actually insert the breakpoints into the memory. */ + whpx_apply_breakpoints(whpx->breakpoints.breakpoints, cpu, true); +#endif + } +#ifdef __x86_64__ + HRESULT hr; + uint64_t exception_mask; + if (whpx->step_pending || + (whpx->breakpoints.breakpoints && + whpx->breakpoints.breakpoints->used)) { + /* + * We are either attempting to single-step one or more CPUs, or + * have one or more breakpoints enabled. Both require intercepting + * the WHvX64ExceptionTypeBreakpointTrap exception. + */ + exception_mask =3D 1UL << WHvX64ExceptionTypeDebugTrapOrFault; + } else { + /* Let the guest handle all exceptions. */ + exception_mask =3D 0; + } + hr =3D whpx_set_exception_exit_bitmap(exception_mask); + if (!SUCCEEDED(hr)) { + error_report("WHPX: Failed to update exception exit mask," + "hr=3D%08lx.", hr); + return 1; + } +#endif + return 0; +} + +/* + * This function is called when the last VCPU has finished running. + * It is used to remove any previously set breakpoints from memory. + */ +int whpx_last_vcpu_stopping(CPUState *cpu) +{ +#ifdef __x86_64__ + whpx_apply_breakpoints(whpx_global.breakpoints.breakpoints, cpu, false= ); +#endif + return 0; +} + +static void do_whpx_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data a= rg) +{ + if (!cpu->vcpu_dirty) { + whpx_get_registers(cpu); + cpu->vcpu_dirty =3D true; + } +} + +static void do_whpx_cpu_synchronize_post_reset(CPUState *cpu, + run_on_cpu_data arg) +{ + whpx_set_registers(cpu, WHPX_SET_RESET_STATE); + cpu->vcpu_dirty =3D false; +} + +static void do_whpx_cpu_synchronize_post_init(CPUState *cpu, + run_on_cpu_data arg) +{ + whpx_set_registers(cpu, WHPX_SET_FULL_STATE); + cpu->vcpu_dirty =3D false; +} + +static void do_whpx_cpu_synchronize_pre_loadvm(CPUState *cpu, + run_on_cpu_data arg) +{ + cpu->vcpu_dirty =3D true; +} + +/* + * CPU support. + */ + +void whpx_cpu_synchronize_state(CPUState *cpu) +{ + if (!cpu->vcpu_dirty) { + run_on_cpu(cpu, do_whpx_cpu_synchronize_state, RUN_ON_CPU_NULL); + } +} + +void whpx_cpu_synchronize_post_reset(CPUState *cpu) +{ + run_on_cpu(cpu, do_whpx_cpu_synchronize_post_reset, RUN_ON_CPU_NULL); +} + +void whpx_cpu_synchronize_post_init(CPUState *cpu) +{ + run_on_cpu(cpu, do_whpx_cpu_synchronize_post_init, RUN_ON_CPU_NULL); +} + +void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu) +{ + run_on_cpu(cpu, do_whpx_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL); +} + +static void whpx_pre_resume_vm(AccelState *as, bool step_pending) +{ + whpx_global.step_pending =3D step_pending; +} + +/* + * Vcpu support. + */ + +int whpx_vcpu_exec(CPUState *cpu) +{ + int ret; + int fatal; + + for (;;) { + if (cpu->exception_index >=3D EXCP_INTERRUPT) { + ret =3D cpu->exception_index; + cpu->exception_index =3D -1; + break; + } + + fatal =3D whpx_vcpu_run(cpu); + + if (fatal) { + error_report("WHPX: Failed to exec a virtual processor"); + abort(); + } + } + + return ret; +} + +void whpx_destroy_vcpu(CPUState *cpu) +{ + struct whpx_state *whpx =3D &whpx_global; + + whp_dispatch.WHvDeleteVirtualProcessor(whpx->partition, cpu->cpu_index= ); +#ifdef __x86_64__ + AccelCPUState *vcpu =3D cpu->accel; + whp_dispatch.WHvEmulatorDestroyEmulator(vcpu->emulator); +#endif + g_free(cpu->accel); +} + + +void whpx_vcpu_kick(CPUState *cpu) +{ + struct whpx_state *whpx =3D &whpx_global; + whp_dispatch.WHvCancelRunVirtualProcessor( + whpx->partition, cpu->cpu_index, 0); +} + +/* + * Memory support. + */ + +static void whpx_update_mapping(hwaddr start_pa, ram_addr_t size, + void *host_va, int add, int rom, + const char *name) +{ + struct whpx_state *whpx =3D &whpx_global; + HRESULT hr; + + /* + if (add) { + printf("WHPX: ADD PA:%p Size:%p, Host:%p, %s, '%s'\n", + (void*)start_pa, (void*)size, host_va, + (rom ? "ROM" : "RAM"), name); + } else { + printf("WHPX: DEL PA:%p Size:%p, Host:%p, '%s'\n", + (void*)start_pa, (void*)size, host_va, name); + } + */ + + if (add) { + hr =3D whp_dispatch.WHvMapGpaRange(whpx->partition, + host_va, + start_pa, + size, + (WHvMapGpaRangeFlagRead | + WHvMapGpaRangeFlagExecute | + (rom ? 0 : WHvMapGpaRangeFlagWri= te))); + } else { + hr =3D whp_dispatch.WHvUnmapGpaRange(whpx->partition, + start_pa, + size); + } + + if (FAILED(hr)) { + error_report("WHPX: Failed to %s GPA range '%s' PA:%p, Size:%p byt= es," + " Host:%p, hr=3D%08lx", + (add ? "MAP" : "UNMAP"), name, + (void *)(uintptr_t)start_pa, (void *)size, host_va, h= r); + } +} + +static void whpx_process_section(MemoryRegionSection *section, int add) +{ + MemoryRegion *mr =3D section->mr; + hwaddr start_pa =3D section->offset_within_address_space; + ram_addr_t size =3D int128_get64(section->size); + unsigned int delta; + uint64_t host_va; + + if (!memory_region_is_ram(mr)) { + return; + } + + delta =3D qemu_real_host_page_size() - (start_pa & ~qemu_real_host_pag= e_mask()); + delta &=3D ~qemu_real_host_page_mask(); + if (delta > size) { + return; + } + start_pa +=3D delta; + size -=3D delta; + size &=3D qemu_real_host_page_mask(); + if (!size || (start_pa & ~qemu_real_host_page_mask())) { + return; + } + + host_va =3D (uintptr_t)memory_region_get_ram_ptr(mr) + + section->offset_within_region + delta; + + whpx_update_mapping(start_pa, size, (void *)(uintptr_t)host_va, add, + memory_region_is_rom(mr), mr->name); +} + +static void whpx_region_add(MemoryListener *listener, + MemoryRegionSection *section) +{ + memory_region_ref(section->mr); + whpx_process_section(section, 1); +} + +static void whpx_region_del(MemoryListener *listener, + MemoryRegionSection *section) +{ + whpx_process_section(section, 0); + memory_region_unref(section->mr); +} + +static void whpx_transaction_begin(MemoryListener *listener) +{ +} + +static void whpx_transaction_commit(MemoryListener *listener) +{ +} + +static void whpx_log_sync(MemoryListener *listener, + MemoryRegionSection *section) +{ + MemoryRegion *mr =3D section->mr; + + if (!memory_region_is_ram(mr)) { + return; + } + + memory_region_set_dirty(mr, 0, int128_get64(section->size)); +} + +static MemoryListener whpx_memory_listener =3D { + .name =3D "whpx", + .begin =3D whpx_transaction_begin, + .commit =3D whpx_transaction_commit, + .region_add =3D whpx_region_add, + .region_del =3D whpx_region_del, + .log_sync =3D whpx_log_sync, + .priority =3D MEMORY_LISTENER_PRIORITY_ACCEL, +}; + +void whpx_memory_init(void) +{ + memory_listener_register(&whpx_memory_listener, &address_space_memory); +} + +/* + * Load the functions from the given library, using the given handle. If a + * handle is provided, it is used, otherwise the library is opened. The + * handle will be updated on return with the opened one. + */ +static bool load_whp_dispatch_fns(HMODULE *handle, + WHPFunctionList function_list) +{ + HMODULE hLib =3D *handle; + + #define WINHV_PLATFORM_DLL "WinHvPlatform.dll" + #define WINHV_EMULATION_DLL "WinHvEmulation.dll" + #define WHP_LOAD_FIELD_OPTIONAL(return_type, function_name, signature)= \ + whp_dispatch.function_name =3D \ + (function_name ## _t)GetProcAddress(hLib, #function_name); \ + + #define WHP_LOAD_FIELD(return_type, function_name, signature) \ + whp_dispatch.function_name =3D \ + (function_name ## _t)GetProcAddress(hLib, #function_name); \ + if (!whp_dispatch.function_name) { \ + error_report("Could not load function %s", #function_name); \ + goto error; \ + } \ + + #define WHP_LOAD_LIB(lib_name, handle_lib) \ + if (!handle_lib) { \ + handle_lib =3D LoadLibrary(lib_name); \ + if (!handle_lib) { \ + error_report("Could not load library %s.", lib_name); \ + goto error; \ + } \ + } \ + + switch (function_list) { + case WINHV_PLATFORM_FNS_DEFAULT: + WHP_LOAD_LIB(WINHV_PLATFORM_DLL, hLib) + LIST_WINHVPLATFORM_FUNCTIONS(WHP_LOAD_FIELD) + break; + case WINHV_EMULATION_FNS_DEFAULT: +#ifdef __x86_64__ + WHP_LOAD_LIB(WINHV_EMULATION_DLL, hLib) + LIST_WINHVEMULATION_FUNCTIONS(WHP_LOAD_FIELD) +#else + abort(); +#endif + break; + case WINHV_PLATFORM_FNS_SUPPLEMENTAL: + WHP_LOAD_LIB(WINHV_PLATFORM_DLL, hLib) + LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_LOAD_FIELD_OPTIONAL) + break; + } + + *handle =3D hLib; + return true; + +error: + if (hLib) { + FreeLibrary(hLib); + } + + return false; +} + +static void whpx_set_kernel_irqchip(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + struct whpx_state *whpx =3D &whpx_global; + OnOffSplit mode; + + if (!visit_type_OnOffSplit(v, name, &mode, errp)) { + return; + } + + switch (mode) { + case ON_OFF_SPLIT_ON: + whpx->kernel_irqchip_allowed =3D true; + whpx->kernel_irqchip_required =3D true; + break; + + case ON_OFF_SPLIT_OFF: + whpx->kernel_irqchip_allowed =3D false; + whpx->kernel_irqchip_required =3D false; + break; + + case ON_OFF_SPLIT_SPLIT: + error_setg(errp, "WHPX: split irqchip currently not supported"); + error_append_hint(errp, + "Try without kernel-irqchip or with kernel-irqchip=3Don|off"); + break; + + default: + /* + * The value was checked in visit_type_OnOffSplit() above. If + * we get here, then something is wrong in QEMU. + */ + abort(); + } +} + +static void whpx_cpu_accel_class_init(ObjectClass *oc, const void *data) +{ + AccelCPUClass *acc =3D ACCEL_CPU_CLASS(oc); + + acc->cpu_instance_init =3D whpx_cpu_instance_init; +} + +static const TypeInfo whpx_cpu_accel_type =3D { + .name =3D ACCEL_CPU_NAME("whpx"), + + .parent =3D TYPE_ACCEL_CPU, + .class_init =3D whpx_cpu_accel_class_init, + .abstract =3D true, +}; + +/* + * Partition support + */ + +bool whpx_apic_in_platform(void) { + return whpx_global.apic_in_platform; +} + +static void whpx_accel_class_init(ObjectClass *oc, const void *data) +{ + AccelClass *ac =3D ACCEL_CLASS(oc); + ac->name =3D "WHPX"; + ac->init_machine =3D whpx_accel_init; + ac->pre_resume_vm =3D whpx_pre_resume_vm; + ac->allowed =3D &whpx_allowed; + + object_class_property_add(oc, "kernel-irqchip", "on|off|split", + NULL, whpx_set_kernel_irqchip, + NULL, NULL); + object_class_property_set_description(oc, "kernel-irqchip", + "Configure WHPX in-kernel irqchip"); +} + +static void whpx_accel_instance_init(Object *obj) +{ + struct whpx_state *whpx =3D &whpx_global; + + memset(whpx, 0, sizeof(struct whpx_state)); + /* Turn on kernel-irqchip, by default */ + whpx->kernel_irqchip_allowed =3D true; +} + +static const TypeInfo whpx_accel_type =3D { + .name =3D ACCEL_CLASS_NAME("whpx"), + .parent =3D TYPE_ACCEL, + .instance_init =3D whpx_accel_instance_init, + .class_init =3D whpx_accel_class_init, +}; + +static void whpx_type_init(void) +{ + type_register_static(&whpx_accel_type); + type_register_static(&whpx_cpu_accel_type); +} + +bool init_whp_dispatch(void) +{ + if (whp_dispatch_initialized) { + return true; + } + + if (!load_whp_dispatch_fns(&hWinHvPlatform, WINHV_PLATFORM_FNS_DEFAULT= )) { + goto error; + } +#ifdef __x86_64__ + if (!load_whp_dispatch_fns(&hWinHvEmulation, WINHV_EMULATION_FNS_DEFAU= LT)) { + goto error; + } +#endif + assert(load_whp_dispatch_fns(&hWinHvPlatform, + WINHV_PLATFORM_FNS_SUPPLEMENTAL)); + whp_dispatch_initialized =3D true; + + return true; +error: + if (hWinHvPlatform) { + FreeLibrary(hWinHvPlatform); + } +#ifdef __x86_64__ + if (hWinHvEmulation) { + FreeLibrary(hWinHvEmulation); + } +#endif + return false; +} + +type_init(whpx_type_init); diff --git a/include/system/whpx-accel-ops.h b/include/system/whpx-accel-op= s.h index 54cfc25a14..ed9d4c49f4 100644 --- a/include/system/whpx-accel-ops.h +++ b/include/system/whpx-accel-ops.h @@ -7,8 +7,8 @@ * See the COPYING file in the top-level directory. */ =20 -#ifndef TARGET_I386_WHPX_ACCEL_OPS_H -#define TARGET_I386_WHPX_ACCEL_OPS_H +#ifndef SYSTEM_WHPX_ACCEL_OPS_H +#define SYSTEM_WHPX_ACCEL_OPS_H =20 #include "system/cpus.h" =20 diff --git a/include/system/whpx-all.h b/include/system/whpx-all.h new file mode 100644 index 0000000000..382b028c83 --- /dev/null +++ b/include/system/whpx-all.h @@ -0,0 +1,12 @@ +#ifndef SYSTEM_WHPX_ALL_H +#define SYSTEM_WHPX_ALL_H + +/* Called by whpx-common */ +int whpx_vcpu_run(CPUState *cpu); +void whpx_get_registers(CPUState *cpu); +void whpx_set_registers(CPUState *cpu, int level); +int whpx_accel_init(AccelState *as, MachineState *ms); +#ifdef __x86_64__ +void whpx_cpu_instance_init(CPUState *cs); +#endif +#endif diff --git a/include/system/whpx-common.h b/include/system/whpx-common.h new file mode 100644 index 0000000000..57c73448a7 --- /dev/null +++ b/include/system/whpx-common.h @@ -0,0 +1,22 @@ +#ifndef SYSTEM_WHPX_COMMON_H +#define SYSTEM_WHPX_COMMON_H + +struct AccelCPUState { +#ifdef __x86_64__ + WHV_EMULATOR_HANDLE emulator; + bool window_registered; + bool interruptable; + bool ready_for_pic_interrupt; + uint64_t tpr; + uint64_t apic_base; + bool interruption_pending; +#endif + /* Must be the last field as it may have a tail */ + WHV_RUN_VP_EXIT_CONTEXT exit_ctx; +}; + +int whpx_first_vcpu_starting(CPUState *cpu); +int whpx_last_vcpu_stopping(CPUState *cpu); +void whpx_memory_init(void); +struct whpx_breakpoint *whpx_lookup_breakpoint_by_addr(uint64_t address); +#endif \ No newline at end of file diff --git a/include/system/whpx-internal.h b/include/system/whpx-internal.h index af1e46a491..4b613c4bb5 100644 --- a/include/system/whpx-internal.h +++ b/include/system/whpx-internal.h @@ -1,5 +1,5 @@ -#ifndef TARGET_I386_WHPX_INTERNAL_H -#define TARGET_I386_WHPX_INTERNAL_H +#ifndef SYSTEM_WHPX_INTERNAL_H +#define SYSTEM_WHPX_INTERNAL_H =20 #include #include diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c index 5a431fc3c7..de013ba88c 100644 --- a/target/i386/whpx/whpx-all.c +++ b/target/i386/whpx/whpx-all.c @@ -33,6 +33,8 @@ =20 #include "system/whpx-internal.h" #include "system/whpx-accel-ops.h" +#include "system/whpx-all.h" +#include "system/whpx-common.h" =20 #include #include @@ -1081,23 +1083,6 @@ static HRESULT whpx_vcpu_configure_single_stepping(C= PUState *cpu, return S_OK; } =20 -/* Tries to find a breakpoint at the specified address. */ -static struct whpx_breakpoint *whpx_lookup_breakpoint_by_addr(uint64_t add= ress) -{ - struct whpx_state *whpx =3D &whpx_global; - int i; - - if (whpx->breakpoints.breakpoints) { - for (i =3D 0; i < whpx->breakpoints.breakpoints->used; i++) { - if (address =3D=3D whpx->breakpoints.breakpoints->data[i].addr= ess) { - return &whpx->breakpoints.breakpoints->data[i]; - } - } - } - - return NULL; -} - /* * Linux uses int3 (0xCC) during startup (see int3_selftest()) and for * debugging user-mode applications. Since the WHPX API does not offer @@ -1303,93 +1288,6 @@ static void whpx_apply_breakpoints( } } =20 -/* - * This function is called when the a VCPU is about to start and no other - * VCPUs have been started so far. Since the VCPU start order could be - * arbitrary, it doesn't have to be VCPU#0. - * - * It is used to commit the breakpoints into memory, and configure WHPX - * to intercept debug exceptions. - * - * Note that whpx_set_exception_exit_bitmap() cannot be called if one or - * more VCPUs are already running, so this is the best place to do it. - */ -static int whpx_first_vcpu_starting(CPUState *cpu) -{ - struct whpx_state *whpx =3D &whpx_global; - HRESULT hr; - - g_assert(bql_locked()); - - if (!QTAILQ_EMPTY(&cpu->breakpoints) || - (whpx->breakpoints.breakpoints && - whpx->breakpoints.breakpoints->used)) { - CPUBreakpoint *bp; - int i =3D 0; - bool update_pending =3D false; - - QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) { - if (i >=3D whpx->breakpoints.original_address_count || - bp->pc !=3D whpx->breakpoints.original_addresses[i]) { - update_pending =3D true; - } - - i++; - } - - if (i !=3D whpx->breakpoints.original_address_count) { - update_pending =3D true; - } - - if (update_pending) { - /* - * The CPU breakpoints have changed since the last call to - * whpx_translate_cpu_breakpoints(). WHPX breakpoints must - * now be recomputed. - */ - whpx_translate_cpu_breakpoints(&whpx->breakpoints, cpu, i); - } - - /* Actually insert the breakpoints into the memory. */ - whpx_apply_breakpoints(whpx->breakpoints.breakpoints, cpu, true); - } - - uint64_t exception_mask; - if (whpx->step_pending || - (whpx->breakpoints.breakpoints && - whpx->breakpoints.breakpoints->used)) { - /* - * We are either attempting to single-step one or more CPUs, or - * have one or more breakpoints enabled. Both require intercepting - * the WHvX64ExceptionTypeBreakpointTrap exception. - */ - - exception_mask =3D 1UL << WHvX64ExceptionTypeDebugTrapOrFault; - } else { - /* Let the guest handle all exceptions. */ - exception_mask =3D 0; - } - - hr =3D whpx_set_exception_exit_bitmap(exception_mask); - if (!SUCCEEDED(hr)) { - error_report("WHPX: Failed to update exception exit mask," - "hr=3D%08lx.", hr); - return 1; - } - - return 0; -} - -/* - * This function is called when the last VCPU has finished running. - * It is used to remove any previously set breakpoints from memory. - */ -static int whpx_last_vcpu_stopping(CPUState *cpu) -{ - whpx_apply_breakpoints(whpx_global.breakpoints.breakpoints, cpu, false= ); - return 0; -} - /* Returns the address of the next instruction that is about to be execute= d. */ static vaddr whpx_vcpu_get_pc(CPUState *cpu, bool exit_context_valid) { @@ -2054,65 +1952,6 @@ static int whpx_vcpu_run(CPUState *cpu) return ret < 0; } =20 -static void do_whpx_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data a= rg) -{ - if (!cpu->vcpu_dirty) { - whpx_get_registers(cpu); - cpu->vcpu_dirty =3D true; - } -} - -static void do_whpx_cpu_synchronize_post_reset(CPUState *cpu, - run_on_cpu_data arg) -{ - whpx_set_registers(cpu, WHPX_SET_RESET_STATE); - cpu->vcpu_dirty =3D false; -} - -static void do_whpx_cpu_synchronize_post_init(CPUState *cpu, - run_on_cpu_data arg) -{ - whpx_set_registers(cpu, WHPX_SET_FULL_STATE); - cpu->vcpu_dirty =3D false; -} - -static void do_whpx_cpu_synchronize_pre_loadvm(CPUState *cpu, - run_on_cpu_data arg) -{ - cpu->vcpu_dirty =3D true; -} - -/* - * CPU support. - */ - -void whpx_cpu_synchronize_state(CPUState *cpu) -{ - if (!cpu->vcpu_dirty) { - run_on_cpu(cpu, do_whpx_cpu_synchronize_state, RUN_ON_CPU_NULL); - } -} - -void whpx_cpu_synchronize_post_reset(CPUState *cpu) -{ - run_on_cpu(cpu, do_whpx_cpu_synchronize_post_reset, RUN_ON_CPU_NULL); -} - -void whpx_cpu_synchronize_post_init(CPUState *cpu) -{ - run_on_cpu(cpu, do_whpx_cpu_synchronize_post_init, RUN_ON_CPU_NULL); -} - -void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu) -{ - run_on_cpu(cpu, do_whpx_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL); -} - -static void whpx_pre_resume_vm(AccelState *as, bool step_pending) -{ - whpx_global.step_pending =3D step_pending; -} - /* * Vcpu support. */ @@ -2241,295 +2080,18 @@ error: return ret; } =20 -int whpx_vcpu_exec(CPUState *cpu) -{ - int ret; - int fatal; - - for (;;) { - if (cpu->exception_index >=3D EXCP_INTERRUPT) { - ret =3D cpu->exception_index; - cpu->exception_index =3D -1; - break; - } - - fatal =3D whpx_vcpu_run(cpu); - - if (fatal) { - error_report("WHPX: Failed to exec a virtual processor"); - abort(); - } - } - - return ret; -} - -void whpx_destroy_vcpu(CPUState *cpu) -{ - struct whpx_state *whpx =3D &whpx_global; - AccelCPUState *vcpu =3D cpu->accel; - - whp_dispatch.WHvDeleteVirtualProcessor(whpx->partition, cpu->cpu_index= ); - whp_dispatch.WHvEmulatorDestroyEmulator(vcpu->emulator); - g_free(cpu->accel); -} - -void whpx_vcpu_kick(CPUState *cpu) -{ - struct whpx_state *whpx =3D &whpx_global; - whp_dispatch.WHvCancelRunVirtualProcessor( - whpx->partition, cpu->cpu_index, 0); -} - -/* - * Memory support. - */ - -static void whpx_update_mapping(hwaddr start_pa, ram_addr_t size, - void *host_va, int add, int rom, - const char *name) -{ - struct whpx_state *whpx =3D &whpx_global; - HRESULT hr; - - /* - if (add) { - printf("WHPX: ADD PA:%p Size:%p, Host:%p, %s, '%s'\n", - (void*)start_pa, (void*)size, host_va, - (rom ? "ROM" : "RAM"), name); - } else { - printf("WHPX: DEL PA:%p Size:%p, Host:%p, '%s'\n", - (void*)start_pa, (void*)size, host_va, name); - } - */ - - if (add) { - hr =3D whp_dispatch.WHvMapGpaRange(whpx->partition, - host_va, - start_pa, - size, - (WHvMapGpaRangeFlagRead | - WHvMapGpaRangeFlagExecute | - (rom ? 0 : WHvMapGpaRangeFlagWri= te))); - } else { - hr =3D whp_dispatch.WHvUnmapGpaRange(whpx->partition, - start_pa, - size); - } - - if (FAILED(hr)) { - error_report("WHPX: Failed to %s GPA range '%s' PA:%p, Size:%p byt= es," - " Host:%p, hr=3D%08lx", - (add ? "MAP" : "UNMAP"), name, - (void *)(uintptr_t)start_pa, (void *)size, host_va, h= r); - } -} - -static void whpx_process_section(MemoryRegionSection *section, int add) -{ - MemoryRegion *mr =3D section->mr; - hwaddr start_pa =3D section->offset_within_address_space; - ram_addr_t size =3D int128_get64(section->size); - unsigned int delta; - uint64_t host_va; - - if (!memory_region_is_ram(mr)) { - return; - } - - delta =3D qemu_real_host_page_size() - (start_pa & ~qemu_real_host_pag= e_mask()); - delta &=3D ~qemu_real_host_page_mask(); - if (delta > size) { - return; - } - start_pa +=3D delta; - size -=3D delta; - size &=3D qemu_real_host_page_mask(); - if (!size || (start_pa & ~qemu_real_host_page_mask())) { - return; - } - - host_va =3D (uintptr_t)memory_region_get_ram_ptr(mr) - + section->offset_within_region + delta; - - whpx_update_mapping(start_pa, size, (void *)(uintptr_t)host_va, add, - memory_region_is_rom(mr), mr->name); -} - -static void whpx_region_add(MemoryListener *listener, - MemoryRegionSection *section) -{ - memory_region_ref(section->mr); - whpx_process_section(section, 1); -} - -static void whpx_region_del(MemoryListener *listener, - MemoryRegionSection *section) -{ - whpx_process_section(section, 0); - memory_region_unref(section->mr); -} - -static void whpx_transaction_begin(MemoryListener *listener) -{ -} - -static void whpx_transaction_commit(MemoryListener *listener) -{ -} - -static void whpx_log_sync(MemoryListener *listener, - MemoryRegionSection *section) -{ - MemoryRegion *mr =3D section->mr; - - if (!memory_region_is_ram(mr)) { - return; - } - - memory_region_set_dirty(mr, 0, int128_get64(section->size)); -} - -static MemoryListener whpx_memory_listener =3D { - .name =3D "whpx", - .begin =3D whpx_transaction_begin, - .commit =3D whpx_transaction_commit, - .region_add =3D whpx_region_add, - .region_del =3D whpx_region_del, - .log_sync =3D whpx_log_sync, - .priority =3D MEMORY_LISTENER_PRIORITY_ACCEL, -}; - -static void whpx_memory_init(void) -{ - memory_listener_register(&whpx_memory_listener, &address_space_memory); -} - -/* - * Load the functions from the given library, using the given handle. If a - * handle is provided, it is used, otherwise the library is opened. The - * handle will be updated on return with the opened one. - */ -static bool load_whp_dispatch_fns(HMODULE *handle, - WHPFunctionList function_list) -{ - HMODULE hLib =3D *handle; - - #define WINHV_PLATFORM_DLL "WinHvPlatform.dll" - #define WINHV_EMULATION_DLL "WinHvEmulation.dll" - #define WHP_LOAD_FIELD_OPTIONAL(return_type, function_name, signature)= \ - whp_dispatch.function_name =3D \ - (function_name ## _t)GetProcAddress(hLib, #function_name); \ - - #define WHP_LOAD_FIELD(return_type, function_name, signature) \ - whp_dispatch.function_name =3D \ - (function_name ## _t)GetProcAddress(hLib, #function_name); \ - if (!whp_dispatch.function_name) { \ - error_report("Could not load function %s", #function_name); \ - goto error; \ - } \ - - #define WHP_LOAD_LIB(lib_name, handle_lib) \ - if (!handle_lib) { \ - handle_lib =3D LoadLibrary(lib_name); \ - if (!handle_lib) { \ - error_report("Could not load library %s.", lib_name); \ - goto error; \ - } \ - } \ - - switch (function_list) { - case WINHV_PLATFORM_FNS_DEFAULT: - WHP_LOAD_LIB(WINHV_PLATFORM_DLL, hLib) - LIST_WINHVPLATFORM_FUNCTIONS(WHP_LOAD_FIELD) - break; - - case WINHV_EMULATION_FNS_DEFAULT: - WHP_LOAD_LIB(WINHV_EMULATION_DLL, hLib) - LIST_WINHVEMULATION_FUNCTIONS(WHP_LOAD_FIELD) - break; - - case WINHV_PLATFORM_FNS_SUPPLEMENTAL: - WHP_LOAD_LIB(WINHV_PLATFORM_DLL, hLib) - LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(WHP_LOAD_FIELD_OPTIONAL) - break; - } - - *handle =3D hLib; - return true; - -error: - if (hLib) { - FreeLibrary(hLib); - } - - return false; -} - -static void whpx_set_kernel_irqchip(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) -{ - struct whpx_state *whpx =3D &whpx_global; - OnOffSplit mode; - - if (!visit_type_OnOffSplit(v, name, &mode, errp)) { - return; - } - - switch (mode) { - case ON_OFF_SPLIT_ON: - whpx->kernel_irqchip_allowed =3D true; - whpx->kernel_irqchip_required =3D true; - break; - - case ON_OFF_SPLIT_OFF: - whpx->kernel_irqchip_allowed =3D false; - whpx->kernel_irqchip_required =3D false; - break; - - case ON_OFF_SPLIT_SPLIT: - error_setg(errp, "WHPX: split irqchip currently not supported"); - error_append_hint(errp, - "Try without kernel-irqchip or with kernel-irqchip=3Don|off"); - break; - - default: - /* - * The value was checked in visit_type_OnOffSplit() above. If - * we get here, then something is wrong in QEMU. - */ - abort(); - } -} - -static void whpx_cpu_instance_init(CPUState *cs) +void whpx_cpu_instance_init(CPUState *cs) { X86CPU *cpu =3D X86_CPU(cs); =20 host_cpu_instance_init(cpu); } =20 -static void whpx_cpu_accel_class_init(ObjectClass *oc, const void *data) -{ - AccelCPUClass *acc =3D ACCEL_CPU_CLASS(oc); - - acc->cpu_instance_init =3D whpx_cpu_instance_init; -} - -static const TypeInfo whpx_cpu_accel_type =3D { - .name =3D ACCEL_CPU_NAME("whpx"), - - .parent =3D TYPE_ACCEL_CPU, - .class_init =3D whpx_cpu_accel_class_init, - .abstract =3D true, -}; - /* * Partition support */ =20 -static int whpx_accel_init(AccelState *as, MachineState *ms) +int whpx_accel_init(AccelState *as, MachineState *ms) { struct whpx_state *whpx; int ret; @@ -2712,77 +2274,3 @@ error: =20 return ret; } - -bool whpx_apic_in_platform(void) { - return whpx_global.apic_in_platform; -} - -static void whpx_accel_class_init(ObjectClass *oc, const void *data) -{ - AccelClass *ac =3D ACCEL_CLASS(oc); - ac->name =3D "WHPX"; - ac->init_machine =3D whpx_accel_init; - ac->pre_resume_vm =3D whpx_pre_resume_vm; - ac->allowed =3D &whpx_allowed; - - object_class_property_add(oc, "kernel-irqchip", "on|off|split", - NULL, whpx_set_kernel_irqchip, - NULL, NULL); - object_class_property_set_description(oc, "kernel-irqchip", - "Configure WHPX in-kernel irqchip"); -} - -static void whpx_accel_instance_init(Object *obj) -{ - struct whpx_state *whpx =3D &whpx_global; - - memset(whpx, 0, sizeof(struct whpx_state)); - /* Turn on kernel-irqchip, by default */ - whpx->kernel_irqchip_allowed =3D true; -} - -static const TypeInfo whpx_accel_type =3D { - .name =3D ACCEL_CLASS_NAME("whpx"), - .parent =3D TYPE_ACCEL, - .instance_init =3D whpx_accel_instance_init, - .class_init =3D whpx_accel_class_init, -}; - -static void whpx_type_init(void) -{ - type_register_static(&whpx_accel_type); - type_register_static(&whpx_cpu_accel_type); -} - -bool init_whp_dispatch(void) -{ - if (whp_dispatch_initialized) { - return true; - } - - if (!load_whp_dispatch_fns(&hWinHvPlatform, WINHV_PLATFORM_FNS_DEFAULT= )) { - goto error; - } - - if (!load_whp_dispatch_fns(&hWinHvEmulation, WINHV_EMULATION_FNS_DEFAU= LT)) { - goto error; - } - - assert(load_whp_dispatch_fns(&hWinHvPlatform, - WINHV_PLATFORM_FNS_SUPPLEMENTAL)); - whp_dispatch_initialized =3D true; - - return true; -error: - if (hWinHvPlatform) { - FreeLibrary(hWinHvPlatform); - } - - if (hWinHvEmulation) { - FreeLibrary(hWinHvEmulation); - } - - return false; -} - -type_init(whpx_type_init); diff --git a/target/i386/whpx/whpx-apic.c b/target/i386/whpx/whpx-apic.c index e1ef6d4e6d..badb404b63 100644 --- a/target/i386/whpx/whpx-apic.c +++ b/target/i386/whpx/whpx-apic.c @@ -18,7 +18,7 @@ #include "hw/pci/msi.h" #include "system/hw_accel.h" #include "system/whpx.h" -#include "whpx-internal.h" +#include "system/whpx-internal.h" =20 struct whpx_lapic_state { struct { --=20 2.39.5 (Apple Git-154) From nobody Sat Nov 15 06:34:09 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753939793; cv=none; d=zohomail.com; s=zohoarc; b=H7gInYFT8z58Bemdlyi8oHxleokpx2CvlT8BJEOsTXFqkdSBDzkRLpUhUi6ZbOUr0AESe7SqIQgrbZGbrjzC6EyKllzvOzE12MWrKOeallSrBqzy07j2VjhK6gBOjufBsKW/pE0I0poeHSfIF9jqhYbTZTZh4EYXuDbTGD7Px90= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753939793; 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=AGjseZ7zt0l8FHwCnnZpSePqyk5P3OktatL+TergPl8=; b=RvJXRIDfUfE1xBV7UCIs53a2j5Qyc9Je6GBndfbC/rPpgHNIYcM8SPWBzFedcm86O+nmskwhPJIpWc2gTgWzF5PwWVoK24LjuooWKJqx7uOdxhz/6B1ctrhxjROzBViYG6YYwTtgobaqjr+sHSbfKtcxLG8v3n1mtN9tsqmiXFs= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753939793388270.71864900889557; Wed, 30 Jul 2025 22:29:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLr7-00011q-4B; Thu, 31 Jul 2025 01:29:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpo-0007RM-NA for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:08 -0400 Received: from p-east3-cluster2-host8-snip4-1.eps.apple.com ([57.103.87.202] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpl-0005lB-Vd for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:08 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id DB934180013C; Thu, 31 Jul 2025 05:28:01 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id C8E3A180012B; Thu, 31 Jul 2025 05:27:59 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=AGjseZ7zt0l8FHwCnnZpSePqyk5P3OktatL+TergPl8=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=D00Xzk/hUA1M+pUNPazVo18rFFQQvBY2DRCBrXNzJYiNTlAftvh3hwCgjV+ngWrmOTysv3f2gNjD+1v9NQVjJmW5RZwtxm69WUMpt1lVv/ZhAifedaO8s6emmZnFm3xBvkJvDc0Rij3sSytxjhLji1QKx9aM/xqS/pgZYjmOocLNOKLrnrZCltb49AfWG+G1zn1fik05NhIn47JUxbGLLlZkX101ZqbyZFYYevYZCdp/TK7sU1fu9BbbQSHSG4yjG4QzPnzrVX3ElrJmeSQrJ6Jm687uvpW4a5vqqBd3X9d7Dn6SKqUb1lH6TUVxWQ9O0NGeRzGzx9HG2k7/YJnhnA== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 3/9] whpx: common: use whpx_cpu_instance_init on x86 only Date: Thu, 31 Jul 2025 07:27:47 +0200 Message-Id: <20250731052753.93255-4-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: cABgd0-QmIkgcGeS8oPHSkR8dxmLUlvg X-Proofpoint-ORIG-GUID: cABgd0-QmIkgcGeS8oPHSkR8dxmLUlvg X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfX9gZch5YZwLfq VSNhL9ppekpHLYXRSMt5zgniXqbwwUwPq3S4TmC8cYSPEZLcc/KciKvRPk9mV53GD5MBJ/oG43C S4T6bYqhO4vDrEOxdu5rVjn2/GJejqdEms95uV2+EQVP+BPu2Norvi6N+biFPOBJtau1Sg2i017 cPiZxUfo7WOWFWbnvTupcQj/H3tkOycL02BnslRL3PwAg5e+zR1AOLVCUDlNeoV7l5bzkuIkdzx DcEbuXG3bMMdmUsfQ7c1nrtU3febRkYmBFWGOEmdeC0yPNulTNFwDzbd4a90wV5//1M5c1ge0= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 mlxlogscore=885 mlxscore=0 malwarescore=0 bulkscore=0 clxscore=1030 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.87.202; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753939797089116600 Content-Type: text/plain; charset="utf-8" We aren't using it on arm64. Signed-off-by: Mohamed Mediouni --- accel/whpx/whpx-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accel/whpx/whpx-common.c b/accel/whpx/whpx-common.c index 0b23deb7c4..43d0200afd 100644 --- a/accel/whpx/whpx-common.c +++ b/accel/whpx/whpx-common.c @@ -486,9 +486,10 @@ static void whpx_set_kernel_irqchip(Object *obj, Visit= or *v, =20 static void whpx_cpu_accel_class_init(ObjectClass *oc, const void *data) { +#ifdef __x86_64__ AccelCPUClass *acc =3D ACCEL_CPU_CLASS(oc); - acc->cpu_instance_init =3D whpx_cpu_instance_init; +#endif } =20 static const TypeInfo whpx_cpu_accel_type =3D { --=20 2.39.5 (Apple Git-154) From nobody Sat Nov 15 06:34:09 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753940152; cv=none; d=zohomail.com; s=zohoarc; b=jIa3fL/8QHFJVR6yOY+PO/v4Z2Hvb0e6uQ7n6tqA/8PwISy4avfMUmFVnmHw3yVSqnqkhMfPq7Rs1HoKUtc6YE2HM7Zxk6HpKcMKYPSnos6XbhRfbyt6THh8b3LUzDoU/eXo8B0kTeOiy87CnH2J0c3hQH+09reKqkVuLKxcflw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753940152; 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=kVAUpBLx4/m/fNnwdKl39CWIws8oTIREVtkkpkX4QQI=; b=EUoMoNwX3oh8lLG2NtwlYFoxyYhpeOiIN0PWZDypQTVe6hRvfzwf9RedK5/vGkl02rOBjm/L5Ra6C8pS06ye6WR/7ZAoyHClMR8umR6Gk4Hmq5kF1m4XZhhMA1gEB8/+7eHhAnuYhSMYa3HCP6N+6on6g1kC9PEBx+GR3NRPXr4= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 175394015285013.414815500008558; Wed, 30 Jul 2025 22:35:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLrD-0001Bg-Db; Thu, 31 Jul 2025 01:29:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpo-0007Qq-CR for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:08 -0400 Received: from p-east3-cluster2-host10-snip4-8.eps.apple.com ([57.103.87.229] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpl-0005lF-Pt for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:07 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id DBF931800131; Thu, 31 Jul 2025 05:28:02 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id 24FC11800122; Thu, 31 Jul 2025 05:28:01 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=kVAUpBLx4/m/fNnwdKl39CWIws8oTIREVtkkpkX4QQI=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=NVJT5iI4veV2grmPcmd/kzVDMOLWOWmYeLgqrxUPdZauX4sgtlHg7ZPY2ljQc0EA3bR73wiIKkQm8cuezj/KJMZODz5WhWZ2hz6nVaXt4G8J+lIGxyL/SH/YNgCR5ttotIm0kzCsCrXyJ9QKsHSpo1iRdXGNlPfKBlWUyN0B10uTOeO/OfOBktfBXFbpx8j6jDIypaZ4aaUcqoxAKCKscanzJGiZkB11n0txQB0Qrdiop7sklfUQaQKS2jo417OqDNDc7EkQrmTF1XKE59w61kbwa5f894KiL05yaf58EEsiP0K0pnrgcmusW2shqjj3WXeI9m30NPBZSzal8cAmLQ== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 4/9] whpx: interrupt controller support Date: Thu, 31 Jul 2025 07:27:48 +0200 Message-Id: <20250731052753.93255-5-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: GOwQkVLzvegpZnGBT-DKZzipub1fSTgw X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfX00Paags5TaIS /I4DWTwpMzMQbuLftEHx6ZBCbQndjNZqZVI7NBWotizhRG5ixNNx7J6x2WqwQbv+PrTNtBSf4zD tG0u5n06kYSWQAhcMeZprCZm1u/Gti2F8Q5VZGZ9X7QUg89STCwARHsW/+9ukkRJcnlS1nqspQn 36uj5UfHYkZLpSlA0bHKuV88A9+avGw+mS0qvajou1vNnZWtqiUqvWeTJZSI6LPiF9p1N9OvU5Q KsDQpqla5m2oXIWZiLpPakt7uYTYUpnj/M4+UkbT2BV/wiXVj9DeY3M1Hvc4LbTuuy/DBJ3Js= X-Proofpoint-ORIG-GUID: GOwQkVLzvegpZnGBT-DKZzipub1fSTgw X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 clxscore=1030 phishscore=0 spamscore=0 mlxlogscore=999 adultscore=0 mlxscore=0 bulkscore=0 suspectscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.87.229; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753940155019116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: Mohamed Mediouni --- hw/intc/arm_gicv3_whpx.c | 285 +++++++++++++++++++++++++++++++++++++++ hw/intc/meson.build | 1 + 2 files changed, 286 insertions(+) create mode 100644 hw/intc/arm_gicv3_whpx.c diff --git a/hw/intc/arm_gicv3_whpx.c b/hw/intc/arm_gicv3_whpx.c new file mode 100644 index 0000000000..97ab164518 --- /dev/null +++ b/hw/intc/arm_gicv3_whpx.c @@ -0,0 +1,285 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * ARM Generic Interrupt Controller using HVF platform support + * + * Copyright (c) 2025 Mohamed Mediouni + * Based on vGICv3 KVM code by Pavel Fedin + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/intc/arm_gicv3_common.h" +#include "qemu/error-report.h" +#include "qemu/module.h" +#include "system/runstate.h" +#include "system/whpx.h" +#include "system/whpx-internal.h" +#include "gicv3_internal.h" +#include "vgic_common.h" +#include "qom/object.h" +#include "target/arm/cpregs.h" + +#include "hw/arm/bsa.h" +#include +#include +#include + +struct WHPXARMGICv3Class { + ARMGICv3CommonClass parent_class; + DeviceRealize parent_realize; + ResettablePhases parent_phases; +}; + +#define TYPE_WHPX_GICV3 "whpx-arm-gicv3" +typedef struct WHPXARMGICv3Class WHPXARMGICv3Class; + +/* This is reusing the GICv3State typedef from ARM_GICV3_ITS_COMMON */ +DECLARE_OBJ_CHECKERS(GICv3State, WHPXARMGICv3Class, + WHPX_GICV3, TYPE_WHPX_GICV3); + +static void whpx_gicv3_check(GICv3State *s) +{ +} + +static void whpx_gicv3_put_cpu(CPUState *cpu_state, run_on_cpu_data arg) +{ +} + +static void whpx_gicv3_put(GICv3State *s) +{ + int ncpu; + + whpx_gicv3_check(s); + + for (ncpu =3D 0; ncpu < s->num_cpu; ncpu++) { + run_on_cpu_data data; + data.host_ptr =3D &s->cpu[ncpu]; + run_on_cpu(s->cpu[ncpu].cpu, whpx_gicv3_put_cpu, data); + } +} + +static void whpx_gicv3_get_cpu(CPUState *cpu_state, run_on_cpu_data arg) +{ +} + +static void whpx_gicv3_get(GICv3State *s) +{ + int ncpu; + + for (ncpu =3D 0; ncpu < s->num_cpu; ncpu++) { + run_on_cpu_data data; + data.host_ptr =3D &s->cpu[ncpu]; + run_on_cpu(s->cpu[ncpu].cpu, whpx_gicv3_get_cpu, data); + } +} + +static void whpx_gicv3_set_irq(void *opaque, int irq, int level) +{ + struct whpx_state *whpx =3D &whpx_global; + + GICv3State *s =3D (GICv3State *)opaque; + if (irq > s->num_irq) { + return; + } + WHV_INTERRUPT_TYPE interrupt_type =3D WHvArm64InterruptTypeFixed; + WHV_INTERRUPT_CONTROL interrupt_control =3D=20 + {interrupt_type =3D WHvArm64InterruptTypeFixed, + .RequestedVector =3D GIC_INTERNAL + irq, .InterruptControl.Asserted=3D= 1}; + + whp_dispatch.WHvRequestInterrupt(whpx->partition, &interrupt_control, = sizeof(interrupt_control)); + + if (!level) { + interrupt_control.InterruptControl.Asserted =3D 0; + whp_dispatch.WHvRequestInterrupt(whpx->partition, &interrupt_contr= ol, sizeof(interrupt_control)); + } + +} + +static void whpx_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + GICv3State *s; + GICv3CPUState *c; + + c =3D (GICv3CPUState *)env->gicv3state; + s =3D c->gic; + + c->icc_pmr_el1 =3D 0; + /* + * Architecturally the reset value of the ICC_BPR registers + * is UNKNOWN. We set them all to 0 here; when the kernel + * uses these values to program the ICH_VMCR_EL2 fields that + * determine the guest-visible ICC_BPR register values, the + * hardware's "writing a value less than the minimum sets + * the field to the minimum value" behaviour will result in + * them effectively resetting to the correct minimum value + * for the host GIC. + */ + c->icc_bpr[GICV3_G0] =3D 0; + c->icc_bpr[GICV3_G1] =3D 0; + c->icc_bpr[GICV3_G1NS] =3D 0; + + c->icc_sre_el1 =3D 0x7; + memset(c->icc_apr, 0, sizeof(c->icc_apr)); + memset(c->icc_igrpen, 0, sizeof(c->icc_igrpen)); + + if (s->migration_blocker) { + return; + } + + c->icc_ctlr_el1[GICV3_S] =3D c->icc_ctlr_el1[GICV3_NS]; +} + +static void whpx_gicv3_reset_hold(Object *obj, ResetType type) +{ + GICv3State *s =3D ARM_GICV3_COMMON(obj); + WHPXARMGICv3Class *kgc =3D WHPX_GICV3_GET_CLASS(s); + + if (kgc->parent_phases.hold) { + kgc->parent_phases.hold(obj, type); + } + + whpx_gicv3_put(s); +} + + +/* + * CPU interface registers of GIC needs to be reset on CPU reset. + * For the calling arm_gicv3_icc_reset() on CPU reset, we register + * below ARMCPRegInfo. As we reset the whole cpu interface under single + * register reset, we define only one register of CPU interface instead + * of defining all the registers. + */ +static const ARMCPRegInfo gicv3_cpuif_reginfo[] =3D { + { .name =3D "ICC_CTLR_EL1", .state =3D ARM_CP_STATE_BOTH, + .opc0 =3D 3, .opc1 =3D 0, .crn =3D 12, .crm =3D 12, .opc2 =3D 4, + /* + * If ARM_CP_NOP is used, resetfn is not called, + * So ARM_CP_NO_RAW is appropriate type. + */ + .type =3D ARM_CP_NO_RAW, + .access =3D PL1_RW, + .readfn =3D arm_cp_read_zero, + .writefn =3D arm_cp_write_ignore, + /* + * We hang the whole cpu interface reset routine off here + * rather than parcelling it out into one little function + * per register + */ + .resetfn =3D whpx_gicv3_icc_reset, + }, +}; + +static void whpx_set_reg(CPUState *cpu, WHV_REGISTER_NAME reg, WHV_REGISTE= R_VALUE val) +{ + struct whpx_state *whpx =3D &whpx_global; + HRESULT hr; + hr =3D whp_dispatch.WHvSetVirtualProcessorRegisters(whpx->partition, c= pu->cpu_index, + ®, 1, &val); + + if (FAILED(hr)) { + error_report("WHPX: Failed to set register %08x, hr=3D%08lx", reg,= hr); + } +} + +static void whpx_gicv3_realize(DeviceState *dev, Error **errp) +{ + GICv3State *s =3D WHPX_GICV3(dev); + WHPXARMGICv3Class *kgc =3D WHPX_GICV3_GET_CLASS(s); + Error *local_err =3D NULL; + int i; + + kgc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + if (s->revision !=3D 3) { + error_setg(errp, "unsupported GIC revision %d for platform GIC", + s->revision); + } + + if (s->security_extn) { + error_setg(errp, "the platform vGICv3 does not implement the " + "security extensions"); + return; + } + + if (s->nmi_support) { + error_setg(errp, "NMI is not supported with the platform GIC"); + return; + } + + if (s->nb_redist_regions > 1) { + error_setg(errp, "Multiple VGICv3 redistributor regions are not " + "supported by WHPX"); + error_append_hint(errp, "A maximum of %d VCPUs can be used", + s->redist_region_count[0]); + return; + } + + gicv3_init_irqs_and_mmio(s, whpx_gicv3_set_irq, NULL); +/* + WHV_ARM64_IC_PARAMETERS param =3D { + .EmulationMode =3D WHvArm64IcEmulationModeGicV3, + .GicV3Parameters =3D { + .GicdBaseAddress =3D s->iomem_dist.addr, + .GicPpiPerformanceMonitorsInterrupt =3D VIRTUAL_PMU_IRQ, + .GicPpiOverflowInterruptFromCntv =3D ARCH_TIMER_VIRT_IRQ + } + }; + hr =3D whp_dispatch.WHvSetPartitionProperty( + whpx->partition, + WHvPartitionPropertyCodeArm64IcParameters, + ¶m, + sizeof(WHV_ARM64_IC_PARAMETERS)); + if (FAILED(hr)) { + error_report("WHPX: failed to set up interrupt controller"); + } +*/ + for (i =3D 0; i < s->num_cpu; i++) { + CPUState *cpu_state =3D qemu_get_cpu(i); + ARMCPU *cpu =3D ARM_CPU(cpu_state); + WHV_REGISTER_VALUE val =3D {.Reg64 =3D 0x080A0000 + (0x20000 * i)}; + whpx_set_reg(cpu_state, WHvArm64RegisterGicrBaseGpa, val); + define_arm_cp_regs(cpu, gicv3_cpuif_reginfo); + printf("addr: 0x%lld\n", s->redist_regions[0].iomem.addr); + } + + if (s->maint_irq) { + error_setg(errp, "Nested virtualisation not currently supported by= WHPX."); + return; + } +} + +static void whpx_gicv3_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + ARMGICv3CommonClass *agcc =3D ARM_GICV3_COMMON_CLASS(klass); + WHPXARMGICv3Class *kgc =3D WHPX_GICV3_CLASS(klass); + + agcc->pre_save =3D whpx_gicv3_get; + agcc->post_load =3D whpx_gicv3_put; + + device_class_set_parent_realize(dc, whpx_gicv3_realize, + &kgc->parent_realize); + resettable_class_set_parent_phases(rc, NULL, whpx_gicv3_reset_hold, NU= LL, + &kgc->parent_phases); +} + +static const TypeInfo whpx_arm_gicv3_info =3D { + .name =3D TYPE_WHPX_GICV3, + .parent =3D TYPE_ARM_GICV3_COMMON, + .instance_size =3D sizeof(GICv3State), + .class_init =3D whpx_gicv3_class_init, + .class_size =3D sizeof(WHPXARMGICv3Class), +}; + +static void whpx_gicv3_register_types(void) +{ + type_register_static(&whpx_arm_gicv3_info); +} + +type_init(whpx_gicv3_register_types) diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 3137521a4a..9342ff0e2c 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -41,6 +41,7 @@ specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic= .c', 'apic_common.c')) specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_co= mmon.c')) specific_ss.add(when: 'CONFIG_ARM_GICV3', if_true: files('arm_gicv3_cpuif.= c')) specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'= )) +specific_ss.add(when: 'CONFIG_WHPX', if_true: files('arm_gicv3_whpx.c')) specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: f= iles('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c')) specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c')) specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c')) --=20 2.39.5 (Apple Git-154) From nobody Sat Nov 15 06:34:09 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753939793; cv=none; d=zohomail.com; s=zohoarc; b=gx99CCfJQ286Yg1sWR5CkRDipAqIsyltbIquRBneZFAawgDsuV6tZIwyOrVij7GCvkPiOmo7t3qhXv0tUAP9vUApcgGczOY1b03r52iIE5j92rKD80cg9c3qJjoAcR00aIuydw3fIA3hA8QKWoiaSBtm5Fqczzv8WZJA0ILe6bQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753939793; 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=NW1fD2Mb3upL6hkpDTSF+2K6D3SQ4d3+mABFysdCU6E=; b=eaZBzDOzxz1wcgKb8fHqrmHriRZ0IcpnYx7kizFtnIjKMq+aBq60m4KnRT82VAAu81t3ignvRbseZ1zqaBxh+9zGfPoNWC2xfCkE1T1bq2bqXbjOUHV1TKapl1fAdHZpvsdsNGYiPQsY0txyHkEFWIMPAr1jNOPmPJxWocwOwx0= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753939792731558.4769219111577; Wed, 30 Jul 2025 22:29:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLr0-0000mB-5f; Thu, 31 Jul 2025 01:29:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpq-0007Uc-8Z for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:10 -0400 Received: from p-east3-cluster2-host1-snip4-7.eps.apple.com ([57.103.87.138] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpn-0005m5-Ji for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:09 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id 43D9D1800120; Thu, 31 Jul 2025 05:28:04 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id 6DC6E180009C; Thu, 31 Jul 2025 05:28:02 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=NW1fD2Mb3upL6hkpDTSF+2K6D3SQ4d3+mABFysdCU6E=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=BOW8IOKNlwDWpXUkv+iEkHTRMM1GCvPFlwnF2RkIfFS1qskpRzQ3urNiLSQOhGjBQFeCUgKyOPQOtRcrft3BtyKBoNkmrYmIvQxFKoBwacvo8mbkGWmgMWDa8cQj95OGB2UwGcY11IWMu4qy5G7jnSkE8gqaIiLptwxp0s1fIW+9uBD3Ti+cvh1+T+DhOyT4nATScgw+TaoKiTK+qjOTEF4US+W+jQ2FnKMJ49kHJr2qM2uD/Zr87Hm151ecFbWkk4dgFOABGgU0LZP6arBVQhF7Ak6cFBcjjvIM9Iwm1qTZBM1qNY+Leq1UAx6dDxZY4fgm0TKh0G2LMrGGlbjR3g== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 5/9] hw/virt: make Qemu aware that WHPX has a vGICv3 Date: Thu, 31 Jul 2025 07:27:49 +0200 Message-Id: <20250731052753.93255-6-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: P--x1FFXyLYH7V36YJfpURK2uykTJ6JF X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfX4zA61keFxr+q Tg/Lovod/aLtkPphSRhhJxCyvO7T/fix8mKikq8wWLGL3Ws68qKGzYN0q/sn9/hXqa2KlRpw/NH Yibw1t3JgsS2r9ghfIrmhZGW+25agylY1OmM37xi/WE1MVU+qVZhoGBLoZ2KcVWnB7MMVogQM1D uqiU2W9+rxOhoMXatQCbwzktA8tLCwrLJxTpxKA/2CxmhjgzVwuXixWp0GcsJWU1qoPUHrmBXEt 3ONKnplKejX8wZKzaI280UTmJZWqBzaJA8uwWxkw5IG5HPWNsr3yo8pp6UV7p6rWE3riLcpW0= X-Proofpoint-ORIG-GUID: P--x1FFXyLYH7V36YJfpURK2uykTJ6JF X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 clxscore=1030 phishscore=0 spamscore=0 mlxlogscore=854 adultscore=0 mlxscore=0 bulkscore=0 suspectscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.87.138; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753939797098116600 Content-Type: text/plain; charset="utf-8" WHPX is a vGICv3-only target without vGICv2 or user-mode irqchip support. Signed-off-by: Mohamed Mediouni --- hw/arm/virt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index ef6be3660f..4996c2075e 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -49,6 +49,7 @@ #include "system/tcg.h" #include "system/kvm.h" #include "system/hvf.h" +#include "system/whpx.h" #include "system/qtest.h" #include "hw/loader.h" #include "qapi/error.h" @@ -2058,6 +2059,8 @@ static void finalize_gic_version(VirtMachineState *vm= s) /* KVM w/o kernel irqchip can only deal with GICv2 */ gics_supported |=3D VIRT_GIC_VERSION_2_MASK; accel_name =3D "KVM with kernel-irqchip=3Doff"; + } else if (whpx_enabled()) { + gics_supported |=3D VIRT_GIC_VERSION_3_MASK; } else if (tcg_enabled() || hvf_enabled() || qtest_enabled()) { gics_supported |=3D VIRT_GIC_VERSION_2_MASK; if (module_object_class_by_name("arm-gicv3")) { --=20 2.39.5 (Apple Git-154) From nobody Sat Nov 15 06:34:09 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753940035; cv=none; d=zohomail.com; s=zohoarc; b=Xy9zzIh/jJSu7HkcQd76TvOiUi1+iTHBY6JbgR1Hd7eOje1P3fVTzk19z33a7tA0KfELw7HUFrNO6+yfokctfc4JoBIuXqJLGLKg52X6VABYlH2ExSqK94zK4cwoRj6BkhxfYkZbTtX3Mi2LCH9qGfKNLp9yL36V2NWKUJVZYus= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753940035; 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=2obuM0xhK8jlFobIsYOi4z9xd0ivaQTiI7sZyyK+v7E=; b=dxUcwoB85KWUhc1sPRTMPmPzlk93tUPXQgMh/U8j1fFYlcL9SLrQidjvUS49c7aDDkTvSm5vfwCAdGPetnqD2GRLm0pIwExn1CCjJRrfjP77J3jQNGpj/ezs2lfqza+v/5gYPKRVOlhBRgutMClTXgYcn5Ew3Q9ZzAbNg6FS5LY= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753940035957519.2822288036042; Wed, 30 Jul 2025 22:33:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLrC-0001AY-Mz; Thu, 31 Jul 2025 01:29:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpr-0007Xw-QN for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:12 -0400 Received: from p-east3-cluster2-host1-snip4-4.eps.apple.com ([57.103.87.135] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpo-0005mT-Pd for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:11 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id 8F80D1800185; Thu, 31 Jul 2025 05:28:05 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id C1D59180011E; Thu, 31 Jul 2025 05:28:03 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=2obuM0xhK8jlFobIsYOi4z9xd0ivaQTiI7sZyyK+v7E=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=WNp/NYnlSVKfMH3FsTk7bNfviwbiW8O2wM3Hfe7olfw5F8cdmjUBtV6OZYxxZwMr4jKcfwb4vLCRkjWSgwmrQsqxzV/UgNP0Q9EbtA1E/B7ljt8RtAGrkh3fyg14qUCXbiwDQjb/t6Qi78u5wfQD5x1C6JTRck+bSAvAdfSn/q7N5VJ9QIihR8AOFXNjNckD8VXNOa760R9bln94h076p2NqrGaYFHJzGtZkIFLgAJ1LulB2Mx5H1HVq/+ucdcR08m8TjNi3nLhpXFhfQRhe7LXMzdlwZjHF/pbzPSS5yooRGjCJruRxtsEkuv4KeNoFT87OdnAP3a9NrKw1henRcQ== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 6/9] hw: intc: arm_gicv3_common: add whpx Date: Thu, 31 Jul 2025 07:27:50 +0200 Message-Id: <20250731052753.93255-7-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: TQTveC6NcbGrMy_-_K7KDhpXCnQMCmMX X-Proofpoint-ORIG-GUID: TQTveC6NcbGrMy_-_K7KDhpXCnQMCmMX X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfX2hjvrK0YWted W2ngVtSsxSdP/sJ3WyCYvc8rEZvLoptV3cPk+YTJFb2GUTIOV+yQQ1XqVe5PEMDPCn30LsdUptG 6CQJSWXjZS3nRrHLupvYygFirgKJWzU4smT65lDGByfYcabRebIwbTE96fY/LTKPYa0zPaDCXGt 9V4bv1A1Ay+jR0dMjaV0NbZTWZbA0SjJbuRM4LsrQgvCCwQlFu05nxXh5yIwhJr4sOnN5EOpvV3 Nbft3YESBRMNWL+Qt5djlRL2fB5jOibNs/+ZT3AsFTXC1b7iNFstA2RQvfdHHCV9SoUQVK3tc= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=762 clxscore=1030 phishscore=0 suspectscore=0 mlxscore=0 adultscore=0 bulkscore=0 spamscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.87.135; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753940037437116600 Content-Type: text/plain; charset="utf-8" Redirect to the platform-specific vGICv3. Signed-off-by: Mohamed Mediouni --- hw/intc/arm_gicv3_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index e438d8c042..a83b075517 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -32,6 +32,7 @@ #include "gicv3_internal.h" #include "hw/arm/linux-boot-if.h" #include "system/kvm.h" +#include "system/whpx.h" =20 =20 static void gicv3_gicd_no_migration_shift_bug_post_load(GICv3State *cs) @@ -662,6 +663,8 @@ const char *gicv3_class_name(void) { if (kvm_irqchip_in_kernel()) { return "kvm-arm-gicv3"; + } else if (whpx_enabled()) { + return "whpx-arm-gicv3"; } else { if (kvm_enabled()) { error_report("Userspace GICv3 is not supported with KVM"); --=20 2.39.5 (Apple Git-154) From nobody Sat Nov 15 06:34:10 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753940079; cv=none; d=zohomail.com; s=zohoarc; b=M+VSDOZbnc7+WqWBe5BJ5Q92tJ5IflTiYhp1om6u3rpC8Uwo5e9whlBOQNyc7zCUZVHZoy4fBvg+6ymOFqoiSmp5U4y3lSfxoxWYgep59OWJ03t0wQ6vU7SlZNLJ7kAU4W+E+Nc9lkrzvV49HxyjvvBaxKvzaH2CkVYAJF/4Bek= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753940079; 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=0B9WtNz3Bi7evvxU+O+xrmr+CV3iIxAYXKA0vmCPAkY=; b=SEd4z0jYe7SKdqcrVqRl1EuipmnAgvyTX90IZeiltFyjjuR3+qfQH0a3u8aO1oNssgqvOu9qgM7QOQ440fRpNIYmVpDeWGV6D+ePDqPnsZ5kCaHAXOx7cDB3gH7pSpzEH+snZF6rXg/i3CTrDK5+ByvIan1n0w2FfPHt/52AK74= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753940079161958.0057556569839; Wed, 30 Jul 2025 22:34:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLrx-0002GA-L4; Thu, 31 Jul 2025 01:30:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpv-0007fa-D6 for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:15 -0400 Received: from p-east3-cluster1-host1-snip4-10.eps.apple.com ([57.103.87.13] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpq-0005nT-TI for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:14 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id 3A9161800183; Thu, 31 Jul 2025 05:28:07 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id 2288C1800122; Thu, 31 Jul 2025 05:28:05 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=0B9WtNz3Bi7evvxU+O+xrmr+CV3iIxAYXKA0vmCPAkY=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=UjAfOWXP6k5zaZGrkdGAQdddXNQTbNtNTw3el8SRxCrJY2aFzrORRqDUPAEvehFv0nBloZ6wjPnqzeuHjE3pHfwecwoWinDop5R6t3FkRGof/ePTahBBRVuSg7pJ0ipIo3arNkJp0ZowHAXVcD5keJzzfm76JqGQVVY46X1irDhhj5505XK72M/AhXJRqGSZGL8sqDIVHDKgAQjL+hLFqtcalnUw0nkWiEQaxEIJ8+hT0a8BY2YKAor8+/aXcgaT4Txnydutk1Xv5ngKiC3cLx49aOiFLS+Uv1r2L60+22GID4GAtVDFNpDc/qQzL0nHL8CcRYbf22YTtx1jNjw7Jg== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 7/9] whpx: add arm64 support Date: Thu, 31 Jul 2025 07:27:51 +0200 Message-Id: <20250731052753.93255-8-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfX+36UcVKc7UdU VaoZcPJYCxgPboJ9/CcuBoW62p4OyfFUwSX7AVbkKZVlb/NkXmsxqQwFirwcQo2t/S+uG9iJ5NC hBxfuXvx+nsLSEXv0vbrVISktrKUS1SyGvBD9SgBcV6VMva553MUwzbE2hXi4iILKrMthU7YKnf gbo/TnS45rmXpvYrNOBddQevx/kWu52/8/Z9kZSMz7xnS+R87gw1OG5NrbKYJ3jCnWknjRASLJ0 aQLHIZBODTyT0J8xApCDT3TWb9RS3OqJM0KbWzpJJA4lJDRs2RrAn174jcsx/IlGO79+RdsU0= X-Proofpoint-GUID: mdlXFN9LyQvsHXOu4jRsmZ4LWTzQgDi8 X-Proofpoint-ORIG-GUID: mdlXFN9LyQvsHXOu4jRsmZ4LWTzQgDi8 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=0 adultscore=0 mlxlogscore=999 clxscore=1030 mlxscore=0 phishscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.87.13; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753940082287116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: Mohamed Mediouni --- accel/whpx/whpx-common.c | 1 + meson.build | 5 +- target/arm/meson.build | 1 + target/arm/whpx/meson.build | 3 + target/arm/whpx/whpx-all.c | 744 ++++++++++++++++++++++++++++++++++++ 5 files changed, 752 insertions(+), 2 deletions(-) create mode 100644 target/arm/whpx/meson.build create mode 100644 target/arm/whpx/whpx-all.c diff --git a/accel/whpx/whpx-common.c b/accel/whpx/whpx-common.c index 43d0200afd..58fd6287ed 100644 --- a/accel/whpx/whpx-common.c +++ b/accel/whpx/whpx-common.c @@ -15,6 +15,7 @@ #include "gdbstub/helpers.h" #include "qemu/accel.h" #include "accel/accel-ops.h" +#include "system/memory.h" #include "system/whpx.h" #include "system/cpus.h" #include "system/runstate.h" diff --git a/meson.build b/meson.build index e53cd5b413..f5823e3c86 100644 --- a/meson.build +++ b/meson.build @@ -327,7 +327,8 @@ accelerator_targets +=3D { 'CONFIG_XEN': xen_targets } =20 if cpu =3D=3D 'aarch64' accelerator_targets +=3D { - 'CONFIG_HVF': ['aarch64-softmmu'] + 'CONFIG_HVF': ['aarch64-softmmu'], + 'CONFIG_WHPX': ['aarch64-softmmu'] } elif cpu =3D=3D 'x86_64' accelerator_targets +=3D { @@ -885,7 +886,7 @@ if get_option('kvm').allowed() and host_os =3D=3D 'linu= x' accelerators +=3D 'CONFIG_KVM' endif if get_option('whpx').allowed() and host_os =3D=3D 'windows' - if get_option('whpx').enabled() and host_machine.cpu() !=3D 'x86_64' + if get_option('whpx').enabled() and host_machine.cpu() in ['x86_64', 'aa= rch64'] error('WHPX requires 64-bit host') elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \ cc.has_header('winhvemulation.h', required: get_option('whpx')) diff --git a/target/arm/meson.build b/target/arm/meson.build index 07d9271aa4..e28bd3f8e2 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -46,6 +46,7 @@ arm_common_system_ss.add(files( )) =20 subdir('hvf') +subdir('whpx') =20 if 'CONFIG_TCG' in config_all_accel subdir('tcg') diff --git a/target/arm/whpx/meson.build b/target/arm/whpx/meson.build new file mode 100644 index 0000000000..1de2ef0283 --- /dev/null +++ b/target/arm/whpx/meson.build @@ -0,0 +1,3 @@ +arm_system_ss.add(when: 'CONFIG_WHPX', if_true: files( + 'whpx-all.c', +)) diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c new file mode 100644 index 0000000000..5769d3497e --- /dev/null +++ b/target/arm/whpx/whpx-all.c @@ -0,0 +1,744 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU Windows Hypervisor Platform accelerator (WHPX) + * + * Copyright (c) 2025 Mohamed Mediouni + * + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "system/address-spaces.h" +#include "system/ioport.h" +#include "gdbstub/helpers.h" +#include "qemu/accel.h" +#include "accel/accel-ops.h" +#include "system/whpx.h" +#include "system/cpus.h" +#include "system/runstate.h" +#include "qemu/main-loop.h" +#include "hw/boards.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "qapi/qapi-types-common.h" +#include "qapi/qapi-visit-common.h" +#include "migration/blocker.h" +#include "accel/accel-cpu-target.h" +#include + +#include "syndrome.h" +#include "cpu.h" +#include "cpregs.h" +#include "internals.h" + +#include "system/whpx-internal.h" +#include "system/whpx-accel-ops.h" +#include "system/whpx-all.h" +#include "system/whpx-common.h" +#include "hw/arm/bsa.h" + +#include +#include + +struct whpx_reg_match { + WHV_REGISTER_NAME reg; + uint64_t offset; +}; + +static const struct whpx_reg_match whpx_reg_match[] =3D { + { WHvArm64RegisterX0, offsetof(CPUARMState, xregs[0]) }, + { WHvArm64RegisterX1, offsetof(CPUARMState, xregs[1]) }, + { WHvArm64RegisterX2, offsetof(CPUARMState, xregs[2]) }, + { WHvArm64RegisterX3, offsetof(CPUARMState, xregs[3]) }, + { WHvArm64RegisterX4, offsetof(CPUARMState, xregs[4]) }, + { WHvArm64RegisterX5, offsetof(CPUARMState, xregs[5]) }, + { WHvArm64RegisterX6, offsetof(CPUARMState, xregs[6]) }, + { WHvArm64RegisterX7, offsetof(CPUARMState, xregs[7]) }, + { WHvArm64RegisterX8, offsetof(CPUARMState, xregs[8]) }, + { WHvArm64RegisterX9, offsetof(CPUARMState, xregs[9]) }, + { WHvArm64RegisterX10, offsetof(CPUARMState, xregs[10]) }, + { WHvArm64RegisterX11, offsetof(CPUARMState, xregs[11]) }, + { WHvArm64RegisterX12, offsetof(CPUARMState, xregs[12]) }, + { WHvArm64RegisterX13, offsetof(CPUARMState, xregs[13]) }, + { WHvArm64RegisterX14, offsetof(CPUARMState, xregs[14]) }, + { WHvArm64RegisterX15, offsetof(CPUARMState, xregs[15]) }, + { WHvArm64RegisterX16, offsetof(CPUARMState, xregs[16]) }, + { WHvArm64RegisterX17, offsetof(CPUARMState, xregs[17]) }, + { WHvArm64RegisterX18, offsetof(CPUARMState, xregs[18]) }, + { WHvArm64RegisterX19, offsetof(CPUARMState, xregs[19]) }, + { WHvArm64RegisterX20, offsetof(CPUARMState, xregs[20]) }, + { WHvArm64RegisterX21, offsetof(CPUARMState, xregs[21]) }, + { WHvArm64RegisterX22, offsetof(CPUARMState, xregs[22]) }, + { WHvArm64RegisterX23, offsetof(CPUARMState, xregs[23]) }, + { WHvArm64RegisterX24, offsetof(CPUARMState, xregs[24]) }, + { WHvArm64RegisterX25, offsetof(CPUARMState, xregs[25]) }, + { WHvArm64RegisterX26, offsetof(CPUARMState, xregs[26]) }, + { WHvArm64RegisterX27, offsetof(CPUARMState, xregs[27]) }, + { WHvArm64RegisterX28, offsetof(CPUARMState, xregs[28]) }, + { WHvArm64RegisterFp, offsetof(CPUARMState, xregs[29]) }, + { WHvArm64RegisterLr, offsetof(CPUARMState, xregs[30]) }, + { WHvArm64RegisterPc, offsetof(CPUARMState, pc) }, +}; + +static const struct whpx_reg_match whpx_fpreg_match[] =3D { + { WHvArm64RegisterQ0, offsetof(CPUARMState, vfp.zregs[0]) }, + { WHvArm64RegisterQ1, offsetof(CPUARMState, vfp.zregs[1]) }, + { WHvArm64RegisterQ2, offsetof(CPUARMState, vfp.zregs[2]) }, + { WHvArm64RegisterQ3, offsetof(CPUARMState, vfp.zregs[3]) }, + { WHvArm64RegisterQ4, offsetof(CPUARMState, vfp.zregs[4]) }, + { WHvArm64RegisterQ5, offsetof(CPUARMState, vfp.zregs[5]) }, + { WHvArm64RegisterQ6, offsetof(CPUARMState, vfp.zregs[6]) }, + { WHvArm64RegisterQ7, offsetof(CPUARMState, vfp.zregs[7]) }, + { WHvArm64RegisterQ8, offsetof(CPUARMState, vfp.zregs[8]) }, + { WHvArm64RegisterQ9, offsetof(CPUARMState, vfp.zregs[9]) }, + { WHvArm64RegisterQ10, offsetof(CPUARMState, vfp.zregs[10]) }, + { WHvArm64RegisterQ11, offsetof(CPUARMState, vfp.zregs[11]) }, + { WHvArm64RegisterQ12, offsetof(CPUARMState, vfp.zregs[12]) }, + { WHvArm64RegisterQ13, offsetof(CPUARMState, vfp.zregs[13]) }, + { WHvArm64RegisterQ14, offsetof(CPUARMState, vfp.zregs[14]) }, + { WHvArm64RegisterQ15, offsetof(CPUARMState, vfp.zregs[15]) }, + { WHvArm64RegisterQ16, offsetof(CPUARMState, vfp.zregs[16]) }, + { WHvArm64RegisterQ17, offsetof(CPUARMState, vfp.zregs[17]) }, + { WHvArm64RegisterQ18, offsetof(CPUARMState, vfp.zregs[18]) }, + { WHvArm64RegisterQ19, offsetof(CPUARMState, vfp.zregs[19]) }, + { WHvArm64RegisterQ20, offsetof(CPUARMState, vfp.zregs[20]) }, + { WHvArm64RegisterQ21, offsetof(CPUARMState, vfp.zregs[21]) }, + { WHvArm64RegisterQ22, offsetof(CPUARMState, vfp.zregs[22]) }, + { WHvArm64RegisterQ23, offsetof(CPUARMState, vfp.zregs[23]) }, + { WHvArm64RegisterQ24, offsetof(CPUARMState, vfp.zregs[24]) }, + { WHvArm64RegisterQ25, offsetof(CPUARMState, vfp.zregs[25]) }, + { WHvArm64RegisterQ26, offsetof(CPUARMState, vfp.zregs[26]) }, + { WHvArm64RegisterQ27, offsetof(CPUARMState, vfp.zregs[27]) }, + { WHvArm64RegisterQ28, offsetof(CPUARMState, vfp.zregs[28]) }, + { WHvArm64RegisterQ29, offsetof(CPUARMState, vfp.zregs[29]) }, + { WHvArm64RegisterQ30, offsetof(CPUARMState, vfp.zregs[30]) }, + { WHvArm64RegisterQ31, offsetof(CPUARMState, vfp.zregs[31]) }, +}; + +#define WHPX_SYSREG(crn, crm, op0, op1, op2) \ + ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2) + +struct whpx_sreg_match { + WHV_REGISTER_NAME reg; + uint32_t key; + uint32_t cp_idx; +}; + +static struct whpx_sreg_match whpx_sreg_match[] =3D { +/* { WHvArm64RegisterDbgbvr0El1, WHPX_SYSREG(0, 0, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr0El1, WHPX_SYSREG(0, 0, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr0El1, WHPX_SYSREG(0, 0, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr0El1, WHPX_SYSREG(0, 0, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr0El1, WHPX_SYSREG(0, 1, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr0El1, WHPX_SYSREG(0, 1, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr0El1, WHPX_SYSREG(0, 1, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr0El1, WHPX_SYSREG(0, 1, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr2El1, WHPX_SYSREG(0, 2, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr2El1, WHPX_SYSREG(0, 2, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr2El1, WHPX_SYSREG(0, 2, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr2El1, WHPX_SYSREG(0, 2, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr3El1, WHPX_SYSREG(0, 3, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr3El1, WHPX_SYSREG(0, 3, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr3El1, WHPX_SYSREG(0, 3, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr3El1, WHPX_SYSREG(0, 3, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr4El1, WHPX_SYSREG(0, 4, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr4El1, WHPX_SYSREG(0, 4, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr4El1, WHPX_SYSREG(0, 4, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr4El1, WHPX_SYSREG(0, 4, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr5El1, WHPX_SYSREG(0, 5, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr5El1, WHPX_SYSREG(0, 5, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr5El1, WHPX_SYSREG(0, 5, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr5El1, WHPX_SYSREG(0, 5, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr6El1, WHPX_SYSREG(0, 6, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr6El1, WHPX_SYSREG(0, 6, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr6El1, WHPX_SYSREG(0, 6, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr6El1, WHPX_SYSREG(0, 6, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr7El1, WHPX_SYSREG(0, 7, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr7El1, WHPX_SYSREG(0, 7, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr7El1, WHPX_SYSREG(0, 7, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr7El1, WHPX_SYSREG(0, 7, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr8El1, WHPX_SYSREG(0, 8, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr8El1, WHPX_SYSREG(0, 8, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr8El1, WHPX_SYSREG(0, 8, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr8El1, WHPX_SYSREG(0, 8, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr9El1, WHPX_SYSREG(0, 9, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr9El1, WHPX_SYSREG(0, 9, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr9El1, WHPX_SYSREG(0, 9, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr9El1, WHPX_SYSREG(0, 9, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr10El1, WHPX_SYSREG(0, 10, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr10El1, WHPX_SYSREG(0, 10, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr10El1, WHPX_SYSREG(0, 10, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr10El1, WHPX_SYSREG(0, 10, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr11El1, WHPX_SYSREG(0, 11, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr11El1, WHPX_SYSREG(0, 11, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr11El1, WHPX_SYSREG(0, 11, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr11El1, WHPX_SYSREG(0, 11, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr12El1, WHPX_SYSREG(0, 12, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr12El1, WHPX_SYSREG(0, 12, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr12El1, WHPX_SYSREG(0, 12, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr12El1, WHPX_SYSREG(0, 12, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr13El1, WHPX_SYSREG(0, 13, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr13El1, WHPX_SYSREG(0, 13, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr13El1, WHPX_SYSREG(0, 13, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr13El1, WHPX_SYSREG(0, 13, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr14El1, WHPX_SYSREG(0, 14, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr14El1, WHPX_SYSREG(0, 14, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr14El1, WHPX_SYSREG(0, 14, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr14El1, WHPX_SYSREG(0, 14, 2, 0, 7) }, + + { WHvArm64RegisterDbgbvr15El1, WHPX_SYSREG(0, 15, 2, 0, 4) }, + { WHvArm64RegisterDbgbcr15El1, WHPX_SYSREG(0, 15, 2, 0, 5) }, + { WHvArm64RegisterDbgwvr15El1, WHPX_SYSREG(0, 15, 2, 0, 6) }, + { WHvArm64RegisterDbgwcr15El1, WHPX_SYSREG(0, 15, 2, 0, 7) }, +*/ +#ifdef SYNC_NO_RAW_REGS + /* + * The registers below are manually synced on init because they are + * marked as NO_RAW. We still list them to make number space sync easi= er. + */ + { WHvArm64RegisterMidrEl1, WHPX_SYSREG(0, 0, 3, 0, 0) }, + { WHvArm64RegisterMpidrEl1, WHPX_SYSREG(0, 0, 3, 0, 5) }, + { WHvArm64RegisterIdPfr0El1, WHPX_SYSREG(0, 4, 3, 0, 0) }, +#endif +// { WHvArm64RegisterIdPfr1El1, WHPX_SYSREG(0, 4, 3, 0, 1) }, +// { WHvArm64RegisterIdDfr0El1, WHPX_SYSREG(0, 5, 3, 0, 0) }, +// { WHvArm64RegisterIdAa64Dfr1El1, WHPX_SYSREG(0, 5, 3, 0, 1) }, +// { WHvArm64RegisterIdAa64Isar0El1, WHPX_SYSREG(0, 6, 3, 0, 0) }, +// { WHvArm64RegisterIdAa64Isar1El1, WHPX_SYSREG(0, 6, 3, 0, 1) }, +#ifdef SYNC_NO_MMFR0 + /* We keep the hardware MMFR0 around. HW limits are there anyway */ + { WHvArm64RegisterIdAa64Mmfr0El1, WHPX_SYSREG(0, 7, 3, 0, 0) }, +#endif +// { WHvArm64RegisterIdAa64Mmfr1El1, WHPX_SYSREG(0, 7, 3, 0, 1) }, +// { WHvArm64RegisterIdAa64Mmfr2El1, WHPX_SYSREG(0, 7, 3, 0, 2) }, +// { WHvArm64RegisterIdAa64Mmfr3El1, WHPX_SYSREG(0, 7, 3, 0, 3) }, + + { WHvArm64RegisterMdscrEl1, WHPX_SYSREG(0, 2, 2, 0, 2) }, + { WHvArm64RegisterSctlrEl1, WHPX_SYSREG(1, 0, 3, 0, 0) }, + { WHvArm64RegisterCpacrEl1, WHPX_SYSREG(1, 0, 3, 0, 2) }, + { WHvArm64RegisterTtbr0El1, WHPX_SYSREG(2, 0, 3, 0, 0) }, + { WHvArm64RegisterTtbr1El1, WHPX_SYSREG(2, 0, 3, 0, 1) }, + { WHvArm64RegisterTcrEl1, WHPX_SYSREG(2, 0, 3, 0, 2) }, + + { WHvArm64RegisterApiAKeyLoEl1, WHPX_SYSREG(2, 1, 3, 0, 0) }, + { WHvArm64RegisterApiAKeyHiEl1, WHPX_SYSREG(2, 1, 3, 0, 1) }, + { WHvArm64RegisterApiBKeyLoEl1, WHPX_SYSREG(2, 1, 3, 0, 2) }, + { WHvArm64RegisterApiBKeyHiEl1, WHPX_SYSREG(2, 1, 3, 0, 3) }, + { WHvArm64RegisterApdAKeyLoEl1, WHPX_SYSREG(2, 2, 3, 0, 0) }, + { WHvArm64RegisterApdAKeyHiEl1, WHPX_SYSREG(2, 2, 3, 0, 1) }, + { WHvArm64RegisterApdBKeyLoEl1, WHPX_SYSREG(2, 2, 3, 0, 2) }, + { WHvArm64RegisterApdBKeyHiEl1, WHPX_SYSREG(2, 2, 3, 0, 3) }, + { WHvArm64RegisterApgAKeyLoEl1, WHPX_SYSREG(2, 3, 3, 0, 0) }, + { WHvArm64RegisterApgAKeyHiEl1, WHPX_SYSREG(2, 3, 3, 0, 1) }, + + { WHvArm64RegisterSpsrEl1, WHPX_SYSREG(4, 0, 3, 0, 0) }, + { WHvArm64RegisterElrEl1, WHPX_SYSREG(4, 0, 3, 0, 1) }, + { WHvArm64RegisterSpEl1, WHPX_SYSREG(4, 1, 3, 0, 0) }, + { WHvArm64RegisterEsrEl1, WHPX_SYSREG(5, 2, 3, 0, 0) }, + { WHvArm64RegisterFarEl1, WHPX_SYSREG(6, 0, 3, 0, 0) }, + { WHvArm64RegisterParEl1, WHPX_SYSREG(7, 4, 3, 0, 0) }, + { WHvArm64RegisterMairEl1, WHPX_SYSREG(10, 2, 3, 0, 0) }, + { WHvArm64RegisterVbarEl1, WHPX_SYSREG(12, 0, 3, 0, 0) }, + { WHvArm64RegisterContextidrEl1, WHPX_SYSREG(13, 0, 3, 0, 1) }, + { WHvArm64RegisterTpidrEl1, WHPX_SYSREG(13, 0, 3, 0, 4) }, + { WHvArm64RegisterCntkctlEl1, WHPX_SYSREG(14, 1, 3, 0, 0) }, + { WHvArm64RegisterCsselrEl1, WHPX_SYSREG(0, 0, 3, 2, 0) }, + { WHvArm64RegisterTpidrEl0, WHPX_SYSREG(13, 0, 3, 3, 2) }, + { WHvArm64RegisterTpidrroEl0, WHPX_SYSREG(13, 0, 3, 3, 3) }, + { WHvArm64RegisterCntvCtlEl0, WHPX_SYSREG(14, 3, 3, 3, 1) }, + { WHvArm64RegisterCntvCvalEl0, WHPX_SYSREG(14, 3, 3, 3, 2) }, + { WHvArm64RegisterSpEl1, WHPX_SYSREG(4, 1, 3, 4, 0) }, +}; + +static void flush_cpu_state(CPUState *cpu) +{ + if (cpu->vcpu_dirty) { + whpx_set_registers(cpu, WHPX_SET_RUNTIME_STATE); + cpu->vcpu_dirty =3D false; + } +} + +static void whpx_get_reg(CPUState *cpu, WHV_REGISTER_NAME reg, WHV_REGISTE= R_VALUE* val) +{ + struct whpx_state *whpx =3D &whpx_global; + HRESULT hr; + + flush_cpu_state(cpu); + + hr =3D whp_dispatch.WHvGetVirtualProcessorRegisters(whpx->partition, c= pu->cpu_index, + ®, 1, val); + + if (FAILED(hr)) { + error_report("WHPX: Failed to get register %08x, hr=3D%08lx", reg,= hr); + } +} + +static void whpx_set_reg(CPUState *cpu, WHV_REGISTER_NAME reg, WHV_REGISTE= R_VALUE val) +{ + struct whpx_state *whpx =3D &whpx_global; + HRESULT hr; + hr =3D whp_dispatch.WHvSetVirtualProcessorRegisters(whpx->partition, c= pu->cpu_index, + ®, 1, &val); + + if (FAILED(hr)) { + error_report("WHPX: Failed to set register %08x, hr=3D%08lx", reg,= hr); + } +} + +static uint64_t whpx_get_gp_reg(CPUState *cpu, int rt) +{ + if (rt >=3D 31) { + return 0; + } + WHV_REGISTER_NAME reg =3D WHvArm64RegisterX0 + rt; + WHV_REGISTER_VALUE val; + whpx_get_reg(cpu, reg, &val); + + return val.Reg64; +} + +static void whpx_set_gp_reg(CPUState *cpu, int rt, uint64_t val) +{ + if (rt >=3D 31) { + abort(); + } + WHV_REGISTER_NAME reg =3D WHvArm64RegisterX0 + rt; + WHV_REGISTER_VALUE reg_val =3D {.Reg64 =3D val}; + + whpx_set_reg(cpu, reg, reg_val); +} + +static int whpx_handle_mmio(CPUState *cpu, WHV_MEMORY_ACCESS_CONTEXT *ctx) +{ + uint64_t syndrome =3D ctx->Syndrome; + + bool isv =3D syndrome & ARM_EL_ISV; + bool iswrite =3D (syndrome >> 6) & 1; + bool sse =3D (syndrome >> 21) & 1; + uint32_t sas =3D (syndrome >> 22) & 3; + uint32_t len =3D 1 << sas; + uint32_t srt =3D (syndrome >> 16) & 0x1f; + uint32_t cm =3D (syndrome >> 8) & 0x1; + uint64_t val =3D 0; + + if (cm) { + /* We don't cache MMIO regions */ + abort(); + return 0; + } + + assert(isv); + + if (iswrite) { + val =3D whpx_get_gp_reg(cpu, srt); + address_space_write(&address_space_memory, + ctx->Gpa, + MEMTXATTRS_UNSPECIFIED, &val, len); + } else { + address_space_read(&address_space_memory, + ctx->Gpa, + MEMTXATTRS_UNSPECIFIED, &val, len); + if (sse) { + val =3D sextract64(val, 0, len * 8); + } + whpx_set_gp_reg(cpu, srt, val); + } + + return 0; +} + +int whpx_vcpu_run(CPUState *cpu) { + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + AccelCPUState *vcpu =3D cpu->accel; + int ret; + + + g_assert(bql_locked()); + + if (whpx->running_cpus++ =3D=3D 0) { + ret =3D whpx_first_vcpu_starting(cpu); + if (ret !=3D 0) { + return ret; + } + } + + bql_unlock(); + + + cpu_exec_start(cpu); + do { + bool advance_pc =3D false; + if (cpu->vcpu_dirty) { + whpx_set_registers(cpu, WHPX_SET_RUNTIME_STATE); + cpu->vcpu_dirty =3D false; + } + + if (qatomic_read(&cpu->exit_request)) { + whpx_vcpu_kick(cpu); + } + + hr =3D whp_dispatch.WHvRunVirtualProcessor( + whpx->partition, cpu->cpu_index, + &vcpu->exit_ctx, sizeof(vcpu->exit_ctx)); + + if (FAILED(hr)) { + error_report("WHPX: Failed to exec a virtual processor," + " hr=3D%08lx", hr); + ret =3D -1; + break; + } + + switch (vcpu->exit_ctx.ExitReason) { + case WHvRunVpExitReasonGpaIntercept: + case WHvRunVpExitReasonUnmappedGpa: + advance_pc =3D true; + ret =3D whpx_handle_mmio(cpu, &vcpu->exit_ctx.MemoryAccess); + break; + case WHvRunVpExitReasonCanceled: + cpu->exception_index =3D EXCP_INTERRUPT; + ret =3D 1; + break; + case WHvRunVpExitReasonNone: + case WHvRunVpExitReasonUnrecoverableException: + case WHvRunVpExitReasonInvalidVpRegisterValue: + case WHvRunVpExitReasonUnsupportedFeature: + default: + error_report("WHPX: Unexpected VP exit code 0x%08x", + vcpu->exit_ctx.ExitReason); + whpx_get_registers(cpu); + bql_lock(); + qemu_system_guest_panicked(cpu_get_crash_info(cpu)); + bql_unlock(); + break; + } + if (advance_pc) { + WHV_REGISTER_VALUE pc; + + flush_cpu_state(cpu); + + whpx_get_reg(cpu, WHvArm64RegisterPc, &pc); + pc.Reg64 +=3D 4; + whpx_set_reg(cpu, WHvArm64RegisterPc, pc); + } + } while (!ret); + + cpu_exec_end(cpu); + + bql_lock(); + current_cpu =3D cpu; + + if (--whpx->running_cpus =3D=3D 0) { + whpx_last_vcpu_stopping(cpu); + } + + qatomic_set(&cpu->exit_request, false); + + return ret < 0; +} + +void whpx_get_registers(CPUState *cpu) { + ARMCPU *arm_cpu =3D ARM_CPU(cpu); + CPUARMState *env =3D &arm_cpu->env; + WHV_REGISTER_VALUE val; + int i; + + for (i =3D 0; i < ARRAY_SIZE(whpx_reg_match); i++) { + whpx_get_reg(cpu, whpx_reg_match[i].reg, &val); + *(uint64_t *)((void *)env + whpx_reg_match[i].offset) =3D val.Reg6= 4; + } + + for (i =3D 0; i < ARRAY_SIZE(whpx_fpreg_match); i++) { + whpx_get_reg(cpu, whpx_reg_match[i].reg, &val); + memcpy((void *)env + whpx_fpreg_match[i].offset, &val, sizeof(val.= Reg128)); + } + + whpx_get_reg(cpu, WHvArm64RegisterPc, &val); + env->pc =3D val.Reg64; + + whpx_get_reg(cpu, WHvArm64RegisterFpcr, &val); + vfp_set_fpcr(env, val.Reg32); + + whpx_get_reg(cpu, WHvArm64RegisterFpsr, &val); + vfp_set_fpsr(env, val.Reg32); + + whpx_get_reg(cpu, WHvArm64RegisterPstate, &val); + pstate_write(env, val.Reg32); + + for (i =3D 0; i < ARRAY_SIZE(whpx_sreg_match); i++) { + if (whpx_sreg_match[i].cp_idx =3D=3D -1) { + continue; + } + + whpx_get_reg(cpu, whpx_sreg_match[i].reg, &val); + + arm_cpu->cpreg_values[whpx_sreg_match[i].cp_idx] =3D val.Reg64; + } + assert(write_list_to_cpustate(arm_cpu)); + + aarch64_restore_sp(env, arm_current_el(env)); +} + +void whpx_set_registers(CPUState *cpu, int level) { + ARMCPU *arm_cpu =3D ARM_CPU(cpu); + CPUARMState *env =3D &arm_cpu->env; + WHV_REGISTER_VALUE val; + int i; + + assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + + for (i =3D 0; i < ARRAY_SIZE(whpx_reg_match); i++) { + val.Reg64 =3D *(uint64_t *)((void *)env + whpx_reg_match[i].offset= ); + whpx_set_reg(cpu, whpx_reg_match[i].reg, val); + } + + for (i =3D 0; i < ARRAY_SIZE(whpx_fpreg_match); i++) { + memcpy(&val.Reg128, (void *)env + whpx_fpreg_match[i].offset, size= of(val.Reg128)); + whpx_set_reg(cpu, whpx_reg_match[i].reg, val); + } + + val.Reg64 =3D env->pc; + whpx_set_reg(cpu, WHvArm64RegisterPc, val); + + val.Reg32 =3D vfp_get_fpcr(env); + whpx_set_reg(cpu, WHvArm64RegisterFpcr, val); + val.Reg32 =3D vfp_get_fpsr(env); + whpx_set_reg(cpu, WHvArm64RegisterFpsr, val); + val.Reg32 =3D pstate_read(env); + whpx_set_reg(cpu, WHvArm64RegisterPstate, val); + + aarch64_save_sp(env, arm_current_el(env)); + + assert(write_cpustate_to_list(arm_cpu, false)); + for (i =3D 0; i < ARRAY_SIZE(whpx_sreg_match); i++) { + if (whpx_sreg_match[i].cp_idx =3D=3D -1) { + continue; + } + + val.Reg64 =3D arm_cpu->cpreg_values[whpx_sreg_match[i].cp_idx]; + whpx_set_reg(cpu, whpx_sreg_match[i].reg, val); + } +} + +static uint32_t max_vcpu_index; + +static void whpx_cpu_update_state(void *opaque, bool running, RunState sta= te) +{ + //CPUARMState *env =3D opaque; + + if (running) { + //env->tsc_valid =3D false; + } +} + +int whpx_init_vcpu(CPUState *cpu) { + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + AccelCPUState *vcpu =3D NULL; + ARMCPU *arm_cpu =3D ARM_CPU(cpu); + CPUARMState *env =3D &arm_cpu->env; + int ret; + + uint32_t sregs_match_len =3D ARRAY_SIZE(whpx_sreg_match); + uint32_t sregs_cnt =3D 0; + WHV_REGISTER_VALUE val; + int i; + + vcpu =3D g_new0(AccelCPUState, 1); + + hr =3D whp_dispatch.WHvCreateVirtualProcessor( + whpx->partition, cpu->cpu_index, 0); + if (FAILED(hr)) { + error_report("WHPX: Failed to create a virtual processor," + " hr=3D%08lx", hr); + ret =3D -EINVAL; + goto error; + } + + /* Assumption that CNTFRQ_EL0 is the same between the VMM and the part= ition. */ + asm volatile("mrs %0, cntfrq_el0" : "=3Dr"(arm_cpu->gt_cntfrq_hz)); + + cpu->vcpu_dirty =3D true; + cpu->accel =3D vcpu; + max_vcpu_index =3D max(max_vcpu_index, cpu->cpu_index); + qemu_add_vm_change_state_handler(whpx_cpu_update_state, env); + + env->aarch64 =3D true; + + /* Allocate enough space for our sysreg sync */ + arm_cpu->cpreg_indexes =3D g_renew(uint64_t, arm_cpu->cpreg_indexes, + sregs_match_len); + arm_cpu->cpreg_values =3D g_renew(uint64_t, arm_cpu->cpreg_values, + sregs_match_len); + arm_cpu->cpreg_vmstate_indexes =3D g_renew(uint64_t, + arm_cpu->cpreg_vmstate_indexe= s, + sregs_match_len); + arm_cpu->cpreg_vmstate_values =3D g_renew(uint64_t, + arm_cpu->cpreg_vmstate_values, + sregs_match_len); + + memset(arm_cpu->cpreg_values, 0, sregs_match_len * sizeof(uint64_t)); + + /* Populate cp list for all known sysregs */ + for (i =3D 0; i < sregs_match_len; i++) { + const ARMCPRegInfo *ri; + uint32_t key =3D whpx_sreg_match[i].key; + + ri =3D get_arm_cp_reginfo(arm_cpu->cp_regs, key); + if (ri) { + assert(!(ri->type & ARM_CP_NO_RAW)); + whpx_sreg_match[i].cp_idx =3D sregs_cnt; + arm_cpu->cpreg_indexes[sregs_cnt++] =3D cpreg_to_kvm_id(key); + } else { + whpx_sreg_match[i].cp_idx =3D -1; + } + } + arm_cpu->cpreg_array_len =3D sregs_cnt; + arm_cpu->cpreg_vmstate_array_len =3D sregs_cnt; + + assert(write_cpustate_to_list(arm_cpu, false)); + + /* Set CP_NO_RAW system registers on init */ + val.Reg64 =3D arm_cpu->midr; + whpx_set_reg(cpu, WHvArm64RegisterMidrEl1, + val); + return 0; + +error: + g_free(vcpu); + + return ret; + +} + +int whpx_accel_init(AccelState *as, MachineState *ms) { + struct whpx_state *whpx; + int ret; + HRESULT hr; + WHV_CAPABILITY whpx_cap; + UINT32 whpx_cap_size; + WHV_PARTITION_PROPERTY prop; + WHV_CAPABILITY_FEATURES features =3D {0}; + + whpx =3D &whpx_global; + + if (!init_whp_dispatch()) { + ret =3D -ENOSYS; + goto error; + } + + whpx->mem_quota =3D ms->ram_size; + + hr =3D whp_dispatch.WHvGetCapability( + WHvCapabilityCodeHypervisorPresent, &whpx_cap, + sizeof(whpx_cap), &whpx_cap_size); + if (FAILED(hr) || !whpx_cap.HypervisorPresent) { + error_report("WHPX: No accelerator found, hr=3D%08lx", hr); + ret =3D -ENOSPC; + goto error; + } + + hr =3D whp_dispatch.WHvGetCapability( + WHvCapabilityCodeFeatures, &features, sizeof(features), NULL); + if (FAILED(hr)) { + error_report("WHPX: Failed to query capabilities, hr=3D%08lx", hr); + ret =3D -EINVAL; + goto error; + } + + if (!features.Arm64Support) { + error_report("WHPX: host OS exposing pre-release WHPX implementati= on. " + "Please update your operating system to at least build 26100.3= 915"); + ret =3D -EINVAL; + goto error; + } + + hr =3D whp_dispatch.WHvCreatePartition(&whpx->partition); + if (FAILED(hr)) { + error_report("WHPX: Failed to create partition, hr=3D%08lx", hr); + ret =3D -EINVAL; + goto error; + } + + memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY)); + prop.ProcessorCount =3D ms->smp.cpus; + hr =3D whp_dispatch.WHvSetPartitionProperty( + whpx->partition, + WHvPartitionPropertyCodeProcessorCount, + &prop, + sizeof(WHV_PARTITION_PROPERTY)); + + if (FAILED(hr)) { + error_report("WHPX: Failed to set partition processor count to %u," + " hr=3D%08lx", prop.ProcessorCount, hr); + ret =3D -EINVAL; + goto error; + } + + if (!whpx->kernel_irqchip_allowed) { + error_report("WHPX: on Arm, only kernel-irqchip=3Don is currently = supported"); + ret =3D -EINVAL; + goto error; + } + + memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY)); + + //prop.Arm64IcParameters =3D=20 + WHV_ARM64_IC_PARAMETERS ic_params =3D { + .EmulationMode =3D WHvArm64IcEmulationModeGicV3, + .GicV3Parameters =3D { + .GicdBaseAddress =3D 0x08000000, + .GitsTranslaterBaseAddress =3D 0x08080000, + .GicLpiIntIdBits =3D 1, + .GicPpiPerformanceMonitorsInterrupt =3D VIRTUAL_PMU_IRQ, + .GicPpiOverflowInterruptFromCntv =3D ARCH_TIMER_VIRT_IRQ + } + }; + prop.Arm64IcParameters =3D ic_params; + + hr =3D whp_dispatch.WHvSetPartitionProperty( + whpx->partition, + WHvPartitionPropertyCodeArm64IcParameters, + &prop, + sizeof(WHV_PARTITION_PROPERTY)); + if (FAILED(hr)) { + error_report("WHPX: Failed to enable GICv3 interrupt controller, h= r=3D%08lx", hr); + ret =3D -EINVAL; + goto error; + } + + hr =3D whp_dispatch.WHvSetupPartition(whpx->partition); + if (FAILED(hr)) { + error_report("WHPX: Failed to setup partition, hr=3D%08lx", hr); + ret =3D -EINVAL; + goto error; + } + + whpx_memory_init(); + + printf("Windows Hypervisor Platform accelerator is operational\n"); + return 0; + +error: + + if (NULL !=3D whpx->partition) { + whp_dispatch.WHvDeletePartition(whpx->partition); + whpx->partition =3D NULL; + } + + return ret; +} \ No newline at end of file --=20 2.39.5 (Apple Git-154) From nobody Sat Nov 15 06:34:10 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753939997; cv=none; d=zohomail.com; s=zohoarc; b=AIToDcmJNeyyDuHdUGQocwO+yPGJOlo1CYt8T5nO62qOoGZOCaha7CBgUc/63pKZkREezS9dsUFHu+jn1E3jYiiqTf6knU5eLdlZRUO4NOCSvZABipvA899X1KsiGprvVsBXxlvwHAVw55U008T3HnqW/HVtw3EpxqUU33snHNs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753939997; 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=SPUPSB/xNUORagiGQbaHcpje+WodA55CW8qDQCYRNy8=; b=dC7RQasmMakOYZEWx1wGvrWxSSu6VirgHz5YBEMiXz/gn+/8asDM5wtN4EfOaIMzW0+wXI1KMwlvjQ2CCPqMSkAKjw0MXs5Bku9uoI5wgc89pMhoFyKkivRII5FeGGe2UJX9TQT7la7qohMzBJ1A+IDUeTOPLDgPWICRMvKEYaI= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753939997526905.5389033780642; Wed, 30 Jul 2025 22:33:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLrF-0001GR-MM; Thu, 31 Jul 2025 01:29:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpu-0007by-4X for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:14 -0400 Received: from p-east3-cluster2-host3-snip4-1.eps.apple.com ([57.103.87.152] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpr-0005nv-Qx for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:13 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id 8CE68180012B; Thu, 31 Jul 2025 05:28:08 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id 729F6180009C; Thu, 31 Jul 2025 05:28:06 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=SPUPSB/xNUORagiGQbaHcpje+WodA55CW8qDQCYRNy8=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=fTfkxRHPLACl5o+/c894a8gjqOmhGcmq6R4OWWEBABI/+leeOmvzA+Q2cPvD1TYuakn6JbN+aVf0o9Cc0uwrTMymkuNXT9slvoGzLRzjjfbPkWOvtKDPbpxwlzl0WA2Ern+2yQCC5BxVj3J7ROstHpEyq5YxnNVbo4ZTx0strNBMalqTsuJ2DHv9wRG1LXJTOAsZ9G1OV+yrkjmDWp26XMNsduK1CafXs5A8kaBjTEw+LeQYoX08eiP4YCW3MssdUxjZcCSljVRS4ZkSR29/ooO3sWri7mYwSGQrUlCj0jrGL+pvCNFE0xlwQof2gxMSZBudiZ42CVMCujmPt5lTzg== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 8/9] whpx: copy over memory tracking logic from hvf Date: Thu, 31 Jul 2025 07:27:52 +0200 Message-Id: <20250731052753.93255-9-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: YdbnKO6uxtkCa7DV_DzkLrvHqYzZFUVh X-Proofpoint-ORIG-GUID: YdbnKO6uxtkCa7DV_DzkLrvHqYzZFUVh X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfX4z8tjG6m0L9e xUq4zAyL2cNHcDy+kYkcLyQ4kk6kfUcP6fJx4ASfoIiq3Icn59ESPFNp2qNioqIpZAgke1I3FGI XQ6dyoimKMpQq5CvCtS7GvXJzWFZwhIOgmyf5j9mFqnubvKxciD6MCWmo2BjBTuAtLJNhiAD3TK f1XM7W54T7hAyzgR8JxTYHz5pq2ixP8aHVHEgDu6v908iqrkwgenaWm/sdNfCWmCJn/dq1lj05f hDYAyEyYSU63AF+tBjTGTGszNXXmUN6SbWcy2OcjUApp3tPHKr91YMhzRNRQXWSp28kiQZx/U= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 phishscore=0 clxscore=1030 mlxlogscore=999 suspectscore=0 bulkscore=0 spamscore=0 mlxscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.87.152; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753939999753116600 Content-Type: text/plain; charset="utf-8" This allows edk2 to work, although u-boot is still not functional. Signed-off-by: Mohamed Mediouni --- accel/whpx/whpx-common.c | 198 ++++++++++++++++++++++++++++----------- 1 file changed, 144 insertions(+), 54 deletions(-) diff --git a/accel/whpx/whpx-common.c b/accel/whpx/whpx-common.c index 58fd6287ed..19415767e4 100644 --- a/accel/whpx/whpx-common.c +++ b/accel/whpx/whpx-common.c @@ -265,89 +265,171 @@ void whpx_vcpu_kick(CPUState *cpu) * Memory support. */ =20 -static void whpx_update_mapping(hwaddr start_pa, ram_addr_t size, - void *host_va, int add, int rom, - const char *name) + /* hvf_slot flags */ +#define WHPX_SLOT_LOG (1 << 0) +typedef struct whpx_slot { + uint64_t start; + uint64_t size; + uint8_t *mem; + int slot_id; + uint32_t flags; + MemoryRegion *region; +} whpx_slot; + +typedef struct WHPXState { + whpx_slot slots[32]; + int num_slots; +} WHPXState; + + WHPXState *whpx_state; + + struct mac_slot { + int present; + uint64_t size; + uint64_t gpa_start; + uint64_t gva; +}; + +struct mac_slot mac_slots[32]; + +static int do_hvf_set_memory(whpx_slot *slot, WHV_MAP_GPA_RANGE_FLAGS flag= s) { struct whpx_state *whpx =3D &whpx_global; + struct mac_slot *macslot; HRESULT hr; =20 - /* - if (add) { - printf("WHPX: ADD PA:%p Size:%p, Host:%p, %s, '%s'\n", - (void*)start_pa, (void*)size, host_va, - (rom ? "ROM" : "RAM"), name); - } else { - printf("WHPX: DEL PA:%p Size:%p, Host:%p, '%s'\n", - (void*)start_pa, (void*)size, host_va, name); + macslot =3D &mac_slots[slot->slot_id]; + + if (macslot->present) { + if (macslot->size !=3D slot->size) { + macslot->present =3D 0; + hr =3D whp_dispatch.WHvUnmapGpaRange(whpx->partition, macslot-= >gpa_start, macslot->size); + if (FAILED(hr)) { + abort(); + } + } } - */ - - if (add) { - hr =3D whp_dispatch.WHvMapGpaRange(whpx->partition, - host_va, - start_pa, - size, - (WHvMapGpaRangeFlagRead | - WHvMapGpaRangeFlagExecute | - (rom ? 0 : WHvMapGpaRangeFlagWri= te))); - } else { - hr =3D whp_dispatch.WHvUnmapGpaRange(whpx->partition, - start_pa, - size); + + if (!slot->size) { + return 0; } =20 - if (FAILED(hr)) { - error_report("WHPX: Failed to %s GPA range '%s' PA:%p, Size:%p byt= es," - " Host:%p, hr=3D%08lx", - (add ? "MAP" : "UNMAP"), name, - (void *)(uintptr_t)start_pa, (void *)size, host_va, h= r); + macslot->present =3D 1; + macslot->gpa_start =3D slot->start; + macslot->size =3D slot->size; + hr =3D whp_dispatch.WHvMapGpaRange(whpx->partition, slot->mem, slot->s= tart, slot->size, flags); + return 0; +} + +static whpx_slot *whpx_find_overlap_slot(uint64_t start, uint64_t size) +{ + whpx_slot *slot; + int x; + for (x =3D 0; x < whpx_state->num_slots; ++x) { + slot =3D &whpx_state->slots[x]; + if (slot->size && start < (slot->start + slot->size) && + (start + size) > slot->start) { + return slot; + } } + return NULL; } =20 -static void whpx_process_section(MemoryRegionSection *section, int add) +static void whpx_set_phys_mem(MemoryRegionSection *section, bool add) { - MemoryRegion *mr =3D section->mr; - hwaddr start_pa =3D section->offset_within_address_space; - ram_addr_t size =3D int128_get64(section->size); - unsigned int delta; - uint64_t host_va; + whpx_slot *mem; + MemoryRegion *area =3D section->mr; + bool writable =3D !area->readonly && !area->rom_device; + WHV_MAP_GPA_RANGE_FLAGS flags; + uint64_t page_size =3D qemu_real_host_page_size(); + + if (!memory_region_is_ram(area)) { + if (writable) { + return; + } else if (!memory_region_is_romd(area)) { + /* + * If the memory device is not in romd_mode, then we actually = want + * to remove the hvf memory slot so all accesses will trap. + */ + add =3D false; + } + } =20 - if (!memory_region_is_ram(mr)) { - return; + if (!QEMU_IS_ALIGNED(int128_get64(section->size), page_size) || + !QEMU_IS_ALIGNED(section->offset_within_address_space, page_size))= { + /* Not page aligned, so we can not map as RAM */ + add =3D false; } =20 - delta =3D qemu_real_host_page_size() - (start_pa & ~qemu_real_host_pag= e_mask()); - delta &=3D ~qemu_real_host_page_mask(); - if (delta > size) { - return; + mem =3D whpx_find_overlap_slot( + section->offset_within_address_space, + int128_get64(section->size)); + + if (mem && add) { + if (mem->size =3D=3D int128_get64(section->size) && + mem->start =3D=3D section->offset_within_address_space && + mem->mem =3D=3D (memory_region_get_ram_ptr(area) + + section->offset_within_region)) { + return; /* Same region was attempted to register, go away. */ + } + } + + /* Region needs to be reset. set the size to 0 and remap it. */ + if (mem) { + mem->size =3D 0; + if (do_hvf_set_memory(mem, 0)) { + error_report("Failed to reset overlapping slot"); + abort(); + } } - start_pa +=3D delta; - size -=3D delta; - size &=3D qemu_real_host_page_mask(); - if (!size || (start_pa & ~qemu_real_host_page_mask())) { + + if (!add) { return; } =20 - host_va =3D (uintptr_t)memory_region_get_ram_ptr(mr) - + section->offset_within_region + delta; + if (area->readonly || + (!memory_region_is_ram(area) && memory_region_is_romd(area))) { + flags =3D WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute; + } else { + flags =3D WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagWrite | WHvMa= pGpaRangeFlagExecute; + } + + /* Now make a new slot. */ + int x; + + for (x =3D 0; x < whpx_state->num_slots; ++x) { + mem =3D &whpx_state->slots[x]; + if (!mem->size) { + break; + } + } + + if (x =3D=3D whpx_state->num_slots) { + error_report("No free slots"); + abort(); + } =20 - whpx_update_mapping(start_pa, size, (void *)(uintptr_t)host_va, add, - memory_region_is_rom(mr), mr->name); + mem->size =3D int128_get64(section->size); + mem->mem =3D memory_region_get_ram_ptr(area) + section->offset_within_= region; + mem->start =3D section->offset_within_address_space; + mem->region =3D area; + + if (do_hvf_set_memory(mem, flags)) { + error_report("Error registering new memory slot"); + abort(); + } } =20 static void whpx_region_add(MemoryListener *listener, MemoryRegionSection *section) { - memory_region_ref(section->mr); - whpx_process_section(section, 1); + whpx_set_phys_mem(section, true); } =20 static void whpx_region_del(MemoryListener *listener, MemoryRegionSection *section) { - whpx_process_section(section, 0); - memory_region_unref(section->mr); + whpx_set_phys_mem(section, false); } =20 static void whpx_transaction_begin(MemoryListener *listener) @@ -531,6 +613,14 @@ static void whpx_accel_instance_init(Object *obj) memset(whpx, 0, sizeof(struct whpx_state)); /* Turn on kernel-irqchip, by default */ whpx->kernel_irqchip_allowed =3D true; + + int x; + whpx_state =3D malloc(sizeof(WHPXState)); + whpx_state->num_slots =3D ARRAY_SIZE(whpx_state->slots); + for (x =3D 0; x < whpx_state->num_slots; ++x) { + whpx_state->slots[x].size =3D 0; + whpx_state->slots[x].slot_id =3D x; + } } =20 static const TypeInfo whpx_accel_type =3D { --=20 2.39.5 (Apple Git-154) From nobody Sat Nov 15 06:34:10 2025 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=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1753940010; cv=none; d=zohomail.com; s=zohoarc; b=X/sXZWInZlKvPpu3Cs4R/3VySU4XZ2ESoZozCJaHytwVbeHuwNZEE76UYfsrU0qo54y2wos4RtfZyQkM72FOZYx1v3w5PPb3K6/zBFbx6VGlVKcud9Vjo8DqH+Q3D5vpO0mDj2rSvD0Y2HTARXkhzPk44a4fwJKH85mBKTcAo1Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753940010; 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=GKg3FYipdydvcj3OMrgW1X0DtxoFeKJoZZ4r3zuTG3k=; b=P6NRUsTgwYE44P+E6fu6RcDGuw9erd6mX1fiqIvcRDi8pmd2bx429c43xpqYFbaQDnKlnWyyRqwBv7n5FKG4UtcYpvOCyygxWTN/5WbnigAE2tCqpuvkZblSZaVlB1G2YbG4KXPNYRbW0WZqmMUuX8okNb+ROA12gb9En3oDfDY= 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=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753940010381431.0416476978023; Wed, 30 Jul 2025 22:33:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uhLrT-0001pJ-Nv; Thu, 31 Jul 2025 01:29:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpv-0007gG-Ea for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:15 -0400 Received: from p-east3-cluster2-host5-snip4-10.eps.apple.com ([57.103.87.181] helo=outbound.qs.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uhLpt-0005oU-Ma for qemu-devel@nongnu.org; Thu, 31 Jul 2025 01:28:15 -0400 Received: from outbound.qs.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPS id DB026180018E; Thu, 31 Jul 2025 05:28:09 +0000 (UTC) Received: from localhost.localdomain (qs-asmtp-me-k8s.p00.prod.me.com [17.57.155.37]) by p00-icloudmta-asmtp-us-east-2d-20-percent-1 (Postfix) with ESMTPSA id C6E42180011E; Thu, 31 Jul 2025 05:28:07 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=GKg3FYipdydvcj3OMrgW1X0DtxoFeKJoZZ4r3zuTG3k=; h=From:To:Subject:Date:Message-Id:MIME-Version:x-icloud-hme; b=WhDrf6xkfZPa3pqcXumg/0qSucXfQUXO9f+FyML61SA/2mARDTFNcbpI6ubd/yzIi9SNaOURdw1DyySRbm9UNXxb04MAtPxy8kXHQxh17kFJeLmMqJt+kGeGNNmAIu4c2g0C14d/aeu95sT+9sLUhKc33AdxKv6EgsfPU6dtApp4JXdhOKCCm+b5sTh6cqRrihoK3wo6idibeoM5yKBI+URks8UCzfVWboxcP8EJ6s3EjAkTThlPB+Vz/gGRECsHelUl788ltLYDu18DwSQpsCz0V3XrXzv2mDD7px+RdLdOD4Zm4vHJ0z7t+jOxJ2X02O8V+cGganiFzUNhJW1QQA== X-Client-IP: 46.189.47.18 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini , Sunil Muthuswamy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Peter Maydell , qemu-arm@nongnu.org, Mohamed Mediouni Subject: [RFC 9/9] target/arm: cpu: mark WHPX as supporting PSCI 1.1 Date: Thu, 31 Jul 2025 07:27:53 +0200 Message-Id: <20250731052753.93255-10-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20250731052753.93255-1-mohamed@unpredictable.fr> References: <20250731052753.93255-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNzMxMDAzNSBTYWx0ZWRfX4+CHG4CxqPxb +sCAJm6CxUuBQEkX74izGCtWliEporQCHDpBhRyLyeIfoZOIHgR/tBy6ROTZ5Wylc++G/2RRfeG ERg6GSibYOCQtMiMTKX61DF+4v1CAV08TNr1QfeyEWY1yiCdVw69mzD3wziIxA6L7oW6Lp2+Ori bXSBiNut2Cuu0juTMA+PDMU7n+cmKshhMIcBlzlUJhLFnwujKSHg6Czhgz6qCJaMHNNbmRSrPkj w+0bmE84hsmkrHiYLkoGc/RB6j3U95uVkGk2MAlsA2k4xIke1yCvyoT11LxGz0Fs8LcSKkf60= X-Proofpoint-ORIG-GUID: HZRh3hX0AmoQwMTIm_XEuhix1h5bjqhY X-Proofpoint-GUID: HZRh3hX0AmoQwMTIm_XEuhix1h5bjqhY X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-07-31_01,2025-07-31_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 phishscore=0 mlxscore=0 mlxlogscore=752 clxscore=1030 bulkscore=0 adultscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2507310035 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=lists.gnu.org; Received-SPF: pass client-ip=57.103.87.181; envelope-from=mohamed@unpredictable.fr; helo=outbound.qs.icloud.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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 @unpredictable.fr) X-ZM-MESSAGEID: 1753940011022116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: Mohamed Mediouni --- target/arm/cpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index e2b2337399..3b69c9786a 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -23,6 +23,7 @@ #include "qemu/timer.h" #include "qemu/log.h" #include "exec/page-vary.h" +#include "system/whpx.h" #include "target/arm/idau.h" #include "qemu/module.h" #include "qapi/error.h" @@ -1496,7 +1497,7 @@ static void arm_cpu_initfn(Object *obj) cpu->psci_version =3D QEMU_PSCI_VERSION_0_1; /* By default assume PSCI= v0.1 */ cpu->kvm_target =3D QEMU_KVM_ARM_TARGET_NONE; =20 - if (tcg_enabled() || hvf_enabled()) { + if (tcg_enabled() || hvf_enabled() || whpx_enabled()) { /* TCG and HVF implement PSCI 1.1 */ cpu->psci_version =3D QEMU_PSCI_VERSION_1_1; } --=20 2.39.5 (Apple Git-154)