From nobody Sat Apr 27 16:29:12 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516655404329699.3163532010606; Mon, 22 Jan 2018 13:10:04 -0800 (PST) Received: from localhost ([::1]:38160 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edjLo-0005an-Uj for importer@patchew.org; Mon, 22 Jan 2018 16:09:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40773) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edjK3-0004Y0-N6 for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edjK0-00021y-PI for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:07 -0500 Received: from mail-sn1nam02on0116.outbound.protection.outlook.com ([104.47.36.116]:8720 helo=NAM02-SN1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1edjK0-00020h-K4 for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:04 -0500 Received: from JUTERRY-DEV2.corp.microsoft.com (2001:4898:80e8:3::64) by SN4PR2101MB0878.namprd21.prod.outlook.com (2603:10b6:803:51::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.464.0; Mon, 22 Jan 2018 21:08:02 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=H5AycOTjJmWSaq+Xtly+Xz+HflLJR7q0sgwxxEm5ZoY=; b=WXTjMllSXTKZhEu/tcvWL4OPboKuVxOMWjGwP1uXycQEn2hZdp0gZVMCymABw7AoYYihyxtN+enVyWGpFCQL/Or8/+6/E798acrhsdDFn6PE5zINrNsl7XxeN+2RQg8iq7GfXxYoAX8j6XxFYO/g7Y2NapxkeniEQ9sTSiMuHzo= To: qemu-devel@nongnu.org Date: Mon, 22 Jan 2018 13:07:46 -0800 Message-Id: <1516655269-1785-2-git-send-email-juterry@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516655269-1785-1-git-send-email-juterry@microsoft.com> References: <1516655269-1785-1-git-send-email-juterry@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:3::64] X-ClientProxiedBy: DM5PR21CA0002.namprd21.prod.outlook.com (2603:10b6:3:ac::12) To SN4PR2101MB0878.namprd21.prod.outlook.com (2603:10b6:803:51::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 33483f73-cb7f-4a58-9387-08d561dc3956 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(48565401081)(4534125)(4602075)(4627221)(201703031133081)(201702281549075)(2017052603307)(7193020); SRVR:SN4PR2101MB0878; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 3:wD53OY01SwOqaLRHYXISkdOitM49zm+d5bDBWdD6L3IOKoT3j+3Y5dFXXoTuICB2kGkA4iRt4Eh+l4IdwP4DxUag/ADOBtbzBv/zT0EC9qPvjD22XvMH9kliZiNWOkDW33LK15LvUVltnrMAYo7JYso7J75fhV7IqCzMAYxQ8LldLLS1u+vVNmL00lu5rPWFICdCE3vNSKkAewrE5vjPzMcvpHXtCsVGbRBmIKqcUMDmR18edADGBXq88QR+uWbn; 25:uw2xfxHw6CmukJ9Ku7OY2v0FPr5suvwNNHTnaYFCyFIolOqqhc7x1+vgg6NLniqLPa9C/K1jAGHA5MLYbgXzDVGa7ZggYXXmPE8Ks7i29hyf7PVo3qNSmPyVleCFgXvefZIXzamMIycT8oT+OZ99rFpbFOTlMAETgelYuvVMdzVUmL47fgElOsTmyxpwG7M7E8Ny4kJJQnFBfYdS54+BeFA3MY4N5fD4cRKHWOgx81QbqBxqpcD1zt1/xgMVEqLMrPizjXjNzBKRowfB/ec0CRNJtZpk14dtv7Y17IJtRDs7P0mMTS++HbN7NlefjmHUAzDGZgvSXmtlhbhz8O0gMw==; 31:hPUSbFEvhyO1y1JPVZWSQ0Fx4oFxgmYOL7PkQsVqgCwZ53wxm2D0KK7lnlSaZYF+VZkVsYg36r2c2zgdVvn5em6fmvc4R/w2+IR5tiwK1RPUDUlZmrvBXNpM771Tvz8IVxE1V5FgaJTX2V6JP6Ks1OtEjajs5sr+OJry6Gup3eQtibWf651XpBjk+xvnsZPclZIAdFK5qXep7bjD31mnlpusQMEKlSudYp5tpiTGOlE= X-MS-TrafficTypeDiagnostic: SN4PR2101MB0878: X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 20:Bh2UrvTleOV+9jl4Ctf6FpmoG0tPvB17YC4sopjJILQouB25MzLtAUlb1X/y5UdgO0kCSeAxyJRdNVU4hUb1e+/0Jc4SFA/mISbTn2ZZbbRHSDqpIPKV4bIgeYBS/UmnzfCKOU1WJrthFSyUBwih9MC6PB+m8LmUJ9v+5O+HpbjEr4R7tYPYzB7BnVrUpYUPhBlyMFsTd/n6ijUF5nBLkjf1xC6xFpxRr8qywidrfXJcMQASIytm6n2D/FKWoT4Va8cirtQtzmdShvMRgkgJLM6lWTgAc4lq5SiUKoLZ4iyvtovpXJ0/Y8H6jTwbChCTn7mYNzx8PLlutSb4MkAVm3KZ8D5TK1yTDnaffliaRNK/Zbc/NI08kGQFkiOD1h6d0VL0NqrcrLzGx0uyP1JdmIic89aTdnvrHR/bZfftzQjosPQWvqS+TNM7eWqqiGbiCAUYqYb6Fyloz6OzN/aOe838XxEfSOtjKlHVdSJZj7HZlraXBh94gknnrgFc2DnI; 4:66G0xJWYuiM/G7aLB0t0I27uUzFTZqapxXFXMPNkfs7J7eXR107B05AvMmQ9rUE1DalhQeCWj2NCspHZSJtL9gORsvM8XOYJA3hJ/zHLFRsWCH6D6YQ4nBqD/0WWj0U9EU1gq5uLPizISnMWWQw3O0OaXOHUElcewHB7mgwmIsc7irDo3lJZtqjQgUYoA1DSkFkTPMVvvFF4sJlS9Oc5FhZIJ9QVoZLLC8GS1ybPgQfG9n8kAUtjqLMTZba0yIIDr1vDNnYH9u5kRXdrO8Tgs1snx1T5iLPSAuVnULJUSobSoHmKJTmqAOdz4P00UoBQWhaxw9OmPntBx6FnEJVCLzbWgu/0c0a0rt3NG8f0g7Y= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(28532068793085)(89211679590171); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(61425038)(6040501)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231046)(2400081)(944501161)(6055026)(61426038)(61427038)(6041288)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(6072148)(201708071742011); SRVR:SN4PR2101MB0878; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:SN4PR2101MB0878; X-Forefront-PRVS: 0560A2214D X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(39860400002)(396003)(366004)(39380400002)(376002)(199004)(189003)(10090500001)(52396003)(76176011)(48376002)(4326008)(7696005)(51416003)(52116002)(50466002)(39060400002)(107886003)(10290500003)(47776003)(305945005)(7736002)(6666003)(2351001)(6116002)(36756003)(2361001)(2950100002)(8676002)(6916009)(81156014)(386003)(81166006)(5660300001)(25786009)(8936002)(59450400001)(105586002)(478600001)(68736007)(50226002)(2906002)(86362001)(22452003)(106356001)(86612001)(6486002)(53936002)(97736004)(6346003)(316002)(16586007); DIR:OUT; SFP:1102; SCL:1; SRVR:SN4PR2101MB0878; H:JUTERRY-DEV2.corp.microsoft.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=juterry@microsoft.com; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR2101MB0878; 23:2bHp0kfuVelfTVVhPsg63tx2AJ9Obu0xPRp9Mua?= =?us-ascii?Q?339nVKpG792dOGvhPbhwuftZNnUF66WzT8xlj6eq6Vr+gZ07NG+FFc5EnaFS?= =?us-ascii?Q?Y7RsTaLk7UASt64nRuDaU2jElQFeRNPd5/pLfwZSm8u/D/I/j3ZXJRvgMxmJ?= =?us-ascii?Q?YNHgdGawPmUDO5Hm9XqMr/5C0zOmdkdFp02+uygL+5kCWl1b9/hOnOLei3+e?= =?us-ascii?Q?pN72XHtCuU8F4O8o745tujxYYAfVWIBS+xrmuZ30ipiSQdqYDah/gPM21Esc?= =?us-ascii?Q?km6kijN8TpTc3eTpUWcyxhYuKeE09kkt6l/ScAsnljCSw1CVPRy+jbxLSsIl?= =?us-ascii?Q?KnjVgmp9ab/3lf54J1+YBVGd49z+6X3DrkqKV90R348eiIP5SOyc2dMOpg94?= =?us-ascii?Q?gVyQ6I9ljYoUpeigeXrxcZzl2Hx1x99rApJNFy2JZoGP/iiKjtQ0VirL/Q6L?= =?us-ascii?Q?IwDynip2DqVEJWdG0mV9tw+zW0GisoTjdkEhUkRTuk1zS8H8slUcVehU7Rvy?= =?us-ascii?Q?gjNcxMNBl1aWP6JF2dJMOZFbNZr1uMyu+MFIEYF9rpt5Qq2XfXnFIGlntVIS?= =?us-ascii?Q?QTyfJXa2zZUUZ0IaAAtTCNP0gTglLIu5DpA3nX8sc4tTpnfzyp3ecJOIMg9z?= =?us-ascii?Q?bNdNFhdZI2fHgyx3M45eylK75QwVCix3+Wfbo03tIt43ln7M1OT+afQnEv1f?= =?us-ascii?Q?1CGbqn1rPJwX1QHxWpkpWwVK2CBo8lFm7gF15om9boKWDkyArb6Aae4uQn8J?= =?us-ascii?Q?k3KW9t/kdWbOELxJAlbjacUv9sdxVJp/rNIXkoenOBPffJpfCSmw7cT7sx0t?= =?us-ascii?Q?tn0nHaJccjVZAvjz63SukXP5Ge7HpPrZDmvXi5sL7fEkgh8vv+7vXSeG1dCm?= =?us-ascii?Q?jfzXDjkhzQKpJzz9KxNJhnWrEa70FLp506RExk0Oq81EvWxeehXDLWEKjhi3?= =?us-ascii?Q?Y3DXxj6mouTGavgjJ3TU0ZR1QxJF2stBOV4dwCmHBVnGo1FlB71n+iv0JV0M?= =?us-ascii?Q?831noxuUn2Cnn6IxDK/hqdG0RWC+tY4RFp7z/yhwJij3NupUv+kLk1rzLFoM?= =?us-ascii?Q?UgAvXEzYWsI9LfOzX8PgS5wr9mb3wW2K4wRj1YXND5pZnl+9Aijwg6uCTgTK?= =?us-ascii?Q?LUBmr3KADunW1Kc1Q7cly62fw66hRlcM5LaxFdiJ092C13cmjDRBwtbc4t2p?= =?us-ascii?Q?At4Y2KHEXhP8ppcxXJZgAhMvK/B40xDIMydsmv5iEylHoX6broEZnSdhay+q?= =?us-ascii?Q?meB6LsIGz3WsV875yoeI=3D?= X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 6:9XWxIGDOuOJBDhNgGNymyq9cKmvpAEhdrgQ8KMkOnd8mWoeA1gJwBaaRmmlhhFzNtY1kGGc2sHfwfe4fsTySour+Pu9BvEyoB/HVeY3u7w768NPPlfTi5LlxXqD7pRc0bDqnFC84Qp6K+PlIEBSxe+lAbTq4k+8wyuEB/LfnQmNqhE3tZiBGGVRO4j/pG14HHPqKE+0JMjMegTxedVT2WQK6N879WJI7iaLEh4ARe3zXiyQEVV38uvxU1uh5hAJLMsjPn/98n8k+EEvoEhqC6Vx2Trsz1ZgF/xjmil6ktfn3PTNuSmXEJAAfyOxSUffYU1kjL4WmxljybRJjL6L6QzfY4tjwUM/W+DrAPeHN+mQ=; 5:Z/SckhcNadOC2ejWpGhQCSrjJy5n9cQcSGeZNx0JS9Wh6lw0euQXcVRxFZzYm1n2I0XGxpviEekcQsm+GyQT7i1X2Xkn1+pj9kQbaxXT6bfvKZSH6GxBr5LaW0LN2NOEXVMlUHCriUZ77nbIIPpAGwodx21Q3E5J/an7BHaWgBs=; 24:mYJWmwMWd5/Fnzi2yDW8Ihe8D5Tm80VIpxeNzBPt+0b9zT6TdUDg26jdt0OcQeWztU8q3mLy7CuRbFR0rJ9NcT3GApD10rZdjLO9QOobBqA=; 7:9OFmQJGcgx0U1lHYEUtiNsCZ+USD3lZPHaIWgeCwbbVReFwnvciEmzGI+Vn79PNCZhiMA0h++/KRfl2XwEmv4IVcUI/QZLHT0bC6TCxGKMlqw82urzWvo1sgxEXME/FBeMtlwF9ghvigFDqLayAoN2GcY3i9znYRvpHXSq8uiU8+uXV1rqKT9SeV0lqYagPNFKUM28s+h1BKTfqkqJce35dl9XkhGSmiFZcYH7vepxQG5bBFfm43Qr4eS4PXEKgX SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jan 2018 21:08:02.0314 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 33483f73-cb7f-4a58-9387-08d561dc3956 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR2101MB0878 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.36.116 Subject: [Qemu-devel] [PATCH v2 1/4] Add the Windows Hypervisor Platform accelerator. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: "Justin Terry \(VM\) via Qemu-devel" Reply-To: "Justin Terry \(VM\)" Cc: "Justin Terry \(VM\)" , pbonzini@redhat.com, rth@twiddle.net, ehabkost@redhat.com, crosthwaite.peter@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduces the configure support for the new Windows Hypervisor Platform th= at allows for hypervisor acceleration from usermode components on the Windows platform. Signed-off-by: Justin Terry (VM) --- configure | 48 +++++++++++++++++++++++++++++++++++++++++++++++- qemu-options.hx | 8 ++++---- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 6d8c996..3a36523 100755 --- a/configure +++ b/configure @@ -222,6 +222,17 @@ supported_hvf_target() { return 1 } =20 +supported_whpx_target() { + test "$whpx" =3D "yes" || return 1 + glob "$1" "*-softmmu" || return 1 + case "${1%-softmmu}" in + i386|x86_64) + return 0 + ;; + esac + return 1 +} + supported_target() { case "$1" in *-softmmu) @@ -248,6 +259,7 @@ supported_target() { supported_xen_target "$1" && return 0 supported_hax_target "$1" && return 0 supported_hvf_target "$1" && return 0 + supported_whpx_target "$1" && return 0 print_error "TCG disabled, but hardware accelerator not available for = '$target'" return 1 } @@ -338,6 +350,7 @@ vhost_user=3D"" kvm=3D"no" hax=3D"no" hvf=3D"no" +whpx=3D"no" rdma=3D"" gprof=3D"no" debug_tcg=3D"no" @@ -1054,6 +1067,10 @@ for opt do ;; --enable-hvf) hvf=3D"yes" ;; + --disable-whpx) whpx=3D"no" + ;; + --enable-whpx) whpx=3D"yes" + ;; --disable-tcg-interpreter) tcg_interpreter=3D"no" ;; --enable-tcg-interpreter) tcg_interpreter=3D"yes" @@ -1548,6 +1565,7 @@ disabled with --disable-FEATURE, default is enabled i= f available: kvm KVM acceleration support hax HAX acceleration support hvf Hypervisor.framework acceleration support + whpx Windows Hypervisor Platform acceleration support rdma RDMA-based migration support vde support for vde network netmap support for netmap network @@ -2446,6 +2464,30 @@ if test "$xen_pv_domain_build" =3D "yes" && fi =20 ########################################## +# Windows Hypervisor Platform accelerator (WHPX) check +if test "$whpx" !=3D "no" ; then + cat > $TMPC << EOF +#include +#include +#include +int main(void) { + WHV_CAPABILITY whpx_cap; + WHvGetCapability(WHvCapabilityCodeFeatures, &whpx_cap, sizeof(whpx_cap= )); + return 0; +} +EOF + if compile_prog "" "-lwinhvplatform -lwinhvemulation" ; then + libs_softmmu=3D"$libs_softmmu -lwinhvplatform -lwinhvemulation" + whpx=3D"yes" + else + if test "$whpx" =3D "yes"; then + feature_not_found "winhvplatform" "winhvemulation is not insta= lled" + fi + whpx=3D"no" + fi +fi + +########################################## # Sparse probe if test "$sparse" !=3D "no" ; then if has cgcc; then @@ -5577,6 +5619,7 @@ echo "Install blobs $blobs" echo "KVM support $kvm" echo "HAX support $hax" echo "HVF support $hvf" +echo "WHPX support $whpx" echo "TCG support $tcg" if test "$tcg" =3D "yes" ; then echo "TCG debug enabled $debug_tcg" @@ -5737,7 +5780,7 @@ if test "$mingw32" =3D "yes" ; then echo "CONFIG_QGA_NTDDDISK=3Dy" >> $config_host_mak fi if test "$guest_agent_msi" =3D "yes"; then - echo "QEMU_GA_MSI_ENABLED=3Dyes" >> $config_host_mak =20 + echo "QEMU_GA_MSI_ENABLED=3Dyes" >> $config_host_mak echo "QEMU_GA_MSI_MINGW_DLL_PATH=3D${QEMU_GA_MSI_MINGW_DLL_PATH}" >> $= config_host_mak echo "QEMU_GA_MSI_WITH_VSS=3D${QEMU_GA_MSI_WITH_VSS}" >> $config_host_= mak echo "QEMU_GA_MSI_ARCH=3D${QEMU_GA_MSI_ARCH}" >> $config_host_mak @@ -6659,6 +6702,9 @@ fi if supported_hvf_target $target; then echo "CONFIG_HVF=3Dy" >> $config_target_mak fi +if supported_whpx_target $target; then + echo "CONFIG_WHPX=3Dy" >> $config_target_mak +fi if test "$target_bigendian" =3D "yes" ; then echo "TARGET_WORDS_BIGENDIAN=3Dy" >> $config_target_mak fi diff --git a/qemu-options.hx b/qemu-options.hx index 5ff741a..9fbe468 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -31,7 +31,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ "-machine [type=3D]name[,prop[=3Dvalue][,...]]\n" " selects emulated machine ('-machine help' for list)\n" " property accel=3Daccel1[:accel2[:...]] selects accele= rator\n" - " supported accelerators are kvm, xen, hax, hvf or tcg = (default: tcg)\n" + " supported accelerators are kvm, xen, hax, hvf, whpx o= r tcg (default: tcg)\n" " kernel_irqchip=3Don|off|split controls accelerated ir= qchip support (default=3Doff)\n" " vmport=3Don|off|auto controls emulation of vmport (de= fault: auto)\n" " kvm_shadow_mem=3Dsize of KVM shadow MMU in bytes\n" @@ -66,7 +66,7 @@ Supported machine properties are: @table @option @item accel=3D@var{accels1}[:@var{accels2}[:...]] This is used to enable an accelerator. Depending on the target architectur= e, -kvm, xen, hax, hvf or tcg can be available. By default, tcg is used. If th= ere is +kvm, xen, hax, hvf, whpx or tcg can be available. By default, tcg is used.= If there is more than one accelerator specified, the next one is used if the previous = one fails to initialize. @item kernel_irqchip=3Don|off @@ -126,13 +126,13 @@ ETEXI =20 DEF("accel", HAS_ARG, QEMU_OPTION_accel, "-accel [accel=3D]accelerator[,thread=3Dsingle|multi]\n" - " select accelerator (kvm, xen, hax, hvf or tcg; use 'h= elp' for a list)\n" + " select accelerator (kvm, xen, hax, hvf, whpx or tcg; = use 'help' for a list)\n" " thread=3Dsingle|multi (enable multi-threaded TCG)", Q= EMU_ARCH_ALL) STEXI @item -accel @var{name}[,prop=3D@var{value}[,...]] @findex -accel This is used to enable an accelerator. Depending on the target architectur= e, -kvm, xen, hax, hvf or tcg can be available. By default, tcg is used. If th= ere is +kvm, xen, hax, hvf, whpx or tcg can be available. By default, tcg is used.= If there is more than one accelerator specified, the next one is used if the previous = one fails to initialize. @table @option --=20 2.7.4 From nobody Sat Apr 27 16:29:12 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516655548100977.9338340698135; Mon, 22 Jan 2018 13:12:28 -0800 (PST) Received: from localhost ([::1]:38312 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edjOF-0007We-CC for importer@patchew.org; Mon, 22 Jan 2018 16:12:27 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40788) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edjK5-0004YE-0j for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edjK1-00022T-LZ for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:08 -0500 Received: from mail-bn3nam01on0096.outbound.protection.outlook.com ([104.47.33.96]:36736 helo=NAM01-BN3-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1edjK1-00022I-FX for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:05 -0500 Received: from JUTERRY-DEV2.corp.microsoft.com (2001:4898:80e8:3::64) by SN4PR2101MB0878.namprd21.prod.outlook.com (2603:10b6:803:51::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.464.0; Mon, 22 Jan 2018 21:08:02 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=AMEEztqBQ2QyFK1AXZbMP7gZqshdonZOfWjOdGaUh9U=; b=MUtVR+QA8/+LY8VPE7p1qZUnqJBvHW37YtQTjV7iXM/39w5FzZrjoy5Fe8ZTAzrLrFLbBr9jwWYKltBz1dTpWGCClYYFwesBZsyNtFrg8rCKrXMi8SIH88QrXAhOjkZz0ohahDIuhrB7Y8Wq0W6rrXz+fQ22W8Frb8O2U3jgQ4k= To: qemu-devel@nongnu.org Date: Mon, 22 Jan 2018 13:07:47 -0800 Message-Id: <1516655269-1785-3-git-send-email-juterry@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516655269-1785-1-git-send-email-juterry@microsoft.com> References: <1516655269-1785-1-git-send-email-juterry@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:3::64] X-ClientProxiedBy: DM5PR21CA0002.namprd21.prod.outlook.com (2603:10b6:3:ac::12) To SN4PR2101MB0878.namprd21.prod.outlook.com (2603:10b6:803:51::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 48645dac-d05b-4288-79aa-08d561dc39de X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(48565401081)(4534125)(4602075)(4627221)(201703031133081)(201702281549075)(2017052603307)(7193020); SRVR:SN4PR2101MB0878; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 3:tNNlazsdPgV6OlvbHBSOMGWSJMvRW4pf5EginzkjYVqLiTIHnViYnDmoIaqvnxDQfh8Eq2X/mXMLZ0DAFuCJO1A/PPFH0LukWSjgtC0BoHOAvFfmepFZvJrMyBQr1gZX6jMRs17ieOoXkJtohmuxAR9UcpZKMm7HNCTmWwvCUJaRCPA7V3sT2LF1wUSoWKMbqGD8X0p/e6UbDKN1oIxu/0eZ9Ptknn12CbpdSJhHzJ1k+K+iExStWV90XLuV2pgp; 25:JN53AoZOBNqFXiKkhbO0TKxO/7hsawJNywuiZs/70IkPs4qNfQiz5xSmoJ6AirxWRws6N5jmWMaDAdGtW+UNH+aSxhOs161yGjCyfitB3RZ0+PU5JmVDm5GzZ/sbto1gz9ns77s8vZhH456Hz7y74S+7PRT/XQtP6KFmwakCv7sQSg7lnz+wLwR8heGdD973/z6qMdYAEjMI+T2yNeqnmczLqC1yZn8Ez4FfC8RudJC+bmrYL3p4APq4dh00KELWJ8F/M+Fg000qTTVh4u59XeEFEO4U/08zE7a5kddtVzMdPUWXf9QrRSBImVbkfmLFIMZ76W/zlr23iA57wkuhHA==; 31:P/IE8/S07+AmSGWpfrGjarDVoqsk8nP5iqX/Crs/cEM4INTIKQ65fozXvwjy7L3Qc6cY6l4bU7J/w57xdJhq3Pd5r+bvK+M6IENVnQ4k1MAyoHApKoEz4PLbKbDJ4Nc6vaP3efh2LY8aq6duN59YNQa6HTd113O+buL+n2FiIE6MpZS6Awx1i8fBOTdiB5Fc0hOPgQfdC2gITmpdI6XGo6jywfMz4e193HWHw+SojGs= X-MS-TrafficTypeDiagnostic: SN4PR2101MB0878: X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 20:wksexolqyKpxht78X8GuoQDmnJfRpfr9Nx8rLORordVDQuaEe5te+uiHXtuxqqIna/eNXckDlTIWj0pC6ItzQN1SO61woGddUtOdvHHaEUP4qm/R+QY7ARsqAjIkUsgSg5jJ9hi0+vFtTvuCfVnnzUblSZAd8HOBwC4kv4pA9TK07W2d4xZlXSGzYqsBrMGW6LElJ0JQQUPSABz7hhbi0cY4POnFOuv+e4uULshdxMqt7Zmp+F+xgO1q8DBlSICqIQG5fYVRVt9a/iRH2ja8lsQ+ERtPHvnH19TxjX6Q6Wa4NP7obqns6zWFpTAhTG5DYmo8ALl/kMOyhukVyvg5cKY0+12cDwslR63qzEGEqx6lRjWFkwkvuUz6lNmUGwVbSepD0QXmCbUvwujDnckMO60O1/D/+wX7e+W7BCZ6F5Ij+2VuXWKPogFxBmjXR7+9Xne8dcXuTeMpfGfq9AKOXGpEPxggrKI/9jlZzyhOJ4qcX0BuZwMGoLnzMLAq8q0S; 4:hyFw8BPrfb+ZJHk6AzSK93F/oeo2SSUhhzk6csdxrJ+KiaEI0NbBZz7JjGTrcYCkI6ALfr0cI7DB1l6gwi8Pc0xvCqEhQHsOw3zVJ0vPSzPB9nvpszquNg+OQsz4PAmKoOk1LKeig1BQK3ZhHcsSMLB1+jNdYkzRWhcyW2Ig9rEkFGyPiwWPO6ysUzHmfG1f+g6Yng/8B8glud4LJFP62hJ8oR4AwXQExbOH8eyxNaGR8Ks77kM9Yt3I9cJc8EOot7/iud81SKdqqslAV1YKrGqRI7MpOuNIKUvPBOqK2xzAfqcT8VTz1ZhtYpfb6LtfKaMH+WauhOn9qB1o7ISx28cZ85MKJ/QZ0bxToXGd4Og= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(28532068793085)(89211679590171); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(61425038)(6040501)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231046)(2400081)(944501161)(6055026)(61426038)(61427038)(6041288)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(6072148)(201708071742011); SRVR:SN4PR2101MB0878; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:SN4PR2101MB0878; X-Forefront-PRVS: 0560A2214D X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(39860400002)(396003)(366004)(39380400002)(376002)(199004)(189003)(10090500001)(52396003)(76176011)(48376002)(4326008)(7696005)(51416003)(52116002)(50466002)(39060400002)(107886003)(10290500003)(47776003)(305945005)(7736002)(6666003)(2351001)(6116002)(36756003)(2361001)(2950100002)(8676002)(6916009)(81156014)(386003)(81166006)(5660300001)(25786009)(8936002)(105586002)(478600001)(68736007)(50226002)(2906002)(86362001)(22452003)(106356001)(86612001)(6486002)(53936002)(97736004)(6346003)(316002)(16586007); DIR:OUT; SFP:1102; SCL:1; SRVR:SN4PR2101MB0878; H:JUTERRY-DEV2.corp.microsoft.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=juterry@microsoft.com; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR2101MB0878; 23:SJj1kfUQ+nx5CtPn2AFAaH9LSuTx24oYYywlEgb?= =?us-ascii?Q?+octRZ+ZmD8c6fLDbL49XVk91df7Nr4yl5IaYVKcTxEM217JqOl+w3+ZnYHr?= =?us-ascii?Q?9mhzPIIAf2G7J+XdR3mHx+NUoHJDVTUG0WOpBtuIfVQYLLWGn/EaiffKOk3r?= =?us-ascii?Q?owNKt3coHcS4QE8GFTJ3rlWTrx7zeHNFz2fyT/mzYdXHJK4b+XqC9jt5zhks?= =?us-ascii?Q?/Wa7qaG2i2X0hyhSwNcBcVvIfkU1iJVBif1V0Od7MJAQoHzhabIhkxjWWj7Z?= =?us-ascii?Q?do8qpikYxCylNJMLlFtVljfrruCEV//Hen0u25+UL5IAOE2oPG2OcCev6Vzg?= =?us-ascii?Q?I8jWUtFiXw8dOpyGtLqm7SVat6/Exb2D3zj+41E89CaUPjVTfTHAfpSYW7qP?= =?us-ascii?Q?T27mSPQOXqjIVs5VNplovcHIo5TB5DFJ8TcerzJTbbX4nHD/rKIn7WGJoE+q?= =?us-ascii?Q?bbEIzovqG+hgRdmoXFIoUt7HBvuWaHauhqjoFwq6IH916Vb9TfJTSAeoCdqx?= =?us-ascii?Q?o7C/sZyeIXCRdgHB6zwurVKmq1kDfGHxcOyBsdYFYorWtFLiNnkhn/9XI8kX?= =?us-ascii?Q?AsUvLq1sxrGl7BM/HLqd5eU9Rk7OGVxrh5mZEGimGl6NX0r5SpDpsO4hQ823?= =?us-ascii?Q?mrSHJodk8GCgdJBpi5BxBX+zsBz6L14nC7xeeZrC3GrG6x5e7CoFX850WKhN?= =?us-ascii?Q?P/7NXi3epoeQhJEGwxnw+Uvx6SEGI6+Y6AFBFFL/ippO0w5VSsSwKch0z1i6?= =?us-ascii?Q?7JACntGW3JBeMkYRRI2IJdREbjt2t9P2iRRmQjzwzrzh8rQ8MJcpyH7PhNUd?= =?us-ascii?Q?61Pf+Mj/hR3vXtUD6Um+Jd1a2qfLnwyXyIUEaTlgV+yR1dSdnhzCM2o1evBU?= =?us-ascii?Q?UjvbwnGh8W6FMwvsh1FGjFpDJcJRKgX4e9Zvyyv4zWKoSheMEGskjxI9Q3jk?= =?us-ascii?Q?AZ7kZyaldj6GXRQnodjljar5smTRtcJNSzqqd1/H5wIbVziqjqpZJ0BQAQt9?= =?us-ascii?Q?rKTsgi7B7AG3759kiKRnsDwXW1T6Q81Pj1K7oeRrfobRsC0Rf3lhHM+Gruqs?= =?us-ascii?Q?QJadAgM7oEf4TDAXv4JT8yH+j1BfMHD9g9FopDpd4pXHrx6DNlrKxL1Y0Tss?= =?us-ascii?Q?q9Ta6bYX9d2zOD/n3gD7LPPcMB7xQQUv0IIVhKoujfmQJUtwhsYOzlVxYWE1?= =?us-ascii?Q?SNgjnTFXzPYAW8A+XBEGroAQ1Wrh3s8uarrgD?= X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 6:9Y3GcC8HDn/W5LW7T+2RcAXoSoegeJKCHM4f/QDUbQzwsrtBihSroIh2FZZvsR644u9UBe01wm0vi5NnjFZMPQrNwry1dVK8PimynqhwtA5fh8TpfzdWNIihS9A5rMhvqj2Z9oIzF2o1IRiGOEmcm26XSjohdwtIk84fbRNMjr2upvc03JPWc5/j0IqzbIrZNS/gEOdhO62x8KEj7Mf4ago4ho+ceBF6FJwkDPDWHoPKRx+vysvqeLCUht0VVqHH5s5q+7FjZWCPTyWwFetaAWHKLkvWZUQ+ExHYMx2UBkwqxTb3H3cCMkSX5Kp2lT2S7SNfyiV9+CNtJWwtEUvD0yUPKzQv+K+WqM+sbi0l1vY=; 5:CTv86+H8VzofoObQi+//srrBFOVtdDZdsURSYnjTcHEOmJ7z6KucpuoPyZoduk2tr684fOAnrBdyArdcuk++9U/G//CrnKb980PbeQts/muLruzBb9ZL3WVhUUqOWFQVxaYDGiLeFxpmbjNwTbrpfcXodxUU3fY6jlZett+ALhw=; 24:vv5al0mrdV9S+de+jOjzlW6ezBVvve+njcOS8ACjip5a2qlMt4CSXNe8Bh2LkLMXJL3/xP8bQe+o7jT687H4fcvz7mlDU3u4R6fd7HNLx4I=; 7:KXpBEENg7i5VgJV17A8Po19XRNI6KnSPICU3uaifldHyJzZzNPi33HLg/vjTQ22/l5lGdIT8tuSDDyu/l/hv05ouS7swg9xIJT2psfFJon5vAs0XnM09RHNqPhu/rnjig+9TOq+1kfCjB7+lQ1BV0BqgYat68JIcG4de7JXWTFNFMQWkP5ZczYqRjzRkfJcuSLXmbwGe4l01Gxy0zod/elDWlqwrrsy02aVyBg+RhNivKpccusGwIF0pybWqJTFR SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jan 2018 21:08:02.9230 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 48645dac-d05b-4288-79aa-08d561dc39de X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR2101MB0878 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.33.96 Subject: [Qemu-devel] [PATCH v2 2/4] Add the WHPX vcpu API X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: "Justin Terry \(VM\) via Qemu-devel" Reply-To: "Justin Terry \(VM\)" Cc: "Justin Terry \(VM\)" , pbonzini@redhat.com, rth@twiddle.net, ehabkost@redhat.com, crosthwaite.peter@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Adds support for the Windows Hypervisor Platform accelerator (WHPX) stubs a= nd introduces the whpx.h sysemu API for managing the vcpu scheduling and management. Signed-off-by: Justin Terry (VM) --- accel/stubs/Makefile.objs | 9 +++++---- accel/stubs/whpx-stub.c | 48 +++++++++++++++++++++++++++++++++++++++++++= ++++ include/sysemu/whpx.h | 40 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 accel/stubs/whpx-stub.c create mode 100644 include/sysemu/whpx.h diff --git a/accel/stubs/Makefile.objs b/accel/stubs/Makefile.objs index 779343b..3894caf 100644 --- a/accel/stubs/Makefile.objs +++ b/accel/stubs/Makefile.objs @@ -1,4 +1,5 @@ -obj-$(call lnot,$(CONFIG_HAX)) +=3D hax-stub.o -obj-$(call lnot,$(CONFIG_HVF)) +=3D hvf-stub.o -obj-$(call lnot,$(CONFIG_KVM)) +=3D kvm-stub.o -obj-$(call lnot,$(CONFIG_TCG)) +=3D tcg-stub.o +obj-$(call lnot,$(CONFIG_HAX)) +=3D hax-stub.o +obj-$(call lnot,$(CONFIG_HVF)) +=3D hvf-stub.o +obj-$(call lnot,$(CONFIG_WHPX)) +=3D whpx-stub.o +obj-$(call lnot,$(CONFIG_KVM)) +=3D kvm-stub.o +obj-$(call lnot,$(CONFIG_TCG)) +=3D tcg-stub.o diff --git a/accel/stubs/whpx-stub.c b/accel/stubs/whpx-stub.c new file mode 100644 index 0000000..5fb049c --- /dev/null +++ b/accel/stubs/whpx-stub.c @@ -0,0 +1,48 @@ +/* + * QEMU Windows Hypervisor Platform accelerator (WHPX) stub + * + * 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 "qemu-common.h" +#include "cpu.h" +#include "sysemu/whpx.h" + +int whpx_init_vcpu(CPUState *cpu) +{ + return -1; +} + +int whpx_vcpu_exec(CPUState *cpu) +{ + return -1; +} + +void whpx_destroy_vcpu(CPUState *cpu) +{ +} + +void whpx_vcpu_kick(CPUState *cpu) +{ +} + +void whpx_cpu_synchronize_state(CPUState *cpu) +{ +} + +void whpx_cpu_synchronize_post_reset(CPUState *cpu) +{ +} + +void whpx_cpu_synchronize_post_init(CPUState *cpu) +{ +} + +void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu) +{ +} diff --git a/include/sysemu/whpx.h b/include/sysemu/whpx.h new file mode 100644 index 0000000..89592ae --- /dev/null +++ b/include/sysemu/whpx.h @@ -0,0 +1,40 @@ +/* + * QEMU Windows Hypervisor Platform accelerator (WHPX) support + * + * Copyright Microsoft, Corp. 2017 + * + * Authors: + * + * 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. + * + */ + +#ifndef QEMU_WHPX_H +#define QEMU_WHPX_H + +#include "config-host.h" +#include "qemu-common.h" + +int whpx_init_vcpu(CPUState *cpu); +int whpx_vcpu_exec(CPUState *cpu); +void whpx_destroy_vcpu(CPUState *cpu); +void whpx_vcpu_kick(CPUState *cpu); + + +void whpx_cpu_synchronize_state(CPUState *cpu); +void whpx_cpu_synchronize_post_reset(CPUState *cpu); +void whpx_cpu_synchronize_post_init(CPUState *cpu); +void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu); + +#ifdef CONFIG_WHPX + +int whpx_enabled(void); + +#else /* CONFIG_WHPX */ + +#define whpx_enabled() (0) + +#endif /* CONFIG_WHPX */ + +#endif /* QEMU_WHPX_H */ --=20 2.7.4 From nobody Sat Apr 27 16:29:12 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516655417355696.0442035336318; Mon, 22 Jan 2018 13:10:17 -0800 (PST) Received: from localhost ([::1]:38162 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edjM4-0005jR-AM for importer@patchew.org; Mon, 22 Jan 2018 16:10:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40801) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edjK7-0004aC-JZ for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edjK3-00023W-Ii for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:11 -0500 Received: from mail-bn3nam01on0113.outbound.protection.outlook.com ([104.47.33.113]:60729 helo=NAM01-BN3-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1edjK3-00023A-AK for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:07 -0500 Received: from JUTERRY-DEV2.corp.microsoft.com (2001:4898:80e8:3::64) by SN4PR2101MB0878.namprd21.prod.outlook.com (2603:10b6:803:51::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.464.0; Mon, 22 Jan 2018 21:08:03 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=ytffzsTb/UxjT+X0q1sfnI4NGclovbKATfaR6xlwYmo=; b=DrMs/MmSwBaGV3NpWws73CZan/KJQ74067Np2iLs2Rc7l5cK1UepHUqJyqjTa2fk6hdonowHKFRayWlVlp1HJ20mz8Tfd5yfWvOcisO6fpLVtrkvr1Jo0uJxoYZmLYQo8ypEEqLJ+4Ez3nT3a1z7akkl5yYuxass3IzoDhUL+Uc= To: qemu-devel@nongnu.org Date: Mon, 22 Jan 2018 13:07:48 -0800 Message-Id: <1516655269-1785-4-git-send-email-juterry@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516655269-1785-1-git-send-email-juterry@microsoft.com> References: <1516655269-1785-1-git-send-email-juterry@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:3::64] X-ClientProxiedBy: DM5PR21CA0002.namprd21.prod.outlook.com (2603:10b6:3:ac::12) To SN4PR2101MB0878.namprd21.prod.outlook.com (2603:10b6:803:51::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d380de7d-75c8-4ee3-507c-08d561dc3a6e X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(48565401081)(4534125)(4602075)(4627221)(201703031133081)(201702281549075)(2017052603307)(7193020); SRVR:SN4PR2101MB0878; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 3:EIUnrCKVrzsViVBcIzmJRgd8wI5ySI1Bo+Wi8I6S8Br5jxvYzevqUQEjiEn2pO2Otf2PErVSTZC6Dudd6EAUhVRrhBi+8X/+AhuYDki686gaIoVHYGA5Cqy0DWM7CENBrRiDTQVt9EHy8yOuHVX5EcARIvmIWFkG2iMUOJ64sxRaz5MswvOEtfxFukgd37cl17CCW6v9UQpkrvMpHhcAm8ZzM8CLmpHU5M2lsK/3JEKkLYY/5ytXnHfykmGYUume; 25:PzgR3MX8rL7U+ydYB5DmuMSqUjfSt3wXtEebv//tWdDGbZJcRmiZCq6Q6cR+XzOCcvtGtEj56eZNib2zh8K3omA8qcJMUPz96eO0wwj0ULcSjw2Su1wAziqjBxJA6XX76S/ZL/jB1NdS7SrGqwV5RaK4SUubsWkk/PK7/pQsw+jTiO2hCsrGG6jPT/NSn4WmWh8wKwS9O1vOrzFPZySNgImMkEj/RnM308R0Jk3iHuMq1sHymeUfh9+tx/snv7XlNktHAv+JwH59HBDepJp9wtasRiGB1zmNGpWv5qIxq82bXxGcXf/M2aMIiqnBAyjcPSTb/qbyC3cYz3YkqLh8eg==; 31:6ajb1PhGe4Le0JV4H7hfwSpzxCozeUaERgFLK3ZlieiyhVE/nw5d//WFyG/Rfq7Nm6wNBDxXXs7UOmb6NUb/cfwozv89WpCgQM79MHdbq0o0U+u461Hqf4GiZhSxM6hXVyBs2yYkScoYV/2SHavdBetE510xg/ifHbXElC8N00qqCq+8DvLy1BhCVS2232LAhtkF5Io4RGvbtHKmNjw4tDAwKyJZvTMVyEAzP20a2o4= X-MS-TrafficTypeDiagnostic: SN4PR2101MB0878: X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 20:4HjnEoqEUkUjFDaAnrS6J/OcZyTbyF8RFcp6T2zujaagE6TNziqhMOCJVprmJ5qDUUY2DwiTBgIQVgOkpdkJwbpqsG6enORNAosU0cq16UKv87pCkmB3YsBMASvksUwc5Mq7AH+MSKnwCI+7/8IpxWWt2C5u6isg2F88kU6RqLks5s/ldjgKGzV1TPZlkPtEwarEwPEuSdRWREx9qrbIHHTWRNtZmV8dUSeln6LhntCKwqynbcjd52Jkf7w3872BjRjvwPzmCZ4zHW4xecfgpdj7WCkHDWIL2cng8HlgaprBtG8jU2yOOGhJPutLLViW8um74eaA72Jwzyh+TEUAXm7uFr/wlVuLmsIsRQ7t3Zu032D/ahG61jiNPL1s2OBGrWyGvbV/xLj2NwiAjlNw4Ikoth1I58JS1kbsUxmKTI9jKneoI94552bIqz5fLgh1qyhVYoeOLXBBLQKGFKnW5wPYzWixROx7fmO+gn37dhTOLj+LzNPwe7s3DO/tYFzX; 4:3vbtClSSUlQUw4CJT0Dx6FWJq7yNms/g9eUSYw/6SQ9lsBziKeshJQ8Kr/wv9mavebhMUHrT39+RfGy+5V5uOgrFMoNwIhlE/8aPQ2IBVGMEVV2AWpIGu4j0/ivB+2DDFjBsejOLKP7jdrMHQbvl0r4BSsMa9LQt0F+rVJ6s6jr3ol+ZEF6EdlXMhQY5EZIlQ4a2LNFJhT2JZF2MD/nvDJY4YGB11ONnjKdPAlwIw0MYvHhV0lJQ7oHCZp1F78IQvvMw+963y5EXtwxEYVxYBm+GPG74Xjss41SBCuxoEWkknGwV7RoI7gUKzhpz3HzDJp6tnSrTuXnaIHMXDYKvC+ni446eplqtmnchp/asrYM= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(28532068793085)(89211679590171); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(61425038)(6040501)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231046)(2400081)(944501161)(6055026)(61426038)(61427038)(6041288)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(6072148)(201708071742011); SRVR:SN4PR2101MB0878; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:SN4PR2101MB0878; X-Forefront-PRVS: 0560A2214D X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(39860400002)(396003)(366004)(39380400002)(376002)(199004)(189003)(10090500001)(52396003)(76176011)(48376002)(4326008)(7696005)(51416003)(52116002)(50466002)(39060400002)(107886003)(10290500003)(47776003)(305945005)(7736002)(6666003)(2351001)(6116002)(36756003)(2361001)(2950100002)(8676002)(6916009)(81156014)(386003)(81166006)(5660300001)(25786009)(8936002)(551934003)(59450400001)(105586002)(478600001)(68736007)(50226002)(2906002)(86362001)(22452003)(106356001)(86612001)(6486002)(53946003)(53936002)(97736004)(6346003)(316002)(16586007)(579004)(19627235001); DIR:OUT; SFP:1102; SCL:1; SRVR:SN4PR2101MB0878; H:JUTERRY-DEV2.corp.microsoft.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=juterry@microsoft.com; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR2101MB0878; 23:1nsOt79Nd64LmngFksMggt5mHZkrW9o/rZvqs+H?= =?us-ascii?Q?daQj/N3A9v90vqBgQy6cIyEAs1TYKShJAAUYD9sedQxllvijfJ9mQGTJcpyI?= =?us-ascii?Q?pxX1Mn5kiYkh9U2qCyieSWpB3BiB2HaO8V31qa7uACy+P5Dga5Tl/SDea4zW?= =?us-ascii?Q?0DlNmkkAfCZOCki+L3wuMrnepbx9/Of70mX5ZhVetFJYhXR3GOWLzBLrkltO?= =?us-ascii?Q?n8imbZuDYcDqGfxK1wUBF3VB+cirvPUwHq1oUsGwREjc/wUkWNrNg+hp7CkS?= =?us-ascii?Q?ktx1Gz8n5abNsWgIlqs/l7hbOOh9OxLVzw2pkf6BQ9DkBnhBl9tf7Zm+t8g2?= =?us-ascii?Q?DplHCG9TTeGcbxDJOCdkZbtGWMh77GwRF5PB/DGIYnlXpgNHGaxTcvG0Z7GM?= =?us-ascii?Q?k4gpyPDfhEsBdN2dYVnJNdyS/k1ueKiZVC8LVWjri5KLI3muL1tp3jKrfFyG?= =?us-ascii?Q?pb8tuiIs94zKvvwmnkchb6iA9Lqc+YPp3UtM5mNVMTV/ieVld42y68+z20WP?= =?us-ascii?Q?RAXNLB+/ukvV0dXYHbWKc8gq0+NslNxUX/6XaeRmP7gT6FvLcvQg+DtmmGey?= =?us-ascii?Q?b3Ug7li2YOXescgXmxIdmsEeuaSoxDSK8KWjRbngsmHbH25M7AaS81pZgvvU?= =?us-ascii?Q?RhEzlYTdblxsj1Jl7qJgRPnFy8RtQuzSKLFYhfCOoJu2qy1E3v55Vjb96umd?= =?us-ascii?Q?azMQKOPtNysO40JLI5yHvp/gx8w8mGexBhAv8EHMYTQ0cS6GbLeCeoh+R8hK?= =?us-ascii?Q?ut23oBex1ajUixKdfDLFTTk+OrjYYH1H94+q33dF7nte5yvtVP0nE5UcqEV5?= =?us-ascii?Q?F8zTFcKb1Jxk67L79D5g673jtj28u+T1hwRPX0EmT1RElc1L/I90vC6G1Orf?= =?us-ascii?Q?o1aBcvWnyUXrFrDW5UK46LSmbsDBmuw5AzaPVkOnN4+U9ViaYUJhF65blesB?= =?us-ascii?Q?oVBE+j3ZUAry2fEZn9nx90OZL1DSrGgnadcv9ORnlRQQnpyVKYnI371Egk0Y?= =?us-ascii?Q?7LzhbiKw2T/BtoflNNbVcdPawxSingwyXC5ACSzJ5uDCMbZVf7e4NcheoOQR?= =?us-ascii?Q?xTuG/5yJme51M7C4+2Am7+QLpviLyLkIuF75EsScdNx/4zwTPDQADWNH3T9E?= =?us-ascii?Q?6qNaN+GOuf+H0v6fkeaVl5q24Am36nm874kHZnNrb6ev0VgvRTdhrGeVkxyU?= =?us-ascii?Q?hoLZXS7xVEIIeHChv4hiNxcN8Dm2dm0eyLRvrYwPwNeY0TnXvIvOvXCuAxw6?= =?us-ascii?Q?adpwXGHofwEepy0Q7CQV9dgbUXNMJ2RQRfbyoX6vSSHeUsuBD02vh/ObTrvu?= =?us-ascii?Q?zr0/VRj78i/ojmmTTcRUdWK5D4b2wZ83XOVmsEQguTls5?= X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 6:eTfWIbdECh4LVVDdm2vyZI6Qe+6J5GfenmxqlWlIhw8y4XM3CBVxXNxQsUL4KBnhXuo82uZ5hCJzA7c0ok8YPgTy/ZlaORPm/Lz2PxJPM/o9JCvGOoHZ4l+dnUr+ow6CH4QDbjSHUwItKARwndkCWznSyXhSB+9ai9oX41+LBDe0uqWmXVN6m1jkGFwP8gSYEbdlHC7zR/hE34YmEkicZlXvJuE/6fQDryQMNIXRMMnixrjEkodm/kn8iZHV9QsbgppNUvzZCXJdxmkFgIJWhBlQ/nMLIQhiH4VUnAo2OW6ZNm0Gi9cBmnDi8CBkfLbiiXkhdqiql+516uzKUVtd16p4N8Q6EVJC+XRn45qZr0Q=; 5:82UAQlN1s8Mz8DixQJT42nttQ2+/e6IXOzhNT7lHqa7N1ZMvzm75H6PKGk6O8rv/59ZETz9x3lYnuuo/2tQpTm4zRx+o1syVEA1toz8n80G8kBea9wcSkTlmUzJ8mA7aF94NLjoXksmrxugB+fkOmCVkl0fwX8E76fE5T824hyI=; 24:3mwpzLGknzqUfsZjcoiZI4hTBsYT8+UNGD2PxLmK4hshzRV7XoCUZusKbnKWQcA2JfRj4HFaLZzQGza31COYB/75jGdRKZOQ44gM9JJ1qFc=; 7:0ZlbJJZixNb0TTnuqIz+Lb5GDK0xqs9siBdtnXvxaCAp77UTdqauxrADOnUjR9jcjwy72dCI6wizCo0MAscW+1FcJl4tb2fLqgbSI9Kq/5pSccrQ8qtukBwBmPWrGRUlKsSxsWynRqO3o1gS/DssQRRiATrVLlyyHHqXX9SJfU9UcLk+Umq5AtGadadkiKcZXZSHMZ6amGdOSdFkqZlkw0RcJoam3BEV7/O7LsA7uPnntjJSVb13l9f5SR1YpAiI SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jan 2018 21:08:03.8637 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d380de7d-75c8-4ee3-507c-08d561dc3a6e X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR2101MB0878 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.33.113 Subject: [Qemu-devel] [PATCH v2 3/4] Introduce the WHPX impl X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: "Justin Terry \(VM\) via Qemu-devel" Reply-To: "Justin Terry \(VM\)" Cc: "Justin Terry \(VM\)" , pbonzini@redhat.com, rth@twiddle.net, ehabkost@redhat.com, crosthwaite.peter@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implements the Windows Hypervisor Platform accelerator (WHPX) target. Which acts as a hypervisor accelerator for QEMU on the Windows platform. This ena= bles QEMU much greater speed over the emulated x86_64 path's that are taken on Windows today. 1. Adds support for vPartition management. 2. Adds support for vCPU management. 3. Adds support for MMIO/PortIO. 4. Registers the WHPX ACCEL_CLASS. Signed-off-by: Justin Terry (VM) --- target/i386/Makefile.objs | 1 + target/i386/whpx-all.c | 1366 +++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 1367 insertions(+) create mode 100644 target/i386/whpx-all.c diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs index 44103a6..f5c6ef2 100644 --- a/target/i386/Makefile.objs +++ b/target/i386/Makefile.objs @@ -14,3 +14,4 @@ ifdef CONFIG_DARWIN obj-$(CONFIG_HAX) +=3D hax-all.o hax-mem.o hax-darwin.o obj-$(CONFIG_HVF) +=3D hvf/ endif +obj-$(CONFIG_WHPX) +=3D whpx-all.o diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c new file mode 100644 index 0000000..0015b27 --- /dev/null +++ b/target/i386/whpx-all.c @@ -0,0 +1,1366 @@ +/* + * 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 "exec/address-spaces.h" +#include "exec/exec-all.h" +#include "exec/ioport.h" +#include "qemu-common.h" +#include "strings.h" +#include "sysemu/accel.h" +#include "sysemu/whpx.h" +#include "sysemu/sysemu.h" +#include "sysemu/cpus.h" +#include "qemu/main-loop.h" +#include "hw/boards.h" +#include "qemu/error-report.h" +#include "qemu/queue.h" +#include "qapi/error.h" +#include "migration/blocker.h" + +#include +#include + +struct whpx_state { + uint64_t mem_quota; + WHV_PARTITION_HANDLE partition; + uint32_t exit_ctx_size; +}; + +static const WHV_REGISTER_NAME whpx_register_names[] =3D { + + /* X64 General purpose registers */ + WHvX64RegisterRax, + WHvX64RegisterRcx, + WHvX64RegisterRdx, + WHvX64RegisterRbx, + WHvX64RegisterRsp, + WHvX64RegisterRbp, + WHvX64RegisterRsi, + WHvX64RegisterRdi, + WHvX64RegisterR8, + WHvX64RegisterR9, + WHvX64RegisterR10, + WHvX64RegisterR11, + WHvX64RegisterR12, + WHvX64RegisterR13, + WHvX64RegisterR14, + WHvX64RegisterR15, + WHvX64RegisterRip, + WHvX64RegisterRflags, + + /* X64 Segment registers */ + WHvX64RegisterEs, + WHvX64RegisterCs, + WHvX64RegisterSs, + WHvX64RegisterDs, + WHvX64RegisterFs, + WHvX64RegisterGs, + WHvX64RegisterLdtr, + WHvX64RegisterTr, + + /* X64 Table registers */ + WHvX64RegisterIdtr, + WHvX64RegisterGdtr, + + /* X64 Control Registers */ + WHvX64RegisterCr0, + WHvX64RegisterCr2, + WHvX64RegisterCr3, + WHvX64RegisterCr4, + WHvX64RegisterCr8, + + /* X64 Debug Registers */ + /* + * WHvX64RegisterDr0, + * WHvX64RegisterDr1, + * WHvX64RegisterDr2, + * WHvX64RegisterDr3, + * WHvX64RegisterDr6, + * WHvX64RegisterDr7, + */ + + /* X64 Floating Point and Vector Registers */ + WHvX64RegisterXmm0, + WHvX64RegisterXmm1, + WHvX64RegisterXmm2, + WHvX64RegisterXmm3, + WHvX64RegisterXmm4, + WHvX64RegisterXmm5, + WHvX64RegisterXmm6, + WHvX64RegisterXmm7, + WHvX64RegisterXmm8, + WHvX64RegisterXmm9, + WHvX64RegisterXmm10, + WHvX64RegisterXmm11, + WHvX64RegisterXmm12, + WHvX64RegisterXmm13, + WHvX64RegisterXmm14, + WHvX64RegisterXmm15, + WHvX64RegisterFpMmx0, + WHvX64RegisterFpMmx1, + WHvX64RegisterFpMmx2, + WHvX64RegisterFpMmx3, + WHvX64RegisterFpMmx4, + WHvX64RegisterFpMmx5, + WHvX64RegisterFpMmx6, + WHvX64RegisterFpMmx7, + WHvX64RegisterFpControlStatus, + WHvX64RegisterXmmControlStatus, + + /* X64 MSRs */ + WHvX64RegisterTsc, + WHvX64RegisterEfer, +#ifdef TARGET_X86_64 + WHvX64RegisterKernelGsBase, +#endif + WHvX64RegisterApicBase, + /* WHvX64RegisterPat, */ + WHvX64RegisterSysenterCs, + WHvX64RegisterSysenterEip, + WHvX64RegisterSysenterEsp, + WHvX64RegisterStar, +#ifdef TARGET_X86_64 + WHvX64RegisterLstar, + WHvX64RegisterCstar, + WHvX64RegisterSfmask, +#endif + + /* Interrupt / Event Registers */ + /* + * WHvRegisterPendingInterruption, + * WHvRegisterInterruptState, + * WHvRegisterPendingEvent0, + * WHvRegisterPendingEvent1 + * WHvX64RegisterDeliverabilityNotifications, + */ +}; + +struct whpx_register_set { + WHV_REGISTER_VALUE values[RTL_NUMBER_OF(whpx_register_names)]; +}; + +struct whpx_vcpu { + WHV_EMULATOR_HANDLE emulator; + bool window_registered; + bool interruptable; + uint64_t tpr; + uint64_t apic_base; + WHV_X64_PENDING_INTERRUPTION_REGISTER interrupt_in_flight; + + /* Must be the last field as it may have a tail */ + WHV_RUN_VP_EXIT_CONTEXT exit_ctx; +}; + +static bool whpx_allowed; + +struct whpx_state whpx_global; + + +/* + * VP support + */ + +static struct whpx_vcpu *get_whpx_vcpu(CPUState *cpu) +{ + return (struct whpx_vcpu *)cpu->hax_vcpu; +} + +static WHV_X64_SEGMENT_REGISTER whpx_seg_q2h(const SegmentCache *qs, int v= 86, + int r86) +{ + WHV_X64_SEGMENT_REGISTER hs; + unsigned flags =3D qs->flags; + + hs.Base =3D qs->base; + hs.Limit =3D qs->limit; + hs.Selector =3D qs->selector; + + if (v86) { + hs.Attributes =3D 0; + hs.SegmentType =3D 3; + hs.Present =3D 1; + hs.DescriptorPrivilegeLevel =3D 3; + hs.NonSystemSegment =3D 1; + + } else { + hs.Attributes =3D (flags >> DESC_TYPE_SHIFT); + + if (r86) { + /* hs.Base &=3D 0xfffff; */ + } + } + + return hs; +} + +static SegmentCache whpx_seg_h2q(const WHV_X64_SEGMENT_REGISTER *hs) +{ + SegmentCache qs; + + qs.base =3D hs->Base; + qs.limit =3D hs->Limit; + qs.selector =3D hs->Selector; + + qs.flags =3D ((uint32_t)hs->Attributes) << DESC_TYPE_SHIFT; + + return qs; +} + +static void whpx_set_registers(CPUState *cpu) +{ + struct whpx_state *whpx =3D &whpx_global; + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + struct CPUX86State *env =3D (CPUArchState *)(cpu->env_ptr); + X86CPU *x86_cpu =3D X86_CPU(cpu); + struct whpx_register_set vcxt =3D {0}; + HRESULT hr; + int idx =3D 0; + int i; + int v86, r86; + + assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + + v86 =3D (env->eflags & VM_MASK); + r86 =3D !(env->cr[0] & CR0_PE_MASK); + + vcpu->tpr =3D cpu_get_apic_tpr(x86_cpu->apic_state); + vcpu->apic_base =3D cpu_get_apic_base(x86_cpu->apic_state); + + /* Indexes for first 16 registers match between HV and QEMU definition= s */ + for (idx =3D 0; idx < CPU_NB_REGS64; idx +=3D 1) { + vcxt.values[idx].Reg64 =3D env->regs[idx]; + } + + /* Same goes for RIP and RFLAGS */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterRip); + vcxt.values[idx++].Reg64 =3D env->eip; + + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterRflags); + vcxt.values[idx++].Reg64 =3D env->eflags; + + /* Translate 6+4 segment registers. HV and QEMU order matches */ + assert(idx =3D=3D WHvX64RegisterEs); + for (i =3D 0; i < 6; i +=3D 1, idx +=3D 1) { + vcxt.values[idx].Segment =3D whpx_seg_q2h(&env->segs[i], v86, r86); + } + + assert(idx =3D=3D WHvX64RegisterLdtr); + vcxt.values[idx++].Segment =3D whpx_seg_q2h(&env->ldt, 0, 0); + + assert(idx =3D=3D WHvX64RegisterTr); + vcxt.values[idx++].Segment =3D whpx_seg_q2h(&env->tr, 0, 0); + + assert(idx =3D=3D WHvX64RegisterIdtr); + vcxt.values[idx].Table.Base =3D env->idt.base; + vcxt.values[idx].Table.Limit =3D env->idt.limit; + idx +=3D 1; + + assert(idx =3D=3D WHvX64RegisterGdtr); + vcxt.values[idx].Table.Base =3D env->gdt.base; + vcxt.values[idx].Table.Limit =3D env->gdt.limit; + idx +=3D 1; + + /* CR0, 2, 3, 4, 8 */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr0); + vcxt.values[idx++].Reg64 =3D env->cr[0]; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr2); + vcxt.values[idx++].Reg64 =3D env->cr[2]; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr3); + vcxt.values[idx++].Reg64 =3D env->cr[3]; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr4); + vcxt.values[idx++].Reg64 =3D env->cr[4]; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr8); + vcxt.values[idx++].Reg64 =3D vcpu->tpr; + + /* 8 Debug Registers - Skipped */ + + /* 16 XMM registers */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterXmm0); + for (i =3D 0; i < 16; i +=3D 1, idx +=3D 1) { + vcxt.values[idx].Reg128.Low64 =3D env->xmm_regs[i].ZMM_Q(0); + vcxt.values[idx].Reg128.High64 =3D env->xmm_regs[i].ZMM_Q(1); + } + + /* 8 FP registers */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterFpMmx0); + for (i =3D 0; i < 8; i +=3D 1, idx +=3D 1) { + vcxt.values[idx].Fp.AsUINT128.Low64 =3D env->fpregs[i].mmx.MMX_Q(0= ); + /* vcxt.values[idx].Fp.AsUINT128.High64 =3D + env->fpregs[i].mmx.MMX_Q(1); + */ + } + + /* FP control status register */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterFpControlStatus); + vcxt.values[idx].FpControlStatus.FpControl =3D env->fpuc; + vcxt.values[idx].FpControlStatus.FpStatus =3D + (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; + vcxt.values[idx].FpControlStatus.FpTag =3D 0; + for (i =3D 0; i < 8; ++i) { + vcxt.values[idx].FpControlStatus.FpTag |=3D (!env->fptags[i]) << i; + } + vcxt.values[idx].FpControlStatus.Reserved =3D 0; + vcxt.values[idx].FpControlStatus.LastFpOp =3D env->fpop; + vcxt.values[idx].FpControlStatus.LastFpRip =3D env->fpip; + idx +=3D 1; + + /* XMM control status register */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterXmmControlStatus); + vcxt.values[idx].XmmControlStatus.LastFpRdp =3D 0; + vcxt.values[idx].XmmControlStatus.XmmStatusControl =3D env->mxcsr; + vcxt.values[idx].XmmControlStatus.XmmStatusControlMask =3D 0x0000ffff; + idx +=3D 1; + + /* MSRs */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterTsc); + vcxt.values[idx++].Reg64 =3D env->tsc; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterEfer); + vcxt.values[idx++].Reg64 =3D env->efer; +#ifdef TARGET_X86_64 + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterKernelGsBase); + vcxt.values[idx++].Reg64 =3D env->kernelgsbase; +#endif + + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterApicBase); + vcxt.values[idx++].Reg64 =3D vcpu->apic_base; + + /* WHvX64RegisterPat - Skipped */ + + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterSysenterCs); + vcxt.values[idx++].Reg64 =3D env->sysenter_cs; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterSysenterEip); + vcxt.values[idx++].Reg64 =3D env->sysenter_eip; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterSysenterEsp); + vcxt.values[idx++].Reg64 =3D env->sysenter_esp; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterStar); + vcxt.values[idx++].Reg64 =3D env->star; +#ifdef TARGET_X86_64 + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterLstar); + vcxt.values[idx++].Reg64 =3D env->lstar; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCstar); + vcxt.values[idx++].Reg64 =3D env->cstar; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterSfmask); + vcxt.values[idx++].Reg64 =3D env->fmask; +#endif + + /* Interrupt / Event Registers - Skipped */ + + assert(idx =3D=3D RTL_NUMBER_OF(whpx_register_names)); + + hr =3D WHvSetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index, + whpx_register_names, + RTL_NUMBER_OF(whpx_register_names= ), + &vcxt.values[0]); + + if (FAILED(hr)) { + error_report("WHPX: Failed to set virtual processor context, hr=3D= %08lx", + hr); + __debugbreak(); + } + + return; +} + +static void whpx_get_registers(CPUState *cpu) +{ + struct whpx_state *whpx =3D &whpx_global; + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + struct CPUX86State *env =3D (CPUArchState *)(cpu->env_ptr); + X86CPU *x86_cpu =3D X86_CPU(cpu); + struct whpx_register_set vcxt; + uint64_t tpr, apic_base; + HRESULT hr; + int idx =3D 0; + int i; + + assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + + hr =3D WHvGetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index, + whpx_register_names, + RTL_NUMBER_OF(whpx_register_names= ), + &vcxt.values[0]); + if (FAILED(hr)) { + error_report("WHPX: Failed to get virtual processor context, hr=3D= %08lx", + hr); + __debugbreak(); + } + + /* Indexes for first 16 registers match between HV and QEMU definition= s */ + for (idx =3D 0; idx < CPU_NB_REGS64; idx +=3D 1) { + env->regs[idx] =3D vcxt.values[idx].Reg64; + } + + /* Same goes for RIP and RFLAGS */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterRip); + env->eip =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterRflags); + env->eflags =3D vcxt.values[idx++].Reg64; + + /* Translate 6+4 segment registers. HV and QEMU order matches */ + assert(idx =3D=3D WHvX64RegisterEs); + for (i =3D 0; i < 6; i +=3D 1, idx +=3D 1) { + env->segs[i] =3D whpx_seg_h2q(&vcxt.values[idx].Segment); + } + + assert(idx =3D=3D WHvX64RegisterLdtr); + env->ldt =3D whpx_seg_h2q(&vcxt.values[idx++].Segment); + assert(idx =3D=3D WHvX64RegisterTr); + env->tr =3D whpx_seg_h2q(&vcxt.values[idx++].Segment); + assert(idx =3D=3D WHvX64RegisterIdtr); + env->idt.base =3D vcxt.values[idx].Table.Base; + env->idt.limit =3D vcxt.values[idx].Table.Limit; + idx +=3D 1; + assert(idx =3D=3D WHvX64RegisterGdtr); + env->gdt.base =3D vcxt.values[idx].Table.Base; + env->gdt.limit =3D vcxt.values[idx].Table.Limit; + idx +=3D 1; + + /* CR0, 2, 3, 4, 8 */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr0); + env->cr[0] =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr2); + env->cr[2] =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr3); + env->cr[3] =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr4); + env->cr[4] =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCr8); + tpr =3D vcxt.values[idx++].Reg64; + if (tpr !=3D vcpu->tpr) { + vcpu->tpr =3D tpr; + cpu_set_apic_tpr(x86_cpu->apic_state, tpr); + } + + /* 8 Debug Registers - Skipped */ + + /* 16 XMM registers */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterXmm0); + for (i =3D 0; i < 16; i +=3D 1, idx +=3D 1) { + env->xmm_regs[i].ZMM_Q(0) =3D vcxt.values[idx].Reg128.Low64; + env->xmm_regs[i].ZMM_Q(1) =3D vcxt.values[idx].Reg128.High64; + } + + /* 8 FP registers */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterFpMmx0); + for (i =3D 0; i < 8; i +=3D 1, idx +=3D 1) { + env->fpregs[i].mmx.MMX_Q(0) =3D vcxt.values[idx].Fp.AsUINT128.Low6= 4; + /* env->fpregs[i].mmx.MMX_Q(1) =3D + vcxt.values[idx].Fp.AsUINT128.High64; + */ + } + + /* FP control status register */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterFpControlStatus); + env->fpuc =3D vcxt.values[idx].FpControlStatus.FpControl; + env->fpstt =3D (vcxt.values[idx].FpControlStatus.FpStatus >> 11) & 0x7; + env->fpus =3D vcxt.values[idx].FpControlStatus.FpStatus & ~0x3800; + for (i =3D 0; i < 8; ++i) { + env->fptags[i] =3D !((vcxt.values[idx].FpControlStatus.FpTag >> i)= & 1); + } + env->fpop =3D vcxt.values[idx].FpControlStatus.LastFpOp; + env->fpip =3D vcxt.values[idx].FpControlStatus.LastFpRip; + idx +=3D 1; + + /* XMM control status register */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterXmmControlStatus); + env->mxcsr =3D vcxt.values[idx].XmmControlStatus.XmmStatusControl; + idx +=3D 1; + + /* MSRs */ + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterTsc); + env->tsc =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterEfer); + env->efer =3D vcxt.values[idx++].Reg64; +#ifdef TARGET_X86_64 + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterKernelGsBase); + env->kernelgsbase =3D vcxt.values[idx++].Reg64; +#endif + + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterApicBase); + apic_base =3D vcxt.values[idx++].Reg64; + if (apic_base !=3D vcpu->apic_base) { + vcpu->apic_base =3D apic_base; + cpu_set_apic_base(x86_cpu->apic_state, vcpu->apic_base); + } + + /* WHvX64RegisterPat - Skipped */ + + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterSysenterCs); + env->sysenter_cs =3D vcxt.values[idx++].Reg64;; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterSysenterEip); + env->sysenter_eip =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterSysenterEsp); + env->sysenter_esp =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterStar); + env->star =3D vcxt.values[idx++].Reg64; +#ifdef TARGET_X86_64 + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterLstar); + env->lstar =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterCstar); + env->cstar =3D vcxt.values[idx++].Reg64; + assert(whpx_register_names[idx] =3D=3D WHvX64RegisterSfmask); + env->fmask =3D vcxt.values[idx++].Reg64; +#endif + + /* Interrupt / Event Registers - Skipped */ + + assert(idx =3D=3D RTL_NUMBER_OF(whpx_register_names)); + + return; +} + +static HRESULT CALLBACK whpx_emu_ioport_callback( + void *ctx, + WHV_EMULATOR_IO_ACCESS_INFO *IoAccess) +{ + MemTxAttrs attrs =3D { 0 }; + address_space_rw(&address_space_io, IoAccess->Port, attrs, + (uint8_t *)&IoAccess->Data, IoAccess->AccessSize, + IoAccess->Direction); + return S_OK; +} + +static HRESULT CALLBACK whpx_emu_memio_callback( + void *ctx, + WHV_EMULATOR_MEMORY_ACCESS_INFO *ma) +{ + cpu_physical_memory_rw(ma->GpaAddress, ma->Data, ma->AccessSize, + ma->Direction); + return S_OK; +} + +static HRESULT CALLBACK whpx_emu_getreg_callback( + void *ctx, + const WHV_REGISTER_NAME *RegisterNames, + UINT32 RegisterCount, + WHV_REGISTER_VALUE *RegisterValues) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + CPUState *cpu =3D (CPUState *)ctx; + + hr =3D WHvGetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index, + RegisterNames, RegisterCount, + RegisterValues); + if (FAILED(hr)) { + error_report("WHPX: Failed to get virtual processor registers," + " hr=3D%08lx", hr); + __debugbreak(); + } + + return hr; +} + +static HRESULT CALLBACK whpx_emu_setreg_callback( + void *ctx, + const WHV_REGISTER_NAME *RegisterNames, + UINT32 RegisterCount, + const WHV_REGISTER_VALUE *RegisterValues) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + CPUState *cpu =3D (CPUState *)ctx; + + hr =3D WHvSetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index, + RegisterNames, RegisterCount, + RegisterValues); + if (FAILED(hr)) { + error_report("WHPX: Failed to set virtual processor registers," + " hr=3D%08lx", hr); + __debugbreak(); + } + + /* + * The emulator just successfully wrote the register state. We clear t= he + * dirty state so we avoid the double write on resume of the VP. + */ + cpu->vcpu_dirty =3D false; + + return hr; +} + +static HRESULT CALLBACK whpx_emu_translate_callback( + void *ctx, + WHV_GUEST_VIRTUAL_ADDRESS Gva, + WHV_TRANSLATE_GVA_FLAGS TranslateFlags, + WHV_TRANSLATE_GVA_RESULT_CODE *TranslationResult, + WHV_GUEST_PHYSICAL_ADDRESS *Gpa) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + CPUState *cpu =3D (CPUState *)ctx; + WHV_TRANSLATE_GVA_RESULT res; + + hr =3D WHvTranslateGva(whpx->partition, cpu->cpu_index, + Gva, TranslateFlags, &res, Gpa); + if (FAILED(hr)) { + error_report("WHPX: Failed to translate GVA, hr=3D%08lx", hr); + __debugbreak(); + } else { + *TranslationResult =3D res.ResultCode; + } + + return hr; +} + +static const WHV_EMULATOR_CALLBACKS whpx_emu_callbacks =3D { + .WHvEmulatorIoPortCallback =3D whpx_emu_ioport_callback, + .WHvEmulatorMemoryCallback =3D whpx_emu_memio_callback, + .WHvEmulatorGetVirtualProcessorRegisters =3D whpx_emu_getreg_callback, + .WHvEmulatorSetVirtualProcessorRegisters =3D whpx_emu_setreg_callback, + .WHvEmulatorTranslateGvaPage =3D whpx_emu_translate_callback, +}; + +static int whpx_handle_mmio(CPUState *cpu, WHV_MEMORY_ACCESS_CONTEXT *ctx) +{ + HRESULT hr; + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + WHV_EMULATOR_STATUS emu_status; + + hr =3D WHvEmulatorTryMmioEmulation(vcpu->emulator, cpu, ctx, &emu_stat= us); + if (FAILED(hr)) { + __debugbreak(); + error_report("WHPX: Failed to parse MMIO access, hr=3D%08lx", hr); + return -1; + } + + if (!emu_status.EmulationSuccessful) { + __debugbreak(); + error_report("WHPX: Failed to emulate MMIO access"); + return -1; + } + + return 0; +} + +static int whpx_handle_portio(CPUState *cpu, + WHV_X64_IO_PORT_ACCESS_CONTEXT *ctx) +{ + HRESULT hr; + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + WHV_EMULATOR_STATUS emu_status; + + hr =3D WHvEmulatorTryIoEmulation(vcpu->emulator, cpu, ctx, &emu_status= ); + if (FAILED(hr)) { + __debugbreak(); + error_report("WHPX: Failed to parse PortIO access, hr=3D%08lx", hr= ); + return -1; + } + + if (!emu_status.EmulationSuccessful) { + __debugbreak(); + error_report("WHPX: Failed to emulate PortMMIO access"); + return -1; + } + + return 0; +} + +static int whpx_handle_halt(CPUState *cpu) +{ + struct CPUX86State *env =3D (CPUArchState *)(cpu->env_ptr); + int ret =3D 0; + + qemu_mutex_lock_iothread(); + if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK)) && + !(cpu->interrupt_request & CPU_INTERRUPT_NMI)) { + cpu->exception_index =3D EXCP_HLT; + cpu->halted =3D true; + ret =3D 1; + } + qemu_mutex_unlock_iothread(); + + return ret; +} + +static void whpx_vcpu_pre_run(CPUState *cpu) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + struct CPUX86State *env =3D (CPUArchState *)(cpu->env_ptr); + X86CPU *x86_cpu =3D X86_CPU(cpu); + int irq; + WHV_X64_PENDING_INTERRUPTION_REGISTER new_int =3D {0}; + UINT32 reg_count =3D 0; + WHV_REGISTER_VALUE reg_values[3] =3D {0}; + WHV_REGISTER_NAME reg_names[3]; + + qemu_mutex_lock_iothread(); + + /* Inject NMI */ + if (!vcpu->interrupt_in_flight.InterruptionPending && + cpu->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) { + if (cpu->interrupt_request & CPU_INTERRUPT_NMI) { + cpu->interrupt_request &=3D ~CPU_INTERRUPT_NMI; + vcpu->interruptable =3D false; + new_int.InterruptionType =3D WHvX64PendingNmi; + new_int.InterruptionPending =3D 1; + new_int.InterruptionVector =3D 2; + } + if (cpu->interrupt_request & CPU_INTERRUPT_SMI) { + qemu_mutex_lock_iothread(); + cpu->interrupt_request &=3D ~CPU_INTERRUPT_SMI; + __debugbreak(); + qemu_mutex_unlock_iothread(); + } + } + + /* + * Force the VCPU out of its inner loop to process any INIT requests or + * commit pending TPR access. + */ + if (cpu->interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR))= { + if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) && + !(env->hflags & HF_SMM_MASK)) { + cpu->exit_request =3D 1; + } + if (cpu->interrupt_request & CPU_INTERRUPT_TPR) { + cpu->exit_request =3D 1; + } + } + + /* Get pending hard interruption or replay one that was overwritten */ + if (!vcpu->interrupt_in_flight.InterruptionPending && + vcpu->interruptable && (env->eflags & IF_MASK)) { + assert(!new_int.InterruptionPending); + if (cpu->interrupt_request & CPU_INTERRUPT_HARD) { + cpu->interrupt_request &=3D ~CPU_INTERRUPT_HARD; + irq =3D cpu_get_pic_interrupt(env); + if (irq >=3D 0) { + new_int.InterruptionType =3D WHvX64PendingInterrupt; + new_int.InterruptionPending =3D 1; + new_int.InterruptionVector =3D irq; + } + } + } + + /* Setup interrupt state if new one was prepared */ + if (new_int.InterruptionPending) { + reg_values[reg_count].PendingInterruption =3D new_int; + reg_names[reg_count] =3D WHvRegisterPendingInterruption; + reg_count +=3D 1; + } + + /* Sync the TPR to the CR8 if was modified during the intercept */ + reg_values[reg_count].Reg64 =3D cpu_get_apic_tpr(x86_cpu->apic_state); + if (reg_values[reg_count].Reg64 !=3D vcpu->tpr) { + vcpu->tpr =3D reg_values[reg_count].Reg64; + cpu->exit_request =3D 1; + reg_names[reg_count] =3D WHvX64RegisterCr8; + reg_count +=3D 1; + } + + /* Update the state of the interrupt delivery notification */ + if (cpu->interrupt_request & CPU_INTERRUPT_HARD) { + reg_values[reg_count].DeliverabilityNotifications.InterruptNotific= ation + =3D 1; + if (vcpu->window_registered !=3D 1) { + vcpu->window_registered =3D 1; + } + reg_names[reg_count] =3D WHvX64RegisterDeliverabilityNotifications; + reg_count +=3D 1; + } + + qemu_mutex_unlock_iothread(); + + if (reg_count) { + hr =3D WHvSetVirtualProcessorRegisters(whpx->partition, cpu->cpu_i= ndex, + reg_names, reg_count, reg_val= ues); + if (FAILED(hr)) { + error_report("WHPX: Failed to set interrupt state registers," + " hr=3D%08lx", hr); + __debugbreak(); + } + } + + return; +} + +static void whpx_vcpu_post_run(CPUState *cpu) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + struct CPUX86State *env =3D (CPUArchState *)(cpu->env_ptr); + X86CPU *x86_cpu =3D X86_CPU(cpu); + WHV_REGISTER_VALUE reg_values[4]; + const WHV_REGISTER_NAME reg_names[4] =3D { + WHvX64RegisterRflags, + WHvX64RegisterCr8, + WHvRegisterPendingInterruption, + WHvRegisterInterruptState, + }; + + hr =3D WHvGetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index, + reg_names, 4, reg_values); + if (FAILED(hr)) { + error_report("WHPX: Failed to get interrupt state regusters," + " hr=3D%08lx", hr); + __debugbreak(); + vcpu->interruptable =3D false; + return; + } + + assert(reg_names[0] =3D=3D WHvX64RegisterRflags); + env->eflags =3D reg_values[0].Reg64; + + assert(reg_names[1] =3D=3D WHvX64RegisterCr8); + if (vcpu->tpr !=3D reg_values[1].Reg64) { + vcpu->tpr =3D reg_values[1].Reg64; + qemu_mutex_lock_iothread(); + cpu_set_apic_tpr(x86_cpu->apic_state, vcpu->tpr); + qemu_mutex_unlock_iothread(); + } + + assert(reg_names[2] =3D=3D WHvRegisterPendingInterruption); + vcpu->interrupt_in_flight =3D reg_values[2].PendingInterruption; + + assert(reg_names[3] =3D=3D WHvRegisterInterruptState); + vcpu->interruptable =3D !reg_values[3].InterruptState.InterruptShadow; + + return; +} + +static void whpx_vcpu_process_async_events(CPUState *cpu) +{ + struct CPUX86State *env =3D (CPUArchState *)(cpu->env_ptr); + X86CPU *x86_cpu =3D X86_CPU(cpu); + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + + if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) && + !(env->hflags & HF_SMM_MASK)) { + + do_cpu_init(x86_cpu); + cpu->vcpu_dirty =3D true; + vcpu->interruptable =3D true; + } + + if (cpu->interrupt_request & CPU_INTERRUPT_POLL) { + cpu->interrupt_request &=3D ~CPU_INTERRUPT_POLL; + apic_poll_irq(x86_cpu->apic_state); + } + + if (((cpu->interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK)) || + (cpu->interrupt_request & CPU_INTERRUPT_NMI)) { + cpu->halted =3D false; + } + + if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) { + if (!cpu->vcpu_dirty) { + whpx_get_registers(cpu); + } + do_cpu_sipi(x86_cpu); + } + + if (cpu->interrupt_request & CPU_INTERRUPT_TPR) { + cpu->interrupt_request &=3D ~CPU_INTERRUPT_TPR; + if (!cpu->vcpu_dirty) { + whpx_get_registers(cpu); + } + apic_handle_tpr_access_report(x86_cpu->apic_state, env->eip, + env->tpr_access_type); + } + + return; +} + +static int whpx_vcpu_run(CPUState *cpu) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + int ret; + + whpx_vcpu_process_async_events(cpu); + if (cpu->halted) { + cpu->exception_index =3D EXCP_HLT; + atomic_set(&cpu->exit_request, false); + return 0; + } + + qemu_mutex_unlock_iothread(); + cpu_exec_start(cpu); + + do { + if (cpu->vcpu_dirty) { + whpx_set_registers(cpu); + cpu->vcpu_dirty =3D false; + } + + whpx_vcpu_pre_run(cpu); + + if (atomic_read(&cpu->exit_request)) { + whpx_vcpu_kick(cpu); + } + + for (;;) { + hr =3D WHvRunVirtualProcessor(whpx->partition, cpu->cpu_index, + &vcpu->exit_ctx, whpx->exit_ctx_si= ze); + + if (SUCCEEDED(hr) && (vcpu->exit_ctx.ExitReason =3D=3D + WHvRunVpExitReasonAlerted)) { + WHvCancelRunVirtualProcessor(whpx->partition, cpu->cpu_ind= ex, + 0); + } else { + break; + } + } + + if (FAILED(hr)) { + error_report("WHPX: Failed to exec a virtual processor," + " hr=3D%08lx", hr); + ret =3D -1; + break; + } + + whpx_vcpu_post_run(cpu); + + switch (vcpu->exit_ctx.ExitReason) { + case WHvRunVpExitReasonMemoryAccess: + ret =3D whpx_handle_mmio(cpu, &vcpu->exit_ctx.MemoryAccess); + break; + + case WHvRunVpExitReasonX64IoPortAccess: + ret =3D whpx_handle_portio(cpu, &vcpu->exit_ctx.IoPortAccess); + break; + + case WHvRunVpExitReasonX64InterruptWindow: + vcpu->window_registered =3D 0; + break; + + case WHvRunVpExitReasonX64Halt: + ret =3D whpx_handle_halt(cpu); + break; + + case WHvRunVpExitReasonCanceled: + cpu->exception_index =3D EXCP_INTERRUPT; + ret =3D 1; + break; + + case WHvRunVpExitReasonNone: + case WHvRunVpExitReasonUnrecoverableException: + case WHvRunVpExitReasonInvalidVpRegisterValue: + case WHvRunVpExitReasonUnsupportedFeature: + case WHvRunVpExitReasonX64MsrAccess: + case WHvRunVpExitReasonX64Cpuid: + case WHvRunVpExitReasonException: + case WHvRunVpExitReasonAlerted: + default: + error_report("WHPX: Unexpected VP exit code %d", + vcpu->exit_ctx.ExitReason); + whpx_get_registers(cpu); + qemu_mutex_lock_iothread(); + qemu_system_guest_panicked(cpu_get_crash_info(cpu)); + qemu_mutex_unlock_iothread(); + break; + } + + } while (!ret); + + cpu_exec_end(cpu); + qemu_mutex_lock_iothread(); + current_cpu =3D cpu; + + atomic_set(&cpu->exit_request, false); + + return ret < 0; +} + +static void do_whpx_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data a= rg) +{ + 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); + cpu->vcpu_dirty =3D false; +} + +static void do_whpx_cpu_synchronize_post_init(CPUState *cpu, + run_on_cpu_data arg) +{ + whpx_set_registers(cpu); + 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); +} + +/* + * Vcpu support. + */ + +static Error *whpx_migration_blocker; + +int whpx_init_vcpu(CPUState *cpu) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + struct whpx_vcpu *vcpu; + Error *local_error =3D NULL; + + /* Add migration blockers for all unsupported features of the + * Windows Hypervisor Platform + */ + if (whpx_migration_blocker =3D=3D NULL) { + error_setg(&whpx_migration_blocker, + "State blocked due to non-migratable CPUID feature support," + "dirty memory tracking support, and XSAVE/XRSTOR support"); + + (void)migrate_add_blocker(whpx_migration_blocker, &local_error); + if (local_error) { + error_report_err(local_error); + error_free(whpx_migration_blocker); + migrate_del_blocker(whpx_migration_blocker); + return -EINVAL; + } + } + + vcpu =3D g_malloc0(FIELD_OFFSET(struct whpx_vcpu, exit_ctx) + + whpx->exit_ctx_size); + + if (!vcpu) { + error_report("WHPX: Failed to allocte VCPU context."); + return -ENOMEM; + } + + hr =3D WHvEmulatorCreateEmulator(whpx_emu_callbacks, &vcpu->emulator); + if (FAILED(hr)) { + error_report("WHPX: Failed to setup instruction completion support= ," + " hr=3D%08lx", hr); + g_free(vcpu); + return -EINVAL; + } + + hr =3D WHvCreateVirtualProcessor(whpx->partition, cpu->cpu_index, 0); + if (FAILED(hr)) { + error_report("WHPX: Failed to create a virtual processor," + " hr=3D%08lx", hr); + WHvEmulatorDestroyEmulator(vcpu->emulator); + g_free(vcpu); + return -EINVAL; + } + + vcpu->interruptable =3D true; + + cpu->vcpu_dirty =3D true; + cpu->hax_vcpu =3D (struct hax_vcpu_state *)vcpu; + + return 0; +} + +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; + struct whpx_vcpu *vcpu =3D get_whpx_vcpu(cpu); + + WHvDeleteVirtualProcessor(whpx->partition, cpu->cpu_index); + WHvEmulatorDestroyEmulator(vcpu->emulator); + g_free(cpu->hax_vcpu); + return; +} + +void whpx_vcpu_kick(CPUState *cpu) +{ + struct whpx_state *whpx =3D &whpx_global; + 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 WHvMapGpaRange(whpx->partition, + host_va, + start_pa, + size, + (WHvMapGpaRangeFlagRead | + WHvMapGpaRangeFlagExecute | + (rom ? 0 : WHvMapGpaRangeFlagWrite))); + } else { + hr =3D 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 *)start_pa, (void *)size, host_va, hr); + } +} + +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_page_= 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 *)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 { + .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 10, +}; + +static void whpx_memory_init(void) +{ + memory_listener_register(&whpx_memory_listener, &address_space_memory); +} + +static void whpx_handle_interrupt(CPUState *cpu, int mask) +{ + cpu->interrupt_request |=3D mask; + + if (!qemu_cpu_is_self(cpu)) { + qemu_cpu_kick(cpu); + } +} + +/* + * Partition support + */ + +static int whpx_accel_init(MachineState *ms) +{ + struct whpx_state *whpx; + int ret; + HRESULT hr; + WHV_CAPABILITY whpx_cap; + WHV_PARTITION_PROPERTY prop; + + whpx =3D &whpx_global; + + memset(whpx, 0, sizeof(struct whpx_state)); + whpx->mem_quota =3D ms->ram_size; + + hr =3D WHvGetCapability(WHvCapabilityCodeHypervisorPresent, &whpx_cap, + sizeof(whpx_cap)); + if (FAILED(hr) || !whpx_cap.HypervisorPresent) { + error_report("WHPX: No accelerator found, hr=3D%08lx", hr); + ret =3D -ENOSPC; + goto error; + } + + hr =3D 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.PropertyCode =3D WHvPartitionPropertyCodeProcessorCount; + prop.ProcessorCount =3D smp_cpus; + hr =3D WHvSetPartitionProperty(whpx->partition, + &prop, + sizeof(WHV_PARTITION_PROPERTY)); + + if (FAILED(hr)) { + error_report("WHPX: Failed to set partition core count to %d," + " hr=3D%08lx", smp_cores, hr); + ret =3D -EINVAL; + goto error; + } + + hr =3D WHvSetupPartition(whpx->partition); + if (FAILED(hr)) { + error_report("WHPX: Failed to setup partition, hr=3D%08lx", hr); + ret =3D -EINVAL; + goto error; + } + + whpx->exit_ctx_size =3D WHvGetRunExitContextSize(); + assert(whpx->exit_ctx_size); + + whpx_memory_init(); + + cpu_interrupt_handler =3D whpx_handle_interrupt; + + printf("Windows Hypervisor Platform accelerator is operational\n"); + return 0; + + error: + + if (NULL !=3D whpx->partition) { + WHvDeletePartition(whpx->partition); + whpx->partition =3D NULL; + } + + + return ret; +} + +int whpx_enabled(void) +{ + return whpx_allowed; +} + +static void whpx_accel_class_init(ObjectClass *oc, void *data) +{ + AccelClass *ac =3D ACCEL_CLASS(oc); + ac->name =3D "WHPX"; + ac->init_machine =3D whpx_accel_init; + ac->allowed =3D &whpx_allowed; +} + +static const TypeInfo whpx_accel_type =3D { + .name =3D ACCEL_CLASS_NAME("whpx"), + .parent =3D TYPE_ACCEL, + .class_init =3D whpx_accel_class_init, +}; + +static void whpx_type_init(void) +{ + type_register_static(&whpx_accel_type); +} + +type_init(whpx_type_init); --=20 2.7.4 From nobody Sat Apr 27 16:29:12 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516655628769183.92733906880937; Mon, 22 Jan 2018 13:13:48 -0800 (PST) Received: from localhost ([::1]:38385 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edjPY-0008KY-3J for importer@patchew.org; Mon, 22 Jan 2018 16:13:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40813) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edjKC-0004eY-L2 for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edjK9-00028g-Eu for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:16 -0500 Received: from mail-sn1nam02on0105.outbound.protection.outlook.com ([104.47.36.105]:2346 helo=NAM02-SN1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1edjK9-00028M-7O for qemu-devel@nongnu.org; Mon, 22 Jan 2018 16:08:13 -0500 Received: from JUTERRY-DEV2.corp.microsoft.com (2001:4898:80e8:3::64) by SN4PR2101MB0878.namprd21.prod.outlook.com (2603:10b6:803:51::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.464.0; Mon, 22 Jan 2018 21:08:04 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=IL5M6+LZQ5LXxzx7P5Je4hRgUq3Nfxi8veP7IxUzGgo=; b=AxA8uh1aYB60YXm97CLHZ2wfMM9G/1rn1ZKW+kPBaKnoZU/cacu31ygCYSMzR67VtNULq+Y0rwyIyUXYgLqqkj4oO6b2/tlP2xPMkj2maaXUUWH3J1hefbt8qJI3DmbsGj2VrREqnjev4bX8rr64WvHNOQEHnzIdkfg/I6IYH7w= To: qemu-devel@nongnu.org Date: Mon, 22 Jan 2018 13:07:49 -0800 Message-Id: <1516655269-1785-5-git-send-email-juterry@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516655269-1785-1-git-send-email-juterry@microsoft.com> References: <1516655269-1785-1-git-send-email-juterry@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:3::64] X-ClientProxiedBy: DM5PR21CA0002.namprd21.prod.outlook.com (2603:10b6:3:ac::12) To SN4PR2101MB0878.namprd21.prod.outlook.com (2603:10b6:803:51::31) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6dca84ec-dc45-431e-a694-08d561dc3b03 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(48565401081)(4534125)(4602075)(4627221)(201703031133081)(201702281549075)(2017052603307)(7193020); SRVR:SN4PR2101MB0878; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 3:FrYYWncIgTKaHp3PxPihD+lX3SaoXLr5VvODEhL9SzIVqFPi0/Bt73SivSC2baKOXpejVe14SDKCzDO64ENQ1Jq7hOPCJv647+NxcArZT0/W2S3SMRX88fMfQLNQ2szF4mrzJmhYdT59J8JkEnSakUXFEe6u9h0xS9AFSmAgKp0rUOiOb3yUfp/OIneKNubmhOZnehvoI+QFUdwBfBVI7hMeHqkPDAxx6+dbFtB2+qwhY1pu+4HzrXchfh2jwPNI; 25:oHqkhvwdHYA969Sbq+ppsk6uCmd8xNAbXc7fcdETDWs7gl6/RtxmPQ8/9Uxskc0pcmQ9TxQJZmMcGheeIw3nsGV3n4yYfY5lNSb++ntdL/wvYx6MBx/3uxO9i2IEBJA/iHdY+cQO3gEkRgjn3uqUdTJtqHhLhwyDHnuTFheMrpHE0C+QUD6pCB9t/62LW4CEj5YwgJ8Vty3u8pVIWlWXx5zdAXFJNtTM2qW+tbyF9EGRI9JVQ8hRPJqsYi+AXXDoVMceJST92AzHO4Hr7/759sB7Ag33D5/c8ZDy5YIqKxsSPFI6VyuVDewv2Nyr1E+CdVfiwozO1saXCAf7r166RQ==; 31:2VVjP+6KkOE6z1vdvGXWDTLCBJlP7oss7j5g6Tpkez+p19lJRDmskHyg2cQa2BSHSMUnna/rdAFceEQ92sFfQs8WgarE9ub1m52umoJvfQRNkmQbp2Zo4UGuyN1HFf87BPJ1vysDToq0w1scZmQ6B3Gw3DeDOnTraYQI/Pa9LIQzzAnQ0RXilNsLBLAdFfCRWzsch9imJHblHspmEJlw7CVa6Wnwp3rA9e0XoI4hJOg= X-MS-TrafficTypeDiagnostic: SN4PR2101MB0878: X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 20:9dikOSjBl3al5xeNSrQeBQJshPp5XU68mM4UO1uADyPmDq/eXPjKxEJeK2Z2qWd9GFtsw6FUF9x2crAIA3KWWPmhmGgXcKi4BQ8LZ2WGtuTW6Yqi7qGsWF9GbEeUHSGGaRvhqhN6SgD0o6gd5kh81SYMFEA0RnhJhlH4U8eQu4yyRqvOb++QJGTRosGfYNzW0n3b9fa6aHtFaUQHqTKzY1GRxZU6KcTyBXJJXDe2MyiC1YTjaK9q/VSjjpr7P/PhXupyrWI/fsCsXZ7Sns0xM5cSGJafdIiFqgGrnFcAxqDAEHj4LRA74Cs0/spvRjcyorRQb1Ceyfg+RdqB69W/itR2OITXHIvT3qqwxI+P7O7yK/LH/wJh1GJIfHDd73rHgCDywI87w48pUAGjQL07JQW73HGc908XgICblqjMdbZel+NtlR1hiZZkDyu2wvyzooKpYX7S2WQDIflXj1EvZ1z1ltj/EQkloUP9SQ+dVRGCQgOFbLR1gdJ0f3M8Cx35; 4:QQ9z32D/B7fE+QDuy44dHFn95rooTeHD+mOHG/RMY8pKASykYZeiAkHCbPmffXOz8qd+KJ2PVWZloRw6gMi/NgJ7LsqwQSuG2RteIgt7CGdoFFFYJBmc5MGbEwrD9AVE/Sz/+F3V8+MDQW+ZIN5virk2Q4YNV0urwDad2Z1uGTrJQJzGDruuoGDNUkRd/5LqDkQAuKyryXbX91iRakEhpwrwKL4iypNayK5Vo9gucXb2acjSrBeowKPytSFdI7K+QQ77bEULUtrWgdlc1uMDeqEbfyrvHu3j+OqlkZtUM1TZEAmXaz1ATb04DEbsVROczNfd0EPpn833gabDnSs3yw== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(28532068793085)(89211679590171); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(61425038)(6040501)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231046)(2400081)(944501161)(6055026)(61426038)(61427038)(6041288)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(6072148)(201708071742011); SRVR:SN4PR2101MB0878; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:SN4PR2101MB0878; X-Forefront-PRVS: 0560A2214D X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(39860400002)(396003)(366004)(39380400002)(376002)(199004)(189003)(10090500001)(52396003)(76176011)(48376002)(4326008)(7696005)(51416003)(52116002)(50466002)(39060400002)(107886003)(10290500003)(47776003)(305945005)(7736002)(6666003)(2351001)(6116002)(36756003)(2361001)(2950100002)(8676002)(6916009)(81156014)(386003)(81166006)(5660300001)(25786009)(8936002)(59450400001)(105586002)(478600001)(68736007)(50226002)(2906002)(86362001)(22452003)(575784001)(106356001)(86612001)(6486002)(53936002)(97736004)(6346003)(316002)(16586007); DIR:OUT; SFP:1102; SCL:1; SRVR:SN4PR2101MB0878; H:JUTERRY-DEV2.corp.microsoft.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=juterry@microsoft.com; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR2101MB0878; 23:ulV03LlUjKSPBk669wRUa+m0lipKMvDpa8RlNj0?= =?us-ascii?Q?ull5bcgTqQtrqxQmhcoldFU9JypdaLUPWADZOyGd1XzYDKRJYceVwxqa7DV7?= =?us-ascii?Q?5Qtod8jVHntTriR6adNN96UmjMTOfWM6wn++sx4UeFHJETwnqUUGK8/TqXc6?= =?us-ascii?Q?XtCK9JKlwMVilYcBRJhgLZ9DfnmjCOdq4bu/1dNCWjePnnfK8Lv3ha+1UZL2?= =?us-ascii?Q?BMSo/wwlnwwd5hwTIAnJpynspV9TgCLXpSy+ItoeXps9PZUFCtFbba8xryHQ?= =?us-ascii?Q?1mS+CWpnfaARyKwNb4cIWvthC4O+e5qDirL5Yih1M/rdSjG+Jv4HVoKBb0rT?= =?us-ascii?Q?6KyFrrmW/0PbSdbaNQo4XIDgc0wHSsm0cIQ8x1v0keb4BYLLm1hzSgNRaMUS?= =?us-ascii?Q?GdMPrEENIMovlFIB2exwqkQqqo0Rmavo6TB5ShZqskrbmP7g+7CN7FlY3g6H?= =?us-ascii?Q?FIXAA+VdSGHXaObAsuseKcO90HQwHs21L4SZxVIIm+W4B7TZthSJQUgu9XvL?= =?us-ascii?Q?na0lB4+o1oBLPTS1UuitE7mGmU+HH9HgS5NO+W6bFUtNVObqlRvYyhqDTkFi?= =?us-ascii?Q?0exPZK7ARIr/wAUP3TlSDTlMTbnLqz1a2SIJH8R+9Wir1vGRlf+ud0KEw3y0?= =?us-ascii?Q?Nud0/gmf+VGZWLm60xjtAy1pe+TUfs9u2IjJX98uOXdP09AOddj/APWaHXhs?= =?us-ascii?Q?bNyx9v/a5Jj34Mzmn2Ot8aGMpFMeG/vc90CIn5mGtyTwIVv2veVQ1KPSdUMl?= =?us-ascii?Q?pKfe4GFkeokkffUjksvvO+3iz5TbpUMmCg5jOyL6urgKjRFnzvd1DZJe+a8B?= =?us-ascii?Q?agLphn1tpSy9+xEEK8N9V1j72gUeOP4seJUyJYaJXJWqNm2pwWuIphXqFhwI?= =?us-ascii?Q?FJtn0GTtar6vl5AbqDUFRHwHK1LihVJGsjzojU9zqoAnKxnXmlp8gifY1UiD?= =?us-ascii?Q?j8SgEag1j5JTilWdcu7v8VMJanSJuQXFGkuxNzlKnLXNy2r4lwxHefYbaj3G?= =?us-ascii?Q?BpbJqXKEuvA6n4lB/bOuxEOCW47uiiVhzZr7XiOhT4S2Gprq6zZFOQqGlMAU?= =?us-ascii?Q?GmZaneatl2t9h2GIXmY++egQA7zPCRzF0bSs2gcIk/N4o5NOvJsnOoMRjUQA?= =?us-ascii?Q?faBuFAzLZZSDOcIG4tZFH5qDEukH7gjfiIU2nPQ7z7W01WbVK7Iy5G23wZ03?= =?us-ascii?Q?4Dk/FKhVca2TNZijazK3AxDdjoiXpct/eYTw3MFIkZKOI6yzpKg3shv+O5X1?= =?us-ascii?Q?ZoXl0tcXmk73Krv/WN8v6tieosfZR7xhZEJXjfAnN?= X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0878; 6:g34VqutdNSte+AX0RRZQjV1o2KXI73qjXifVM5CuH7ecbzI/3DIzpygwLNCYagFQKUUMEKom+Jv+SH2xayvxO2qwrmuhfXXPk9pOSTYc+3/ADW7AFaZ14WBBynFARWVHE3hBXBJEZkm8flhYtI9BgT/2Ru5QOqs9mBF7hjNDiUFg+4/0VaRmIHv7coCFWfM30qgEz+W6ssIknLjtkVXStCB37Un11ph/qgSJ0RSaxztF81piL0KrlIr/yVVemc8IyAG/2tqVEMzqDfLFImHduL3/m4FWGFzaB/4cLpUK+I3DhYSU0r7ck7TPCn7iOTZthSFRi/n/ElkueUOig8AwkLN+yCa18aLzhs3IGC5ivUE=; 5:Bunez+I6m8VTWqEqdbLVEfbdywxvRY0hBsm7o9HstVqh/vXm36lvfGfDLMDaHy8iF9ZIZrrl4LVGdBj9tsmQf1LzqfnBdtZX26nRxqeEsuXOsj3V4ug+sNK0WjGDJqpvvdJIPjs/L6QoxUUncfVQItDqywIWqS6Hod4bI4lVuO8=; 24:LcMBotZMi4DK+aVNmUW6bqP5HxB5csRinp5glWjTcgKQ+Ma4nxpe95t+eR5MhDk8yl92uopifB7ElSRAXOxEa6iLlQD4uLZNyaPAEOadlIM=; 7:QkJ1/dWvMTpw7IY45RziadHNKlRu3s/G+KIVDqx6RArX8+iFxbU/agEGg5lLKc3zZS9Lpv0RcZehzUW1KSmHMRqFPYGprMBSCzG9ESRj5Us6EOgviGE8xPaHZWdPDEqL07RAsjnSl/QBZrqHfMpzm4ni2XgJorLvCCL78HR1E5/yBDAzXxaJumQ/PWK28002waFGxDku6fgIq2Zw+TpU2l55d0r8aM2z4Fl+dwAmXD7VPtz/yvTQ5pVXNrFnJniA SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jan 2018 21:08:04.8423 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6dca84ec-dc45-431e-a694-08d561dc3b03 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR2101MB0878 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.36.105 Subject: [Qemu-devel] [PATCH v2 4/4] Add the WHPX acceleration enlightenments X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: "Justin Terry \(VM\) via Qemu-devel" Reply-To: "Justin Terry \(VM\)" Cc: "Justin Terry \(VM\)" , pbonzini@redhat.com, rth@twiddle.net, ehabkost@redhat.com, crosthwaite.peter@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implements the WHPX accelerator cpu enlightenments to actually use the whpx= -all accelerator on Windows platforms. Signed-off-by: Justin Terry (VM) --- cpus.c | 66 +++++++++++++++++++++++++++++++++++++++++++= +++- include/sysemu/hw_accel.h | 13 ++++++++++ target/i386/helper.c | 2 +- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/cpus.c b/cpus.c index 2cb0af9..1495ed5 100644 --- a/cpus.c +++ b/cpus.c @@ -38,6 +38,7 @@ #include "sysemu/kvm.h" #include "sysemu/hax.h" #include "sysemu/hvf.h" +#include "sysemu/whpx.h" #include "qmp-commands.h" #include "exec/exec-all.h" =20 @@ -1539,6 +1540,46 @@ static void *qemu_hvf_cpu_thread_fn(void *arg) return NULL; } =20 +static void *qemu_whpx_cpu_thread_fn(void *arg) +{ + CPUState *cpu =3D arg; + int r; + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id =3D qemu_get_thread_id(); + current_cpu =3D cpu; + + r =3D whpx_init_vcpu(cpu); + if (r < 0) { + fprintf(stderr, "whpx_init_vcpu failed: %s\n", strerror(-r)); + exit(1); + } + + /* signal CPU creation */ + cpu->created =3D true; + qemu_cond_signal(&qemu_cpu_cond); + + do { + if (cpu_can_run(cpu)) { + r =3D whpx_vcpu_exec(cpu); + if (r =3D=3D EXCP_DEBUG) { + cpu_handle_guest_debug(cpu); + } + } + while (cpu_thread_is_idle(cpu)) { + qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); + } + qemu_wait_io_event_common(cpu); + } while (!cpu->unplug || cpu_can_run(cpu)); + + whpx_destroy_vcpu(cpu); + cpu->created =3D false; + qemu_cond_signal(&qemu_cpu_cond); + qemu_mutex_unlock_iothread(); + return NULL; +} + #ifdef _WIN32 static void CALLBACK dummy_apc_func(ULONG_PTR unused) { @@ -1630,7 +1671,9 @@ static void qemu_cpu_kick_thread(CPUState *cpu) } #else /* _WIN32 */ if (!qemu_cpu_is_self(cpu)) { - if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) { + if (whpx_enabled()) { + whpx_vcpu_kick(cpu); + } else if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) { fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n", __func__, GetLastError()); exit(1); @@ -1877,6 +1920,25 @@ static void qemu_hvf_start_vcpu(CPUState *cpu) } } =20 +static void qemu_whpx_start_vcpu(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + cpu->thread =3D g_malloc0(sizeof(QemuThread)); + cpu->halt_cond =3D g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/WHPX", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_whpx_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +#ifdef _WIN32 + cpu->hThread =3D qemu_thread_get_handle(cpu->thread); +#endif + while (!cpu->created) { + qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); + } +} + static void qemu_dummy_start_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -1915,6 +1977,8 @@ void qemu_init_vcpu(CPUState *cpu) qemu_hvf_start_vcpu(cpu); } else if (tcg_enabled()) { qemu_tcg_init_vcpu(cpu); + } else if (whpx_enabled()) { + qemu_whpx_start_vcpu(cpu); } else { qemu_dummy_start_vcpu(cpu); } diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h index 469ffda..d2ddfb5 100644 --- a/include/sysemu/hw_accel.h +++ b/include/sysemu/hw_accel.h @@ -14,6 +14,7 @@ #include "qom/cpu.h" #include "sysemu/hax.h" #include "sysemu/kvm.h" +#include "sysemu/whpx.h" =20 static inline void cpu_synchronize_state(CPUState *cpu) { @@ -23,6 +24,9 @@ static inline void cpu_synchronize_state(CPUState *cpu) if (hax_enabled()) { hax_cpu_synchronize_state(cpu); } + if (whpx_enabled()) { + whpx_cpu_synchronize_state(cpu); + } } =20 static inline void cpu_synchronize_post_reset(CPUState *cpu) @@ -33,6 +37,9 @@ static inline void cpu_synchronize_post_reset(CPUState *c= pu) if (hax_enabled()) { hax_cpu_synchronize_post_reset(cpu); } + if (whpx_enabled()) { + whpx_cpu_synchronize_post_reset(cpu); + } } =20 static inline void cpu_synchronize_post_init(CPUState *cpu) @@ -43,6 +50,9 @@ static inline void cpu_synchronize_post_init(CPUState *cp= u) if (hax_enabled()) { hax_cpu_synchronize_post_init(cpu); } + if (whpx_enabled()) { + whpx_cpu_synchronize_post_init(cpu); + } } =20 static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) @@ -53,6 +63,9 @@ static inline void cpu_synchronize_pre_loadvm(CPUState *c= pu) if (hax_enabled()) { hax_cpu_synchronize_pre_loadvm(cpu); } + if (whpx_enabled()) { + whpx_cpu_synchronize_pre_loadvm(cpu); + } } =20 #endif /* QEMU_HW_ACCEL_H */ diff --git a/target/i386/helper.c b/target/i386/helper.c index f63eb3d..9fba146 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -986,7 +986,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess = access) X86CPU *cpu =3D x86_env_get_cpu(env); CPUState *cs =3D CPU(cpu); =20 - if (kvm_enabled()) { + if (kvm_enabled() || whpx_enabled()) { env->tpr_access_type =3D access; =20 cpu_interrupt(cs, CPU_INTERRUPT_TPR); --=20 2.7.4