From nobody Thu Apr 25 16:32:10 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 151579245412470.81308421415872; Fri, 12 Jan 2018 13:27:34 -0800 (PST) Received: from localhost ([::1]:39992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ea6rG-0000uG-A1 for importer@patchew.org; Fri, 12 Jan 2018 16:27:26 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50311) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ea5qx-00034S-CA for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ea5qv-0001jW-S6 for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:03 -0500 Received: from mail-dm3nam03on0726.outbound.protection.outlook.com ([2a01:111:f400:fe49::726]:3340 helo=NAM03-DM3-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 1ea5qv-0001gV-LP for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:01 -0500 Received: from JUTERRY-DEV2.corp.microsoft.com (2001:4898:80e8:f::4b) by SN4PR2101MB0879.namprd21.prod.outlook.com (2603:10b6:803:51::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.428.4; Fri, 12 Jan 2018 20:22:58 +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=WAwHRoAoM7cg95y2B3/We043HO/z7UxmqXCnSKrAHtE=; b=UEbqo4qyhyv/asKYDOtkQkTpHHj15b8trENky0P7s4wJCd+dcl2atGg3Wn5ybjZDuiaQ4HVdV8zTz5JVrgXzomG2RSmYeSRIjM8sLDcxSaqg6Tpj2EyU/QIu2PWd27j7u0MNQr37U8mUtEd+HfArkwW4PoraUzyI+5h7UguS3VU= To: qemu-devel@nongnu.org Date: Fri, 12 Jan 2018 12:22:25 -0800 Message-Id: <1515788548-3570-2-git-send-email-juterry@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515788548-3570-1-git-send-email-juterry@microsoft.com> References: <1515788548-3570-1-git-send-email-juterry@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:f::4b] X-ClientProxiedBy: DM5PR1401CA0003.namprd14.prod.outlook.com (2603:10b6:4:4a::13) To SN4PR2101MB0879.namprd21.prod.outlook.com (2603:10b6:803:51::32) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: aec59edf-25e2-4134-61b2-08d559fa45b5 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020086)(4652020)(5600026)(4604075)(4534117)(4602075)(4627213)(201703031133081)(201702281549075)(48565401081)(2017052603307)(7193020); SRVR:SN4PR2101MB0879; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 3:WsYO1Yh/FdWbATovCr0OrGLuAWosD6qtepQVH4zbUPbBY0QJ7+GKMegWbzOo+8+GPXBh3dGHdeZY5jHyK3rTAkrm192iNSIblsJ4Mv3JWAJUwBazT4BTBDn/oNC7E7b5DOT/GN+1YEYxRvfC8Qxq+JzAPq9AKG5x5L+debLYBe3WBaRnbAYdE0ZFUp8wyXVdBPofTUValB2hUJBsKkWy3pm4+gdkf4chW61yUOspUoXI/QZA8McDQr5Kms/0ahvU; 25:N/yooaLBYaQ+F/NQ9eNmTwcHQRVHHNkCQdUwFSTsyxi0J6l9Ij1EVBCBqvVby6avlpWLGl62eEXkbHHll44QoQ5E7oDv9vM2cHrVfk9X5cQKvyRX47XTOwjgwqCHWvcT2PhA8eZVcdHYdEWn1pte9/n92D0jmgI729a3NQj1+BoGpitnW9xcs+0bQLzzNxR+3hB154MrHkn2aFszOZYu1Lb/SJ9zx/GHz6L8MrDSrIoY4PqCQYCrRItrzJ/OfTLBmaZtYQA2Ql12gqkadwuseilYT7WEzJbPbzs0fkMZM4my8JWeSorvSp4xxHz/XUZkZFws4WL8BIe3vuQdSqnjhA==; 31:ukVQOsKNoJZqtcqFEwzGwWK3OFskJqHd5OeoB04jDky0Ftp5s4ZpXeWw3qKGnG7/tEu6qWllEDlYSG9ByDQ7cwvw9Ix8Knwwu0dO5Tv33frMlrgJQk4kvn4rxjk8faW1vV3JgQmPtjPqedzMhxgMxig6Naj6VJa/lP3PMhlbfB2S0rRNb2LCrfYLYoeBZ+36SVrmtdp1hFVBBH8c0/9yV8xvazYq3tYQXEXoCVPJNkU= X-MS-TrafficTypeDiagnostic: SN4PR2101MB0879: Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=juterry@microsoft.com; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 20:FY7uVCbtShM2Ws4CzVv95dKDQUbALrA4v1dpvitG7hZ3xqyGtR+9Hf0PBS2cgHm3TRAC64epybxFbX+k9hlVMdhjfZunv5nb5QbwAWIKyOCM8mYj8/SzGCsGCqT42jkiJV8G+flvE5O/Gho8BcxsW9X+DLT3rerhX0lYHe8WNR/ztu0X63XMEIpQEaD4DNrzXb/4yOwRipU4RteNlxXJX1Fp0JAOQMbWh0vIxCjkU8dPU9U+OAbyijT6JZW05Y38Koz4cL76kbN4t2+9CFpj1ONsJM1IQZEanmJ0Brhn2hVgGyI+kHhhWLMnqb6sVT62zqJmGgLjFWlFuDXb10lN/s9bEKl38GcrJNcTCyOuEnHJY4phLJ4HE4UQY8JPOXy9qffamrGg8uJ0K98vZBcL7MM9es8uHew2QpusYy0i3kwUbtQfOKkKXSQdw7ej1Ng1edZ2/97ZVd+QA7fcmGmgmptQUr9l06trYM4qPyWHHHHRFlOwy/7Wmpe9XTuTGJo2; 4:GU8Zp9K4sqp3vJiLBqsmndS8H4DE1UL1za5y2QgQ5Vvx4gMkle735JJdPrdDqzGcphkovgu888MY5STPWId/1rgpdEusgX9nveQrCmN/Z5voyswFxoSc2PsTPXmdMqkCcyxF5s6/N6tn2+I9hi7L9t7+FyubEO/YLE04tx3zIXMK8WEFFmtUG1BtV5Rmh/taZ9ZZdmO0YdkTH4atqsQYTq3JJxmKKYxprRg5iFKH7SmgY5hulkU96CST9lY0ciQjwJHn2ZMhDvOg9Wsrze9I2cLwWXSymhGgePpFLbt8lx2lwU66KxERaFu5nOmWtK+mM0lf1jH8fFKZTNkRwrqnZaooTmmvltt494H+6p98V2M= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(28532068793085)(89211679590171); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(61425038)(6040470)(2401047)(5005006)(8121501046)(3002001)(93006095)(93001095)(10201501046)(3231023)(944501147)(6055026)(61426038)(61427038)(6041268)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123558120)(20161123560045)(6072148)(201708071742011); SRVR:SN4PR2101MB0879; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:SN4PR2101MB0879; X-Forefront-PRVS: 0550778858 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(396003)(39380400002)(39860400002)(366004)(346002)(376002)(199004)(189003)(39060400002)(106356001)(6116002)(316002)(105586002)(22452003)(2351001)(97736004)(25786009)(16586007)(86362001)(5660300001)(53936002)(6916009)(2361001)(6486002)(2950100002)(6666003)(86612001)(51416003)(7696005)(52116002)(52396003)(10290500003)(50466002)(478600001)(305945005)(10090500001)(48376002)(47776003)(386003)(68736007)(81166006)(8676002)(107886003)(81156014)(59450400001)(2906002)(4326008)(8936002)(50226002)(7736002)(36756003)(76176011); DIR:OUT; SFP:1102; SCL:1; SRVR:SN4PR2101MB0879; 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) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR2101MB0879; 23:m9OgzZNu+h12hgI+uuputUa3JKrbRq/E23J7nGy?= =?us-ascii?Q?+ZvZRo5cL+osHjRHA8OmWsie6UQwnH8GLD1hsLMi8PmIQl2AQBGba2Seh89E?= =?us-ascii?Q?unYUzTzi8RsuyjNo/yFmdJE6OU24jKWf2Wz3fDPSYYI5s7BkyaTDiSR+8vNt?= =?us-ascii?Q?9jmUlXozqxWf0jQzlwMHLI5xXMuzGe1Jr20ved8MXA+uTIeCQBoXIJRuSeyB?= =?us-ascii?Q?nUtOr3il2l4sdzElIz5Bxsttu81A1yec10HKT5QuGm/jGeHkMU0FO8FQqbmA?= =?us-ascii?Q?EjSY1Ke1KpdztFad+bfVj2TXHVTbuzreKqMZPlzojiextwoirpGiv1oYdhXW?= =?us-ascii?Q?VF2q9wkVF41ld9mtIaTLDKJxiPlKrMmWBKVdvt/H8LCt5vevnUXY096+nHZZ?= =?us-ascii?Q?wZpchrrtx89fjMCu6HNIlXrWRQXnEoMvwTjvTI20TSbLXppq6KOdIZQK/NpI?= =?us-ascii?Q?gxwrJZH1jkAi1KQWNJ7KnqV5siOC84NHKhAi0tFtctMg7vnfoLtqMdueZPe5?= =?us-ascii?Q?5sxbAJG6/Gshur/ixO3Ie8mRGIoN7abMfYaa4OA+41yX+US8kQ8EwW4AClt+?= =?us-ascii?Q?3NO9IjU+cqATd84xV1AiYQYWEl9JuyJmC0HPQMAqjx1PQLrQ1ly4s62t+JYs?= =?us-ascii?Q?9Du0XX0+zcXcdf7Oefl3LCLt85Fj5HbPCYwDHYHiMKH6IjDs6ie0C1T9BIHF?= =?us-ascii?Q?qFS5enXFY892MQZg8F+Oj+i3XNUa6VgKy4auNuYKI0yOXojHDlBRCsD30wgO?= =?us-ascii?Q?OsnwP//Lg36glgoFxlFKOUnYqCGT7FUXF7kjfuCdMOK2FCpE4LvNqf9vQAxY?= =?us-ascii?Q?hGh0r/yKy0u0AYvLDIdG/b3Ff6KmvXqhAZ22Lj36noT09w+lmvqIHxYyYnr5?= =?us-ascii?Q?SgnCWc1Y9tsKlhQJuOgChfIuwul7TAI4xEzeR8aB5/Ai85uy40MkBvDK6W5V?= =?us-ascii?Q?j4tN/V3DTWJ8Bt/uQL6F4IGyIUz/kGT+tHJ44N83OLlPcKIGOMehxTp0wlZ6?= =?us-ascii?Q?Od2u/NFLJ7FG1bZThniOfUviVnawlCTnEkhiswoh6sueSqShGT95owzu6jFU?= =?us-ascii?Q?dirI0BDC5sVrEPEjivIrpiIx973i3tpr1nY4pKuhzVOK7Wt5pPXlp+vPdQCj?= =?us-ascii?Q?PyUrtH6pCxBswIzqQy52py4Da0DNmHa+tU1noIZ9USmIMMvHLlZZQqgHZSf5?= =?us-ascii?Q?7i3HGvNjldbdZcTI5K1pXbdv6Bhfi0Z154ugxK4ahwYCuctY3vPkTsE/Phg?= =?us-ascii?Q?=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 6:3IUasdVGvwcN5d7C43NFCWTQklyydKbcNY+qc/ehY6w85q95qA7Jvv0pzjbMY+7sNTQM6xZkzL+qqnSlP/TWdlm7wMgKyTG82x1/mL6vn8VRAATiRRsGE+EICUhXlDH1wLJVvxsIbvZ+IQXHpaFGRzmQaDqzk+aHpMD2rtbCSkiHU3oNhIm6XRMV3VMRPTTLiwovR7HsM5Bf20sT4ZQyRAI/BTu523djKom9FOFgGpwKhjTwoLzMPeFwc5/X3pDMzCyAkK/C2EnQOZHWfj9EkIhPOHQbSEAWFB1kDKskPWO5B9woTHachuxA3rssjcDHzKZG6ovEQX25R60ciq4AKinDvkahQNV1WxiTlBasb/M=; 5:8egh2SBoR6Btt9jc1fbpp292eR0+CDaT67jplMhxfCWSRrKndb3Ukt2ov7h8squPI2ChBOJDqTeipQ9c/c/E+pO20yQuGql8hyXziSi1ug9Y74DBpuFEJmIwz7m12hsUosx5lDuIQTC/kojFCtIEOwlPaWC3MumPCmLILqZyD/A=; 24:yiNS/vHw9ZytWe16cuRA4A5tjjvmA001n9lWojVYjEJ7XWnrgmDfJ0Tp2Wy9SYVR43q24kxqEIwnitmkwD3RN2PLhaYoQjUDEjXbHLo3vyA=; 7:btkz8vWuLVRR9A2NCWnw+lUrFF1HyBQXoO0LJH2ril7DGrmuadluPnKZ2AyjxLN+f00EZ/AzhcVedju9H962+oWm8+uNXAShc16BaVDVKxK1VBEDsDwTwe9ZUblhAS0sseuB0jSAeRarAr/gzeL4QGbb0GCMInYOC1EkJv/22F/3WpiIwm5f1DdL1LmUsxanuoxcdjciX7QO0iWrWNgX4fXfGdrozSvb22OvIFyG6sayaKV+enA6/DRQ1VEh+WDD SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jan 2018 20:22:58.3691 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: aec59edf-25e2-4134-61b2-08d559fa45b5 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR2101MB0879 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 2a01:111:f400:fe49::726 X-Mailman-Approved-At: Fri, 12 Jan 2018 16:25:15 -0500 Subject: [Qemu-devel] [PATCH 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 89bd662..8d5a065 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 @@ -5565,6 +5607,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" @@ -5719,7 +5762,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 @@ -6641,6 +6684,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 678181c..8c8f132 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 Thu Apr 25 16:32:10 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 1515792541477190.0020043672605; Fri, 12 Jan 2018 13:29:01 -0800 (PST) Received: from localhost ([::1]:40135 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ea6sg-0002UR-Et for importer@patchew.org; Fri, 12 Jan 2018 16:28:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50314) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ea5qx-00034f-OA for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ea5qw-0001l7-Nu for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:03 -0500 Received: from mail-dm3nam03on0710.outbound.protection.outlook.com ([2a01:111:f400:fe49::710]:61152 helo=NAM03-DM3-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 1ea5qw-0001jf-Hs for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:02 -0500 Received: from JUTERRY-DEV2.corp.microsoft.com (2001:4898:80e8:f::4b) by SN4PR2101MB0879.namprd21.prod.outlook.com (2603:10b6:803:51::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.428.4; Fri, 12 Jan 2018 20:22:59 +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=9ZmtZoEwLyM77WocpU/1fynAjpQSpeGyVGIGXSiDAOc=; b=KdbFBS+b98r5skX9lKCby6AkN8l6RzV+QO9TQYLGhnD76deMzgXQPKzLpO03eruqdOViqALlqKVL1AWnfZxzQjkjIzzbHZ5KnfNr1UwZEjzNwy5rc2/rqqOZoJPJunfgtE6xiPNXmodyQGjkE41Bdg51bDl33wMlN4zLdmPWhME= To: qemu-devel@nongnu.org Date: Fri, 12 Jan 2018 12:22:26 -0800 Message-Id: <1515788548-3570-3-git-send-email-juterry@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515788548-3570-1-git-send-email-juterry@microsoft.com> References: <1515788548-3570-1-git-send-email-juterry@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:f::4b] X-ClientProxiedBy: DM5PR1401CA0003.namprd14.prod.outlook.com (2603:10b6:4:4a::13) To SN4PR2101MB0879.namprd21.prod.outlook.com (2603:10b6:803:51::32) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 946887e2-0b69-4338-bc25-08d559fa4671 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020086)(4652020)(5600026)(4604075)(4534117)(4602075)(4627213)(201703031133081)(201702281549075)(48565401081)(2017052603307)(7193020); SRVR:SN4PR2101MB0879; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 3:+rnRgEa/tqVW+RysChyXr9vR0Fq/rlvCIs/fF++gr0zrSjd/R18l1p4G+Nb8SELCeujK19udZGV6tDazUFf0sK/NIyWacqH/ClYu3LR9/bUHfE9qxxCOFjekKd5YDSZ2qLKUTY2jXhC/aftc2CRa3DTQ307hemgvcG5AuZw1W7CTD/x5Ob7xqh9QhEujttxQ/vp/IjBEoGHuQ1MB8kKoznOOHReWyeZvbEhA4GhoG0nlRIQs2TnIo93iTGFY0Pwv; 25:UWOvhNnJaLcyfoxNdHk6WhW/WEotnp9ROAY2eTISNAc5D0DTuv93mJPmOKCMK6gWfhUbRnL4DHcLlpQtENugqKY86SJkWOTLGwb5dZVZNZKJyNXcPfrLoi8d7jMFv9ambJO4+mUywnFPOZGkeMo7mvYFm6QXWak5y6UY/EwvGocU/QR47SNzP8pV6wVLYmbQU/G0L/6bdD6v7trtYjvTqXNWNUp58Hhk/qpTdUkzwpFOQ3VjvRLuYtkdjVbt6kRl9pheyVlpspQQmQ4YtrBy3ScS0CarbO5muZHDyA6aYlrVDGDMp6J+h2LYGtiNPllt9e0xsYXjAlckA1JVp0Gagg==; 31:+SirRCZgvdYIHU5GxFm614oAFX+1Reio7kuB04bO76ZvWJHoyNdzXyDYEuqJkkWNCSEfZojYLdBK47pCTxGBNDiy1X6WcUhanN9pHMhotYqsmavPI0NRkiqUZLEkdW0a4BhI6GBQGvSXLE7wQWDNzcp2LtWssBGxJ8FMweoIRQ7FXPyJN9hQNUanumyc9wArS60pLtBpC6RKA5L7JC7aRgu5TKk7QO4U7i+z6HO6ToM= X-MS-TrafficTypeDiagnostic: SN4PR2101MB0879: Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=juterry@microsoft.com; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 20:BOBEEdyiuNBvPQrmwXl6k1xQlSnWDA4HKcB7E+Yjlh+y8zgCu7tSKz+is2uoDqeP2WWqQXziwIqNkonrf2YbPP6oM8ETtuIrlbAlzK+4Z68frT1wC6lB7VTBywRN3odbOPvqUz5kuq1whnG+aPYCnLjAAAeg0nyraC01MNURBrEJl0G5YvjqFUUQ2IMHh3P27Yf/okFceA7kFOjfcz5YP2Kk4fSdeDdzkPwGr+3RlzuwJUbc6zIr1paJiKUlJWj+EzOtveZ4810UXjbUMy1HM2M73fEnycJzlYKzKUU1DMr12wovuixEej4hIEXlOGjCeZrB9VodY/S1shZUdMSPX/VKRCAeR/z1oYoFbNGAruSGcS/XOdIKPA5Ur0qvjKuSrAo2OhsyxN8TI0WCN1noGkPUFzZUnf8LhbAe4yci38v2F4D7VJXSM2Xn2zaUkwM6lGNdXjoThn0hAlqgJG56oqov2HMEG87/oDiMkX1hSx1VcqPTC4sqxp2ITwdkQoi/; 4:O5UiUhQ2jOdxutNjoXFnrFMtAzSPTGaVQAYzl6EyNzfT3zPMSpfO0+XF3YYKhw7Vgnh1OAoQDvxHx8pHMQRef+G6+xRACCL1rbkwvfXK7Do+fWFIbL/L7VnFKIE+rnGFNoCap2xBfWxJ6XJ+7axcGCyEN7SpGefrKnkEWlPjmDjuy6BJ4cUHlZlOKKsTlMbJcP2R8VjxXx4KwO8GsK69U0JaVD2cz5Odxh+vKBWK8c5zxpBLiIKC3dUonLeQhh73Z7LwwLTt21DABK3UlL3MH3YX9S8hoHbTGztMw5oKAqFwzV88N3dJpCv5kepcIAW3sFEeQl75VPheYWeonqrGs35JODdxQ6tZVvxeIssokH4= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(28532068793085)(89211679590171); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(61425038)(6040470)(2401047)(5005006)(8121501046)(3002001)(93006095)(93001095)(10201501046)(3231023)(944501147)(6055026)(61426038)(61427038)(6041268)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123558120)(20161123560045)(6072148)(201708071742011); SRVR:SN4PR2101MB0879; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:SN4PR2101MB0879; X-Forefront-PRVS: 0550778858 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(396003)(39380400002)(39860400002)(366004)(346002)(376002)(199004)(189003)(39060400002)(106356001)(6116002)(316002)(105586002)(22452003)(2351001)(97736004)(25786009)(16586007)(86362001)(5660300001)(53936002)(6916009)(2361001)(6486002)(2950100002)(6666003)(86612001)(51416003)(7696005)(52116002)(52396003)(10290500003)(50466002)(478600001)(305945005)(10090500001)(48376002)(47776003)(386003)(68736007)(81166006)(8676002)(107886003)(81156014)(2906002)(4326008)(8936002)(50226002)(7736002)(36756003)(76176011); DIR:OUT; SFP:1102; SCL:1; SRVR:SN4PR2101MB0879; 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) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR2101MB0879; 23:A5wbOEn+QsFH/8G1ajcpeyVV6RWrmwTfZw8m1LM?= =?us-ascii?Q?XTxzGMVZ1lZRwznOGD16bsPviH5Fq2d736CJUDHp6GqtbzIM0mE6si8KjvDB?= =?us-ascii?Q?RYQvUBEbl9nnijohJ9iNA+c7rhgrrYw/yJEsNGDeRNb/5TxkGUulRHFzOe1V?= =?us-ascii?Q?B3ibnVuWO9qd99onTe6Trtw9+PWcPqbLuUDDHFpGaH84Gyspg3cIIKQGPrS2?= =?us-ascii?Q?8AnAhxQq2lCNCEKHZibT5Geyb2rpqlxKuHbwf+8cGzMOc+INv582L22jtXis?= =?us-ascii?Q?Hvo98tDV6YEpwju1u+xW/EzeJn40JkC6sKU/VE8erSkwQkkKlhrbWt4oUGLo?= =?us-ascii?Q?Y3rlhs6eXH8P2ZWOUpVj9Q/sSyzCDGCgiBAMKU6YqwPVotb/9oOMX6SPANdR?= =?us-ascii?Q?r12OnsNEdvlS00J+G5Bog+/ZbgD91/H0seGGMpn8NvFwkrcEiJXjhaj61MCg?= =?us-ascii?Q?r59AAz1BtlEKKVaIZrFytP+5qPbwFgJw7Rdn4y8In8MtIIB3B++7TdOsHRCZ?= =?us-ascii?Q?+/szjKFvcgK/mczIjTKHsBGuXcASAB6K/1/MPSyvjq4sYQ9BNDM7KTM3voIp?= =?us-ascii?Q?xM7Qkujf5BtJQ5nApZ08Vu40D2/D8Rbg+ru+FOKI+qNbrEcozMO2mlrnScPZ?= =?us-ascii?Q?GBkxUeyzHUkq1gdHHF3IkSn6r9KSqdxV/kWFTX8rV5c7oC5aXdsXJlVwH9py?= =?us-ascii?Q?DXm19HCFJQQv5cFZXRpAezSMZ3mhYmxjr8n7JItVdC546PBwxTUlaafWCFxI?= =?us-ascii?Q?f8To4+xx0xZD9K2P0QkOhH+sPY78teUpSaBialVZZXg3VwFHTRDLfVQj5zjU?= =?us-ascii?Q?D6VcdGQsijFy+TxaMuCTQ9dZSexad1dgN+A3JWMiYIODAFOOIBkc/Bajh+zk?= =?us-ascii?Q?3pFqZfeuCcdBN8iOXHQC9u793RwaOSh6qAW7lZXjlJVx4vBBHxyV2juxw7nB?= =?us-ascii?Q?tbOmCmi3RC+K8Sg3OmxfYuz2QR/BjFpXYdyyNfOD5LG17twF4FGjDDHXK+7Q?= =?us-ascii?Q?91V/SJOIHsqZu7lGWSlC40c0+HA1ZJVXduQLBi75QabZQ7JRUR90BgXwT6r6?= =?us-ascii?Q?0eI7hqIonbDHU9QMjBsrH4MW24ubW8u7hVpRSuZbr6EPE11diSZGwdDMHD0O?= =?us-ascii?Q?m1YSaS3wYvyXAqX5WKF1bLoRpScZnGf4Xl96Ai4isRkcJ4rU+G5DbYjJlt/b?= =?us-ascii?Q?GxULvCpFDqPJsfn3QQIa5JgUp3CA0hRtZVlYz?= X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 6:WaAkO8lZJniTTDv00hQwfPMjWuLy3FedJUgWsbxfegmzMlNlWh163EJsMMYW7UPNxr0xawdm9GTaMJWXLOhbX/RR8kJjdKp66LbZYPgiSs/N5uXARq5BTZhi/Cgc4plAL3TK1VnHeU0hFvivEzMGBnSfjPSQAsNYZTWRmWUcfrl30Dpknz4EnmC8Sh6GDLhMh9rUX4o+HcGMuWzo8jgzLDPk4Jrl54vvCoZIjJ0rzQSUlvt1syYC/x+AeGqtCtcXObB8HKgzSm3AdtNEiVhsLrrEZEC9U+mgGHXq/I6n30RUyRJtsi4uEPf0ohUtiGxn7Vu1aUhTgbPfJl67SougCBB7Cu52gz1ckbIQniNZa0Q=; 5:xNe1POMi+zbo/WtQb6gwSMyXsAEA3tkbrWMEPsxS6EjJGTBTVYIlD94z0AWhn/DVL4EFpjen/40czkTY+nfkVXtBYTCmW4//FTFmbUxtFte4JJZCuFe988hROgSmpo5aZ+WkeFh6/AtN8ELcdNkhaqk+Ti3mK8PyuKsuMvF9o4o=; 24:nEPjGNdrM2pMFQyoOZ0j6nCMrO6yQcsZ40pHW6Ew4xNLklYoMhkl2C3zP/96LXckAxp2DpoDuyFfvIAaU71i/lPRaCZqmiU8KQ7FZbvM4t4=; 7:Y0tTPXlJIVVJw5fwWsYtJwu8Dq7irmTguZXa0LSP6ZW5eOX7tU90Q4egnn52z0LP6ZJmvHsQfnP53Q/RiH39OnUpbTnVDEiM51F+3AS5hmhfITwcy5ncQ7U2KcPOBm+D9XxcpHTjcmDn4zlWXh0U/F0GSCwuLoixnlefChZgUfCac+mmYtJCtmt5aWnuzabv2AC3pSGaKb0tCufI1DRTcLHTW4WtNpBmP/c2RIlQFnvOpvfyNyGxmeZpZH0fyedt SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jan 2018 20:22:59.6191 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 946887e2-0b69-4338-bc25-08d559fa4671 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR2101MB0879 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 2a01:111:f400:fe49::710 X-Mailman-Approved-At: Fri, 12 Jan 2018 16:25:15 -0500 Subject: [Qemu-devel] [PATCH 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..c1d2451 --- /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..49e6663 --- /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 */ \ No newline at end of file --=20 2.7.4 From nobody Thu Apr 25 16:32:10 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 15157924542652.9836673454306037; Fri, 12 Jan 2018 13:27:34 -0800 (PST) Received: from localhost ([::1]:39994 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ea6rN-0000yN-8E for importer@patchew.org; Fri, 12 Jan 2018 16:27:33 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50374) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ea5r4-000378-AU for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ea5qz-0001oD-Ip for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:10 -0500 Received: from mail-dm3nam03on070e.outbound.protection.outlook.com ([2a01:111:f400:fe49::70e]:54637 helo=NAM03-DM3-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 1ea5qz-0001nM-8r for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:05 -0500 Received: from JUTERRY-DEV2.corp.microsoft.com (2001:4898:80e8:f::4b) by SN4PR2101MB0879.namprd21.prod.outlook.com (2603:10b6:803:51::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.428.4; Fri, 12 Jan 2018 20:23:00 +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=Q291dKM+7uaCANfoWYpixKhKfbVYHoMUi+6eiB134Ok=; b=Y7dKKj3Q8SM2i+fryEgiv5uM6UyeFPW11noRMbVTFR+cu7WMgCn+huYLXUe77KmFaoChl8El6ENK7WR5E6rZOTgDOrzhHqPOX7eeCesVU4+Mrul3PQb6VCf+tfuLvNWeA7NaiNOsWjzTBxI0oW+t2GWSQTvOP69ffMHIHfj+3ww= To: qemu-devel@nongnu.org Date: Fri, 12 Jan 2018 12:22:27 -0800 Message-Id: <1515788548-3570-4-git-send-email-juterry@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515788548-3570-1-git-send-email-juterry@microsoft.com> References: <1515788548-3570-1-git-send-email-juterry@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:f::4b] X-ClientProxiedBy: DM5PR1401CA0003.namprd14.prod.outlook.com (2603:10b6:4:4a::13) To SN4PR2101MB0879.namprd21.prod.outlook.com (2603:10b6:803:51::32) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 21d9bf2e-57f0-49f5-b580-08d559fa470c X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020086)(4652020)(5600026)(4604075)(4534117)(4602075)(4627213)(201703031133081)(201702281549075)(48565401081)(2017052603307)(7193020); SRVR:SN4PR2101MB0879; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 3:qphrfDSZloskK9EftDlBF1nJLTiQfOCNcYfyCDA6wMvWkUnSWTJ4WwnRkebVutht8Iiw/SF4Hg8b8MPH0Y5dlz6QSOvzn1c8u4qUppn8QBEDMtc4g4VldauqeeIZ+fyoel/jE1jCL7g8JjIA9uJAVKnbQNPhMbqv73M0f3UkDnwP2iMzusuMml+Fq7kBRrUdH8I6tEkD3zZXRABfuLyH9bs4ueRqs97nsEhF7UTTgEkwuMRc/b6oTr1KSxX3xtjs; 25:6PxUs5ay3AZ22WoQWQcr56ZoIbRZU2gpZ2ycmkzEJbSbgEBOMtnupwDrsizEQSKBJfn8IjGAGW1J6WMwUY2SqD6PRjdx3hNSFV+fAm637UyWFN5XiIdeVO1oDqJoeXYOGu/7nneENqR28nUj0ZMOoDufVzQlrnX1HjPvzHVg2yMibrU9bsUtF08QrI56mrIpWae7RKo2rgwN+jUR2SdSRj1V0VkLIWvSjUV0DQjCIe5wK+pyu+zqRCOKUByG1gsnYNrhr4sspKd/p6joKtN7jn/f1+rYQ9XTpL2/cEBttQWm9+WRrQHg3MeH+4FmmJdQLGsgsOEpJuFNeoE1/INQqA==; 31:6x+diBWdaCrJhNCDGndP7fy149VXACGXg13EB3oWGilFYC9ioXDeeWZSf57xqVG8JRGKdtvF38hm9vW22VEU1gPMEgyj4Ff5Nnf3I5pExE2rkJI9oFPgb+SqXeB2gDBwEULZiQD9tGDrvC73e6HIrEJhCo/X2hcvqCab8P4WVVDf2G7CMoqWC9S4ok3BFNBPDoSBQc8SbglSZ/hI1Fng3AQITwyjxiuqMaf4wJfqxBc= X-MS-TrafficTypeDiagnostic: SN4PR2101MB0879: Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=juterry@microsoft.com; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 20:WBRrZF1uVAOUSarvajTaGBwoPYFJy6zKTfPdJ0zLxeyxtn4P6EG+2SaUvXucT2wzNwAyu4X/zrM/EGjjcAM3cxbUSn/2pDQ/sBRyfHlb42FD82fqIwnquTmVokqNOtgtKTC3K3df7P3ijWiEAhQXjdKNaPODPsri+G5whO8MHu8WSXNSctYflEOKfmPylPAOuCF854jnzYRzzzAfZVs26Y21j1OjRMgJFvFUMG9r0zrgYf0/tbeTsBF9jsanBT3zP11Ze0Jp1Q+ieBttBd98otV4Cx6GM/roVMDSDjr3topmgVTdBSpU9I1FClcY/PZdN94PSeIGW0fSGVK6Z2xHly7yfvWECa10gGuXlvvEnvoTFx3BjtVCXdbaYRF58su2uTTQ7x3enJ2JFcmEAY455PwyTwRdhXXLwfzsp5ee0YBvx+F5DiitYnRn8prQ4qTMm+Kmzury2zR93uy/QPGj6c+giMnrhRvF/fCsXbUy0QYRxL3sNt6vaC8MjzqWUfWE; 4:lfPLNzr66No4tst2GfBUOJryWfHR9PKhJblEPLda+8uG2ZL14fk6T/7p+T0awktYZaNohyuoSPvQg+q5IRsw/D6LV1P6Pjk4/i6QCDnxEM20XYCAzpCTijh8/fZXPOShf1FjObHxUOYgW/DG8OEewNMDcgVfuKtDZJRtH3U1VxIP7RhI9rmTmT9k3/UUe7loyTLaTkknAXHZw3GZ5J71xCrEM+XKRUZk49jk0IhiNqQ4fh7WMHR3CU0CjRzI+5ZkGDD1lqp5d13dG4pqCV4o/jHe7S1ItwciGm1K8Khmvi6d5DyQoumR27K9Qd9grkx6CYx6owrHIGpug5KBjWMupLzNcmR4hAdHwgWxhjxW3WU= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(28532068793085)(89211679590171); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(61425038)(6040470)(2401047)(5005006)(8121501046)(3002001)(93006095)(93001095)(10201501046)(3231023)(944501147)(6055026)(61426038)(61427038)(6041268)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123558120)(20161123560045)(6072148)(201708071742011); SRVR:SN4PR2101MB0879; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:SN4PR2101MB0879; X-Forefront-PRVS: 0550778858 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(396003)(39380400002)(39860400002)(366004)(346002)(376002)(199004)(189003)(39060400002)(106356001)(6116002)(316002)(105586002)(22452003)(2351001)(97736004)(25786009)(16586007)(86362001)(5660300001)(53936002)(6916009)(2361001)(53946003)(6486002)(2950100002)(6666003)(86612001)(51416003)(7696005)(52116002)(52396003)(10290500003)(50466002)(478600001)(305945005)(10090500001)(48376002)(47776003)(386003)(68736007)(81166006)(8676002)(107886003)(81156014)(59450400001)(2906002)(551934003)(4326008)(8936002)(50226002)(7736002)(36756003)(76176011)(579004)(19627235001); DIR:OUT; SFP:1102; SCL:1; SRVR:SN4PR2101MB0879; 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) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR2101MB0879; 23:gK5P6yPlPFNwvYLzanJZ3lSZfx9RoQ5WTE5fqe9?= =?us-ascii?Q?zC0/RJBgR5RgO6h4ef1hq4aIRG1FJf3wWAGvqsq4C0oWRU/RvCCvC85WxTzx?= =?us-ascii?Q?52ubrM/yjwX4pVoRWmXPpeoV5bylhBAoYmqCVEg8fd+l5rEl0eTs5NCwsSGs?= =?us-ascii?Q?2oJNRgrdcJZh948o6aeuMFgn3S8tICseFgW0EUjUT2U58hy9aWX8Ph02ICHk?= =?us-ascii?Q?kjODliH3emENvZkWQtpEKEr6WHjtZdYrWmM7kjp0aOdOap9xltY1dl7tHbPT?= =?us-ascii?Q?cDeaR6smETwGGLv/QzUJjWx3tmTUuDRA9A/YqRXoF7iI9cRKhKaLueT9z91Q?= =?us-ascii?Q?8BcStntfu7NIq+Nena2F0b14l6mWIWWQNEl6iE5QTmCWBDsnHTiiPiCxodv0?= =?us-ascii?Q?NQaGbd+yPjS82VwLv9RAx11f7WbfH5HKOGPk8CutrK6JY9gWREoltcznbsdt?= =?us-ascii?Q?5O8v25LwGHIIPdVDaWGJ6LZHZ9nP56DVRl/JMxX9yIEYWXLu1TrU+EGifFHJ?= =?us-ascii?Q?vh/4xOCnTtWmrWNz5s40g50Pxej6w1+1RHJSaFmV1+dV9XuutGDmYXQ5HSsI?= =?us-ascii?Q?ZWDZeotDhVVB+Yig6vnuM2Lw4US9OTOC4k4/o57eqPiy42tm3bHzb6QmhOcC?= =?us-ascii?Q?o5rSN6St7KWSrCHfC2LDRQ2RFkoPqscomAR4QhNn+7Vn8LFgSzqWKBqBJmGf?= =?us-ascii?Q?mXTHr0wh4teE/zen5BkKxwYydI1Mczajpg9PwDK+yufiRq85S/E3s/YyUbVY?= =?us-ascii?Q?SZEkas8gArX+dERj/8Crzv0NymBp4dIXGDQhWni/3x1bVAQqhUjNFZ1cVgD0?= =?us-ascii?Q?TkArubLHu3gRjXXMm7LelpjlVEGGPlQjsctIYxw6tfhDtfSVGGuOz5yVO4mI?= =?us-ascii?Q?BR2wM05c/fF+9YlOSehiiVuB6E26NEPl+c/4vbGMshFAs2FftwGyUpfjcxjG?= =?us-ascii?Q?VzAsOhW4Jc5L2uvk32idZgPHdPwYIBINaRlJwCP8hUi9qFLzmzZ4B/LoC/OG?= =?us-ascii?Q?9Hy4YO9vKhGXFZqOeFTWkeUJ91ldcW5AdpOE1wDaK/ldHEi1PlwbKVFnXNfk?= =?us-ascii?Q?z/upKWpb99+vaBgvZeuYj2suBvpN8FWUrsNpVuPZzhob81elgZCcaFOi6VwI?= =?us-ascii?Q?X/jn7IjqsRRKWBxOVSAdJGCUd+XNr4VbvkeuvU4tu92LToJWeZ5pFHMkKcnN?= =?us-ascii?Q?CdwIDtG8n2Z+IQvWwDBkonWkiOmXZj0HJsIvazz94xjB/PzrYAox2RL+e8Yk?= =?us-ascii?Q?KcabWnLtFmNyOfEAs3JbzadMYh1kt9+NjnZ3k+R2xl7AGcklolKAp3ZfxGOt?= =?us-ascii?Q?O9MjIP+Q3hiM8Pf68bPYZN8U=3D?= X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 6:MIp6YVAuYqAAEsgMfQCSda8HoyRvswyaapyuzbYZnpgfyZ78EWs2kGKG2Q/pz/lGet2jAaj2Hd2hSE1k9wZATl70yLg8sJoOm7idGb1fAM1s9BSeJ1xtnTR0WYwfHdAi3cuH9i5nphEYx0PDe8Y2MALqaX3M57l54s0ITiwcYUpRRrTJbPKHl6b4pF395hvqEopllAFkqZUVC1URmHBjKjHQs6YX/LV9wJa8zaerWALDxLUaXoT1dH/9opPKpJv0NvDIxwgs3g4yNqdPwHgwBrxFWsRSbK2wW5GNK0ha94JmpTjneUW4pOqzsEm1Kj69nPW8xrNwmKmKE8xfa0ZQfedtJR2peEcxqcD2oL5vwQs=; 5:VDbYB9OrAP8mQLImiFDcyBx/p/3/lJwtHKaIUFSkMx3F4om/1zEJKlyxWv5jOQxNTAtJCt86J1hLCW7ZafCNXl4kOUZZAatkLn7Q1KXmJEBh9LGhBR6hWjkYjxuk857SxafAQx9kkhFQQZVBs71rmSaAyUkHaGBpVzqOLHKW8tc=; 24:YsN9jNftzsIFbNk9VKaxOB/5Q5pADok+t9+oGIQG5BZLEMT2crYo/D0Tn0LnK8/YfOB0xbs+xHpShLtDm6kSU9xQYZ8MN1//oVuBo1nXeVE=; 7:CUAcGjslfPBAbHXQNdeKTN8r+EEFpyjykMdd3jFMIdtxpI0giXl/EV40ZsIiCSHeMo9/yL1nEJeguNSprwva67C30ytqB125a85FT8W6PfNs+DZK8SELmNcoh3XbwbAauDsFEi3FhDAgeKwzgaaYMu4YP4aZcDmA8KLbWHVKSMPbJYQC+jTt90uIFTvv78QOo0L/r+j1JZB0pawn/LTvQ6LQZICHIo7koHcr4m8nV+iEJ2s+7ElJUyX4R3lR/5CR SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jan 2018 20:23:00.6348 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 21d9bf2e-57f0-49f5-b580-08d559fa470c X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR2101MB0879 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 2a01:111:f400:fe49::70e X-Mailman-Approved-At: Fri, 12 Jan 2018 16:25:15 -0500 Subject: [Qemu-devel] [PATCH 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 | 1395 +++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 1396 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..9829303 --- /dev/null +++ b/target/i386/whpx-all.c @@ -0,0 +1,1395 @@ +/* + * 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 +#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.SegmentType =3D (flags >> DESC_TYPE_SHIFT) & 15; + hs.NonSystemSegment =3D (flags & DESC_S_MASK) !=3D 0; + hs.DescriptorPrivilegeLevel =3D (flags & DESC_DPL_MASK) !=3D 0; + hs.Present =3D (flags & DESC_P_MASK) !=3D 0; + hs.Reserved =3D 0; + hs.Available =3D (flags & DESC_AVL_MASK) !=3D 0; + hs.Long =3D (flags >> DESC_L_SHIFT) & 1; + hs.Default =3D (flags >> DESC_B_SHIFT) & 1; + hs.Granularity =3D (flags & DESC_G_MASK) !=3D 0; + + 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 hs->SegmentType << DESC_TYPE_SHIFT; + if (hs->NonSystemSegment) { + qs.flags |=3D DESC_S_MASK; + } + if (hs->DescriptorPrivilegeLevel) { + qs.flags |=3D DESC_DPL_MASK; + } + if (hs->Present) { + qs.flags |=3D DESC_P_MASK; + } + if (hs->Available) { + qs.flags |=3D DESC_AVL_MASK; + } + if (hs->Long) { + qs.flags |=3D DESC_L_MASK; + } + if (hs->Default) { + qs.flags |=3D DESC_B_MASK; + } + if (hs->Granularity) { + qs.flags |=3D DESC_G_MASK; + } + + 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].Segment.Base =3D env->idt.base; + vcxt.values[idx].Segment.Limit =3D env->idt.limit; + vcxt.values[idx].Segment.Selector =3D 0; + vcxt.values[idx].Segment.Attributes =3D 0; + idx +=3D 1; + + assert(idx =3D=3D WHvX64RegisterGdtr); + vcxt.values[idx].Segment.Base =3D env->gdt.base; + vcxt.values[idx].Segment.Limit =3D env->gdt.limit; + vcxt.values[idx].Segment.Selector =3D 0; + vcxt.values[idx].Segment.Attributes =3D 0; + 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].Segment.Base; + env->idt.limit =3D vcxt.values[idx].Segment.Limit; + idx +=3D 1; + assert(idx =3D=3D WHvX64RegisterGdtr); + env->gdt.base =3D vcxt.values[idx].Segment.Base; + env->gdt.limit =3D vcxt.values[idx].Segment.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.Hi= gh64; + } + + /* 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_INF= O* IoAccess) +{ + MemTxAttrs attrs =3D { 0 }; + address_space_rw(&address_space_io, IoAccess->Port, attrs, + (uint8_t*)&IoAccess->Data, IoAccess->AccessSize, IoAc= cess->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->D= irection); + return S_OK; +} + +static HRESULT CALLBACK whpx_emu_getreg_callback(void* ctx, + const WHV_REGISTER_NAME* R= egisterNames, + UINT32 RegisterCount, + WHV_REGISTER_VALUE* Regist= erValues) +{ + 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* R= egisterNames, + 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(); + } + + return hr; +} + +static HRESULT CALLBACK whpx_emu_translate_callback(void* ctx, + WHV_GUEST_VIRTUAL_ADDRE= SS Gva, + WHV_TRANSLATE_GVA_FLAGS= TranslateFlags, + WHV_TRANSLATE_GVA_RESUL= T_CODE* TranslationResult, + WHV_GUEST_PHYSICAL_ADDR= ESS* 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 void whpx_populate_instruction_stream(uint32_t cpu_index, + WHV_VP_EXIT_CONTEXT* vp_ctx, + uint8_t* bytes, uint8_t* count, + size_t buffer_size) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + ram_addr_t ip; + size_t copy_size; + hwaddr hw_ip; + WHV_TRANSLATE_GVA_RESULT res; + + ip =3D vp_ctx->Rip + *count; + if (!vp_ctx->ExecutionState.EferLma || !vp_ctx->Cs.Long) { + ip +=3D vp_ctx->Cs.Base; + } + + buffer_size -=3D *count; + bytes +=3D *count; + + for (;;) { + copy_size =3D min(buffer_size, (TARGET_PAGE_SIZE - + (ip & TARGET_PAGE_MASK))); + if (!copy_size) { + return; + } + + hr =3D WHvTranslateGva(whpx->partition, cpu_index, ip, + WHvTranslateGvaFlagValidateExecute, &res, + &hw_ip); + if (FAILED(hr)) { + error_report("WHPX: Failed to translate GVA, hr=3D%08lx", hr); + __debugbreak(); + return; + } else if (WHvTranslateGvaResultSuccess !=3D res.ResultCode) { + error_report("WHPX: Failed to translate GVA"); + __debugbreak(); + return; + } + + cpu_physical_memory_rw(hw_ip, bytes, copy_size, 0); + + *count +=3D copy_size; + bytes +=3D copy_size; + buffer_size -=3D copy_size; + ip +=3D copy_size; + } +} + +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; + + whpx_populate_instruction_stream(cpu->cpu_index, &ctx->VpContext, + ctx->InstructionBytes, + &ctx->InstructionByteCount, + sizeof(ctx->InstructionBytes)); + + 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_CONTEX= T* ctx) +{ + HRESULT hr; + struct whpx_vcpu* vcpu =3D get_whpx_vcpu(cpu); + WHV_EMULATOR_STATUS emu_status; + + whpx_populate_instruction_stream(cpu->cpu_index, &ctx->VpContext, + ctx->InstructionBytes, + &ctx->InstructionByteCount, + sizeof(ctx->InstructionBytes)); + + 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) { + 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 reg_values[reg_count].DeliverabilityN= otifications.InterruptNotification) { + vcpu->window_registered =3D reg_values[reg_count].DeliverabilityNo= tifications.InterruptNotification; + 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 o 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: + 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_ct= x.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_da= ta arg) +{ + whpx_set_registers(cpu); + cpu->vcpu_dirty =3D false; +} + +static void do_whpx_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_d= ata 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. + */ + +int whpx_init_vcpu(CPUState *cpu) +{ + HRESULT hr; + struct whpx_state *whpx =3D &whpx_global; + struct whpx_vcpu* vcpu; + + 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(cpu->hax_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%08= lx", hr); + WHvEmulatorDestroyEmulator(vcpu->emulator); + g_free(cpu->hax_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* ho= st_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 Thu Apr 25 16:32:10 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 1515792624275161.35957092338515; Fri, 12 Jan 2018 13:30:24 -0800 (PST) Received: from localhost ([::1]:40221 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ea6u7-0003Lr-AN for importer@patchew.org; Fri, 12 Jan 2018 16:30:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50339) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ea5r1-00035j-0b for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ea5qz-0001ot-RK for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:07 -0500 Received: from mail-dm3nam03on070e.outbound.protection.outlook.com ([2a01:111:f400:fe49::70e]:54637 helo=NAM03-DM3-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 1ea5qz-0001nM-MR for qemu-devel@nongnu.org; Fri, 12 Jan 2018 15:23:05 -0500 Received: from JUTERRY-DEV2.corp.microsoft.com (2001:4898:80e8:f::4b) by SN4PR2101MB0879.namprd21.prod.outlook.com (2603:10b6:803:51::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.428.4; Fri, 12 Jan 2018 20:23:01 +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=MRjqHAQKOZVTLXpYbuGwQTK1wo7hHhF99EoyrhexR1Q=; b=hKtGnzwxfg0EfessIE1uaAtA1p9fFWyZxRmMqgOupunEnNkORkYDguChPEGxFDXUdnbN9gzZ5651w30P1s3m2f7BckgfXJPJZShg7DikA5ECpIdMGvAIBk4PH6PhLplrPS4bKFvEoHmQGaHdf+hmhW04l2lP5hNF9u5YtcvPnwg= To: qemu-devel@nongnu.org Date: Fri, 12 Jan 2018 12:22:28 -0800 Message-Id: <1515788548-3570-5-git-send-email-juterry@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515788548-3570-1-git-send-email-juterry@microsoft.com> References: <1515788548-3570-1-git-send-email-juterry@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:f::4b] X-ClientProxiedBy: DM5PR1401CA0003.namprd14.prod.outlook.com (2603:10b6:4:4a::13) To SN4PR2101MB0879.namprd21.prod.outlook.com (2603:10b6:803:51::32) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 55d03940-33c9-4a0b-25b3-08d559fa479e X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020086)(4652020)(5600026)(4604075)(4534117)(4602075)(4627213)(201703031133081)(201702281549075)(48565401081)(2017052603307)(7193020); SRVR:SN4PR2101MB0879; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 3:14cLfqtYIFyXM2Eh3BPVT4Fdw45Mgx5HEhD2eVY73POTQ3bhmbKE1JGEqajXhsfcwgdQBoh4jgr1CjjEPINz0uF5Muhpl8mpRvYfJm+KyPEDd+mlvLsl5XZsJ+TKWgUpMJhNdj5j6DpS62xK1tVirwliJNryeHszurN5sFr52knNTymj5bADS5SPDBgKedNxXW6gV5Dg3YADZYIh0qQ33Ma2/en9BK+ymGIFR+w9Ud+YfPsjj/OJC2Sn4ZNyYiK5; 25:hsWI9PsZGeorRqgh8pgGVq6XSa8Pcbe7u2fXojheXIKXe5HjJ+Wxi2xjDgCuYdgfV75xL3BA3ohmP9kq/+S+wWadJVM4sSPbKOP2YFM7IcsmUcENmm/AFeKyepzfvVXNX6fpD1Cwnvdw0anSrRkVgmlGJalXb1j4rpu0YjmNMC64oIqSNXsJJryOY7pR1bQaGRgrWzvUoDyUvW0wskgtPRWO+313lMUCLgozzX2pqXpsTTNPo3iSn2Z2dP4U1Kx0FXTBhenB8Of7VWtbaHcMBSzcDaypHOWhSmgFVzfpSJrf8M3K7TIEzSFDzA7A/sazc0prEONOvTmBUk8PF1CtBQ==; 31:AOh3Y9/I7RLffALHYngRNL1YQYejQ7/xfHiPKqLKgSs0MjolaD8W94HIW21BZEYwxYHqh7sLz1rPjED119Z9z7lw7G3O4Se0GbuDVNngucS2BbvTjHsztKH5Th/xJpfWYB6cTTsqqVLq2bJ8sDBqtEg4+rrZrxzuj7JPn1sFXWosCTDm2QRldqZ7xU+3kTuzbiX5yAmpy1txOzD/dGU/CKJitxQ3PGuiJl3rHGZb4qo= X-MS-TrafficTypeDiagnostic: SN4PR2101MB0879: Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=juterry@microsoft.com; X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 20:9pbFc1yTrKxzQBzaASlgeSKSUK7WpwSRQnfeo8g1tuoJVyEwKtwoNHOGz5SrysVApdXhNGsP3ldx6QomC5/xCu3zg/WjW7p0Zl8J5cPMWWztA4X7DzHfhCQBb1e4PWOp4ZgCAsbBSzEM+0RwmBjmupVlJFyXun6H/NqSF7fbhyXh6BS3pyKKpq3e9u/5Eo0shTVtUDS2sxOvZcBt5QpyZ8aBdZibgp09nj3B3Ilq8SypaqeM3VEsqftl2W5B3qCsMpfs7+DZFp88uE1+JvJU6GxlMsg8roK5R5p8gUQv1b4A1M7JKyqckg/fsx5yBQQBZAT1LrpsIwInqx/nzRadsCqMWp+IdhDz1oPIiFPSGccPatYgHhq0GQiRdRb3MyaC9feVuK+41137dQPAowhe6shgqmH0fs5gCI4T9v4eSprN4tcfCryyJEXp68f3mkbX4NyZqXUUqCvnQKDBZ+ZRsvPESzE7kjWHxdkUux/jQq4N8aBjwyhHQREFRQsj4Z1a; 4:0gK9QaMAz3EltjUp2kXSBuzLP3RiGqNbSlsxX3vVcBeqaJ7KFavON/cZFuh1zlYmwyIAV7ZEQsxPosv2lbfH2E22rB3XBtYashLjtpXx2nqHQdIvFNVTOBkDY9HwM/zjl1x4E84adbvwvfM5YIVJGni8BUjUliSp49UU5Cos1S6T2Aq1S8z5uBc3roCkmPu5byrQL3yPlfUAO+ejwPxBEh3pYHmA4pbyIlEt2L7iJswhJsH/OqHgRew5IIXYUUkFXHWo0kTaYy/yFpivxOXIn6/nvL18tJUo9cCALbZtsMpvLT/+sElMmjbiug25UeOcrBs/uByIvyG8kXrvhVjZHQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(28532068793085)(89211679590171); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(61425038)(6040470)(2401047)(5005006)(8121501046)(3002001)(93006095)(93001095)(10201501046)(3231023)(944501147)(6055026)(61426038)(61427038)(6041268)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123558120)(20161123560045)(6072148)(201708071742011); SRVR:SN4PR2101MB0879; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:SN4PR2101MB0879; X-Forefront-PRVS: 0550778858 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(396003)(39380400002)(39860400002)(366004)(346002)(376002)(199004)(189003)(39060400002)(106356001)(6116002)(316002)(105586002)(22452003)(2351001)(97736004)(25786009)(16586007)(86362001)(5660300001)(53936002)(6916009)(2361001)(6486002)(2950100002)(6666003)(86612001)(51416003)(7696005)(52116002)(52396003)(10290500003)(50466002)(478600001)(305945005)(10090500001)(48376002)(47776003)(386003)(68736007)(81166006)(8676002)(107886003)(81156014)(59450400001)(2906002)(4326008)(8936002)(50226002)(7736002)(36756003)(76176011); DIR:OUT; SFP:1102; SCL:1; SRVR:SN4PR2101MB0879; 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) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR2101MB0879; 23:LcrCWXEnLGkF0oiPiTK20amn7U37gypdHVIyR9A?= =?us-ascii?Q?yhNdvYSZguz0Zh5EMW6JtdXVLqEyQ7xpG4LU8B5PXQVUL+gyurXsh7mE8e1W?= =?us-ascii?Q?GwT3fIcV9UqsDViGvv/fqF10EoOvX0BgKcBEbU+uhp8VAQFCLrnNsDT29q3f?= =?us-ascii?Q?q+FWMKOZk8koFcRqgSf6vrl8qs4tc+m9S9qpDckF7g/lUa5rygVUZ9w3S5eG?= =?us-ascii?Q?sMNEfJkZcCxW5hysp94hUjNcK9BPBYeMksz9HeqU9Ck6zCzIarespIKT/wKj?= =?us-ascii?Q?VDvPIltn5v9+7kzv1DN4gMYcklLXEzr2uHur19gBIQw3Fa4v0WEccCRXnaoZ?= =?us-ascii?Q?OTesGJ2iUAmcv4tu6KBA/7OG9dRTyekQLkZ7CLqRxFceol4k1TOqeiiD4tFS?= =?us-ascii?Q?nk0U//uMZyLBBM+oXVVbeY+WIrd9hTRVir/3HcF7sOvG/kXDPkwlowUOED0/?= =?us-ascii?Q?zAC1WVS8NPUVkQSPPh0hV5yveGnNqPhcIftBH2KcVr1VxE3URgItUHjLWvig?= =?us-ascii?Q?OIGk79JWxULP0VWPdc25rSf8kd5fEbNlnWOdm2DLKQNHcsOkSX3AwebE0TNM?= =?us-ascii?Q?clHEKq1DV9ticHVZ5ek0E+2Af90SzpvnrF1YvFbi20n7aMdA1E2Qemuqok2B?= =?us-ascii?Q?BHv8QiNx9U2XU5NTS9Ii2Z5gZVTXiNg3rNLxXYtFDedShkvX7OdhF5YCkrNd?= =?us-ascii?Q?uFdvtdbK70b4C/2LhpDPNLEZkTRCeX2zcYfGB4QPPnn6hmHwc+0+meJHvuY5?= =?us-ascii?Q?hZ/MuGNMgjT+LpR7PkrYF4OvBNUVQAHM6T1yDW865ebDdw27CH1FrILsI3kw?= =?us-ascii?Q?ZbarLlcY2gyKgNte2AOo+QDMDhmC0rEfw5YZcQ4T15QDj8MsPho+XGYGN6VL?= =?us-ascii?Q?0qAvKWvNxykW1Ozd2KmtsTPXJQmxIOP+19mc7kGDkbsROkSvr5CJiCeK9z0c?= =?us-ascii?Q?F2F1IVA7nJtjpros5Bl6bqyGc2oyAOUvdIUGd2WeXI0KcJDH91hi+srSFQ3o?= =?us-ascii?Q?r6cMm5XLTAnpwS82DjHX9caci5oDCPfz6R+e8kPAG66pd+cTdTogHQ53p3Hz?= =?us-ascii?Q?TjSb7VdnQfp/D2auUKwPQS5YBvELPJclcu7dXHKGLpIVw2iFMSePeK8WXI8t?= =?us-ascii?Q?QYIje4X/x6M0ySslV3tmrzNXem/9cgoOyqf054AfdfwzGPc3uBd1a81AKaBQ?= =?us-ascii?Q?O5iH2zyh4PEnsJSGlKtDaA3Ao51VI1kfmVhk7DHf5k8JSTceCdOQz1ZFs3w?= =?us-ascii?Q?=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; SN4PR2101MB0879; 6:vzGPm8Fh5deJFkUH/a22/v2AM6FjOGFFg8rNK81W2TLLPcWdtHm6R1Niv9ZKuQS9OX7M8a/A4IFEhAj313x00BxDmzG23bjTShKQMmt3QzLlVrSuewfe81nVXeDcZckKSITQmmM26y8P1iwVHYwgX3hFAgH07iltrtmsEjroBSI5JtoPLGPeFj9A4+30TNYyRdgniwDHgLw4RJre81cmafAOmGW7sj+TkE8Jf601i7V+K/TMJETwWLknGmXzhLfHXWNSTEFZaPp54+de6LlEnh3GmTP4zzj6AXzcjexAn8JDMkA9egNm22cEhAWBTZYQX9dGOiERm000azt2k0AHmVFQ4JmSC7Np4QIyGodaBZQ=; 5:sbHrvFN0h7Iq6uM28szOq7qpsVTIVfo5Ajq9XRLvvTJ7zNl/f2mu6RgovuRP9j5x0DV4ofvBSumkN4wJgl7eOL+Ghne86ZvIziHkFnOmo33ss/6X96S+ez+H/Qx/oaQL8iuq+RkRTC3IbN2FMUidzWdG0wK90XusLtklS8EEnC4=; 24:iAhqKf5z+NQ6ml9onaQWSDyers5ERrgt5pukOwhhGdJrJxqBd1u4SobiqKpydO1oTDCdTlTJcZ5GgPyivGF7y3sCrpTUi3aZwSzH+SJpxwA=; 7:4t82vZHle+5kxgdUGo/lJ6Ox/N382jbIBFkXQCD1gKCqYnFDvB8CpLZ6oGup1lJdNYLzqxF/5louuiVTpVm737OLkFFpMpL7mkuETZYvtMmf6v/s1pGIRd6EgMTijTkVbnDiNeQvQJkKjzUaHilCJDr21kCaxoa3rLbIJ62dOWlx6Xc2lOrfXXmM7Dihm9ArKk27roWXNEWT9FyWGjxhOlCOBh/kkPzWiP/t0DEIjedFfOUs1QCEsPN33DY1zv9Z SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jan 2018 20:23:01.5879 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 55d03940-33c9-4a0b-25b3-08d559fa479e X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR2101MB0879 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 2a01:111:f400:fe49::70e X-Mailman-Approved-At: Fri, 12 Jan 2018 16:25:15 -0500 Subject: [Qemu-devel] [PATCH 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 e8139de..48df958 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 @@ -1507,6 +1508,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) { @@ -1598,7 +1639,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); @@ -1845,6 +1888,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]; @@ -1883,6 +1945,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