From nobody Fri May 3 09:01:14 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1578407200; cv=none; d=zohomail.com; s=zohoarc; b=TOSQgmXdHyzG2lLTHZ1/Zq5dy2Pj5N9Frs67AZy+jrD0nE3rsIyy/GFoi5qt5mY4j1cqIFj8lLbsoJpXanp0H8npD8u/LMTw9vr1B9q6sbogC/c9coL27TuNNFRYBP8pQXO9OSAySYkK6gyni4KSViXJwGMhHqH5yKprdqRTCpA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1578407200; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=u38y6bjAz3ea8krlLOqTdniZ5q8A8IUw7eYicfUeud4=; b=MPvN776UielaIFJEwdRftQIpgOqZ66HId/pTXg2e8HidLrdZ2ZAHqzf9VmQoOh5Yus5nrHf46X6tvhQdg6hwZAfmHOF0rMLGoBbIYB87y3QvcdAaNME1SaWS6RlF2lrC/AGzCRZmd6YL71mcY3bhk0xQ+Rg+dl/ht9UUll+QjZ4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1578407200756739.3307463288562; Tue, 7 Jan 2020 06:26:40 -0800 (PST) Received: from localhost ([::1]:49702 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iopod-0003QQ-6c for importer@patchew.org; Tue, 07 Jan 2020 09:26:39 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35844) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iooNm-0003SU-OL for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iooNl-0000ri-Cx for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:50 -0500 Received: from mout.gmx.net ([212.227.15.18]:43037) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iooNk-0000q3-V6 for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:49 -0500 Received: from localhost.localdomain ([89.71.135.231]) by mail.gmx.com (mrgmx005 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MGQjH-1iuWLu2UO5-00GrT2; Tue, 07 Jan 2020 13:54:43 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1578401683; bh=eNuBNnxJHzrGSGh2b0nw38wxbBQv+W8/M0AHAXoAGfI=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=ig+J8yro9ouUOZWQ7+z60n7kxPT2qeydkt/eUskNTBGwZCS0RasDk8VsHfcGf/vuV 8jMU+c8Kdu3MoHsx8ywBw+J0MFkBTILSHc7Vk/Yo7bZFPRsK89odwZEP2v3PpYn1lH zKO9qhluRGbmXLVHZTN1QIN4jMaFw96aEz9hXNqw= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c From: Kamil Rytarowski To: qemu-devel@nongnu.org Subject: [PATCH 1/4] Add the NVMM vcpu API Date: Tue, 7 Jan 2020 13:53:58 +0100 Message-Id: <20200107125401.18126-2-n54@gmx.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107125401.18126-1-n54@gmx.com> References: <20200107125401.18126-1-n54@gmx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:Q78W7+Nh/tS5mATSSNafgTjei8zku2qFw1wmn9izQX2pCirF4bd 2f6RoAZBOPFeBXhvETFpjy0BAuNhtZrGn6mFeEFXeQgC5tIsMZKOrt2y9lDNAn/f0+DkgSn 5Dkq2qVPGb62LbDSegWa5+ngC05H2txWzc0mLRQVeGacM6ccYD/DvDH27PTX9O1id7fCUh8 HOeKtqW+XRBgNkZEAIeZQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:KSEg4hHAqDA=:naNWZVKx8X4B/Qq9wWDEan VjoO47gFLwyotVOqZtUw9gjANpXHUyD6QM9vkS8gGoa/pPG9WW3RXKfAX1ErOk9nQKjLJxxoJ GsPIW79FrvRJ6USP7Sl8SAPodtDcF/CeapWIH56LnutwTe9EFhtABdWViobxkErsYIdcBEDj5 YJ1YGN2ZaTB71lRSgheXMuxDqdZgZDnpxAQONLj+qqbJmbkuq+B2arsFs8DUrb7QLuodi4zjZ LuaoovgrM9/Z84+hGi8cB6CT8w7XgG2IBBWfNNZ1X4ADUuoULGKKvDehu14GxSfJbNEp5m1Sz PJW7K9nY86YuBmlpASdKaR8WbfV15xlB6ySWAjxtF3/pVnz8cfXxFM9FC6OllRfUpstXydmHR Eyg8beMsy726gRxRGjxbZyAD+X3BzvDVcbgz/AZbdMhh85U1Z15gP59ouOo+GvtvRqSWyuZny 3XpuBm8GpcL2vKm+poKrbe6CJ/T9f6cfISgrwzj65dmbuMi41s1GqkC1dt71kbXcfoZhaMTML 6sYPCu9zmtS75ZW00wwWobBx6C5l0aSdcP88FtetpzB/zY1qtNgc1pAX9EfwqhvnhF7J/DNgl Y7euLzfujYVIesfYjOArKupRmb+PiX2oDZ26Eh4aPp76IQr9RQLT/H2UbtxBqiXvrSWdtS8Id VGwmhc7fn93MQMQLleOL2Lc7orQ9CbM6VH/HVWnq5q3bJBlqp7PrN3Qgl8F+X/7T4dyY3wshH c6Rm0O3Id55vTgavXPeyliwQIZ8ZT/VZbJl07jKXqich7UibxtaIsjijZ0bUIN8IID6IPLsmC TNhz6nztS+uOKXroc3loy4f1EaOxmOBtnyyYIAWPbNOEQ4Vkp/oWYVkY2ZNlYJs0LqS4m+Vil JbQ/3kncyqi/Mb5UNM/V7PVKhlkEMDNmyOISrmC6KoXtpAs5gaDTrdnhH3yi3KPBB8uZO5jhP zJuYIAejlU2ZNtabt5XIK7r2uMO+s/21GBE9cCZxcA2lU9Z5y+ezDGQQRntK1nbUG0Ow9yrZv p+oMIdocBrxLcJcOLbEz6zcOPxtVog1Fxs3BoxrVbWWVfr2uWOUsvDva9MUV10UVP4FHiVGos WcZbBL988zK+CG/kOWSiJ01dP6BgioytSbuC6ZlyqvAPK48OpdPJwgfPgwyQ6tlvhalapQxJt vnfU9KNreawJiXQ0kABwByC9jSiEnHh4v+YPJhaiPLOOWwf9asC3ft3jyO/byl8k/E3h4w5Vs UQCiPhxyIb9j7AHzeoCJ2XWR3RBi7aU85tHwzhw== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.15.18 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbonzini@redhat.com, Kamil Rytarowski , Maxime Villard , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Maxime Villard Adds support for the NetBSD Virtual Machine Monitor (NVMM) stubs and introduces the nvmm.h sysemu API for managing the vcpu scheduling and management. Signed-off-by: Maxime Villard Signed-off-by: Kamil Rytarowski Reviewed-by: Sergio Lopez --- accel/stubs/Makefile.objs | 1 + accel/stubs/nvmm-stub.c | 43 +++++++++++++++++++++++++++++++++++++++ include/sysemu/nvmm.h | 35 +++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 accel/stubs/nvmm-stub.c create mode 100644 include/sysemu/nvmm.h diff --git a/accel/stubs/Makefile.objs b/accel/stubs/Makefile.objs index 3894caf95d..09f2d3e1dd 100644 --- a/accel/stubs/Makefile.objs +++ b/accel/stubs/Makefile.objs @@ -1,5 +1,6 @@ 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_NVMM)) +=3D nvmm-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/nvmm-stub.c b/accel/stubs/nvmm-stub.c new file mode 100644 index 0000000000..c2208b84a3 --- /dev/null +++ b/accel/stubs/nvmm-stub.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018-2019 Maxime Villard, All rights reserved. + * + * NetBSD Virtual Machine Monitor (NVMM) accelerator stub. + * + * 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/nvmm.h" + +int nvmm_init_vcpu(CPUState *cpu) +{ + return -1; +} + +int nvmm_vcpu_exec(CPUState *cpu) +{ + return -1; +} + +void nvmm_destroy_vcpu(CPUState *cpu) +{ +} + +void nvmm_cpu_synchronize_state(CPUState *cpu) +{ +} + +void nvmm_cpu_synchronize_post_reset(CPUState *cpu) +{ +} + +void nvmm_cpu_synchronize_post_init(CPUState *cpu) +{ +} + +void nvmm_cpu_synchronize_pre_loadvm(CPUState *cpu) +{ +} diff --git a/include/sysemu/nvmm.h b/include/sysemu/nvmm.h new file mode 100644 index 0000000000..10496f3980 --- /dev/null +++ b/include/sysemu/nvmm.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-2019 Maxime Villard, All rights reserved. + * + * NetBSD Virtual Machine Monitor (NVMM) accelerator support. + * + * 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_NVMM_H +#define QEMU_NVMM_H + +#include "config-host.h" +#include "qemu-common.h" + +int nvmm_init_vcpu(CPUState *); +int nvmm_vcpu_exec(CPUState *); +void nvmm_destroy_vcpu(CPUState *); + +void nvmm_cpu_synchronize_state(CPUState *); +void nvmm_cpu_synchronize_post_reset(CPUState *); +void nvmm_cpu_synchronize_post_init(CPUState *); +void nvmm_cpu_synchronize_pre_loadvm(CPUState *); + +#ifdef CONFIG_NVMM + +int nvmm_enabled(void); + +#else /* CONFIG_NVMM */ + +#define nvmm_enabled() (0) + +#endif /* CONFIG_NVMM */ + +#endif /* CONFIG_NVMM */ -- 2.24.0 From nobody Fri May 3 09:01:14 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1578407149; cv=none; d=zohomail.com; s=zohoarc; b=X/BYhtVGGrQMEk3ttwNYyrl9pzxNq0tAEU5n1LNwbugDdvT136qt5MYCXFvaQ1QooCWtYAiyyzam7BpD9c2dAZecDjjISAiykzdfuUWMHvLJCHVnPb4R+Gtcu8d/eSl4FCWWhZcp+SRterVNVUztpDZjqII1rfaVvP1C8WepOck= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1578407149; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=+3iF06G64ABK91+3MUYOdFHmfi3DaT8rXzaGsXtYxCw=; b=n9Hs6WZ2r2nJrd54ur7XP3V4eYE1p4OGkrQlU6CNafCnTMZSbQSei3LAdHE1B4dobdJXiMQ9aFCgADxvuJaRnefk75dJgDagQXxuuVKcKxKRz8oO6LdR6asNorwG8NloydbjxCcLCYLgxdls0jhoHakJlVNj7HpmkRBxCnJ6DqE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1578407149427466.68779943040545; Tue, 7 Jan 2020 06:25:49 -0800 (PST) Received: from localhost ([::1]:49696 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iopno-0002F7-1h for importer@patchew.org; Tue, 07 Jan 2020 09:25:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35900) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iooNt-0003jU-1u for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iooNr-0000z3-Dt for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:56 -0500 Received: from mout.gmx.net ([212.227.15.15]:36531) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iooNr-0000xO-3p for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:55 -0500 Received: from localhost.localdomain ([89.71.135.231]) by mail.gmx.com (mrgmx005 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MTiPv-1jGT5a44Uv-00TySy; Tue, 07 Jan 2020 13:54:44 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1578401684; bh=MNe65IX81php0msP6hBmroHHZoRYTXqyhunZqXPS9uk=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=KSha5Lcj98BJiycOGEot7524k7lEY9j/56sF8kouCxxiuquwZ0jIkoDJAyhTvH6bb gm2Y00VrnNhRoytocEVTZoQ9bYPLkWb/fe7GiE8oAAoDTbmel7trKD0Z4tFqw1S815 aDEIf6m4YIkHIpWrLlI584WoGTvU5L5vvjqelrqo= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c From: Kamil Rytarowski To: qemu-devel@nongnu.org Subject: [PATCH 2/4] Add the NetBSD Virtual Machine Monitor accelerator. Date: Tue, 7 Jan 2020 13:53:59 +0100 Message-Id: <20200107125401.18126-3-n54@gmx.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107125401.18126-1-n54@gmx.com> References: <20200107125401.18126-1-n54@gmx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:Va58LnAqGNV5aMYRzW+KSTjJlXVucQcpbQU7cQEiD5oWpMCFvkq EwH/w7ih5DBhEDWLBikLLj8wTg6GdNfKwjURQCOeFI5BJJyMwjFyNiS8Lw2UXZ1GHeGFb5f ka2Noz5/V3G4hP6gksCZTxQg9Fd2L6wnUimUiBcY65YZbIBpjzAQX6f9O2xle1KOnN2dR7A dCTBzFet37HhWtecvagyQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:otGnVlpPJlY=:stqlQCrGUYHWbt+5GoOHfG ZmFH4ED7afmuGmD1Jrxkt3vXZ1UMJHn+JHfpXzsyiVvFeFA/wp2p8RKfQQUbeQg7WoC+/ERXm De4UjRektYT/pILq6hzt7A5yXJyHNDYrveFwBooi7daU7RO5rUZ9vfDY2JSIJk6c1hNlX1J7F Se12qPyTPN1ZmfWFhFllwahwY/UhHWWdnMRgtnUb2gKl1YYHxopkmd3tN9jsbGUe0CH0mTY0a EUmXAoPv7K5VpUm22vkH5sn5VStSXotgLVMlDDv04b61ZQAEUqFbP0mwJxG6dCLojd3u4Wa4W 7c5mRzavrM3yDdGtM3v0hhVdSuWVNWoSX2dZ7znez/U1GYEjocdtm3rqotfn1M2Y9bF5cln2M FLnmYcXIVl4iyzkBUmgPyffAJHnREV9K6BVfgPeZGxXYKd04QanAyqxlJ2mWz6TL/T2Zj6MRR i0fAWUX5sTLhna1ZOSrcAhfSX5TRThDJjEEDY/2AsE5HhSf/w8mtWBteKUzTM6wut93mmb/Sf zpmjlzotRSjfXspefrpm3JS1JZXqCMWl3WoBq+6N+X0qkancjwiNm3HpB1pvjytbTn6WYxjeX EvH7FonMYR2NpO9p/3oTNRrlbkCd03+Tgewtxz6j7sBkQ+bnCr7UPD5d0cgvsMPXSCtaNnR5w 7Fr/wUi6KrqUtLrxn0FpiV6rG1J4SJOaznB7+VUouSnE+sL2QlYpNMm6pM1pNTzmC6vDOHT00 KwPyGArOP/hBYQs0Z8rZZ/b3ETEZIiOSeu27nNEDR9mETUrKgckCxxmRojjwfrV/Uu2HVq4T3 nOSx6h5Vz3TFGBTUiBNGOXLQtpDZhx+a+KyLCcGQDqJLRdmisVAZAqAw4dEpDj5tZNC4ndSB+ Wx80i9Ulz/eorw15k6/U968nc3O59ToFvd8ya0vXmctkZGPJWwck01loAzAW5fKiQzhOAzLz/ nqCNRVPmmXF2E6CSTlipdDD8OItmuAxDqHnnh39ERxgKpUkGHWdc2xdgO9pL3pbMdb9ceNwpY kD9Cchwm+Sb8wgPSwg7z1LwccbnB9/+DozeDVyFbdHKJFG3rNxnXnxKt4EJsRSWgpeMK3WUD0 Z4ffHtm+z7xvblr/bGAI3ELXoWxYaVsNSDBgTiubGwnXv25wPaKsz9Fvc6QJM24PezgOkYtpv gJV+usXqi1WhQJjVZz4ci9sGbB1lJI7CpuMuPRXM7JxNUWF/xk2EXlssF00PLNpb3h73WNDEn URY5xY9oKGJSLafTcXU5eupAlUNBwj4JxTV8SYw== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.15.15 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbonzini@redhat.com, Kamil Rytarowski , Maxime Villard , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Maxime Villard Introduces the configure support for the new NetBSD Virtual Machine Monitor= that allows for hypervisor acceleration from usermode components on the NetBSD platform. Signed-off-by: Maxime Villard Signed-off-by: Kamil Rytarowski --- configure | 36 ++++++++++++++++++++++++++++++++++++ qemu-options.hx | 4 ++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 0ce2c0354a..eb456a271e 100755 --- a/configure +++ b/configure @@ -241,6 +241,17 @@ supported_whpx_target() { return 1 } +supported_nvmm_target() { + test "$nvmm" =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) @@ -268,6 +279,7 @@ supported_target() { supported_hax_target "$1" && return 0 supported_hvf_target "$1" && return 0 supported_whpx_target "$1" && return 0 + supported_nvmm_target "$1" && return 0 print_error "TCG disabled, but hardware accelerator not available for = '$target'" return 1 } @@ -387,6 +399,7 @@ kvm=3D"no" hax=3D"no" hvf=3D"no" whpx=3D"no" +nvmm=3D"no" rdma=3D"" pvrdma=3D"" gprof=3D"no" @@ -1168,6 +1181,10 @@ for opt do ;; --enable-whpx) whpx=3D"yes" ;; + --disable-nvmm) nvmm=3D"no" + ;; + --enable-nvmm) nvmm=3D"yes" + ;; --disable-tcg-interpreter) tcg_interpreter=3D"no" ;; --enable-tcg-interpreter) tcg_interpreter=3D"yes" @@ -1768,6 +1785,7 @@ disabled with --disable-FEATURE, default is enabled i= f available: hax HAX acceleration support hvf Hypervisor.framework acceleration support whpx Windows Hypervisor Platform acceleration support + nvmm NetBSD Virtual Machine Monitor acceleration support rdma Enable RDMA-based migration pvrdma Enable PVRDMA support vde support for vde network @@ -2757,6 +2775,20 @@ if test "$whpx" !=3D "no" ; then fi fi +########################################## +# NetBSD Virtual Machine Monitor (NVMM) accelerator check +if test "$nvmm" !=3D "no" ; then + if check_include "nvmm.h" ; then + nvmm=3D"yes" + LIBS=3D"-lnvmm $LIBS" + else + if test "$nvmm" =3D "yes"; then + feature_not_found "NVMM" "NVMM is not available" + fi + nvmm=3D"no" + fi +fi + ########################################## # Sparse probe if test "$sparse" !=3D "no" ; then @@ -6495,6 +6527,7 @@ echo "KVM support $kvm" echo "HAX support $hax" echo "HVF support $hvf" echo "WHPX support $whpx" +echo "NVMM support $nvmm" echo "TCG support $tcg" if test "$tcg" =3D "yes" ; then echo "TCG debug enabled $debug_tcg" @@ -7771,6 +7804,9 @@ fi if test "$target_aligned_only" =3D "yes" ; then echo "TARGET_ALIGNED_ONLY=3Dy" >> $config_target_mak fi +if supported_nvmm_target $target; then + echo "CONFIG_NVMM=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 e9d6231438..f2dbac68ef 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, whpx o= r tcg (default: tcg)\n" + " supported accelerators are kvm, xen, hax, hvf, nvmm, = whpx or tcg (default: tcg)\n" " vmport=3Don|off|auto controls emulation of vmport (de= fault: auto)\n" " dump-guest-core=3Don|off include guest memory in a co= re dump (default=3Don)\n" " mem-merge=3Don|off controls memory merge support (def= ault: on)\n" @@ -63,7 +63,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, whpx or tcg can be available. By default, tcg is used.= If there is +kvm, xen, hax, hvf, nvmm, 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 vmport=3Don|off|auto -- 2.24.0 From nobody Fri May 3 09:01:14 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1578407615; cv=none; d=zohomail.com; s=zohoarc; b=Rhh+Sn/Z2xBPXCEXGAZhH1AgDWk92T/8RwGUKGYI6i7BFf0lAr1Y3vw5N7Jwl4GoQ9m2h3xWu/IJ7eVWpsG+jMcJRF098wK7fuFj+HIEOzDu3bSdYlp5S8YF8oJ5p5kwkEiQEJa9VDo8Hh2axcOMcDW8cEg0GniTCK/vZT3Pi8o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1578407615; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Ae02c9+Dht4TqAVpVhaJvaRLVhlPD9KQsy4gIqDLJ0U=; b=HkId8Mj4rRq/eX7RbITDIucqW8DRM1dcsVudUCWzHhF41GV688ryO9aO8mbNBdqHdrWc69ey18zsYiTP+HQ3acvXG7LXBMDert5TBSjfVV82Haz2QEfSFm7v1YxcXHVo/dKu2OVCdJffbAp3Lw6tLEHN2m9F4cl2QS3QNGWr3ac= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15784076156142.203480220950155; Tue, 7 Jan 2020 06:33:35 -0800 (PST) Received: from localhost ([::1]:49874 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iopvJ-0003jh-TC for importer@patchew.org; Tue, 07 Jan 2020 09:33:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35917) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iooNv-0003oq-18 for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:55:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iooNr-0000yn-1X for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:58 -0500 Received: from mout.gmx.net ([212.227.15.15]:50735) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iooNq-0000wc-J9 for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:54 -0500 Received: from localhost.localdomain ([89.71.135.231]) by mail.gmx.com (mrgmx005 [212.227.17.184]) with ESMTPSA (Nemesis) id 1Mr9Fs-1jRwDy1MYg-00oHPL; Tue, 07 Jan 2020 13:54:44 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1578401684; bh=n44YHEX1p1VkrkkdjvWZo5GGbPcjONvWX2YWt/VhJ7Y=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=GHh2qQBYB7FNQgr3MPNoKkZ3Qei30GfJrNWjhSJNtLngl76m9i8c5ujvXoIhWmWtP gfxdnS0xDZIfWKCsSOiOnLZs3lgj0ndBZ6QDLBxI00vRS+mOl9AcU9ItHJyUhKaYoZ yf8UDqNK1l+qEj9GNfj3oJNeuE9Tfb1weGCd/pgM= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c From: Kamil Rytarowski To: qemu-devel@nongnu.org Subject: [PATCH 3/4] Introduce the NVMM impl Date: Tue, 7 Jan 2020 13:54:00 +0100 Message-Id: <20200107125401.18126-4-n54@gmx.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107125401.18126-1-n54@gmx.com> References: <20200107125401.18126-1-n54@gmx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:trYJ18+KXR3biISaDvLwyLiaTkPtEe2rlNFt3Rvo1/xUM/9ESfE LxgbGEopiWxTMzjdNNn56kzsFQq07Oir3ndkoVKSDSw2Im3uCugC1+9/206nFti9na99d4+ fOzeVz0DLhoL/3iDLvcAWm9tTYuiDAol888Fu5XS96zGlbqH95WUGiTM1b2zBOm5m0Ojaar V/BhAw55rylAPVLlxgN3g== X-UI-Out-Filterresults: notjunk:1;V03:K0:VfCnPjfn6Ac=:O9Jea3odWqdplaZl2KhZyR kfNGreTfHVdkUwNoxEH0e09TWkVM9i0U/3Yp/XHlQoD1lxl0Ds5/WPN9erQsy+7FiOXRKCW/N Bo9uCTFJ48MeWSnY/OhfBYwnhyRDcEctC/kmuMep3VcTa/VRVA/03QwuUqUfKtu77qVMRiHvI kKUN9YiyrvZqSjVRlKawqR9lVD1DkCiZ2oQbDTJt8cedYBp6hrZFItFSmBLNT6coDXEWPUX7i saegvSZdnpNTRb1xvbn4xQJqe2ZEF0mdEKQUfTCNiOfDvGU+zR7+PG8OwaFz81wOlBVO7KRMh o1ECRt6XGNOPpG6TE21IfXtuQcFSqf+t4BoGk+c9w7MHm5F7YHgYrNYoIZ9YPYUTkUc3S7l0Q Lkn3yfdz6GXGJV2JYwcfo14UzpzDYKNjodpzhk302ZfRX6vAX8b0NGLuVy9+ud6U2GHT6yGHl 1Amr+fl5eUMlDbseBukiZ2Ff7D8DZCWR02Rpp7pNXvGQPLvuLbsyMcwL3b+zUmXv+/Q5PUvF/ PpScuqvd/iKYmRBPG0OMK2sy+wMiClH/0y+cdv55/s/8lFPIjKZlJtvxsdWiLtbfRY0CEVIM7 9Wk3j9n4OPgYhPAjcZlEhWoWm5fRUYU5IfhAOjBcXjIBKCgyj/dFts+na+3roImabpDrFeWvv wgEcD9tveZzb9Jvvy9RNUL0XNyFueq7+Muetg1eySdtGLBoo09GK9Us/v6Ra/f6cAjX1a93cz TrAbSjLJx6r1yEz77olma9ESslKPCxxSBtwQz40gLxUcawKYeHz56YyBsY4BesXapjrzmyVIF DC2KBuQPet+PRipmfTLGXdEo1DHoX4xgoqVWwa0B2rmUbYepgPJnHTdEbi3HggcD0FjlKUuXT HmNO9M80JVHcdKKFKOErRnqqwSU8IPSRhSGVKUFwqLBNtu/RANeoSFlPIWRwicwX4DMWjS9IG PDHs5xNT/lAqSVTUv4nU6q2s93n25tHflC3g4rDMeh23+8NsAs38xxwr00R6zJe6Jp1W+27do 762UHa0iUt6Z5tZMxNys4GJzKpZf7Cl93/DfvIMcCvwpiP7GMSyJnr8cnraaP1O0+gBjNEePA f1bu+fY3H9m4HtPU0vN5I3f8l1sVAc5KF1MB1VsHScEpFMQNpjl8p6a8edU8JuaFBemxchAxZ 40d5/EuBJwEhEGPCWT61Yuamh9RDOVQ9qUHoh1DeuMy+qybeVqHyXRbYB275Sf4EHgvvwct8y PaJ67cx6OsSx9KQriXEMitNYL3JRgULxz7t/7OA== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.15.15 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbonzini@redhat.com, Kamil Rytarowski , Maxime Villard , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Maxime Villard Implements the NetBSD Virtual Machine Monitor (NVMM) target. Which acts as a hypervisor accelerator for QEMU on the NetBSD platform. This enab= les QEMU much greater speed over the emulated x86_64 path's that are taken on NetBSD today. Signed-off-by: Maxime Villard Signed-off-by: Kamil Rytarowski Reviewed-by: Sergio Lopez --- target/i386/Makefile.objs | 1 + target/i386/nvmm-all.c | 1222 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1223 insertions(+) create mode 100644 target/i386/nvmm-all.c diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs index 48e0c28434..bdcdb32e93 100644 --- a/target/i386/Makefile.objs +++ b/target/i386/Makefile.objs @@ -17,6 +17,7 @@ obj-$(CONFIG_HAX) +=3D hax-all.o hax-mem.o hax-posix.o endif obj-$(CONFIG_HVF) +=3D hvf/ obj-$(CONFIG_WHPX) +=3D whpx-all.o +obj-$(CONFIG_NVMM) +=3D nvmm-all.o endif obj-$(CONFIG_SEV) +=3D sev.o obj-$(call lnot,$(CONFIG_SEV)) +=3D sev-stub.o diff --git a/target/i386/nvmm-all.c b/target/i386/nvmm-all.c new file mode 100644 index 0000000000..66b08f4f66 --- /dev/null +++ b/target/i386/nvmm-all.c @@ -0,0 +1,1222 @@ +/* + * Copyright (c) 2018-2019 Maxime Villard, All rights reserved. + * + * NetBSD Virtual Machine Monitor (NVMM) accelerator for QEMU. + * + * 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/ioport.h" +#include "qemu-common.h" +#include "strings.h" +#include "sysemu/accel.h" +#include "sysemu/nvmm.h" +#include "sysemu/sysemu.h" +#include "sysemu/cpus.h" +#include "qemu/main-loop.h" +#include "hw/boards.h" +#include "qemu/error-report.h" +#include "qemu/queue.h" +#include "qapi/error.h" +#include "migration/blocker.h" + +#include + +struct qemu_vcpu { + struct nvmm_vcpu vcpu; + uint8_t tpr; + bool stop; + + /* Window-exiting for INTs/NMIs. */ + bool int_window_exit; + bool nmi_window_exit; + + /* The guest is in an interrupt shadow (POP SS, etc). */ + bool int_shadow; +}; + +struct qemu_machine { + struct nvmm_capability cap; + struct nvmm_machine mach; +}; + +/* -----------------------------------------------------------------------= --- */ + +static bool nvmm_allowed; +static struct qemu_machine qemu_mach; + +static struct qemu_vcpu * +get_qemu_vcpu(CPUState *cpu) +{ + return (struct qemu_vcpu *)cpu->hax_vcpu; +} + +static struct nvmm_machine * +get_nvmm_mach(void) +{ + return &qemu_mach.mach; +} + +/* -----------------------------------------------------------------------= --- */ + +static void +nvmm_set_segment(struct nvmm_x64_state_seg *nseg, const SegmentCache *qseg) +{ + uint32_t attrib =3D qseg->flags; + + nseg->selector =3D qseg->selector; + nseg->limit =3D qseg->limit; + nseg->base =3D qseg->base; + nseg->attrib.type =3D __SHIFTOUT(attrib, DESC_TYPE_MASK); + nseg->attrib.s =3D __SHIFTOUT(attrib, DESC_S_MASK); + nseg->attrib.dpl =3D __SHIFTOUT(attrib, DESC_DPL_MASK); + nseg->attrib.p =3D __SHIFTOUT(attrib, DESC_P_MASK); + nseg->attrib.avl =3D __SHIFTOUT(attrib, DESC_AVL_MASK); + nseg->attrib.l =3D __SHIFTOUT(attrib, DESC_L_MASK); + nseg->attrib.def =3D __SHIFTOUT(attrib, DESC_B_MASK); + nseg->attrib.g =3D __SHIFTOUT(attrib, DESC_G_MASK); +} + +static void +nvmm_set_registers(CPUState *cpu) +{ + struct CPUX86State *env =3D (CPUArchState *)cpu->env_ptr; + struct nvmm_machine *mach =3D get_nvmm_mach(); + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + struct nvmm_vcpu *vcpu =3D &qcpu->vcpu; + struct nvmm_x64_state *state =3D vcpu->state; + uint64_t bitmap; + size_t i; + int ret; + + assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + + /* GPRs. */ + state->gprs[NVMM_X64_GPR_RAX] =3D env->regs[R_EAX]; + state->gprs[NVMM_X64_GPR_RCX] =3D env->regs[R_ECX]; + state->gprs[NVMM_X64_GPR_RDX] =3D env->regs[R_EDX]; + state->gprs[NVMM_X64_GPR_RBX] =3D env->regs[R_EBX]; + state->gprs[NVMM_X64_GPR_RSP] =3D env->regs[R_ESP]; + state->gprs[NVMM_X64_GPR_RBP] =3D env->regs[R_EBP]; + state->gprs[NVMM_X64_GPR_RSI] =3D env->regs[R_ESI]; + state->gprs[NVMM_X64_GPR_RDI] =3D env->regs[R_EDI]; + state->gprs[NVMM_X64_GPR_R8] =3D env->regs[R_R8]; + state->gprs[NVMM_X64_GPR_R9] =3D env->regs[R_R9]; + state->gprs[NVMM_X64_GPR_R10] =3D env->regs[R_R10]; + state->gprs[NVMM_X64_GPR_R11] =3D env->regs[R_R11]; + state->gprs[NVMM_X64_GPR_R12] =3D env->regs[R_R12]; + state->gprs[NVMM_X64_GPR_R13] =3D env->regs[R_R13]; + state->gprs[NVMM_X64_GPR_R14] =3D env->regs[R_R14]; + state->gprs[NVMM_X64_GPR_R15] =3D env->regs[R_R15]; + + /* RIP and RFLAGS. */ + state->gprs[NVMM_X64_GPR_RIP] =3D env->eip; + state->gprs[NVMM_X64_GPR_RFLAGS] =3D env->eflags; + + /* Segments. */ + nvmm_set_segment(&state->segs[NVMM_X64_SEG_CS], &env->segs[R_CS]); + nvmm_set_segment(&state->segs[NVMM_X64_SEG_DS], &env->segs[R_DS]); + nvmm_set_segment(&state->segs[NVMM_X64_SEG_ES], &env->segs[R_ES]); + nvmm_set_segment(&state->segs[NVMM_X64_SEG_FS], &env->segs[R_FS]); + nvmm_set_segment(&state->segs[NVMM_X64_SEG_GS], &env->segs[R_GS]); + nvmm_set_segment(&state->segs[NVMM_X64_SEG_SS], &env->segs[R_SS]); + + /* Special segments. */ + nvmm_set_segment(&state->segs[NVMM_X64_SEG_GDT], &env->gdt); + nvmm_set_segment(&state->segs[NVMM_X64_SEG_LDT], &env->ldt); + nvmm_set_segment(&state->segs[NVMM_X64_SEG_TR], &env->tr); + nvmm_set_segment(&state->segs[NVMM_X64_SEG_IDT], &env->idt); + + /* Control registers. */ + state->crs[NVMM_X64_CR_CR0] =3D env->cr[0]; + state->crs[NVMM_X64_CR_CR2] =3D env->cr[2]; + state->crs[NVMM_X64_CR_CR3] =3D env->cr[3]; + state->crs[NVMM_X64_CR_CR4] =3D env->cr[4]; + state->crs[NVMM_X64_CR_CR8] =3D qcpu->tpr; + state->crs[NVMM_X64_CR_XCR0] =3D env->xcr0; + + /* Debug registers. */ + state->drs[NVMM_X64_DR_DR0] =3D env->dr[0]; + state->drs[NVMM_X64_DR_DR1] =3D env->dr[1]; + state->drs[NVMM_X64_DR_DR2] =3D env->dr[2]; + state->drs[NVMM_X64_DR_DR3] =3D env->dr[3]; + state->drs[NVMM_X64_DR_DR6] =3D env->dr[6]; + state->drs[NVMM_X64_DR_DR7] =3D env->dr[7]; + + /* FPU. */ + state->fpu.fx_cw =3D env->fpuc; + state->fpu.fx_sw =3D (env->fpus & ~0x3800) | ((env->fpstt & 0x7) << 11= ); + state->fpu.fx_tw =3D 0; + for (i =3D 0; i < 8; i++) { + state->fpu.fx_tw |=3D (!env->fptags[i]) << i; + } + state->fpu.fx_opcode =3D env->fpop; + state->fpu.fx_ip.fa_64 =3D env->fpip; + state->fpu.fx_dp.fa_64 =3D env->fpdp; + state->fpu.fx_mxcsr =3D env->mxcsr; + state->fpu.fx_mxcsr_mask =3D 0x0000FFFF; + assert(sizeof(state->fpu.fx_87_ac) =3D=3D sizeof(env->fpregs)); + memcpy(state->fpu.fx_87_ac, env->fpregs, sizeof(env->fpregs)); + for (i =3D 0; i < 16; i++) { + memcpy(&state->fpu.fx_xmm[i].xmm_bytes[0], + &env->xmm_regs[i].ZMM_Q(0), 8); + memcpy(&state->fpu.fx_xmm[i].xmm_bytes[8], + &env->xmm_regs[i].ZMM_Q(1), 8); + } + + /* MSRs. */ + state->msrs[NVMM_X64_MSR_EFER] =3D env->efer; + state->msrs[NVMM_X64_MSR_STAR] =3D env->star; +#ifdef TARGET_X86_64 + state->msrs[NVMM_X64_MSR_LSTAR] =3D env->lstar; + state->msrs[NVMM_X64_MSR_CSTAR] =3D env->cstar; + state->msrs[NVMM_X64_MSR_SFMASK] =3D env->fmask; + state->msrs[NVMM_X64_MSR_KERNELGSBASE] =3D env->kernelgsbase; +#endif + state->msrs[NVMM_X64_MSR_SYSENTER_CS] =3D env->sysenter_cs; + state->msrs[NVMM_X64_MSR_SYSENTER_ESP] =3D env->sysenter_esp; + state->msrs[NVMM_X64_MSR_SYSENTER_EIP] =3D env->sysenter_eip; + state->msrs[NVMM_X64_MSR_PAT] =3D env->pat; + state->msrs[NVMM_X64_MSR_TSC] =3D env->tsc; + + bitmap =3D + NVMM_X64_STATE_SEGS | + NVMM_X64_STATE_GPRS | + NVMM_X64_STATE_CRS | + NVMM_X64_STATE_DRS | + NVMM_X64_STATE_MSRS | + NVMM_X64_STATE_FPU; + + ret =3D nvmm_vcpu_setstate(mach, vcpu, bitmap); + if (ret =3D=3D -1) { + error_report("NVMM: Failed to set virtual processor context," + " error=3D%d", errno); + } +} + +static void +nvmm_get_segment(SegmentCache *qseg, const struct nvmm_x64_state_seg *nseg) +{ + qseg->selector =3D nseg->selector; + qseg->limit =3D nseg->limit; + qseg->base =3D nseg->base; + + qseg->flags =3D + __SHIFTIN((uint32_t)nseg->attrib.type, DESC_TYPE_MASK) | + __SHIFTIN((uint32_t)nseg->attrib.s, DESC_S_MASK) | + __SHIFTIN((uint32_t)nseg->attrib.dpl, DESC_DPL_MASK) | + __SHIFTIN((uint32_t)nseg->attrib.p, DESC_P_MASK) | + __SHIFTIN((uint32_t)nseg->attrib.avl, DESC_AVL_MASK) | + __SHIFTIN((uint32_t)nseg->attrib.l, DESC_L_MASK) | + __SHIFTIN((uint32_t)nseg->attrib.def, DESC_B_MASK) | + __SHIFTIN((uint32_t)nseg->attrib.g, DESC_G_MASK); +} + +static void +nvmm_get_registers(CPUState *cpu) +{ + struct CPUX86State *env =3D (CPUArchState *)cpu->env_ptr; + struct nvmm_machine *mach =3D get_nvmm_mach(); + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + struct nvmm_vcpu *vcpu =3D &qcpu->vcpu; + X86CPU *x86_cpu =3D X86_CPU(cpu); + struct nvmm_x64_state *state =3D vcpu->state; + uint64_t bitmap, tpr; + size_t i; + int ret; + + assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + + bitmap =3D + NVMM_X64_STATE_SEGS | + NVMM_X64_STATE_GPRS | + NVMM_X64_STATE_CRS | + NVMM_X64_STATE_DRS | + NVMM_X64_STATE_MSRS | + NVMM_X64_STATE_FPU; + + ret =3D nvmm_vcpu_getstate(mach, vcpu, bitmap); + if (ret =3D=3D -1) { + error_report("NVMM: Failed to get virtual processor context," + " error=3D%d", errno); + } + + /* GPRs. */ + env->regs[R_EAX] =3D state->gprs[NVMM_X64_GPR_RAX]; + env->regs[R_ECX] =3D state->gprs[NVMM_X64_GPR_RCX]; + env->regs[R_EDX] =3D state->gprs[NVMM_X64_GPR_RDX]; + env->regs[R_EBX] =3D state->gprs[NVMM_X64_GPR_RBX]; + env->regs[R_ESP] =3D state->gprs[NVMM_X64_GPR_RSP]; + env->regs[R_EBP] =3D state->gprs[NVMM_X64_GPR_RBP]; + env->regs[R_ESI] =3D state->gprs[NVMM_X64_GPR_RSI]; + env->regs[R_EDI] =3D state->gprs[NVMM_X64_GPR_RDI]; + env->regs[R_R8] =3D state->gprs[NVMM_X64_GPR_R8]; + env->regs[R_R9] =3D state->gprs[NVMM_X64_GPR_R9]; + env->regs[R_R10] =3D state->gprs[NVMM_X64_GPR_R10]; + env->regs[R_R11] =3D state->gprs[NVMM_X64_GPR_R11]; + env->regs[R_R12] =3D state->gprs[NVMM_X64_GPR_R12]; + env->regs[R_R13] =3D state->gprs[NVMM_X64_GPR_R13]; + env->regs[R_R14] =3D state->gprs[NVMM_X64_GPR_R14]; + env->regs[R_R15] =3D state->gprs[NVMM_X64_GPR_R15]; + + /* RIP and RFLAGS. */ + env->eip =3D state->gprs[NVMM_X64_GPR_RIP]; + env->eflags =3D state->gprs[NVMM_X64_GPR_RFLAGS]; + + /* Segments. */ + nvmm_get_segment(&env->segs[R_ES], &state->segs[NVMM_X64_SEG_ES]); + nvmm_get_segment(&env->segs[R_CS], &state->segs[NVMM_X64_SEG_CS]); + nvmm_get_segment(&env->segs[R_SS], &state->segs[NVMM_X64_SEG_SS]); + nvmm_get_segment(&env->segs[R_DS], &state->segs[NVMM_X64_SEG_DS]); + nvmm_get_segment(&env->segs[R_FS], &state->segs[NVMM_X64_SEG_FS]); + nvmm_get_segment(&env->segs[R_GS], &state->segs[NVMM_X64_SEG_GS]); + + /* Special segments. */ + nvmm_get_segment(&env->gdt, &state->segs[NVMM_X64_SEG_GDT]); + nvmm_get_segment(&env->ldt, &state->segs[NVMM_X64_SEG_LDT]); + nvmm_get_segment(&env->tr, &state->segs[NVMM_X64_SEG_TR]); + nvmm_get_segment(&env->idt, &state->segs[NVMM_X64_SEG_IDT]); + + /* Control registers. */ + env->cr[0] =3D state->crs[NVMM_X64_CR_CR0]; + env->cr[2] =3D state->crs[NVMM_X64_CR_CR2]; + env->cr[3] =3D state->crs[NVMM_X64_CR_CR3]; + env->cr[4] =3D state->crs[NVMM_X64_CR_CR4]; + tpr =3D state->crs[NVMM_X64_CR_CR8]; + if (tpr !=3D qcpu->tpr) { + qcpu->tpr =3D tpr; + cpu_set_apic_tpr(x86_cpu->apic_state, tpr); + } + env->xcr0 =3D state->crs[NVMM_X64_CR_XCR0]; + + /* Debug registers. */ + env->dr[0] =3D state->drs[NVMM_X64_DR_DR0]; + env->dr[1] =3D state->drs[NVMM_X64_DR_DR1]; + env->dr[2] =3D state->drs[NVMM_X64_DR_DR2]; + env->dr[3] =3D state->drs[NVMM_X64_DR_DR3]; + env->dr[6] =3D state->drs[NVMM_X64_DR_DR6]; + env->dr[7] =3D state->drs[NVMM_X64_DR_DR7]; + + /* FPU. */ + env->fpuc =3D state->fpu.fx_cw; + env->fpstt =3D (state->fpu.fx_sw >> 11) & 0x7; + env->fpus =3D state->fpu.fx_sw & ~0x3800; + for (i =3D 0; i < 8; i++) { + env->fptags[i] =3D !((state->fpu.fx_tw >> i) & 1); + } + env->fpop =3D state->fpu.fx_opcode; + env->fpip =3D state->fpu.fx_ip.fa_64; + env->fpdp =3D state->fpu.fx_dp.fa_64; + env->mxcsr =3D state->fpu.fx_mxcsr; + assert(sizeof(state->fpu.fx_87_ac) =3D=3D sizeof(env->fpregs)); + memcpy(env->fpregs, state->fpu.fx_87_ac, sizeof(env->fpregs)); + for (i =3D 0; i < 16; i++) { + memcpy(&env->xmm_regs[i].ZMM_Q(0), + &state->fpu.fx_xmm[i].xmm_bytes[0], 8); + memcpy(&env->xmm_regs[i].ZMM_Q(1), + &state->fpu.fx_xmm[i].xmm_bytes[8], 8); + } + + /* MSRs. */ + env->efer =3D state->msrs[NVMM_X64_MSR_EFER]; + env->star =3D state->msrs[NVMM_X64_MSR_STAR]; +#ifdef TARGET_X86_64 + env->lstar =3D state->msrs[NVMM_X64_MSR_LSTAR]; + env->cstar =3D state->msrs[NVMM_X64_MSR_CSTAR]; + env->fmask =3D state->msrs[NVMM_X64_MSR_SFMASK]; + env->kernelgsbase =3D state->msrs[NVMM_X64_MSR_KERNELGSBASE]; +#endif + env->sysenter_cs =3D state->msrs[NVMM_X64_MSR_SYSENTER_CS]; + env->sysenter_esp =3D state->msrs[NVMM_X64_MSR_SYSENTER_ESP]; + env->sysenter_eip =3D state->msrs[NVMM_X64_MSR_SYSENTER_EIP]; + env->pat =3D state->msrs[NVMM_X64_MSR_PAT]; + env->tsc =3D state->msrs[NVMM_X64_MSR_TSC]; + + x86_update_hflags(env); +} + +static bool +nvmm_can_take_int(CPUState *cpu) +{ + struct CPUX86State *env =3D (CPUArchState *)cpu->env_ptr; + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + struct nvmm_vcpu *vcpu =3D &qcpu->vcpu; + struct nvmm_machine *mach =3D get_nvmm_mach(); + + if (qcpu->int_window_exit) { + return false; + } + + if (qcpu->int_shadow || !(env->eflags & IF_MASK)) { + struct nvmm_x64_state *state =3D vcpu->state; + + /* Exit on interrupt window. */ + nvmm_vcpu_getstate(mach, vcpu, NVMM_X64_STATE_INTR); + state->intr.int_window_exiting =3D 1; + nvmm_vcpu_setstate(mach, vcpu, NVMM_X64_STATE_INTR); + + return false; + } + + return true; +} + +static bool +nvmm_can_take_nmi(CPUState *cpu) +{ + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + + /* + * Contrary to INTs, NMIs always schedule an exit when they are + * completed. Therefore, if window-exiting is enabled, it means + * NMIs are blocked. + */ + if (qcpu->nmi_window_exit) { + return false; + } + + return true; +} + +/* + * Called before the VCPU is run. We inject events generated by the I/O + * thread, and synchronize the guest TPR. + */ +static void +nvmm_vcpu_pre_run(CPUState *cpu) +{ + struct CPUX86State *env =3D (CPUArchState *)cpu->env_ptr; + struct nvmm_machine *mach =3D get_nvmm_mach(); + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + struct nvmm_vcpu *vcpu =3D &qcpu->vcpu; + X86CPU *x86_cpu =3D X86_CPU(cpu); + struct nvmm_x64_state *state =3D vcpu->state; + struct nvmm_vcpu_event *event =3D vcpu->event; + bool has_event =3D false; + bool sync_tpr =3D false; + uint8_t tpr; + int ret; + + qemu_mutex_lock_iothread(); + + tpr =3D cpu_get_apic_tpr(x86_cpu->apic_state); + if (tpr !=3D qcpu->tpr) { + qcpu->tpr =3D tpr; + sync_tpr =3D true; + } + + /* + * 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))= { + cpu->exit_request =3D 1; + } + + if (!has_event && (cpu->interrupt_request & CPU_INTERRUPT_NMI)) { + if (nvmm_can_take_nmi(cpu)) { + cpu->interrupt_request &=3D ~CPU_INTERRUPT_NMI; + event->type =3D NVMM_VCPU_EVENT_INTR; + event->vector =3D 2; + has_event =3D true; + } + } + + if (!has_event && (cpu->interrupt_request & CPU_INTERRUPT_HARD)) { + if (nvmm_can_take_int(cpu)) { + cpu->interrupt_request &=3D ~CPU_INTERRUPT_HARD; + event->type =3D NVMM_VCPU_EVENT_INTR; + event->vector =3D cpu_get_pic_interrupt(env); + has_event =3D true; + } + } + + /* Don't want SMIs. */ + if (cpu->interrupt_request & CPU_INTERRUPT_SMI) { + cpu->interrupt_request &=3D ~CPU_INTERRUPT_SMI; + } + + if (sync_tpr) { + ret =3D nvmm_vcpu_getstate(mach, vcpu, NVMM_X64_STATE_CRS); + if (ret =3D=3D -1) { + error_report("NVMM: Failed to get CPU state," + " error=3D%d", errno); + } + + state->crs[NVMM_X64_CR_CR8] =3D qcpu->tpr; + + ret =3D nvmm_vcpu_setstate(mach, vcpu, NVMM_X64_STATE_CRS); + if (ret =3D=3D -1) { + error_report("NVMM: Failed to set CPU state," + " error=3D%d", errno); + } + } + + if (has_event) { + ret =3D nvmm_vcpu_inject(mach, vcpu); + if (ret =3D=3D -1) { + error_report("NVMM: Failed to inject event," + " error=3D%d", errno); + } + } + + qemu_mutex_unlock_iothread(); +} + +/* + * Called after the VCPU ran. We synchronize the host view of the TPR and + * RFLAGS. + */ +static void +nvmm_vcpu_post_run(CPUState *cpu, struct nvmm_vcpu_exit *exit) +{ + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + struct CPUX86State *env =3D (CPUArchState *)cpu->env_ptr; + X86CPU *x86_cpu =3D X86_CPU(cpu); + uint64_t tpr; + + env->eflags =3D exit->exitstate.rflags; + qcpu->int_shadow =3D exit->exitstate.int_shadow; + qcpu->int_window_exit =3D exit->exitstate.int_window_exiting; + qcpu->nmi_window_exit =3D exit->exitstate.nmi_window_exiting; + + tpr =3D exit->exitstate.cr8; + if (qcpu->tpr !=3D tpr) { + qcpu->tpr =3D tpr; + qemu_mutex_lock_iothread(); + cpu_set_apic_tpr(x86_cpu->apic_state, qcpu->tpr); + qemu_mutex_unlock_iothread(); + } +} + +/* -----------------------------------------------------------------------= --- */ + +static void +nvmm_io_callback(struct nvmm_io *io) +{ + MemTxAttrs attrs =3D { 0 }; + int ret; + + ret =3D address_space_rw(&address_space_io, io->port, attrs, io->data, + io->size, !io->in); + if (ret !=3D MEMTX_OK) { + error_report("NVMM: I/O Transaction Failed " + "[%s, port=3D%u, size=3D%zu]", (io->in ? "in" : "out"), + io->port, io->size); + } + + /* XXX Needed, otherwise infinite loop. */ + current_cpu->vcpu_dirty =3D false; +} + +static void +nvmm_mem_callback(struct nvmm_mem *mem) +{ + cpu_physical_memory_rw(mem->gpa, mem->data, mem->size, mem->write); + + /* XXX Needed, otherwise infinite loop. */ + current_cpu->vcpu_dirty =3D false; +} + +static struct nvmm_assist_callbacks nvmm_callbacks =3D { + .io =3D nvmm_io_callback, + .mem =3D nvmm_mem_callback +}; + +/* -----------------------------------------------------------------------= --- */ + +static int +nvmm_handle_mem(struct nvmm_machine *mach, struct nvmm_vcpu *vcpu) +{ + int ret; + + ret =3D nvmm_assist_mem(mach, vcpu); + if (ret =3D=3D -1) { + error_report("NVMM: Mem Assist Failed [gpa=3D%p]", + (void *)vcpu->exit->u.mem.gpa); + } + + return ret; +} + +static int +nvmm_handle_io(struct nvmm_machine *mach, struct nvmm_vcpu *vcpu) +{ + int ret; + + ret =3D nvmm_assist_io(mach, vcpu); + if (ret =3D=3D -1) { + error_report("NVMM: I/O Assist Failed [port=3D%d]", + (int)vcpu->exit->u.io.port); + } + + return ret; +} + +static int +nvmm_handle_rdmsr(struct nvmm_machine *mach, CPUState *cpu, + struct nvmm_vcpu_exit *exit) +{ + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + struct nvmm_vcpu *vcpu =3D &qcpu->vcpu; + X86CPU *x86_cpu =3D X86_CPU(cpu); + struct nvmm_x64_state *state =3D vcpu->state; + uint64_t val; + int ret; + + switch (exit->u.rdmsr.msr) { + case MSR_IA32_APICBASE: + val =3D cpu_get_apic_base(x86_cpu->apic_state); + break; + case MSR_MTRRcap: + case MSR_MTRRdefType: + case MSR_MCG_CAP: + case MSR_MCG_STATUS: + val =3D 0; + break; + default: /* More MSRs to add? */ + val =3D 0; + error_report("NVMM: Unexpected RDMSR 0x%x, ignored", + exit->u.rdmsr.msr); + break; + } + + ret =3D nvmm_vcpu_getstate(mach, vcpu, NVMM_X64_STATE_GPRS); + if (ret =3D=3D -1) { + return -1; + } + + state->gprs[NVMM_X64_GPR_RAX] =3D (val & 0xFFFFFFFF); + state->gprs[NVMM_X64_GPR_RDX] =3D (val >> 32); + state->gprs[NVMM_X64_GPR_RIP] =3D exit->u.rdmsr.npc; + + ret =3D nvmm_vcpu_setstate(mach, vcpu, NVMM_X64_STATE_GPRS); + if (ret =3D=3D -1) { + return -1; + } + + return 0; +} + +static int +nvmm_handle_wrmsr(struct nvmm_machine *mach, CPUState *cpu, + struct nvmm_vcpu_exit *exit) +{ + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + struct nvmm_vcpu *vcpu =3D &qcpu->vcpu; + X86CPU *x86_cpu =3D X86_CPU(cpu); + struct nvmm_x64_state *state =3D vcpu->state; + uint64_t val; + int ret; + + val =3D exit->u.wrmsr.val; + + switch (exit->u.wrmsr.msr) { + case MSR_IA32_APICBASE: + cpu_set_apic_base(x86_cpu->apic_state, val); + break; + case MSR_MTRRdefType: + case MSR_MCG_STATUS: + break; + default: /* More MSRs to add? */ + error_report("NVMM: Unexpected WRMSR 0x%x [val=3D0x%lx], ignored", + exit->u.wrmsr.msr, val); + break; + } + + ret =3D nvmm_vcpu_getstate(mach, vcpu, NVMM_X64_STATE_GPRS); + if (ret =3D=3D -1) { + return -1; + } + + state->gprs[NVMM_X64_GPR_RIP] =3D exit->u.wrmsr.npc; + + ret =3D nvmm_vcpu_setstate(mach, vcpu, NVMM_X64_STATE_GPRS); + if (ret =3D=3D -1) { + return -1; + } + + return 0; +} + +static int +nvmm_handle_halted(struct nvmm_machine *mach, CPUState *cpu, + struct nvmm_vcpu_exit *exit) +{ + 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 int +nvmm_inject_ud(struct nvmm_machine *mach, struct nvmm_vcpu *vcpu) +{ + struct nvmm_vcpu_event *event =3D vcpu->event; + + event->type =3D NVMM_VCPU_EVENT_EXCP; + event->vector =3D 6; + event->u.excp.error =3D 0; + + return nvmm_vcpu_inject(mach, vcpu); +} + +static int +nvmm_vcpu_loop(CPUState *cpu) +{ + struct CPUX86State *env =3D (CPUArchState *)cpu->env_ptr; + struct nvmm_machine *mach =3D get_nvmm_mach(); + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + struct nvmm_vcpu *vcpu =3D &qcpu->vcpu; + X86CPU *x86_cpu =3D X86_CPU(cpu); + struct nvmm_vcpu_exit *exit =3D vcpu->exit; + int ret; + + /* + * Some asynchronous events must be handled outside of the inner + * VCPU loop. They are handled here. + */ + if (cpu->interrupt_request & CPU_INTERRUPT_INIT) { + nvmm_cpu_synchronize_state(cpu); + do_cpu_init(x86_cpu); + /* XXX: reset the INT/NMI windows */ + } + 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) { + nvmm_cpu_synchronize_state(cpu); + do_cpu_sipi(x86_cpu); + } + if (cpu->interrupt_request & CPU_INTERRUPT_TPR) { + cpu->interrupt_request &=3D ~CPU_INTERRUPT_TPR; + nvmm_cpu_synchronize_state(cpu); + apic_handle_tpr_access_report(x86_cpu->apic_state, env->eip, + env->tpr_access_type); + } + + 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); + + /* + * Inner VCPU loop. + */ + do { + if (cpu->vcpu_dirty) { + nvmm_set_registers(cpu); + cpu->vcpu_dirty =3D false; + } + + if (qcpu->stop) { + cpu->exception_index =3D EXCP_INTERRUPT; + qcpu->stop =3D false; + ret =3D 1; + break; + } + + nvmm_vcpu_pre_run(cpu); + + if (atomic_read(&cpu->exit_request)) { + qemu_cpu_kick_self(); + } + + ret =3D nvmm_vcpu_run(mach, vcpu); + if (ret =3D=3D -1) { + error_report("NVMM: Failed to exec a virtual processor," + " error=3D%d", errno); + break; + } + + nvmm_vcpu_post_run(cpu, exit); + + switch (exit->reason) { + case NVMM_VCPU_EXIT_NONE: + break; + case NVMM_VCPU_EXIT_MEMORY: + ret =3D nvmm_handle_mem(mach, vcpu); + break; + case NVMM_VCPU_EXIT_IO: + ret =3D nvmm_handle_io(mach, vcpu); + break; + case NVMM_VCPU_EXIT_INT_READY: + case NVMM_VCPU_EXIT_NMI_READY: + case NVMM_VCPU_EXIT_TPR_CHANGED: + break; + case NVMM_VCPU_EXIT_HALTED: + ret =3D nvmm_handle_halted(mach, cpu, exit); + break; + case NVMM_VCPU_EXIT_SHUTDOWN: + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + cpu->exception_index =3D EXCP_INTERRUPT; + ret =3D 1; + break; + case NVMM_VCPU_EXIT_RDMSR: + ret =3D nvmm_handle_rdmsr(mach, cpu, exit); + break; + case NVMM_VCPU_EXIT_WRMSR: + ret =3D nvmm_handle_wrmsr(mach, cpu, exit); + break; + case NVMM_VCPU_EXIT_MONITOR: + case NVMM_VCPU_EXIT_MWAIT: + ret =3D nvmm_inject_ud(mach, vcpu); + break; + default: + error_report("NVMM: Unexpected VM exit code 0x%lx [hw=3D0x%lx]= ", + exit->reason, exit->u.inv.hwcode); + nvmm_get_registers(cpu); + qemu_mutex_lock_iothread(); + qemu_system_guest_panicked(cpu_get_crash_info(cpu)); + qemu_mutex_unlock_iothread(); + ret =3D -1; + break; + } + } while (ret =3D=3D 0); + + cpu_exec_end(cpu); + qemu_mutex_lock_iothread(); + current_cpu =3D cpu; + + atomic_set(&cpu->exit_request, false); + + return ret < 0; +} + +/* -----------------------------------------------------------------------= --- */ + +static void +do_nvmm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) +{ + nvmm_get_registers(cpu); + cpu->vcpu_dirty =3D true; +} + +static void +do_nvmm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg) +{ + nvmm_set_registers(cpu); + cpu->vcpu_dirty =3D false; +} + +static void +do_nvmm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) +{ + nvmm_set_registers(cpu); + cpu->vcpu_dirty =3D false; +} + +static void +do_nvmm_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_data arg) +{ + cpu->vcpu_dirty =3D true; +} + +void nvmm_cpu_synchronize_state(CPUState *cpu) +{ + if (!cpu->vcpu_dirty) { + run_on_cpu(cpu, do_nvmm_cpu_synchronize_state, RUN_ON_CPU_NULL); + } +} + +void nvmm_cpu_synchronize_post_reset(CPUState *cpu) +{ + run_on_cpu(cpu, do_nvmm_cpu_synchronize_post_reset, RUN_ON_CPU_NULL); +} + +void nvmm_cpu_synchronize_post_init(CPUState *cpu) +{ + run_on_cpu(cpu, do_nvmm_cpu_synchronize_post_init, RUN_ON_CPU_NULL); +} + +void nvmm_cpu_synchronize_pre_loadvm(CPUState *cpu) +{ + run_on_cpu(cpu, do_nvmm_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL); +} + +/* -----------------------------------------------------------------------= --- */ + +static Error *nvmm_migration_blocker; + +static void +nvmm_ipi_signal(int sigcpu) +{ + struct qemu_vcpu *qcpu; + + if (current_cpu) { + qcpu =3D get_qemu_vcpu(current_cpu); + qcpu->stop =3D true; + } +} + +static void +nvmm_init_cpu_signals(void) +{ + struct sigaction sigact; + sigset_t set; + + /* Install the IPI handler. */ + memset(&sigact, 0, sizeof(sigact)); + sigact.sa_handler =3D nvmm_ipi_signal; + sigaction(SIG_IPI, &sigact, NULL); + + /* Allow IPIs on the current thread. */ + sigprocmask(SIG_BLOCK, NULL, &set); + sigdelset(&set, SIG_IPI); + pthread_sigmask(SIG_SETMASK, &set, NULL); +} + +int +nvmm_init_vcpu(CPUState *cpu) +{ + struct nvmm_machine *mach =3D get_nvmm_mach(); + struct nvmm_vcpu_conf_cpuid cpuid; + struct nvmm_vcpu_conf_tpr tpr; + Error *local_error =3D NULL; + struct qemu_vcpu *qcpu; + int ret, err; + + nvmm_init_cpu_signals(); + + if (nvmm_migration_blocker =3D=3D NULL) { + error_setg(&nvmm_migration_blocker, + "NVMM: Migration not supported"); + + (void)migrate_add_blocker(nvmm_migration_blocker, &local_error); + if (local_error) { + error_report_err(local_error); + migrate_del_blocker(nvmm_migration_blocker); + error_free(nvmm_migration_blocker); + return -EINVAL; + } + } + + qcpu =3D g_malloc0(sizeof(*qcpu)); + if (qcpu =3D=3D NULL) { + error_report("NVMM: Failed to allocate VCPU context."); + return -ENOMEM; + } + + ret =3D nvmm_vcpu_create(mach, cpu->cpu_index, &qcpu->vcpu); + if (ret =3D=3D -1) { + err =3D errno; + error_report("NVMM: Failed to create a virtual processor," + " error=3D%d", err); + g_free(qcpu); + return -err; + } + + memset(&cpuid, 0, sizeof(cpuid)); + cpuid.mask =3D 1; + cpuid.leaf =3D 0x00000001; + cpuid.u.mask.set.edx =3D CPUID_MCE | CPUID_MCA | CPUID_MTRR; + ret =3D nvmm_vcpu_configure(mach, &qcpu->vcpu, NVMM_VCPU_CONF_CPUID, + &cpuid); + if (ret =3D=3D -1) { + err =3D errno; + error_report("NVMM: Failed to configure a virtual processor," + " error=3D%d", err); + g_free(qcpu); + return -err; + } + + ret =3D nvmm_vcpu_configure(mach, &qcpu->vcpu, NVMM_VCPU_CONF_CALLBACK= S, + &nvmm_callbacks); + if (ret =3D=3D -1) { + err =3D errno; + error_report("NVMM: Failed to configure a virtual processor," + " error=3D%d", err); + g_free(qcpu); + return -err; + } + + if (qemu_mach.cap.arch.vcpu_conf_support & NVMM_CAP_ARCH_VCPU_CONF_TPR= ) { + memset(&tpr, 0, sizeof(tpr)); + tpr.exit_changed =3D 1; + ret =3D nvmm_vcpu_configure(mach, &qcpu->vcpu, NVMM_VCPU_CONF_TPR,= &tpr); + if (ret =3D=3D -1) { + err =3D errno; + error_report("NVMM: Failed to configure a virtual processor," + " error=3D%d", err); + g_free(qcpu); + return -err; + } + } + + cpu->vcpu_dirty =3D true; + cpu->hax_vcpu =3D (struct hax_vcpu_state *)qcpu; + + return 0; +} + +int +nvmm_vcpu_exec(CPUState *cpu) +{ + int ret, fatal; + + while (1) { + if (cpu->exception_index >=3D EXCP_INTERRUPT) { + ret =3D cpu->exception_index; + cpu->exception_index =3D -1; + break; + } + + fatal =3D nvmm_vcpu_loop(cpu); + + if (fatal) { + error_report("NVMM: Failed to execute a VCPU."); + abort(); + } + } + + return ret; +} + +void +nvmm_destroy_vcpu(CPUState *cpu) +{ + struct nvmm_machine *mach =3D get_nvmm_mach(); + struct qemu_vcpu *qcpu =3D get_qemu_vcpu(cpu); + + nvmm_vcpu_destroy(mach, &qcpu->vcpu); + g_free(cpu->hax_vcpu); +} + +/* -----------------------------------------------------------------------= --- */ + +static void +nvmm_update_mapping(hwaddr start_pa, ram_addr_t size, uintptr_t hva, + bool add, bool rom, const char *name) +{ + struct nvmm_machine *mach =3D get_nvmm_mach(); + int ret, prot; + + if (add) { + prot =3D PROT_READ | PROT_EXEC; + if (!rom) { + prot |=3D PROT_WRITE; + } + ret =3D nvmm_gpa_map(mach, hva, start_pa, size, prot); + } else { + ret =3D nvmm_gpa_unmap(mach, hva, start_pa, size); + } + + if (ret =3D=3D -1) { + error_report("NVMM: Failed to %s GPA range '%s' PA:%p, " + "Size:%p bytes, HostVA:%p, error=3D%d", + (add ? "map" : "unmap"), name, (void *)(uintptr_t)start_pa, + (void *)size, (void *)hva, errno); + } +} + +static void +nvmm_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; + uintptr_t hva; + + if (!memory_region_is_ram(mr)) { + return; + } + + /* Adjust start_pa and size so that they are page-aligned. */ + 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; + } + + hva =3D (uintptr_t)memory_region_get_ram_ptr(mr) + + section->offset_within_region + delta; + + nvmm_update_mapping(start_pa, size, hva, add, + memory_region_is_rom(mr), mr->name); +} + +static void +nvmm_region_add(MemoryListener *listener, MemoryRegionSection *section) +{ + memory_region_ref(section->mr); + nvmm_process_section(section, 1); +} + +static void +nvmm_region_del(MemoryListener *listener, MemoryRegionSection *section) +{ + nvmm_process_section(section, 0); + memory_region_unref(section->mr); +} + +static void +nvmm_transaction_begin(MemoryListener *listener) +{ + /* nothing */ +} + +static void +nvmm_transaction_commit(MemoryListener *listener) +{ + /* nothing */ +} + +static void +nvmm_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 nvmm_memory_listener =3D { + .begin =3D nvmm_transaction_begin, + .commit =3D nvmm_transaction_commit, + .region_add =3D nvmm_region_add, + .region_del =3D nvmm_region_del, + .log_sync =3D nvmm_log_sync, + .priority =3D 10, +}; + +static void +nvmm_ram_block_added(RAMBlockNotifier *n, void *host, size_t size) +{ + struct nvmm_machine *mach =3D get_nvmm_mach(); + uintptr_t hva =3D (uintptr_t)host; + int ret; + + ret =3D nvmm_hva_map(mach, hva, size); + + if (ret =3D=3D -1) { + error_report("NVMM: Failed to map HVA, HostVA:%p " + "Size:%p bytes, error=3D%d", + (void *)hva, (void *)size, errno); + } +} + +static struct RAMBlockNotifier nvmm_ram_notifier =3D { + .ram_block_added =3D nvmm_ram_block_added +}; + +/* -----------------------------------------------------------------------= --- */ + +static void +nvmm_handle_interrupt(CPUState *cpu, int mask) +{ + cpu->interrupt_request |=3D mask; + + if (!qemu_cpu_is_self(cpu)) { + qemu_cpu_kick(cpu); + } +} + +/* -----------------------------------------------------------------------= --- */ + +static int +nvmm_accel_init(MachineState *ms) +{ + int ret, err; + + ret =3D nvmm_init(); + if (ret =3D=3D -1) { + err =3D errno; + error_report("NVMM: Initialization failed, error=3D%d", errno); + return -err; + } + + ret =3D nvmm_capability(&qemu_mach.cap); + if (ret =3D=3D -1) { + err =3D errno; + error_report("NVMM: Unable to fetch capability, error=3D%d", errno= ); + return -err; + } + if (qemu_mach.cap.version !=3D 1) { + error_report("NVMM: Unsupported version %u", qemu_mach.cap.version= ); + return -EPROGMISMATCH; + } + if (qemu_mach.cap.state_size !=3D sizeof(struct nvmm_x64_state)) { + error_report("NVMM: Wrong state size %u", qemu_mach.cap.state_size= ); + return -EPROGMISMATCH; + } + + ret =3D nvmm_machine_create(&qemu_mach.mach); + if (ret =3D=3D -1) { + err =3D errno; + error_report("NVMM: Machine creation failed, error=3D%d", errno); + return -err; + } + + memory_listener_register(&nvmm_memory_listener, &address_space_memory); + ram_block_notifier_add(&nvmm_ram_notifier); + + cpu_interrupt_handler =3D nvmm_handle_interrupt; + + printf("NetBSD Virtual Machine Monitor accelerator is operational\n"); + return 0; +} + +int +nvmm_enabled(void) +{ + return nvmm_allowed; +} + +static void +nvmm_accel_class_init(ObjectClass *oc, void *data) +{ + AccelClass *ac =3D ACCEL_CLASS(oc); + ac->name =3D "NVMM"; + ac->init_machine =3D nvmm_accel_init; + ac->allowed =3D &nvmm_allowed; +} + +static const TypeInfo nvmm_accel_type =3D { + .name =3D ACCEL_CLASS_NAME("nvmm"), + .parent =3D TYPE_ACCEL, + .class_init =3D nvmm_accel_class_init, +}; + +static void +nvmm_type_init(void) +{ + type_register_static(&nvmm_accel_type); +} + +type_init(nvmm_type_init); -- 2.24.0 From nobody Fri May 3 09:01:14 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1578406755; cv=none; d=zohomail.com; s=zohoarc; b=N0kQc6YrZyih8fgRLd+r0Rp7OxNaAvhzjWt4gPPCZI8K/YpZcdWn301IwpmQarS/Sj7z5uI3vr3jv2HPMgFzXDp4xu3bnbTdS+lQSnmGh5NIB1z5HcQvta5nR2GqXQakDOnJh3MVeRfvA6f52DqlXXdlVt3gU0knLZ5Asd73fqM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1578406755; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=P9QYC2hK1U9OosH4lKrz17YD9nEjLS1NzBwXqMX1RQM=; b=E9XeC/+vaCeizhuCKI9EBzO+P8bfRUmpsD2wCuShorZJIKt8d7JB9LiuhkJgXBd9Q7PjoZ1p/UnWsQVl6MmQIrzUaPFCNyhTkDYdQI5jfjCV73vOmd6FOJmRK2Ugu72KkELQVQZPJA1HNL2qD4CfTTa5VH7TFRyG2j/SN4EYUhA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1578406755853591.0040784203263; Tue, 7 Jan 2020 06:19:15 -0800 (PST) Received: from localhost ([::1]:49578 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iophS-0000mt-2W for importer@patchew.org; Tue, 07 Jan 2020 09:19:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35861) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iooNn-0003V2-QI for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iooNm-0000tL-8X for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:51 -0500 Received: from mout.gmx.net ([212.227.15.18]:34979) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iooNl-0000r6-V8 for qemu-devel@nongnu.org; Tue, 07 Jan 2020 07:54:50 -0500 Received: from localhost.localdomain ([89.71.135.231]) by mail.gmx.com (mrgmx005 [212.227.17.184]) with ESMTPSA (Nemesis) id 1M5fMe-1in8M23BGc-007H5v; Tue, 07 Jan 2020 13:54:44 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1578401685; bh=Esy/6Z9NMXlz6p4L3fdFRS0GPpSdZw4kBhSs2vKJIV8=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=OLIdfRRGkA1fEOXI1WAMZvtjgaafqUbQdDQC3wpXYNC2yRBzzyJ89eMJCpQOfUCYY VglFqkK8o6j67ksmM6qbiS/Lz5ZQOdIPuTs5Y++JaP3gXcecNtF0Xoy248EeRZoY+r IMVRedOqjStovLh1Suc5GrcWmy0B/Bg9NCQQxyCA= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c From: Kamil Rytarowski To: qemu-devel@nongnu.org Subject: [PATCH 4/4] Add the NVMM acceleration enlightenments Date: Tue, 7 Jan 2020 13:54:01 +0100 Message-Id: <20200107125401.18126-5-n54@gmx.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107125401.18126-1-n54@gmx.com> References: <20200107125401.18126-1-n54@gmx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:vNZ6nz0iU75MIVWsUHT2AsPq62FvQ01v2ST4svHbbtuRxqgN5AZ BlnZyWsn2FN5jgGspMcwXymWa+PqVsaxscv3CiU7ZxmVnXMTsIIeyiW85cnizPumaWku7Yl e+CCtdsTEZcnWJv7laXJyB7M2QkKIfjTibQsfT8jHXYVHcwnJ0I8FNY67cgOaR+Uzur9amE unE4oP+fUwnrrN9VbW3kw== X-UI-Out-Filterresults: notjunk:1;V03:K0:XOcp1Ra8bCE=:W0c4Nc5RZAwy4zAqiBXP2r 7CAX/p4zeXc4tiMP1HDEpgXNvCi7caR9OFCtX9kM3eedW+KhFW28hdFsiQ1cfoiBwnm5F7236 jEOXa49RY7f/jm0yQ2UiZQQntaH5eNL1dyHaiiGIv1kjylwqhNcfTy5eQ3w+lpT4iL6Q4BtBm QujXpkzgm75WN3KgpMILFc36Zk258qOy+qndqzuPN7OtIHvEowL8xC8ivbWzNIBJSzZpazNXj Lg7G6boBaS+w8EiJg8yxMHasdx1B/Id1p+WqOOsHIeigSC/qBd2AyEpXvUdyxTAxmOL2SMmaO KYZprv14TinmwipAFuUJdMhq3Et2RtLsCOuZ9GPJXHkAdhdOqv55M93itbT2+hSXu/w2V9WAj zN/DHD47J9lY/4jXEe5q9EcZC4lvQs1dHYJ+5ER9fi1yen9Pg6mwGsQiOpYmsRUx2yH/+cTg5 sfJdnlVuhcAO+LggB0qPHA0pni+BtmEf+51kDNSK73pk8duZeyX9mYfHrfJZR97gtvHaNg7SR awAzwzUX0640roU1/K7pelXFbnLK1boHrWmvXq/gbwQ3hoaVfvkZ9do7KJnNPJXuodJ3/Bgc4 QfWsYJX0pJMOD/ic6JFg2O3/0lNxTby/oPUFojiwYMckkeiGAU4NUYOic89N+IVJgHO+P58mh XWDpApeHyEF1v8xHdhZQb1NgO7Hl8ZweSMjlkW6KB0vB+VJtAcs3Sy/L3kjjcaA4FMirebnx5 aPEvq/NVBFUjXQd/VEjhGjW+jHxiea4dritVmkjC0ZCIEbn8X2QIZ0q4Mdz7pGex2dgFd4Jo/ 0vwEB4JRVdZeQT9oFEJkRBFqwo47UFuNXvXpKXKnmwZvBsV/SVjwI9rCftY19dcF7xsKtm0mt n2NlMpkhwzsq2zCdyvhhongv1Y8+2ocMGEGtQxmJNOBY21YsJViAxJVoE3UTwAn9sR6aE9ICK JZXyhYZAuujNURLk42eX9b2rJKxyeSv/WRSnfUYXHiarcX7u/GFkqxvWMlwIFdt3qtYDZVaZy k19cWLFKnvDJOrIW+x8pXhtdpCbCkqxaPEkgChMl8dzi/O1FolfsLoehQeWBKjizh48ODsdc1 juuolkP//8bMaRvN5d+eRyRVSOE1KS0buICVXqE/vFAi4AO5YqrH67urF49s/Ms173OHbS1BF jze9eHJXiloIiRsmL98T6ImNEFX0debgnt+kUDPXYy+1mWwBVIauKRG+C/UzstoCUdA4XEpew /NOzSjWmGAjZizP9f9w3QVuHd9hBy1qz61F7Lig== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.15.18 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbonzini@redhat.com, Kamil Rytarowski , Maxime Villard , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Maxime Villard Implements the NVMM accelerator cpu enlightenments to actually use the nvmm= -all accelerator on NetBSD platforms. Signed-off-by: Maxime Villard Signed-off-by: Kamil Rytarowski Reviewed-by: Sergio Lopez --- cpus.c | 58 +++++++++++++++++++++++++++++++++++++++ include/sysemu/hw_accel.h | 14 ++++++++++ target/i386/helper.c | 2 +- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index b472378b70..3c3f63588c 100644 --- a/cpus.c +++ b/cpus.c @@ -42,6 +42,7 @@ #include "sysemu/hax.h" #include "sysemu/hvf.h" #include "sysemu/whpx.h" +#include "sysemu/nvmm.h" #include "exec/exec-all.h" #include "qemu/thread.h" @@ -1666,6 +1667,48 @@ static void *qemu_whpx_cpu_thread_fn(void *arg) return NULL; } +static void *qemu_nvmm_cpu_thread_fn(void *arg) +{ + CPUState *cpu =3D arg; + int r; + + assert(nvmm_enabled()); + + rcu_register_thread(); + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id =3D qemu_get_thread_id(); + current_cpu =3D cpu; + + r =3D nvmm_init_vcpu(cpu); + if (r < 0) { + fprintf(stderr, "nvmm_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 nvmm_vcpu_exec(cpu); + if (r =3D=3D EXCP_DEBUG) { + cpu_handle_guest_debug(cpu); + } + } + qemu_wait_io_event(cpu); + } while (!cpu->unplug || cpu_can_run(cpu)); + + nvmm_destroy_vcpu(cpu); + cpu->created =3D false; + qemu_cond_signal(&qemu_cpu_cond); + qemu_mutex_unlock_iothread(); + rcu_unregister_thread(); + return NULL; +} + #ifdef _WIN32 static void CALLBACK dummy_apc_func(ULONG_PTR unused) { @@ -2029,6 +2072,19 @@ static void qemu_whpx_start_vcpu(CPUState *cpu) #endif } +static void qemu_nvmm_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/NVMM", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_nvmm_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +} + static void qemu_dummy_start_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -2069,6 +2125,8 @@ void qemu_init_vcpu(CPUState *cpu) qemu_tcg_init_vcpu(cpu); } else if (whpx_enabled()) { qemu_whpx_start_vcpu(cpu); + } else if (nvmm_enabled()) { + qemu_nvmm_start_vcpu(cpu); } else { qemu_dummy_start_vcpu(cpu); } diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h index 0ec2372477..dbfa7a02f9 100644 --- a/include/sysemu/hw_accel.h +++ b/include/sysemu/hw_accel.h @@ -15,6 +15,7 @@ #include "sysemu/hax.h" #include "sysemu/kvm.h" #include "sysemu/whpx.h" +#include "sysemu/nvmm.h" static inline void cpu_synchronize_state(CPUState *cpu) { @@ -27,6 +28,9 @@ static inline void cpu_synchronize_state(CPUState *cpu) if (whpx_enabled()) { whpx_cpu_synchronize_state(cpu); } + if (nvmm_enabled()) { + nvmm_cpu_synchronize_state(cpu); + } } static inline void cpu_synchronize_post_reset(CPUState *cpu) @@ -40,6 +44,10 @@ static inline void cpu_synchronize_post_reset(CPUState *= cpu) if (whpx_enabled()) { whpx_cpu_synchronize_post_reset(cpu); } + if (nvmm_enabled()) { + nvmm_cpu_synchronize_post_reset(cpu); + } + } static inline void cpu_synchronize_post_init(CPUState *cpu) @@ -53,6 +61,9 @@ static inline void cpu_synchronize_post_init(CPUState *cp= u) if (whpx_enabled()) { whpx_cpu_synchronize_post_init(cpu); } + if (nvmm_enabled()) { + nvmm_cpu_synchronize_post_init(cpu); + } } static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) @@ -66,6 +77,9 @@ static inline void cpu_synchronize_pre_loadvm(CPUState *c= pu) if (whpx_enabled()) { whpx_cpu_synchronize_pre_loadvm(cpu); } + if (nvmm_enabled()) { + nvmm_cpu_synchronize_pre_loadvm(cpu); + } } #endif /* QEMU_HW_ACCEL_H */ diff --git a/target/i386/helper.c b/target/i386/helper.c index c3a6e4fabe..2e79d61329 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -981,7 +981,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess = access) X86CPU *cpu =3D env_archcpu(env); CPUState *cs =3D env_cpu(env); - if (kvm_enabled() || whpx_enabled()) { + if (kvm_enabled() || whpx_enabled() || nvmm_enabled()) { env->tpr_access_type =3D access; cpu_interrupt(cs, CPU_INTERRUPT_TPR); -- 2.24.0