add support for Hypervisor.framework in QEMU
v3 cover add support for Hypervisor.framework in QEMU
================
Changes in v3:
(1) Fixed licensing issues in patch 3.
(2) Revert to late adding of compilation rules in Makefile.objs (patch 8/14); files aren't ready to compile earlier.
(3) Make a single patch just for fixing style (patch 4/14).
(4) Fix data type for hvf_fd field.
(5) Add comment that return value of -1 in apic function added in 7/14 means "no interrupt".
================
================
Changes in v2:
(1) Removed legacy option "-enable-hvf" in favor of "-M accel=hvf"
(2) Added missing copyright headers; replace fprintfs for error_report; improved commit description.
(3) Moved patch that adds compilation rules in Makefile.objs right after the patch that adds the new files from Google's repo.
(4) Removed conditional macros from cpus.c and cpu.c
(5) Moved patch that fixes coding style to patch # 3
(6) Fix commit message in apic patch
(7) Squash some commits to avoid code churn
================
The following patchset adds to QEMU the supporting for macOS's native hypervisor, Hypervisor.framework (hvf). The code base is taken from Google's Android emulator at
https://android.googlesource.com/platform/external/qemu/+/emu-master-dev.
Apart from general code refactoring, some additional features were implemented:
retrieve the set of features supported by host cpu and hvf (cpuid); dirty page tracking for VGA memory area; reimplementation of the event injection mechanism to allow injection of exceptions during vmexits, which is exemplified by the injection of a GP fault when the guest vmexits due to execution of the vmcall instruction; changing the emulator's use of CPUState structure in favor of CPUX86State, so as to in the future remove data structures that are uselessly specific to hvf and unified some of the state between kvm/tcg and hvf.
Some features initially planned to implement that didn't make it include:
page fault handling in the emulator and implementing the dummy_signal to handle the SIG_IPI signal without race conditions. Hopefully these can be implemented in the near future.
Sergio Andres Gomez Del Real (14):
hvf: add support for Hypervisor.framework in the configure script
hvf: add code base from Google's QEMU repository
hvf: fix licensing issues; isolate task handling code (GPL v2-only)
hvf: run hvf code through checkpatch.pl and fix style issues
hvf: add code to cpus.c and do refactoring in preparation for
compiling
hvf: handle fields from CPUState and CPUX86State
apic: add function to apic that will be used by hvf
hvf: add compilation rules to Makefile.objs
hvf: use new helper functions for put/get xsave
hvf: implement hvf_get_supported_cpuid
hvf: refactor cpuid code
hvf: implement vga dirty page tracking
hvf: refactor event injection code for hvf
hvf: inject General Protection Fault when vmexit through vmcall
configure | 38 + cpus.c | 86 ++ hw/intc/apic.c | 12 + include/hw/i386/apic.h | 1 + include/qom/cpu.h | 2 + include/sysemu/hvf.h | 107 ++ qemu-options.hx | 10 +- target/i386/Makefile.objs | 1 + target/i386/cpu-qom.h | 4 +- target/i386/cpu.c | 79 +- target/i386/cpu.h | 38 +- target/i386/hvf-all.c | 963 +++++++++++++++ target/i386/hvf-i386.h | 48 + target/i386/hvf-utils/Makefile.objs | 1 + target/i386/hvf-utils/README.md | 7 + target/i386/hvf-utils/vmcs.h | 371 ++++++ target/i386/hvf-utils/vmx.h | 222 ++++ target/i386/hvf-utils/x86.c | 184 +++ target/i386/hvf-utils/x86.h | 476 ++++++++ target/i386/hvf-utils/x86_cpuid.c | 417 +++++++ target/i386/hvf-utils/x86_cpuid.h | 52 + target/i386/hvf-utils/x86_decode.c | 2186 +++++++++++++++++++++++++++++++++++ target/i386/hvf-utils/x86_decode.h | 325 ++++++ target/i386/hvf-utils/x86_descr.c | 124 ++ target/i386/hvf-utils/x86_descr.h | 55 + target/i386/hvf-utils/x86_emu.c | 1536 ++++++++++++++++++++++++ target/i386/hvf-utils/x86_emu.h | 49 + target/i386/hvf-utils/x86_flags.c | 333 ++++++ target/i386/hvf-utils/x86_flags.h | 243 ++++ target/i386/hvf-utils/x86_gen.h | 53 + target/i386/hvf-utils/x86_mmu.c | 273 +++++ target/i386/hvf-utils/x86_mmu.h | 45 + target/i386/hvf-utils/x86_task.c | 201 ++++ target/i386/hvf-utils/x86_task.h | 18 + target/i386/hvf-utils/x86hvf.c | 463 ++++++++ target/i386/hvf-utils/x86hvf.h | 39 + target/i386/kvm.c | 2 - 37 files changed, 9031 insertions(+), 33 deletions(-) create mode 100644 include/sysemu/hvf.h create mode 100644 target/i386/hvf-all.c create mode 100644 target/i386/hvf-i386.h create mode 100644 target/i386/hvf-utils/Makefile.objs create mode 100644 target/i386/hvf-utils/README.md create mode 100644 target/i386/hvf-utils/vmcs.h create mode 100644 target/i386/hvf-utils/vmx.h create mode 100644 target/i386/hvf-utils/x86.c create mode 100644 target/i386/hvf-utils/x86.h create mode 100644 target/i386/hvf-utils/x86_cpuid.c create mode 100644 target/i386/hvf-utils/x86_cpuid.h create mode 100644 target/i386/hvf-utils/x86_decode.c create mode 100644 target/i386/hvf-utils/x86_decode.h create mode 100644 target/i386/hvf-utils/x86_descr.c create mode 100644 target/i386/hvf-utils/x86_descr.h create mode 100644 target/i386/hvf-utils/x86_emu.c create mode 100644 target/i386/hvf-utils/x86_emu.h create mode 100644 target/i386/hvf-utils/x86_flags.c create mode 100644 target/i386/hvf-utils/x86_flags.h create mode 100644 target/i386/hvf-utils/x86_gen.h create mode 100644 target/i386/hvf-utils/x86_mmu.c create mode 100644 target/i386/hvf-utils/x86_mmu.h create mode 100644 target/i386/hvf-utils/x86_task.c create mode 100644 target/i386/hvf-utils/x86_task.h create mode 100644 target/i386/hvf-utils/x86hvf.c create mode 100644 target/i386/hvf-utils/x86hvf.h
Signature · 1 line
2.14.1
PATCH v3 1/14 hvf: add support for Hypervisor.framework in the configure script
This patch adds to the configure script the code to support the --enable-hvf argument. If the OS is Darwin, it checks for presence of HVF in the system. The patch also adds strings related to HVF in the file qemu-options.hx.
QEMU will only support the modern syntax style '-M accel=hvf' no enable hvf; the legacy '-enable-hvf' will not be supported.
--- configure | 38 ++++++++++++++++++++++++++++++++++++++ qemu-options.hx | 10 +++++----- 2 files changed, 43 insertions(+), 5 deletions(-)
configure +38 -0
@@ -211,6 +211,17 @@ supported_xen_target() { return 1 } +supported_hvf_target() { + test "$hvf" = "yes" || return 1 + glob "$1" "*-softmmu" || return 1 + case "${1%-softmmu}" in + x86_64) + return 0 + ;; + esac + return 1 +} + supported_target() { case "$1" in *-softmmu)
@@ -236,6 +247,7 @@ supported_target() { supported_kvm_target "$1" && return 0 supported_xen_target "$1" && return 0 supported_hax_target "$1" && return 0 + supported_hvf_target "$1" && return 0 print_error "TCG disabled, but hardware accelerator not available for '$target'" return 1 }
@@ -309,6 +321,7 @@ vhost_vsock="no" vhost_user="" kvm="no" hax="no" +hvf="no" rdma="" gprof="no" debug_tcg="no"
@@ -727,6 +740,7 @@ Darwin) bsd="yes" darwin="yes" hax="yes" + hvf="yes" LDFLAGS_SHARED="-bundle -undefined dynamic_lookup" if [ "$cpu" = "x86_64" ] ; then QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
@@ -1027,6 +1041,10 @@ for opt do ;; --enable-hax) hax="yes" ;; + --disable-hvf) hvf="no" + ;; + --enable-hvf) hvf="yes" + ;; --disable-tcg-interpreter) tcg_interpreter="no" ;; --enable-tcg-interpreter) tcg_interpreter="yes"
@@ -1499,6 +1517,7 @@ disabled with --disable-FEATURE, default is enabled if available: bluez bluez stack connectivity kvm KVM acceleration support hax HAX acceleration support + hvf Hypervisor.framework acceleration support rdma RDMA-based migration support vde support for vde network netmap support for netmap network
@@ -4900,6 +4919,21 @@ then fi +################################################# +# Check to see if we have the Hypervisor framework +if [ "$darwin" == "yes" ] ; then + cat > $TMPC << EOF +#include <Hypervisor/hv.h> +int main() { return 0;} +EOF + if ! compile_object ""; then + hvf='no' + else + hvf='yes' + LDFLAGS="-framework Hypervisor $LDFLAGS" + fi +fi + ################################################# # Sparc implicitly links with --relax, which is # incompatible with -r, so --no-relax should be
@@ -5356,6 +5390,7 @@ if test "$tcg" = "yes" ; then echo "TCG debug enabled $debug_tcg" echo "TCG interpreter $tcg_interpreter" fi +echo "HVF support $hvf" echo "RDMA support $rdma" echo "fdt support $fdt" echo "preadv support $preadv"
@@ -6388,6 +6423,9 @@ fi if supported_hax_target $target; then echo "CONFIG_HAX=y" >> $config_target_mak fi +if supported_hvf_target $target; then + echo "CONFIG_HVF=y" >> $config_target_mak +fi if test "$target_bigendian" = "yes" ; then echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak fi
qemu-options.hx +5 -5
@@ -31,7 +31,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ "-machine [type=]name[,prop[=value][,...]]\n" " selects emulated machine ('-machine help' for list)\n" " property accel=accel1[:accel2[:...]] selects accelerator\n" - " supported accelerators are kvm, xen, hax or tcg (default: tcg)\n" + " supported accelerators are kvm, xen, hax, hvf or tcg (default: tcg)\n" " kernel_irqchip=on|off|split controls accelerated irqchip support (default=off)\n" " vmport=on|off|auto controls emulation of vmport (default: auto)\n" " kvm_shadow_mem=size of KVM shadow MMU in bytes\n"
@@ -66,7 +66,7 @@ Supported machine properties are: @table @option @item accel=@var{accels1}[:@var{accels2}[:...]] This is used to enable an accelerator. Depending on the target architecture, -kvm, xen, hax or tcg can be available. By default, tcg is used. If there is +kvm, xen, hax, hvf 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=on|off
@@ -120,13 +120,13 @@ ETEXI DEF("accel", HAS_ARG, QEMU_OPTION_accel, "-accel [accel=]accelerator[,thread=single|multi]\n" - " select accelerator (kvm, xen, hax or tcg; use 'help' for a list)\n" - " thread=single|multi (enable multi-threaded TCG)\n", QEMU_ARCH_ALL) + " select accelerator (kvm, xen, hax, hvf or tcg; use 'help' for a list)\n" + " thread=single|multi (enable multi-threaded TCG)", QEMU_ARCH_ALL) STEXI @item -accel @var{name}[,prop=@var{value}[,...]] @findex -accel This is used to enable an accelerator. Depending on the target architecture, -kvm, xen, hax or tcg can be available. By default, tcg is used. If there is +kvm, xen, hax, hvf 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
Signature · 1 line
2.14.1
PATCH v3 2/14 hvf: add code base from Google's QEMU repository
In reply to Sergio Andres Gomez Del RealThis file begins tracking the files that will be the code base for HVF support in QEMU. This code base is part of Google's QEMU version of their Android emulator, and can be found at
https://android.googlesource.com/platform/external/qemu/+/emu-master-dev
This code is based on Veertu Inc's vdhh (Veertu Desktop Hosted Hypervisor), found at https://github.com/veertuinc/vdhh. Everything is appropriately licensed under GPL v2-or-later, except for the code inside x86_task.c and x86_task.h, which, deriving from KVM (the Linux kernel), is licensed GPL v2-only.
This code base already implements a very great deal of functionality, although Google's version removed from Vertuu's the support for APIC page and hyperv-related stuff. According to the Android Emulator Release Notes, Revision 26.1.3 (August 2017), "Hypervisor.framework is now enabled by default on macOS for 32-bit x86 images to improve performance and macOS compatibility", although we better use with caution for, as the same Revision warns us, "If you experience issues with it specifically, please file a bug report...". The code hasn't seen much update in the last 5 months, so I think that we can further develop the code with occasional visiting Google's repository to see if there has been any update.
The code's style isn't aligned to QEMU's standards; this will be fixed in a subsequent patch in this series.
On top of this code base we are implementing the following features: fix the code that passes the cpuid features to the guest; implementing dirty page tracking for vga memory region; reimplementing the event injection mechanism for exception injection and many other minor fixes/refactoring that are documented in their respective patches. It is important to note that this patch still doesn't add rules for compiling these files, because some glue code in cpus.c and other issues need to be handled before the HVF files compile cleanly. This will be done in subsequent patches.
--- cpus.c | 42 + include/sysemu/hvf.h | 99 +++ target/i386/hvf-all.c | 1000 +++++++++++++++++++++ target/i386/hvf-i386.h | 48 + target/i386/hvf-utils/Makefile.objs | 1 + target/i386/hvf-utils/README.md | 7 + target/i386/hvf-utils/vmcs.h | 368 ++++++++ target/i386/hvf-utils/vmx.h | 200 +++++ target/i386/hvf-utils/x86.c | 174 ++++ target/i386/hvf-utils/x86.h | 470 ++++++++++ target/i386/hvf-utils/x86_cpuid.c | 270 ++++++ target/i386/hvf-utils/x86_cpuid.h | 51 ++ target/i386/hvf-utils/x86_decode.c | 1659 +++++++++++++++++++++++++++++++++++ target/i386/hvf-utils/x86_decode.h | 314 +++++++ target/i386/hvf-utils/x86_descr.c | 124 +++ target/i386/hvf-utils/x86_descr.h | 40 + target/i386/hvf-utils/x86_emu.c | 1466 +++++++++++++++++++++++++++++++ target/i386/hvf-utils/x86_emu.h | 33 + target/i386/hvf-utils/x86_flags.c | 317 +++++++ target/i386/hvf-utils/x86_flags.h | 218 +++++ target/i386/hvf-utils/x86_gen.h | 53 ++ target/i386/hvf-utils/x86_mmu.c | 254 ++++++ target/i386/hvf-utils/x86_mmu.h | 45 + target/i386/hvf-utils/x86hvf.c | 501 +++++++++++ target/i386/hvf-utils/x86hvf.h | 36 + 25 files changed, 7790 insertions(+) create mode 100644 include/sysemu/hvf.h create mode 100644 target/i386/hvf-all.c create mode 100644 target/i386/hvf-i386.h create mode 100644 target/i386/hvf-utils/Makefile.objs create mode 100644 target/i386/hvf-utils/README.md create mode 100644 target/i386/hvf-utils/vmcs.h create mode 100644 target/i386/hvf-utils/vmx.h create mode 100644 target/i386/hvf-utils/x86.c create mode 100644 target/i386/hvf-utils/x86.h create mode 100644 target/i386/hvf-utils/x86_cpuid.c create mode 100644 target/i386/hvf-utils/x86_cpuid.h create mode 100644 target/i386/hvf-utils/x86_decode.c create mode 100644 target/i386/hvf-utils/x86_decode.h create mode 100644 target/i386/hvf-utils/x86_descr.c create mode 100644 target/i386/hvf-utils/x86_descr.h create mode 100644 target/i386/hvf-utils/x86_emu.c create mode 100644 target/i386/hvf-utils/x86_emu.h create mode 100644 target/i386/hvf-utils/x86_flags.c create mode 100644 target/i386/hvf-utils/x86_flags.h create mode 100644 target/i386/hvf-utils/x86_gen.h create mode 100644 target/i386/hvf-utils/x86_mmu.c create mode 100644 target/i386/hvf-utils/x86_mmu.h create mode 100644 target/i386/hvf-utils/x86hvf.c create mode 100644 target/i386/hvf-utils/x86hvf.h
cpus.c +42 -0
@@ -1434,6 +1434,48 @@ static void *qemu_hax_cpu_thread_fn(void *arg)return NULL ; } +/* The HVF-specific vCPU thread function. This one should only run when the host +* CPU supports the VMX "unrestricted guest" feature. */ +static void *qemu_hvf_cpu_thread_fn (void *arg) +{ +CPUState *cpu = arg; + +int r; + +assert (hvf_enabled ()); + +rcu_register_thread (); + +qemu_mutex_lock_iothread (); +qemu_thread_get_self (cpu->thread); + + cpu->thread_id =qemu_get_thread_id (); + cpu->can_do_io =1 ; + current_cpu = cpu; + +hvf_init_vcpu (cpu); + +/* signal CPU creation */ + cpu->created = true; +qemu_cond_signal (&qemu_cpu_cond); + +do { +if (cpu_can_run (cpu)) { + r =hvf_vcpu_exec (cpu); +if (r ==EXCP_DEBUG ) { +cpu_handle_guest_debug (cpu); + } + } +qemu_hvf_wait_io_event (cpu); + }while (!cpu->unplug ||cpu_can_run (cpu)); + +hvf_vcpu_destroy (cpu); + cpu->created = false; +qemu_cond_signal (&qemu_cpu_cond); +qemu_mutex_unlock_iothread (); +return NULL ; +} +#ifdef _WIN32 static void CALLBACK dummy_apc_func(ULONG_PTR unused) {
include/sysemu/hvf.h new file +99 -0
99 lines not on this page · raw message
target/i386/hvf-all.c new file +1000 -0
1,000 lines not on this page · raw message
target/i386/hvf-i386.h new file +48 -0
48 lines not on this page · raw message
target/i386/hvf-utils/Makefile.objs new file +1 -0
@@ -0,0 +1 @@ +obj-y += x86.o x86_cpuid.o x86_decode.o x86_descr.o x86_emu.o x86_flags.o x86_mmu.o x86hvf.o
target/i386/hvf-utils/README.md new file +7 -0
@@ -0,0 +1,7 @@ +# OS X Hypervisor.framework support in QEMU + +These sources (and ../hvf-all.c) are adapted from Veertu Inc's vdhh (Veertu Desktop Hosted Hypervisor) (last known location: https://github.com/veertuinc/vdhh) with some minor changes, the most significant of which were: + +1. Adapt to our current QEMU's `CPUState` structure and `address_space_rw` API; many struct members have been moved around (emulated x86 state, kvm_xsave_buf) due to historical differences + QEMU needing to handle more emulation targets. +2. Removal of `apic_page` and hyperv-related functionality. +3. More relaxed use of `qemu_mutex_lock_iothread`.
target/i386/hvf-utils/vmcs.h new file +368 -0
368 lines not on this page · raw message
target/i386/hvf-utils/vmx.h new file +200 -0
200 lines not on this page · raw message
target/i386/hvf-utils/x86.c new file +174 -0
174 lines not on this page · raw message
target/i386/hvf-utils/x86.h new file +470 -0
470 lines not on this page · raw message
target/i386/hvf-utils/x86_cpuid.c new file +270 -0
270 lines not on this page · raw message
target/i386/hvf-utils/x86_cpuid.h new file +51 -0
51 lines not on this page · raw message
target/i386/hvf-utils/x86_decode.c new file +1659 -0
264 lines not on this page · raw message
target/i386/hvf-utils/x86_decode.h new file +314 -0
314 lines not on this page · raw message
target/i386/hvf-utils/x86_descr.c new file +124 -0
124 lines not on this page · raw message
target/i386/hvf-utils/x86_descr.h new file +40 -0
Lines of this file are not shown. View the raw message.
target/i386/hvf-utils/x86_emu.c new file +1466 -0
1,466 lines not on this page · raw message
target/i386/hvf-utils/x86_emu.h new file +33 -0
Lines of this file are not shown. View the raw message.
target/i386/hvf-utils/x86_flags.c new file +317 -0
317 lines not on this page · raw message
target/i386/hvf-utils/x86_flags.h new file +218 -0
218 lines not on this page · raw message
target/i386/hvf-utils/x86_gen.h new file +53 -0
53 lines not on this page · raw message
target/i386/hvf-utils/x86_mmu.c new file +254 -0
254 lines not on this page · raw message
target/i386/hvf-utils/x86_mmu.h new file +45 -0
45 lines not on this page · raw message
target/i386/hvf-utils/x86hvf.c new file +501 -0
501 lines not on this page · raw message
target/i386/hvf-utils/x86hvf.h new file +36 -0
Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.14.1
Part of the diff is not shown here. View the raw message.
PATCH v3 3/14 hvf: fix licensing issues; isolate task handling code (GPL v2-only)
In reply to Sergio Andres Gomez Del RealThis patch replaces the license header for those files that were either GPL v2-or-v3, or GPL v2-only; the replacing license is GPL v2-or-later. The code for task switching/handling, which is derived from KVM and hence is GPL v2-only, is isolated in the new files (with this license) x86_task.c/.h
--- target/i386/hvf-all.c | 173 +++---------------------------- target/i386/hvf-utils/Makefile.objs | 2 +- target/i386/hvf-utils/vmx.h | 14 +-- target/i386/hvf-utils/x86.c | 14 +-- target/i386/hvf-utils/x86.h | 14 +-- target/i386/hvf-utils/x86_cpuid.c | 6 +- target/i386/hvf-utils/x86_cpuid.h | 14 +-- target/i386/hvf-utils/x86_decode.c | 14 +-- target/i386/hvf-utils/x86_decode.h | 14 +-- target/i386/hvf-utils/x86_descr.c | 14 +-- target/i386/hvf-utils/x86_descr.h | 14 +-- target/i386/hvf-utils/x86_emu.c | 14 +-- target/i386/hvf-utils/x86_emu.h | 14 +-- target/i386/hvf-utils/x86_gen.h | 14 +-- target/i386/hvf-utils/x86_mmu.c | 14 +-- target/i386/hvf-utils/x86_mmu.h | 14 +-- target/i386/hvf-utils/x86_task.c | 201 ++++++++++++++++++++++++++++++++++++ target/i386/hvf-utils/x86_task.h | 18 ++++ target/i386/hvf-utils/x86hvf.c | 14 +-- target/i386/hvf-utils/x86hvf.h | 14 +-- 20 files changed, 340 insertions(+), 270 deletions(-) create mode 100644 target/i386/hvf-utils/x86_task.c create mode 100644 target/i386/hvf-utils/x86_task.h
target/i386/hvf-all.c +12 -161
@@ -5,15 +5,19 @@// Copyright 2017 The Android Open Source Project // // QEMU Hypervisor.framework support -// -// This software is licensed under the terms of the GNU General Public -// License version 2, as published by the Free Software Foundation, and -// may be copied, distributed, and modified under those terms. -// +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this program; if not, see <http://www.gnu.org/licenses/>. #include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/error-report.h"
@@ -28,6 +32,7 @@#include "hvf-utils/x86_decode.h" #include "hvf-utils/x86_emu.h" #include "hvf-utils/x86_cpuid.h" +#include "hvf-utils/x86_task.h" #include "hvf-utils/x86hvf.h" #include <Hypervisor/hv.h>
@@ -224,160 +229,6 @@ void update_apic_tpr(CPUState *cpu)#define VECTORING_INFO_VECTOR_MASK 0xff -// TODO: taskswitch handling -static void save_state_to_tss32 (CPUState *cpu,struct x86_tss_segment32 *tss) -{ -/* CR3 and ldt selector are not saved intentionally */ - tss->eip =EIP (cpu); - tss->eflags =EFLAGS (cpu); - tss->eax =EAX (cpu); - tss->ecx =ECX (cpu); - tss->edx =EDX (cpu); - tss->ebx =EBX (cpu); - tss->esp =ESP (cpu); - tss->ebp =EBP (cpu); - tss->esi =ESI (cpu); - tss->edi =EDI (cpu); - - tss->es =vmx_read_segment_selector (cpu,REG_SEG_ES ).sel; - tss->cs =vmx_read_segment_selector (cpu,REG_SEG_CS ).sel; - tss->ss =vmx_read_segment_selector (cpu,REG_SEG_SS ).sel; - tss->ds =vmx_read_segment_selector (cpu,REG_SEG_DS ).sel; - tss->fs =vmx_read_segment_selector (cpu,REG_SEG_FS ).sel; - tss->gs =vmx_read_segment_selector (cpu,REG_SEG_GS ).sel; -} - -static void load_state_from_tss32 (CPUState *cpu,struct x86_tss_segment32 *tss) -{ -wvmcs (cpu->hvf_fd,VMCS_GUEST_CR3 , tss->cr3); - -RIP (cpu) = tss->eip; -EFLAGS (cpu) = tss->eflags |2 ; - -/* General purpose registers */ -RAX (cpu) = tss->eax; -RCX (cpu) = tss->ecx; -RDX (cpu) = tss->edx; -RBX (cpu) = tss->ebx; -RSP (cpu) = tss->esp; -RBP (cpu) = tss->ebp; -RSI (cpu) = tss->esi; -RDI (cpu) = tss->edi; - -vmx_write_segment_selector (cpu, (x68_segment_selector ){{tss->ldt}},REG_SEG_LDTR ); -vmx_write_segment_selector (cpu, (x68_segment_selector ){{tss->es}},REG_SEG_ES ); -vmx_write_segment_selector (cpu, (x68_segment_selector ){{tss->cs}},REG_SEG_CS ); -vmx_write_segment_selector (cpu, (x68_segment_selector ){{tss->ss}},REG_SEG_SS ); -vmx_write_segment_selector (cpu, (x68_segment_selector ){{tss->ds}},REG_SEG_DS ); -vmx_write_segment_selector (cpu, (x68_segment_selector ){{tss->fs}},REG_SEG_FS ); -vmx_write_segment_selector (cpu, (x68_segment_selector ){{tss->gs}},REG_SEG_GS ); - -#if 0 -load_segment (cpu,REG_SEG_LDTR , tss->ldt); -load_segment (cpu,REG_SEG_ES , tss->es); -load_segment (cpu,REG_SEG_CS , tss->cs); -load_segment (cpu,REG_SEG_SS , tss->ss); -load_segment (cpu,REG_SEG_DS , tss->ds); -load_segment (cpu,REG_SEG_FS , tss->fs); -load_segment (cpu,REG_SEG_GS , tss->gs); -#endif -} - -static int task_switch_32 (CPUState *cpu,x68_segment_selector tss_sel,x68_segment_selector old_tss_sel, -uint64_t old_tss_base,struct x86_segment_descriptor *new_desc) -{ -struct x86_tss_segment32 tss_seg; -uint32_t new_tss_base =x86_segment_base (new_desc); -uint32_t eip_offset = offsetof(struct x86_tss_segment32 , eip); -uint32_t ldt_sel_offset = offsetof(struct x86_tss_segment32 , ldt); - -vmx_read_mem (cpu, &tss_seg, old_tss_base,sizeof (tss_seg)); -save_state_to_tss32 (cpu, &tss_seg); - -vmx_write_mem (cpu, old_tss_base + eip_offset, &tss_seg.eip, ldt_sel_offset - eip_offset); -vmx_read_mem (cpu, &tss_seg, new_tss_base,sizeof (tss_seg)); - -if (old_tss_sel.sel !=0xffff ) { - tss_seg.prev_tss = old_tss_sel.sel; - -vmx_write_mem (cpu, new_tss_base, &tss_seg.prev_tss,sizeof (tss_seg.prev_tss)); - } -load_state_from_tss32 (cpu, &tss_seg); -return 0 ; -} - -static void vmx_handle_task_switch (CPUState *cpu,x68_segment_selector tss_sel,int reason,bool gate_valid,uint8_t gate,uint64_t gate_type) -{ -uint64_t rip =rreg (cpu->hvf_fd,HV_X86_RIP ); -if (!gate_valid || (gate_type !=VMCS_INTR_T_HWEXCEPTION && - gate_type !=VMCS_INTR_T_HWINTR && - gate_type !=VMCS_INTR_T_NMI )) { -int ins_len =rvmcs (cpu->hvf_fd,VMCS_EXIT_INSTRUCTION_LENGTH ); -macvm_set_rip (cpu, rip + ins_len); -return ; - } - -load_regs (cpu); - -struct x86_segment_descriptor curr_tss_desc, next_tss_desc; -int ret; -x68_segment_selector old_tss_sel =vmx_read_segment_selector (cpu,REG_SEG_TR ); -uint64_t old_tss_base =vmx_read_segment_base (cpu,REG_SEG_TR ); -uint32_t desc_limit; -struct x86_call_gate task_gate_desc; -struct vmx_segment vmx_seg; - -x86_read_segment_descriptor (cpu, &next_tss_desc, tss_sel); -x86_read_segment_descriptor (cpu, &curr_tss_desc, old_tss_sel); - -if (reason ==TSR_IDT_GATE && gate_valid) { -int dpl; - - ret =x86_read_call_gate (cpu, &task_gate_desc, gate); - - dpl = task_gate_desc.dpl; -x68_segment_selector cs =vmx_read_segment_selector (cpu,REG_SEG_CS ); -if (tss_sel.rpl > dpl || cs.rpl > dpl) - ;//DPRINTF("emulate_gp"); - } - - desc_limit =x86_segment_limit (&next_tss_desc); -if (!next_tss_desc.p || ((desc_limit <0x67 && (next_tss_desc.type &8 )) || desc_limit <0x2b )) { -VM_PANIC ("emulate_ts" ); - } - -if (reason ==TSR_IRET || reason ==TSR_JMP ) { - curr_tss_desc.type &= ~(1 <<1 );/* clear busy flag */ -x86_write_segment_descriptor (cpu, &curr_tss_desc, old_tss_sel); - } - -if (reason ==TSR_IRET ) -EFLAGS (cpu) &= ~RFLAGS_NT ; - -if (reason !=TSR_CALL && reason !=TSR_IDT_GATE ) - old_tss_sel.sel =0xffff ; - -if (reason !=TSR_IRET ) { - next_tss_desc.type |= (1 <<1 );/* set busy flag */ -x86_write_segment_descriptor (cpu, &next_tss_desc, tss_sel); - } - -if (next_tss_desc.type &8 ) - ret =task_switch_32 (cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc); -else -//ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc); -VM_PANIC ("task_switch_16" ); - -macvm_set_cr0 (cpu->hvf_fd,rvmcs (cpu->hvf_fd,VMCS_GUEST_CR0 ) |CR0_TS ); -x86_segment_descriptor_to_vmx (cpu, tss_sel, &next_tss_desc, &vmx_seg); -vmx_write_segment_descriptor (cpu, &vmx_seg,REG_SEG_TR ); - -store_regs (cpu); - -hv_vcpu_invalidate_tlb (cpu->hvf_fd); -hv_vcpu_flush (cpu->hvf_fd); -} -static void hvf_handle_interrupt (CPUState * cpu,int mask) { cpu->interrupt_request |= mask;
target/i386/hvf-utils/Makefile.objs +1 -1
@@ -1 +1 @@ -obj-y += x86.o x86_cpuid.o x86_decode.o x86_descr.o x86_emu.o x86_flags.o x86_mmu.o x86hvf.o +obj-y += x86.o x86_cpuid.o x86_decode.o x86_descr.o x86_emu.o x86_flags.o x86_mmu.o x86hvf.o x86_task.o
target/i386/hvf-utils/vmx.h +7 -7
@@ -6,17 +6,17 @@* Interfaces to Hypervisor.framework to read/write X86 registers and VMCS. * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef VMX_H
target/i386/hvf-utils/x86.c +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h"
target/i386/hvf-utils/x86.h +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Veertu Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #pragma once
target/i386/hvf-utils/x86_cpuid.c +3 -3
@@ -4,18 +4,18 @@* Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2017 Google Inc. * -* This library is free software; you can redistribute it and/or +* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * -* This library is distributed in the hope that it will be useful, +* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, see <http://www.gnu.org/licenses/>. +* License along with this program; if not, see <http://www.gnu.org/licenses/>. * * cpuid */
target/i386/hvf-utils/x86_cpuid.h +7 -7
@@ -2,17 +2,17 @@* Copyright (C) 2016 Veertu Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __CPUID_H__#define __CPUID_H__
target/i386/hvf-utils/x86_decode.c +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h"
target/i386/hvf-utils/x86_decode.h +7 -7
@@ -2,17 +2,17 @@* Copyright (C) 2016 Veertu Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #pragma once
target/i386/hvf-utils/x86_descr.c +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h"
target/i386/hvf-utils/x86_descr.h +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #pragma once
target/i386/hvf-utils/x86_emu.c +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ /////////////////////////////////////////////////////////////////////////
target/i386/hvf-utils/x86_emu.h +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __X86_EMU_H__#define __X86_EMU_H__
target/i386/hvf-utils/x86_gen.h +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __X86_GEN_H__#define __X86_GEN_H__
target/i386/hvf-utils/x86_mmu.c +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h"
target/i386/hvf-utils/x86_mmu.h +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __X86_MMU_H__#define __X86_MMU_H__
target/i386/hvf-utils/x86_task.c new file +201 -0
201 lines not on this page · raw message
target/i386/hvf-utils/x86_task.h new file +18 -0
@@ -0,0 +1,18 @@ +/* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 or +* (at your option) version 3 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, see <http://www.gnu.org/licenses/>. +*/ +#ifndef HVF_TASK +#define HVF_TASK +void vmx_handle_task_switch (CPUState *cpu,x68_segment_selector tss_sel, +int reason,bool gate_valid,uint8_t gate,uint64_t gate_type); +#endif
target/i386/hvf-utils/x86hvf.c +7 -7
@@ -4,17 +4,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h"
target/i386/hvf-utils/x86hvf.h +7 -7
@@ -3,17 +3,17 @@* Copyright (C) 2017 Google Inc, * * This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 or -* (at your option) version 3 of the License. +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* You should have received a copy of the GNU General Public License along -* with this program; if not, see <http://www.gnu.org/licenses/>. +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef X86HVF_H #define X86HVF_H
Signature · 1 line
2.14.1
PATCH v3 4/14 hvf: run hvf code through checkpatch.pl and fix style issues
In reply to Sergio Andres Gomez Del Real--- include/sysemu/hvf.h | 19 +- target/i386/hvf-all.c | 647 +++++----- target/i386/hvf-i386.h | 2 +- target/i386/hvf-utils/vmcs.h | 484 ++++---- target/i386/hvf-utils/vmx.h | 92 +- target/i386/hvf-utils/x86.c | 80 +- target/i386/hvf-utils/x86.h | 110 +- target/i386/hvf-utils/x86_cpuid.c | 337 ++--- target/i386/hvf-utils/x86_cpuid.h | 5 +- target/i386/hvf-utils/x86_decode.c | 2378 ++++++++++++++++++++++-------------- target/i386/hvf-utils/x86_decode.h | 26 +- target/i386/hvf-utils/x86_descr.h | 23 +- target/i386/hvf-utils/x86_emu.c | 1324 ++++++++++---------- target/i386/hvf-utils/x86_flags.c | 52 +- target/i386/hvf-utils/x86_flags.h | 99 +- target/i386/hvf-utils/x86_mmu.c | 81 +- target/i386/hvf-utils/x86_mmu.h | 6 +- target/i386/hvf-utils/x86hvf.c | 53 +- target/i386/hvf-utils/x86hvf.h | 3 +- 19 files changed, 3285 insertions(+), 2536 deletions(-)
include/sysemu/hvf.h +9 -10
@@ -58,17 +58,16 @@ hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);/* Returns 1 if HVF is available and enabled, 0 otherwise. */ int hvf_enabled (void ); - -/* Disable HVF if |disable| is 1, otherwise, enable it iff it is supported by the host CPU. -* Use hvf_enabled() after this to get the result. */ +/* Disable HVF if |disable| is 1, otherwise, enable it iff it is supported by +* the host CPU. Use hvf_enabled() after this to get the result. */ void hvf_disable (int disable); -/* Returns non-0 if the host CPU supports the VMX "unrestricted guest" feature which -* allows the virtual CPU to directly run in "real mode". If true, this allows QEMU to run -* several vCPU threads in parallel (see cpus.c). Otherwise, only a a single TCG thread -* can run, and it will call HVF to run the current instructions, except in case of -* "real mode" (paging disabled, typically at boot time), or MMIO operations. */ -// int hvf_ug_platform(void); does not apply to HVF; assume we must be in UG mode +/* Returns non-0 if the host CPU supports the VMX "unrestricted guest" feature +* which allows the virtual CPU to directly run in "real mode". If true, this +* allows QEMU to run several vCPU threads in parallel (see cpus.c). Otherwise, +* only a a single TCG thread can run, and it will call HVF to run the current +* instructions, except in case of "real mode" (paging disabled, typically at +* boot time), or MMIO operations. */ int hvf_sync_vcpus (void );
@@ -82,7 +81,7 @@ void _hvf_cpu_synchronize_post_init(CPUState *, run_on_cpu_data);void hvf_vcpu_destroy (CPUState *);void hvf_raise_event (CPUState *); -// void hvf_reset_vcpu_state(void *opaque); +/* void hvf_reset_vcpu_state(void *opaque); */ void vmx_reset_vcpu (CPUState *);void __hvf_cpu_synchronize_state (CPUState *,run_on_cpu_data );void __hvf_cpu_synchronize_post_reset (CPUState *,run_on_cpu_data );
target/i386/hvf-all.c +334 -313
861 lines not on this page · raw message
target/i386/hvf-i386.h +1 -1
@@ -41,7 +41,7 @@ struct hvf_state {/* Functions exported to host specific mode */ /* Host specific functions */ -int hvf_inject_interrupt (CPUArchState * env,int vector); +int hvf_inject_interrupt (CPUArchState *env,int vector);int hvf_vcpu_run (struct hvf_vcpu_state *vcpu);#endif
target/i386/hvf-utils/vmcs.h +242 -242
578 lines not on this page · raw message
target/i386/hvf-utils/vmx.h +53 -39
194 lines not on this page · raw message
target/i386/hvf-utils/x86.c +44 -36
136 lines not on this page · raw message
target/i386/hvf-utils/x86.h +58 -52
226 lines not on this page · raw message
target/i386/hvf-utils/x86_cpuid.c +173 -164
361 lines not on this page · raw message
target/i386/hvf-utils/x86_cpuid.h +3 -2
@@ -44,8 +44,9 @@ struct x86_cpuid {struct CPUState ; -void init_cpuid (struct CPUState * cpu); -void get_cpuid_func (struct CPUState *cpu,int func,int cnt,uint32_t *eax,uint32_t *ebx,uint32_t *ecx,uint32_t *edx); +void init_cpuid (struct CPUState *cpu); +void get_cpuid_func (struct CPUState *cpu,int func,int cnt,uint32_t *eax, +uint32_t *ebx,uint32_t *ecx,uint32_t *edx);#endif /* __CPUID_H__ */
target/i386/hvf-utils/x86_decode.c +1452 -926
592 lines not on this page · raw message
target/i386/hvf-utils/x86_emu.c +696 -628
1,324 lines not on this page · raw message
target/i386/hvf-utils/x86_flags.c +34 -18
52 lines not on this page · raw message
target/i386/hvf-utils/x86_flags.h +63 -36
99 lines not on this page · raw message
target/i386/hvf-utils/x86_mmu.c +50 -31
81 lines not on this page · raw message
target/i386/hvf-utils/x86hvf.c +34 -19
53 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.14.1
Part of the diff is not shown here. View the raw message.
PATCH v3 5/14 hvf: add code to cpus.c and do refactoring in preparation for compiling
In reply to Sergio Andres Gomez Del RealThe files originally added from Google's repository in previous patches won't compile cleanly unless some glue code is added to cpus.c and some other reorganization is done. This patch adds that code and does some general refactoring in preparation for compiling in subsequent patches.
--- cpus.c | 44 +++++++++++++++++++ include/sysemu/hvf.h | 22 ++++++---- target/i386/hvf-all.c | 89 +++++++++++++++------------------------ target/i386/hvf-utils/x86.c | 2 +- target/i386/hvf-utils/x86_cpuid.h | 2 +- target/i386/hvf-utils/x86_descr.h | 6 +++ target/i386/hvf-utils/x86_emu.c | 5 +-- target/i386/hvf-utils/x86_emu.h | 15 +++++++ target/i386/hvf-utils/x86_flags.h | 2 + target/i386/hvf-utils/x86hvf.c | 3 -- target/i386/hvf-utils/x86hvf.h | 2 + 11 files changed, 120 insertions(+), 72 deletions(-)
cpus.c +44 -0
@@ -37,6 +37,7 @@#include "sysemu/hw_accel.h" #include "sysemu/kvm.h" #include "sysemu/hax.h" +#include "sysemu/hvf.h" #include "qmp-commands.h" #include "exec/exec-all.h"
@@ -900,6 +901,9 @@ void cpu_synchronize_all_states(void)CPU_FOREACH (cpu) {cpu_synchronize_state (cpu); +if (hvf_enabled ()) { +hvf_cpu_synchronize_state (cpu); + } } }
@@ -909,6 +913,9 @@ void cpu_synchronize_all_post_reset(void)CPU_FOREACH (cpu) {cpu_synchronize_post_reset (cpu); +if (hvf_enabled ()) { +hvf_cpu_synchronize_post_reset (cpu); + } } }
@@ -918,6 +925,9 @@ void cpu_synchronize_all_post_init(void)CPU_FOREACH (cpu) {cpu_synchronize_post_init (cpu); +if (hvf_enabled ()) { +hvf_cpu_synchronize_post_init (cpu); + } } }
@@ -1098,6 +1108,14 @@ static void qemu_kvm_wait_io_event(CPUState *cpu)qemu_wait_io_event_common (cpu); } +static void qemu_hvf_wait_io_event (CPUState *cpu) +{ +while (cpu_thread_is_idle (cpu)) { +qemu_cond_wait (cpu->halt_cond, &qemu_global_mutex); + } +qemu_wait_io_event_common (cpu); +} +static void *qemu_kvm_cpu_thread_fn (void *arg) {CPUState *cpu = arg;
@@ -1564,6 +1582,9 @@ static void qemu_cpu_kick_thread(CPUState *cpu)fprintf (stderr,"qemu:%s: %s" , __func__,strerror (err)); exit(1); } +if (hvf_enabled ()) { +cpu_exit (cpu); + }#else /* _WIN32 */ if (!qemu_cpu_is_self (cpu)) {if (!QueueUserAPC (dummy_apc_func, cpu->hThread,0 )) {
@@ -1780,6 +1801,27 @@ static void qemu_kvm_start_vcpu(CPUState *cpu) } } +static void qemu_hvf_start_vcpu (CPUState *cpu) +{ +char thread_name[VCPU_THREAD_NAME_SIZE ]; + +/* HVF currently does not support TCG, and only runs in +* unrestricted-guest mode. */ +assert (hvf_enabled ()); + + cpu->thread =g_malloc0 (sizeof (QemuThread)); + cpu->halt_cond =g_malloc0 (sizeof (QemuCond)); +qemu_cond_init (cpu->halt_cond); + +snprintf (thread_name,VCPU_THREAD_NAME_SIZE ,"CPU %d/HVF" , + cpu->cpu_index); +qemu_thread_create (cpu->thread, thread_name, qemu_hvf_cpu_thread_fn, + cpu,QEMU_THREAD_JOINABLE ); +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 ];
@@ -1816,6 +1858,8 @@ void qemu_init_vcpu(CPUState *cpu)qemu_kvm_start_vcpu (cpu); }else if (hax_enabled ()) {qemu_hax_start_vcpu (cpu); + }else if (hvf_enabled ()) { +qemu_hvf_start_vcpu (cpu); }else if (tcg_enabled ()) {qemu_tcg_init_vcpu (cpu); }else {
include/sysemu/hvf.h +13 -9
@@ -15,15 +15,24 @@#include "config-host.h" #include "qemu/osdep.h" #include "qemu-common.h" -#include "hw/hw.h" -#include "target/i386/cpu.h" #include "qemu/bitops.h" #include "exec/memory.h" #include "sysemu/accel.h" + +extern int hvf_disabled; +#ifdef CONFIG_HVF #include <Hypervisor/hv.h> #include <Hypervisor/hv_vmx.h> #include <Hypervisor/hv_error.h> - +#include "target/i386/cpu.h" +#include "hw/hw.h" +uint32_t hvf_get_supported_cpuid (uint32_t func,uint32_t idx, +int reg); +#define hvf_enabled () !hvf_disabled +#else +#define hvf_enabled () 0 +#define hvf_get_supported_cpuid (func, idx, reg) 0 +#endif typedef struct hvf_slot { uint64_t start;
@@ -41,7 +50,6 @@ struct hvf_vcpu_caps {uint64_t vmx_cap_preemption_timer; }; -int __hvf_set_memory (hvf_slot *); typedef struct HVFState { AccelState parent; hvf_slot slots[32];
@@ -56,8 +64,6 @@ void hvf_handle_io(CPUArchState *, uint16_t, void *, int, int, int);hvf_slot *hvf_find_overlap_slot (uint64_t ,uint64_t ); -/* Returns 1 if HVF is available and enabled, 0 otherwise. */ -int hvf_enabled (void );/* Disable HVF if |disable| is 1, otherwise, enable it iff it is supported by * the host CPU. Use hvf_enabled() after this to get the result. */ void hvf_disable (int disable);
@@ -83,12 +89,10 @@ void hvf_vcpu_destroy(CPUState *);void hvf_raise_event (CPUState *);/* void hvf_reset_vcpu_state(void *opaque); */ void vmx_reset_vcpu (CPUState *); -void __hvf_cpu_synchronize_state (CPUState *,run_on_cpu_data ); -void __hvf_cpu_synchronize_post_reset (CPUState *,run_on_cpu_data );void vmx_update_tpr (CPUState *);void update_apic_tpr (CPUState *); -int apic_get_highest_priority_irr (DeviceState *);int hvf_put_registers (CPUState *); +void vmx_clear_int_window_exiting (CPUState *cpu);#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
target/i386/hvf-all.c +35 -54
189 lines not on this page · raw message
target/i386/hvf-utils/x86.c +1 -1
@@ -26,7 +26,7 @@#include "x86_mmu.h" #include "x86_descr.h" -static uint32_t x86_segment_access_rights (struct x86_segment_descriptor *var) +/* static uint32_t x86_segment_access_rights(struct x86_segment_descriptor *var) { uint32_t ar;
target/i386/hvf-utils/x86_cpuid.h +1 -1
@@ -35,7 +35,7 @@ struct x86_cpuid {uint32_t features, ext_features, ext2_features, ext3_features;uint32_t kvm_features, svm_features;uint32_t xlevel; -char model_id[48 ]; +char model_id[50 ];int vendor_override;uint32_t flags;uint32_t xlevel2;
target/i386/hvf-utils/x86_descr.h +6 -0
@@ -47,3 +47,9 @@ void x86_segment_descriptor_to_vmx(struct CPUState *cpu,x68_segment_selector selector, struct x86_segment_descriptor *desc, struct vmx_segment *vmx_desc); + +uint32_t vmx_read_segment_limit (CPUState *cpu,x86_reg_segment seg); +uint32_t vmx_read_segment_ar (CPUState *cpu,x86_reg_segment seg); +void vmx_segment_to_x86_descriptor (struct CPUState *cpu, +struct vmx_segment *vmx_desc, +struct x86_segment_descriptor *desc);
target/i386/hvf-utils/x86_emu.c +1 -4
@@ -45,7 +45,6 @@#include "vmcs.h" #include "vmx.h" -static void print_debug (struct CPUState *cpu);void hvf_handle_io (struct CPUState *cpu,uint16_t port,void *data,int direction,int size,uint32_t count);
@@ -1473,13 +1472,11 @@ void load_regs(struct CPUState *cpu)RRX (cpu,REG_RBP ) =rreg (cpu->hvf_fd,HV_X86_RBP );for (i =8 ; i <16 ; i++) {RRX (cpu, i) =rreg (cpu->hvf_fd,HV_X86_RAX + i); - } +RFLAGS (cpu) =rreg (cpu->hvf_fd,HV_X86_RFLAGS );rflags_to_lflags (cpu);RIP (cpu) =rreg (cpu->hvf_fd,HV_X86_RIP ); - -//print_debug(cpu); }void store_regs (struct CPUState *cpu)
target/i386/hvf-utils/x86_emu.h +15 -0
@@ -30,4 +30,19 @@ void store_regs(struct CPUState *cpu);void simulate_rdmsr (struct CPUState *cpu);void simulate_wrmsr (struct CPUState *cpu); +addr_t read_reg (struct CPUState *cpu,int reg,int size); +void write_reg (struct CPUState *cpu,int reg,addr_t val,int size); +addr_t read_val_from_reg (addr_t reg_ptr,int size); +void write_val_to_reg (addr_t reg_ptr,addr_t val,int size); +void write_val_ext (struct CPUState *cpu,addr_t ptr,addr_t val,int size); +uint8_t *read_mmio (struct CPUState *cpu,addr_t ptr,int bytes); +addr_t read_val_ext (struct CPUState *cpu,addr_t ptr,int size); + +void exec_movzx (struct CPUState *cpu,struct x86_decode *decode); +void exec_shl (struct CPUState *cpu,struct x86_decode *decode); +void exec_movsx (struct CPUState *cpu,struct x86_decode *decode); +void exec_ror (struct CPUState *cpu,struct x86_decode *decode); +void exec_rol (struct CPUState *cpu,struct x86_decode *decode); +void exec_rcl (struct CPUState *cpu,struct x86_decode *decode); +void exec_rcr (struct CPUState *cpu,struct x86_decode *decode);#endif
target/i386/hvf-utils/x86_flags.h +2 -0
@@ -242,4 +242,6 @@ void SET_FLAGS_SHL32(struct CPUState *cpu, uint32_t v, int count, uint32_t res);void SET_FLAGS_SHL16 (struct CPUState *cpu,uint16_t v,int count,uint16_t res);void SET_FLAGS_SHL8 (struct CPUState *cpu,uint8_t v,int count,uint8_t res); +bool _get_OF (struct CPUState *cpu); +bool _get_CF (struct CPUState *cpu);#endif /* __X86_FLAGS_H__ */
target/i386/hvf-utils/x86hvf.c +0 -3
@@ -35,8 +35,6 @@#include <Hypervisor/hv_vmx.h> #include <stdint.h> -void hvf_cpu_synchronize_state (struct CPUState * cpu_state); -void hvf_set_segment (struct CPUState *cpu,struct vmx_segment *vmx_seg,SegmentCache *qseg,bool is_tr) {
@@ -112,7 +110,6 @@ void hvf_put_xsave(CPUState *cpu_state) } } -void vmx_update_tpr (CPUState *cpu);void hvf_put_segments (CPUState *cpu_state) {CPUX86State *env = &X86_CPU (cpu_state)->env;
target/i386/hvf-utils/x86hvf.h +2 -0
@@ -34,4 +34,6 @@ void hvf_get_xsave(CPUState *cpu_state);void hvf_get_msrs (CPUState *cpu_state);void vmx_clear_int_window_exiting (CPUState *cpu);void hvf_get_segments (CPUState *cpu_state); +void vmx_update_tpr (CPUState *cpu); +void hvf_cpu_synchronize_state (CPUState *cpu_state);#endif
Signature · 1 line
2.14.1
PATCH v3 6/14 hvf: handle fields from CPUState and CPUX86State
In reply to Sergio Andres Gomez Del RealThis commit is a small refactoring of hvf's emulation code: it moves the HVFX86EmulatorState field to CPUX86State, and in general changes, for the emulation functions, the parameter with signature 'CPUState *' for 'CPUX86State *' so we don't have to get the 'env' (which is what we really need) through the 'cpu' everytime.
This commit also adds some fields specific to hvf in CPUState and CPUX86State. It also adds some handy #defines.
--- include/qom/cpu.h | 2 + target/i386/cpu.h | 38 ++- target/i386/hvf-all.c | 73 ++-- target/i386/hvf-utils/x86.c | 4 +- target/i386/hvf-utils/x86.h | 34 +- target/i386/hvf-utils/x86_decode.c | 363 ++++++++++---------- target/i386/hvf-utils/x86_decode.h | 23 +- target/i386/hvf-utils/x86_emu.c | 681 +++++++++++++++++++------------------ target/i386/hvf-utils/x86_emu.h | 29 +- target/i386/hvf-utils/x86_flags.c | 194 +++++------ target/i386/hvf-utils/x86_flags.h | 106 +++--- target/i386/hvf-utils/x86hvf.c | 16 +- 12 files changed, 801 insertions(+), 762 deletions(-)
include/qom/cpu.h +2 -0
@@ -407,6 +407,8 @@ struct CPUState {* unnecessary flushes. */ uint16_t pending_tlb_flush; + +int hvf_fd; };QTAILQ_HEAD (CPUTailQ, CPUState);
target/i386/cpu.h +34 -4
@@ -23,6 +23,9 @@#include "qemu-common.h" #include "cpu-qom.h" #include "standard-headers/asm-x86/hyperv.h" +#if defined(CONFIG_HVF ) +#include "target/i386/hvf-utils/x86.h" +#endif #ifdef TARGET_X86_64 #define TARGET_LONG_BITS 64
@@ -82,16 +85,20 @@#define R_GS 5/* segment descriptor fields */ -#define DESC_G_MASK (1 << 23) +#define DESC_G_SHIFT 23 +#define DESC_G_MASK (1 << DESC_G_SHIFT)#define DESC_B_SHIFT 22#define DESC_B_MASK (1 << DESC_B_SHIFT)#define DESC_L_SHIFT 21/* x86_64 only : 64 bit code segment */ #define DESC_L_MASK (1 << DESC_L_SHIFT) -#define DESC_AVL_MASK (1 << 20) -#define DESC_P_MASK (1 << 15) +#define DESC_AVL_SHIFT 20 +#define DESC_AVL_MASK (1 << DESC_AVL_SHIFT) +#define DESC_P_SHIFT 15 +#define DESC_P_MASK (1 << DESC_P_SHIFT)#define DESC_DPL_SHIFT 13#define DESC_DPL_MASK (3 << DESC_DPL_SHIFT) -#define DESC_S_MASK (1 << 12) +#define DESC_S_SHIFT 12 +#define DESC_S_MASK (1 << DESC_S_SHIFT)#define DESC_TYPE_SHIFT 8#define DESC_TYPE_MASK (15 << DESC_TYPE_SHIFT)#define DESC_A_MASK (1 << 8)
@@ -631,6 +638,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];#define CPUID_7_0_EBX_AVX512BW (1U << 30)/* AVX-512 Byte and Word Instructions */ #define CPUID_7_0_EBX_AVX512VL (1U << 31)/* AVX-512 Vector Length Extensions */ +#define CPUID_7_0_ECX_AVX512BMI (1U << 1)#define CPUID_7_0_ECX_VBMI (1U << 1)/* AVX-512 Vector Byte Manipulation Instrs */ #define CPUID_7_0_ECX_UMIP (1U << 2)#define CPUID_7_0_ECX_PKU (1U << 3)
@@ -806,6 +814,20 @@ typedef struct SegmentCache { float64 _d_##n[(bits)/64]; \ } +typedef union { +uint8_t _b[16 ]; +uint16_t _w[8 ]; +uint32_t _l[4 ]; +uint64_t _q[2 ]; +}XMMReg ; + +typedef union { +uint8_t _b[32 ]; +uint16_t _w[16 ]; +uint32_t _l[8 ]; +uint64_t _q[4 ]; +}YMMReg ; + typedef MMREG_UNION(ZMMReg, 512) ZMMReg; typedef MMREG_UNION(MMXReg, 64) MMXReg;
@@ -1041,7 +1063,11 @@ typedef struct CPUX86State {ZMMReg xmm_t0;MMXReg mmx_t0; +XMMReg ymmh_regs[CPU_NB_REGS ]; +uint64_t opmask_regs[NB_OPMASK_REGS ]; +YMMReg zmmh_regs[CPU_NB_REGS ]; +ZMMReg hi16_zmm_regs[CPU_NB_REGS ];/* sysenter registers */ uint32_t sysenter_cs;
@@ -1164,11 +1190,15 @@ typedef struct CPUX86State {int32_t interrupt_injected;uint8_t soft_interrupt;uint8_t has_error_code; +uint32_t ins_len;uint32_t sipi_vector;bool tsc_valid;int64_t tsc_khz;int64_t user_tsc_khz;/* for sanity check only */ void *kvm_xsave_buf; +#if defined(CONFIG_HVF ) +HVFX86EmulatorState *hvf_emul; +#endif uint64_t mcg_cap;uint64_t mcg_ctl;
target/i386/hvf-all.c +37 -36
200 lines not on this page · raw message
target/i386/hvf-utils/x86.c +3 -1
@@ -127,7 +127,9 @@ bool x86_is_real(struct CPUState *cpu)bool x86_is_v8086 (struct CPUState *cpu) { -return x86_is_protected (cpu) && (RFLAGS (cpu) &RFLAGS_VM ); +X86CPU *x86_cpu =X86_CPU (cpu); +CPUX86State *env = &x86_cpu->env; +return x86_is_protected (cpu) && (RFLAGS (env) &RFLAGS_VM ); }bool x86_is_long_mode (struct CPUState *cpu)
target/i386/hvf-utils/x86.h +17 -17
@@ -23,7 +23,7 @@#include <sys/mman.h> #include <stdarg.h> #include "qemu-common.h" -#include "x86_flags.h" +#include "x86_gen.h" /* exceptions */ typedef enum x86_exception {
@@ -356,13 +356,14 @@ typedef struct x68_segment_selector { }; } __attribute__ ((__packed__)) x68_segment_selector; +typedef struct lazy_flags { +addr_t result; +addr_t auxbits; +}lazy_flags ; +/* Definition of hvf_x86_state is here */ -struct hvf_x86_state { -int hlt; -uint64_t init_tsc; - +typedef struct HVFX86EmulatorState { int interruptable; -uint64_t exp_rip; uint64_t fetch_rip; uint64_t rip; struct x86_register regs[16];
@@ -370,8 +371,7 @@ struct hvf_x86_state {struct lazy_flags lflags;struct x86_efer efer;uint8_t mmio_buf[4096 ]; -uint8_t *apic_page; -}; +} HVFX86EmulatorState;/* * hvf xsave area
@@ -381,12 +381,12 @@ struct hvf_xsave_buf { };/* useful register access macros */ -#define RIP (cpu) (cpu->hvf_x86->rip) -#define EIP (cpu) ((uint32_t)cpu->hvf_x86->rip) -#define RFLAGS (cpu) (cpu->hvf_x86->rflags.rflags) -#define EFLAGS (cpu) (cpu->hvf_x86->rflags.eflags) +#define RIP (cpu) (cpu->hvf_emul->rip) +#define EIP (cpu) ((uint32_t)cpu->hvf_emul->rip) +#define RFLAGS (cpu) (cpu->hvf_emul->rflags.rflags) +#define EFLAGS (cpu) (cpu->hvf_emul->rflags.eflags) -#define RRX (cpu, reg) (cpu->hvf_x86->regs[reg].rrx) +#define RRX (cpu, reg) (cpu->hvf_emul->regs[reg].rrx)#define RAX (cpu) RRX(cpu, REG_RAX)#define RCX (cpu) RRX(cpu, REG_RCX)#define RDX (cpu) RRX(cpu, REG_RDX)
@@ -404,7 +404,7 @@ struct hvf_xsave_buf {#define R14 (cpu) RRX(cpu, REG_R14)#define R15 (cpu) RRX(cpu, REG_R15) -#define ERX (cpu, reg) (cpu->hvf_x86->regs[reg].erx) +#define ERX (cpu, reg) (cpu->hvf_emul->regs[reg].erx)#define EAX (cpu) ERX(cpu, REG_RAX)#define ECX (cpu) ERX(cpu, REG_RCX)#define EDX (cpu) ERX(cpu, REG_RDX)
@@ -414,7 +414,7 @@ struct hvf_xsave_buf {#define ESI (cpu) ERX(cpu, REG_RSI)#define EDI (cpu) ERX(cpu, REG_RDI) -#define RX (cpu, reg) (cpu->hvf_x86->regs[reg].rx) +#define RX (cpu, reg) (cpu->hvf_emul->regs[reg].rx)#define AX (cpu) RX(cpu, REG_RAX)#define CX (cpu) RX(cpu, REG_RCX)#define DX (cpu) RX(cpu, REG_RDX)
@@ -424,13 +424,13 @@ struct hvf_xsave_buf {#define SI (cpu) RX(cpu, REG_RSI)#define DI (cpu) RX(cpu, REG_RDI) -#define RL (cpu, reg) (cpu->hvf_x86->regs[reg].lx) +#define RL (cpu, reg) (cpu->hvf_emul->regs[reg].lx)#define AL (cpu) RL(cpu, REG_RAX)#define CL (cpu) RL(cpu, REG_RCX)#define DL (cpu) RL(cpu, REG_RDX)#define BL (cpu) RL(cpu, REG_RBX) -#define RH (cpu, reg) (cpu->hvf_x86->regs[reg].hx) +#define RH (cpu, reg) (cpu->hvf_emul->regs[reg].hx)#define AH (cpu) RH(cpu, REG_RAX)#define CH (cpu) RH(cpu, REG_RCX)#define DH (cpu) RH(cpu, REG_RDX)
target/i386/hvf-utils/x86_decode.c +182 -181
974 lines not on this page · raw message
target/i386/hvf-utils/x86_decode.h +12 -11
@@ -23,6 +23,7 @@#include <stdarg.h> #include "qemu-common.h" #include "x86.h" +#include "cpu.h" typedef enum x86_prefix { /* group 1 */
@@ -304,21 +305,21 @@ typedef struct x86_decode {uint64_t sign (uint64_t val,int size); -uint32_t decode_instruction (CPUState *cpu,struct x86_decode *decode); +uint32_t decode_instruction (CPUX86State *env,struct x86_decode *decode); -addr_t get_reg_ref (CPUState *cpu,int reg,int is_extended,int size); -addr_t get_reg_val (CPUState *cpu,int reg,int is_extended,int size); -void calc_modrm_operand (CPUState *cpu,struct x86_decode *decode, +addr_t get_reg_ref (CPUX86State *env,int reg,int is_extended,int size); +addr_t get_reg_val (CPUX86State *env,int reg,int is_extended,int size); +void calc_modrm_operand (CPUX86State *env,struct x86_decode *decode,struct x86_decode_op *op); -addr_t decode_linear_addr (struct CPUState *cpu,struct x86_decode *decode, +addr_t decode_linear_addr (CPUX86State *env,struct x86_decode *decode,addr_t addr,x86_reg_segment seg); -void init_decoder (CPUState *cpu); -void calc_modrm_operand16 (CPUState *cpu,struct x86_decode *decode, +void init_decoder (void ); +void calc_modrm_operand16 (CPUX86State *env,struct x86_decode *decode,struct x86_decode_op *op); -void calc_modrm_operand32 (CPUState *cpu,struct x86_decode *decode, +void calc_modrm_operand32 (CPUX86State *env,struct x86_decode *decode,struct x86_decode_op *op); -void calc_modrm_operand64 (CPUState *cpu,struct x86_decode *decode, +void calc_modrm_operand64 (CPUX86State *env,struct x86_decode *decode,struct x86_decode_op *op); -void set_addressing_size (CPUState *cpu,struct x86_decode *decode); -void set_operand_size (CPUState *cpu,struct x86_decode *decode); +void set_addressing_size (CPUX86State *env,struct x86_decode *decode); +void set_operand_size (CPUX86State *env,struct x86_decode *decode);
target/i386/hvf-utils/x86_emu.c +343 -338
1,475 lines not on this page · raw message
target/i386/hvf-utils/x86_emu.h +15 -14
@@ -20,9 +20,10 @@#include "x86.h" #include "x86_decode.h" +#include "cpu.h" -void init_emu (struct CPUState *cpu); -bool exec_instruction (struct CPUState *cpu,struct x86_decode *ins); +void init_emu (void ); +bool exec_instruction (struct CPUX86State *env,struct x86_decode *ins);void load_regs (struct CPUState *cpu);void store_regs (struct CPUState *cpu);
@@ -30,19 +31,19 @@ void store_regs(struct CPUState *cpu);void simulate_rdmsr (struct CPUState *cpu);void simulate_wrmsr (struct CPUState *cpu); -addr_t read_reg (struct CPUState *cpu,int reg,int size); -void write_reg (struct CPUState *cpu,int reg,addr_t val,int size); +addr_t read_reg (CPUX86State *env,int reg,int size); +void write_reg (CPUX86State *env,int reg,addr_t val,int size);addr_t read_val_from_reg (addr_t reg_ptr,int size);void write_val_to_reg (addr_t reg_ptr,addr_t val,int size); -void write_val_ext (struct CPUState *cpu,addr_t ptr,addr_t val,int size); -uint8_t *read_mmio (struct CPUState *cpu,addr_t ptr,int bytes); -addr_t read_val_ext (struct CPUState *cpu,addr_t ptr,int size); +void write_val_ext (struct CPUX86State *env,addr_t ptr,addr_t val,int size); +uint8_t *read_mmio (struct CPUX86State *env,addr_t ptr,int bytes); +addr_t read_val_ext (struct CPUX86State *env,addr_t ptr,int size); -void exec_movzx (struct CPUState *cpu,struct x86_decode *decode); -void exec_shl (struct CPUState *cpu,struct x86_decode *decode); -void exec_movsx (struct CPUState *cpu,struct x86_decode *decode); -void exec_ror (struct CPUState *cpu,struct x86_decode *decode); -void exec_rol (struct CPUState *cpu,struct x86_decode *decode); -void exec_rcl (struct CPUState *cpu,struct x86_decode *decode); -void exec_rcr (struct CPUState *cpu,struct x86_decode *decode); +void exec_movzx (struct CPUX86State *env,struct x86_decode *decode); +void exec_shl (struct CPUX86State *env,struct x86_decode *decode); +void exec_movsx (struct CPUX86State *env,struct x86_decode *decode); +void exec_ror (struct CPUX86State *env,struct x86_decode *decode); +void exec_rol (struct CPUX86State *env,struct x86_decode *decode); +void exec_rcl (struct CPUX86State *env,struct x86_decode *decode); +void exec_rcr (struct CPUX86State *env,struct x86_decode *decode);#endif
target/i386/hvf-utils/x86_flags.c +97 -97
81 lines not on this page · raw message
target/i386/hvf-utils/x86_flags.h +51 -55
106 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.14.1
Part of the diff is not shown here. View the raw message.
PATCH v3 7/14 apic: add function to apic that will be used by hvf
In reply to Sergio Andres Gomez Del RealThis commit adds the function apic_get_highest_priority_irr to apic.c and exports it through the interface in apic.h for use by hvf.
--- hw/intc/apic.c | 12 ++++++++++++ include/hw/i386/apic.h | 1 + 2 files changed, 13 insertions(+)
hw/intc/apic.c +12 -0
@@ -305,6 +305,18 @@ static void apic_set_tpr(APICCommonState *s, uint8_t val) } } +int apic_get_highest_priority_irr (DeviceState *dev) +{ +APICCommonState *s; + +if (!dev) { +/* no interrupts */ +return -1 ; + } + s =APIC_COMMON (dev); +return get_highest_priority_int (s->irr); +} +static uint8_t apic_get_tpr (APICCommonState *s) {apic_sync_vapic (s,SYNC_FROM_VAPIC );
include/hw/i386/apic.h +1 -0
@@ -20,6 +20,7 @@ void apic_init_reset(DeviceState *s);void apic_sipi (DeviceState *s);void apic_poll_irq (DeviceState *d);void apic_designate_bsp (DeviceState *d,bool bsp); +int apic_get_highest_priority_irr (DeviceState *dev);/* pc.c */ DeviceState *cpu_get_current_apic (void );
Signature · 1 line
2.14.1
PATCH v3 8/14 hvf: add compilation rules to Makefile.objs
In reply to Sergio Andres Gomez Del RealThis commit adds to target/i386/Makefile.objs the necessary rules so that the new files for hvf are compiled by the build system. It also adds handling of the -enable-hvf argument in the main function in vl.c.
--- target/i386/Makefile.objs | 1 + 1 file changed, 1 insertion(+)
target/i386/Makefile.objs +1 -0
@@ -12,4 +12,5 @@ obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-windows.o endif ifdef CONFIG_DARWIN obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-darwin.o +obj-$(CONFIG_HVF) += hvf-utils/ hvf-all.o endif
Signature · 1 line
2.14.1
Re: [Qemu-devel] [PATCH v3 08/14] hvf: add compilation rules to Makefile.objs
Note that until this patch (8/14) there is no compiling. I tried to put this patch earlier in the patchset but found difficulties because some things need to be done before the hvf code compiles well.
Also, the commit message needs to be updated (remove the -enable-hvf part).
Quoted 24 lines · Sergio Andres Gomez Del Real
This commit adds to target/i386/Makefile.objs the necessary rules so that the new files for hvf are compiled by the build system. It also adds handling of the -enable-hvf argument in the main function in
vl.c.Signed-off-by Sergio Andres Gomez Del Real <[email protected]>--- target/i386/Makefile.objs | 1 + 1 file changed, 1 insertion(+)target/i386/Makefile.objs +1
-1@@ -12,4 +12,5 @@ obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-windows.o endif ifdef CONFIG_DARWIN obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-darwin.o +obj-$(CONFIG_HVF) += hvf-utils/ hvf-all.o endif --2.14.1
Re: [Qemu-devel] [PATCH v3 08/14] hvf: add compilation rules to Makefile.objs
Stefan, is this acceptable? I mean delaying the compiling; up until patch 7 no hvf code is compiled. Or should I just squash everything from patch 2 to 7?
El 4/09/2017 23:03, "Sergio Andrés Gómez del Real" < [email protected]> escribió:
Note that until this patch (8/14) there is no compiling. I tried to put this patch earlier in the patchset but found difficulties because some things need to be done before the hvf code compiles well.
Also, the commit message needs to be updated (remove the -enable-hvf part).
Quoted 24 lines · Sergio Andres Gomez Del Real
This commit adds to target/i386/Makefile.objs the necessary rules so that the new files for hvf are compiled by the build system. It also adds handling of the -enable-hvf argument in the main function in
vl.c.Signed-off-by Sergio Andres Gomez Del Real <[email protected]>--- target/i386/Makefile.objs | 1 + 1 file changed, 1 insertion(+)target/i386/Makefile.objs +1
-1@@ -12,4 +12,5 @@ obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-windows.o endif ifdef CONFIG_DARWIN obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-darwin.o +obj-$(CONFIG_HVF) += hvf-utils/ hvf-all.o endif --2.14.1
Re: [Qemu-devel] [PATCH v3 08/14] hvf: add compilation rules to Makefile.objs
Quoted 3 lines · Sergio Andrés Gómez del Real
Stefan, is this acceptable? I mean delaying the compiling; up until patch 7 no hvf code is compiled. Or should I just squash everything from patch 2 to 7?
It's okay. Feel free to delay until patch 7 for now.
There is value in importing code verbatim and making changes in separate patches. That way it's easy to diff the code against the upstream source to verify that it was imported correctly.
Stefan
PATCH v3 9/14 hvf: use new helper functions for put/get xsave
In reply to Sergio Andres Gomez Del RealThis commit makes use of the helper functions for handling xsave in xsave_helper.c, which are shared with kvm.
--- target/i386/hvf-utils/x86hvf.c | 63 ++++++------------------------------------ 1 file changed, 8 insertions(+), 55 deletions(-)
target/i386/hvf-utils/x86hvf.c +8 -55
@@ -76,36 +76,13 @@ void hvf_get_segment(SegmentCache *qseg, struct vmx_segment *vmx_seg)void hvf_put_xsave (CPUState *cpu_state) { -int x;struct hvf_xsave_buf *xsave; - + xsave =X86_CPU (cpu_state)->env.kvm_xsave_buf; -memset (xsave,0 ,sizeof (*xsave)); - -memcpy (&xsave->data[4 ], &X86_CPU (cpu_state)->env.fpdp,sizeof (X86_CPU (cpu_state)->env.fpdp)); -memcpy (&xsave->data[2 ], &X86_CPU (cpu_state)->env.fpip,sizeof (X86_CPU (cpu_state)->env.fpip)); -memcpy (&xsave->data[8 ], &X86_CPU (cpu_state)->env.fpregs,sizeof (X86_CPU (cpu_state)->env.fpregs)); -memcpy (&xsave->data[144 ], &X86_CPU (cpu_state)->env.ymmh_regs,sizeof (X86_CPU (cpu_state)->env.ymmh_regs)); -memcpy (&xsave->data[288 ], &X86_CPU (cpu_state)->env.zmmh_regs,sizeof (X86_CPU (cpu_state)->env.zmmh_regs)); -memcpy (&xsave->data[272 ], &X86_CPU (cpu_state)->env.opmask_regs,sizeof (X86_CPU (cpu_state)->env.opmask_regs)); -memcpy (&xsave->data[240 ], &X86_CPU (cpu_state)->env.bnd_regs,sizeof (X86_CPU (cpu_state)->env.bnd_regs)); -memcpy (&xsave->data[256 ], &X86_CPU (cpu_state)->env.bndcs_regs,sizeof (X86_CPU (cpu_state)->env.bndcs_regs)); -memcpy (&xsave->data[416 ], &X86_CPU (cpu_state)->env.hi16_zmm_regs,sizeof (X86_CPU (cpu_state)->env.hi16_zmm_regs)); - - xsave->data[0 ] = (uint16_t )X86_CPU (cpu_state)->env.fpuc; - xsave->data[0 ] |= (X86_CPU (cpu_state)->env.fpus <<16 ); - xsave->data[0 ] |= (X86_CPU (cpu_state)->env.fpstt &7 ) <<11 ; - -for (x =0 ; x <8 ; ++x) - xsave->data[1 ] |= ((!X86_CPU (cpu_state)->env.fptags[x]) << x); - xsave->data[1 ] |= (uint32_t )(X86_CPU (cpu_state)->env.fpop <<16 ); - -memcpy (&xsave->data[40 ], &X86_CPU (cpu_state)->env.xmm_regs,sizeof (X86_CPU (cpu_state)->env.xmm_regs)); - - xsave->data[6 ] =X86_CPU (cpu_state)->env.mxcsr; - *(uint64_t *)&xsave->data[128 ] =X86_CPU (cpu_state)->env.xstate_bv; - -if (hv_vcpu_write_fpstate (cpu_state->hvf_fd, xsave->data,4096 )){ + +x86_cpu_xsave_all_areas (X86_CPU (cpu_state), xsave); + +if (hv_vcpu_write_fpstate (cpu_state->hvf_fd, xsave->data,4096 )) {abort (); } }
@@ -187,39 +164,15 @@ void hvf_put_msrs(CPUState *cpu_state)void hvf_get_xsave (CPUState *cpu_state) { -int x;struct hvf_xsave_buf *xsave; - + xsave =X86_CPU (cpu_state)->env.kvm_xsave_buf; - +if (hv_vcpu_read_fpstate (cpu_state->hvf_fd, xsave->data,4096 )) {abort (); } -memcpy (&X86_CPU (cpu_state)->env.fpdp, &xsave->data[4 ],sizeof (X86_CPU (cpu_state)->env.fpdp)); -memcpy (&X86_CPU (cpu_state)->env.fpip, &xsave->data[2 ],sizeof (X86_CPU (cpu_state)->env.fpip)); -memcpy (&X86_CPU (cpu_state)->env.fpregs, &xsave->data[8 ],sizeof (X86_CPU (cpu_state)->env.fpregs)); -memcpy (&X86_CPU (cpu_state)->env.ymmh_regs, &xsave->data[144 ],sizeof (X86_CPU (cpu_state)->env.ymmh_regs)); -memcpy (&X86_CPU (cpu_state)->env.zmmh_regs, &xsave->data[288 ],sizeof (X86_CPU (cpu_state)->env.zmmh_regs)); -memcpy (&X86_CPU (cpu_state)->env.opmask_regs, &xsave->data[272 ],sizeof (X86_CPU (cpu_state)->env.opmask_regs)); -memcpy (&X86_CPU (cpu_state)->env.bnd_regs, &xsave->data[240 ],sizeof (X86_CPU (cpu_state)->env.bnd_regs)); -memcpy (&X86_CPU (cpu_state)->env.bndcs_regs, &xsave->data[256 ],sizeof (X86_CPU (cpu_state)->env.bndcs_regs)); -memcpy (&X86_CPU (cpu_state)->env.hi16_zmm_regs, &xsave->data[416 ],sizeof (X86_CPU (cpu_state)->env.hi16_zmm_regs)); - - -X86_CPU (cpu_state)->env.fpuc = (uint16_t )xsave->data[0 ]; -X86_CPU (cpu_state)->env.fpus = (uint16_t )(xsave->data[0 ] >>16 ); -X86_CPU (cpu_state)->env.fpstt = (X86_CPU (cpu_state)->env.fpus >>11 ) &7 ; -X86_CPU (cpu_state)->env.fpop = (uint16_t )(xsave->data[1 ] >>16 ); - -for (x =0 ; x <8 ; ++x) -X86_CPU (cpu_state)->env.fptags[x] = - ((((uint16_t )xsave->data[1 ] >> x) &1 ) ==0 ); - -memcpy (&X86_CPU (cpu_state)->env.xmm_regs, &xsave->data[40 ],sizeof (X86_CPU (cpu_state)->env.xmm_regs)); - -X86_CPU (cpu_state)->env.mxcsr = xsave->data[6 ]; -X86_CPU (cpu_state)->env.xstate_bv = *(uint64_t *)&xsave->data[128 ]; +x86_cpu_xrstor_all_areas (X86_CPU (cpu_state), xsave); }void hvf_get_segments (CPUState *cpu_state)
Signature · 1 line
2.14.1
PATCH v3 10/14 hvf: implement hvf_get_supported_cpuid
In reply to Sergio Andres Gomez Del RealThis commit implements hvf_get_supported_cpuid, which returns the set of features supported by both the host processor and the hypervisor.
--- target/i386/hvf-utils/x86_cpuid.c | 138 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+)
target/i386/hvf-utils/x86_cpuid.c +138 -0
@@ -24,6 +24,7 @@#include "x86_cpuid.h" #include "x86.h" #include "vmx.h" +#include "sysemu/hvf.h" #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \ CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
@@ -94,6 +95,27 @@ struct x86_cpuid builtin_cpus[] = {static struct x86_cpuid *_cpuid; +static uint64_t xgetbv (uint32_t xcr) +{ +uint32_t eax, edx; + + __asm__volatile ("xgetbv" + :"=a" (eax),"=d" (edx) + :"c" (xcr)); + +return (((uint64_t )edx) <<32 ) | eax; +} + +static bool vmx_mpx_supported () +{ +uint64_t cap_exit, cap_entry; + +hv_vmx_read_capability (HV_VMX_CAP_ENTRY , &cap_entry); +hv_vmx_read_capability (HV_VMX_CAP_EXIT , &cap_exit); + +return ((cap_exit & (1 <<23 )) && (cap_entry & (1 <<16 ))); +} +void init_cpuid (struct CPUState *cpu) { _cpuid = &builtin_cpus[2 ];/* core2duo */
@@ -277,3 +299,119 @@ void get_cpuid_func(struct CPUState *cpu, int func, int cnt, uint32_t *eax,break ; } } + +uint32_t hvf_get_supported_cpuid (uint32_t func,uint32_t idx, +int reg) +{ +uint64_t cap; +uint32_t eax, ebx, ecx, edx; + +host_cpuid (func, idx, &eax, &ebx, &ecx, &edx); + +switch (func) { +case 0 : + eax = eax < (uint32_t )0xd ? eax : (uint32_t )0xd ; +break ; +case 1 : + edx &=CPUID_FP87 |CPUID_VME |CPUID_DE |CPUID_PSE |CPUID_TSC | +CPUID_MSR |CPUID_PAE |CPUID_MCE |CPUID_CX8 |CPUID_APIC | +CPUID_SEP |CPUID_MTRR |CPUID_PGE |CPUID_MCA |CPUID_CMOV | +CPUID_PAT |CPUID_PSE36 |CPUID_CLFLUSH |CPUID_MMX | +CPUID_FXSR |CPUID_SSE |CPUID_SSE2 |CPUID_SS ; + ecx &=CPUID_EXT_SSE3 |CPUID_EXT_PCLMULQDQ |CPUID_EXT_SSSE3 | +CPUID_EXT_FMA |CPUID_EXT_CX16 |CPUID_EXT_PCID | +CPUID_EXT_SSE41 |CPUID_EXT_SSE42 |CPUID_EXT_MOVBE | +CPUID_EXT_POPCNT |CPUID_EXT_AES |CPUID_EXT_XSAVE | +CPUID_EXT_AVX |CPUID_EXT_F16C |CPUID_EXT_RDRAND ; +break ; +case 6 : + eax =4 ; + ebx =0 ; + ecx =0 ; + edx =0 ; +break ; +case 7 : +if (idx ==0 ) { + ebx &=CPUID_7_0_EBX_FSGSBASE |CPUID_7_0_EBX_BMI1 | +CPUID_7_0_EBX_HLE |CPUID_7_0_EBX_AVX2 | +CPUID_7_0_EBX_SMEP |CPUID_7_0_EBX_BMI2 | +CPUID_7_0_EBX_ERMS |CPUID_7_0_EBX_RTM | +CPUID_7_0_EBX_RDSEED |CPUID_7_0_EBX_ADX | +CPUID_7_0_EBX_SMAP |CPUID_7_0_EBX_AVX512IFMA | +CPUID_7_0_EBX_AVX512F |CPUID_7_0_EBX_AVX512PF | +CPUID_7_0_EBX_AVX512ER |CPUID_7_0_EBX_AVX512CD | +CPUID_7_0_EBX_CLFLUSHOPT |CPUID_7_0_EBX_CLWB | +CPUID_7_0_EBX_AVX512DQ |CPUID_7_0_EBX_SHA_NI | +CPUID_7_0_EBX_AVX512BW |CPUID_7_0_EBX_AVX512VL | +CPUID_7_0_EBX_INVPCID |CPUID_7_0_EBX_MPX ; + +if (!vmx_mpx_supported ()) { + ebx &= ~CPUID_7_0_EBX_MPX ; + } +hv_vmx_read_capability (HV_VMX_CAP_PROCBASED2 , &cap); +if (!(cap &CPU_BASED2_INVPCID )) { + ebx &= ~CPUID_7_0_EBX_INVPCID ; + } + + ecx &=CPUID_7_0_ECX_AVX512BMI |CPUID_7_0_ECX_AVX512_VPOPCNTDQ ; + edx &=CPUID_7_0_EDX_AVX512_4VNNIW |CPUID_7_0_EDX_AVX512_4FMAPS ; + }else { + ebx =0 ; + ecx =0 ; + edx =0 ; + } + eax =0 ; +break ; +case 0xD : +if (idx ==0 ) { +uint64_t host_xcr0 =xgetbv (0 ); +uint64_t supp_xcr0 = host_xcr0 & (XSTATE_FP_MASK |XSTATE_SSE_MASK | +XSTATE_YMM_MASK |XSTATE_BNDREGS_MASK | +XSTATE_BNDCSR_MASK |XSTATE_OPMASK_MASK | + XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK); + eax &= supp_xcr0; +if (!vmx_mpx_supported ()) { + eax &= ~(XSTATE_BNDREGS_MASK |XSTATE_BNDCSR_MASK ); + } + }else if (idx ==1 ) { +hv_vmx_read_capability (HV_VMX_CAP_PROCBASED2 , &cap); + eax &=CPUID_XSAVE_XSAVEOPT |CPUID_XSAVE_XGETBV1 ; +if (!(cap &CPU_BASED2_XSAVES_XRSTORS )) { + eax &= ~CPUID_XSAVE_XSAVES ; + } + } +break ; +case 0x80000001 : +/* LM only if HVF in 64-bit mode */ + edx &=CPUID_FP87 |CPUID_VME |CPUID_DE |CPUID_PSE |CPUID_TSC | +CPUID_MSR |CPUID_PAE |CPUID_MCE |CPUID_CX8 |CPUID_APIC | +CPUID_EXT2_SYSCALL |CPUID_MTRR |CPUID_PGE |CPUID_MCA |CPUID_CMOV | +CPUID_PAT |CPUID_PSE36 |CPUID_EXT2_MMXEXT |CPUID_MMX | +CPUID_FXSR |CPUID_EXT2_FXSR |CPUID_EXT2_PDPE1GB |CPUID_EXT2_3DNOWEXT | +CPUID_EXT2_3DNOW |CPUID_EXT2_LM |CPUID_EXT2_RDTSCP |CPUID_EXT2_NX ; +hv_vmx_read_capability (HV_VMX_CAP_PROCBASED , &cap); +if (!(cap &CPU_BASED_TSC_OFFSET )) { + edx &= ~CPUID_EXT2_RDTSCP ; + } + ecx &=CPUID_EXT3_LAHF_LM |CPUID_EXT3_CMP_LEG |CPUID_EXT3_CR8LEG | +CPUID_EXT3_ABM |CPUID_EXT3_SSE4A |CPUID_EXT3_MISALIGNSSE | +CPUID_EXT3_3DNOWPREFETCH |CPUID_EXT3_OSVW |CPUID_EXT3_XOP | +CPUID_EXT3_FMA4 |CPUID_EXT3_TBM ; +break ; +default : +return 0 ; + } + +switch (reg) { +case R_EAX : +return eax; +case R_EBX : +return ebx; +case R_ECX : +return ecx; +case R_EDX : +return edx; +default : +return 0 ; + } +}
Signature · 1 line
2.14.1
PATCH v3 11/14 hvf: refactor cpuid code
In reply to Sergio Andres Gomez Del RealThis patch generalizes some code in cpu.c, sharing code and data between hvf and kvm. It also beings calling the new hvf_get_supported_cpuid where appropriate.
--- target/i386/cpu-qom.h | 4 +-- target/i386/cpu.c | 76 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 58 insertions(+), 22 deletions(-)
target/i386/cpu-qom.h +2 -2
@@ -47,7 +47,7 @@ typedef struct X86CPUDefinition X86CPUDefinition;/** * X86CPUClass: * @cpu_def: CPU model definition -* @kvm_required: Whether CPU model requires KVM to be enabled. +* @host_cpuid_required: Whether CPU model requires cpuid from host. * @ordering: Ordering on the "-cpu help" CPU model list. * @migration_safe: See CpuDefinitionInfo::migration_safe * @static_model: See CpuDefinitionInfo::static
@@ -66,7 +66,7 @@ typedef struct X86CPUClass {*/ X86CPUDefinition *cpu_def; -bool kvm_required; +bool host_cpuid_required;int ordering;bool migration_safe;bool static_model;
target/i386/cpu.c +56 -20
193 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH v3 12/14 hvf: implement vga dirty page tracking
In reply to Sergio Andres Gomez Del RealThis commit implements setting the tracking of dirty pages, using hvf's interface to protect guest memory. It uses the MemoryListener callback mechanism through .log_start/stop/sync
--- include/sysemu/hvf.h | 5 ++++ target/i386/hvf-all.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 7 deletions(-)
include/sysemu/hvf.h +5 -0
@@ -34,11 +34,16 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,#define hvf_get_supported_cpuid (func, idx, reg) 0#endif +/* hvf_slot flags */ +#define HVF_SLOT_LOG (1 << 0) +typedef struct hvf_slot {uint64_t start;uint64_t size;uint8_t *mem;int slot_id; +uint32_t flags; +MemoryRegion *region; }hvf_slot ;struct hvf_vcpu_caps {
target/i386/hvf-all.c +67 -7
116 lines not on this page · raw message
Signature · 1 line
2.14.1
PATCH v3 13/14 hvf: refactor event injection code for hvf
In reply to Sergio Andres Gomez Del RealThis commit refactors the event-injection code for hvf through using the appropriate fields already provided by CPUX86State. At vmexit, it fills these fields so that hvf_inject_interrupts can just retrieve them without calling into hvf.
--- target/i386/cpu.c | 3 ++ target/i386/hvf-all.c | 57 ++++++++++++++++++++++++++++++++---- target/i386/hvf-utils/vmcs.h | 3 ++ target/i386/hvf-utils/vmx.h | 8 ++++++ target/i386/hvf-utils/x86hvf.c | 65 ++++++++++++++++++++---------------------- target/i386/kvm.c | 2 -- 6 files changed, 97 insertions(+), 41 deletions(-)
target/i386/cpu.c +3 -0
@@ -3247,6 +3247,9 @@ static void x86_cpu_reset(CPUState *s)memset (env->mtrr_var,0 ,sizeof (env->mtrr_var));memset (env->mtrr_fixed,0 ,sizeof (env->mtrr_fixed)); + env->interrupt_injected =-1 ; + env->exception_injected =-1 ; + env->nmi_injected = false;#if !defined(CONFIG_USER_ONLY )/* We hard-wire the BSP to the first CPU. */ apic_designate_bsp (cpu->apic_state, s->cpu_index ==0 );
target/i386/hvf-all.c +52 -5
76 lines not on this page · raw message
target/i386/hvf-utils/vmcs.h +3 -0
@@ -299,6 +299,7 @@/* * VMCS IDT-Vectoring information fields */ +#define VMCS_IDT_VEC_VECNUM 0xFF#define VMCS_IDT_VEC_VALID (1U << 31)#define VMCS_IDT_VEC_TYPE 0x700#define VMCS_IDT_VEC_ERRCODE_VALID (1U << 11)
@@ -306,6 +307,8 @@#define VMCS_IDT_VEC_NMI (2 << 8)#define VMCS_IDT_VEC_HWEXCEPTION (3 << 8)#define VMCS_IDT_VEC_SWINTR (4 << 8) +#define VMCS_IDT_VEC_PRIV_SWEXCEPTION (5 << 8) +#define VMCS_IDT_VEC_SWEXCEPTION (6 << 8)/* * VMCS Guest interruptibility field
target/i386/hvf-utils/vmx.h +8 -0
@@ -181,6 +181,10 @@ static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)static inline void vmx_clear_nmi_blocking (CPUState *cpu) { +X86CPU *x86_cpu =X86_CPU (cpu); +CPUX86State *env = &x86_cpu->env; + + env->hflags2 &= ~HF2_NMI_MASK ;uint32_t gi = (uint32_t )rvmcs (cpu->hvf_fd,VMCS_GUEST_INTERRUPTIBILITY ); gi &= ~VMCS_INTERRUPTIBILITY_NMI_BLOCKING ;wvmcs (cpu->hvf_fd,VMCS_GUEST_INTERRUPTIBILITY , gi);
@@ -188,6 +192,10 @@ static inline void vmx_clear_nmi_blocking(CPUState *cpu)static inline void vmx_set_nmi_blocking (CPUState *cpu) { +X86CPU *x86_cpu =X86_CPU (cpu); +CPUX86State *env = &x86_cpu->env; + + env->hflags2 |=HF2_NMI_MASK ;uint32_t gi = (uint32_t )rvmcs (cpu->hvf_fd,VMCS_GUEST_INTERRUPTIBILITY ); gi |=VMCS_INTERRUPTIBILITY_NMI_BLOCKING ;wvmcs (cpu->hvf_fd,VMCS_GUEST_INTERRUPTIBILITY , gi);
target/i386/hvf-utils/x86hvf.c +31 -34
95 lines not on this page · raw message
target/i386/kvm.c +0 -2
@@ -1030,8 +1030,6 @@ void kvm_arch_reset_vcpu(X86CPU *cpu) {CPUX86State *env = &cpu->env; - env->exception_injected =-1 ; - env->interrupt_injected =-1 ; env->xcr0 =1 ;if (kvm_irqchip_in_kernel ()) { env->mp_state = cpu_is_bsp(cpu) ? KVM_MP_STATE_RUNNABLE :
Signature · 1 line
2.14.1
PATCH v3 14/14 hvf: inject General Protection Fault when vmexit through vmcall
In reply to Sergio Andres Gomez Del RealThis commit injects a GP fault when the guest vmexit's by executing a vmcall instruction.
--- target/i386/hvf-all.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
target/i386/hvf-all.c +3 -1
@@ -903,7 +903,9 @@ int hvf_vcpu_exec(CPUState *cpu)macvm_set_rip (cpu, rip + ins_len);break ;case VMX_REASON_VMCALL : -/* TODO: inject #GP fault */ + env->exception_injected =EXCP0D_GPF ; + env->has_error_code = true; + env->error_code =0 ;break ;default :error_report ("%llx: unhandled exit %llx\n" , rip, exit_reason);
Signature · 1 line
2.14.1
This patchset didn't address every issue, so it won't be the definite version.
Hopefully however the licensing issue will get fixed with this version.
Quoted 139 lines · Sergio Andres Gomez Del Real
================
Changes in v3:
(1) Fixed licensing issues in patch 3.
(2) Revert to late adding of compilation rules in Makefile.objs (patch
8/14);
files aren't ready to compile earlier.
(3) Make a single patch just for fixing style (patch 4/14).
(4) Fix data type forhvf_fdfield.
(5) Add comment that return value of -1 in apic function added in 7/14
means
"no interrupt".
================================
Changes in v2:
(1) Removed legacy option "-enable-hvf" in favor of "-M accel=hvf"
(2) Added missing copyright headers; replace fprintfs forerror_report; improved commit description.
(3) Moved patch that adds compilation rules in Makefile.objs right after the patch that adds the new files from Google's repo.
(4) Removed conditional macros fromcpus.candcpu.c
(5) Moved patch that fixes coding style to patch # 3
(6) Fix commit message in apic patch
(7) Squash some commits to avoid code churn
================The following patchset adds to QEMU the supporting for macOS's native hypervisor, Hypervisor.framework (hvf). The code base is taken from Google's Android emulator at
https://android.googlesource.com/platform/external/qemu/+/emu-master-dev.Apart from general code refactoring, some additional features were implemented:
retrieve the set of features supported by host cpu and hvf (cpuid); dirty page tracking for VGA memory area; reimplementation of the event injection mechanism to allow injection of exceptions during vmexits, which is
exemplified by the injection of a GP fault when the guest vmexits due to execution of the vmcall instruction; changing the emulator's use of CPUState
structure in favor of CPUX86State, so as to in the future remove data structures
that are uselessly specific to hvf and unified some of the state between kvm/tcg
and hvf.
Some features initially planned to implement that didn't make it include:
page fault handling in the emulator and implementing thedummy_signalto handle
theSIG_IPIsignal without race conditions. Hopefully these can be implemented
in the near future.Sergio Andres Gomez Del Real (14):
hvf: add support for Hypervisor.framework in the configure script
hvf: add code base from Google's QEMU repository
hvf: fix licensing issues; isolate task handling code (GPL v2-only)
hvf: run hvf code through checkpatch.pl and fix style issues
hvf: add code tocpus.cand do refactoring in preparation for
compiling
hvf: handle fields from CPUState and CPUX86State
apic: add function to apic that will be used by hvf
hvf: add compilation rules to Makefile.objs
hvf: use new helper functions for put/get xsave
hvf: implementhvf_get_supported_cpuid
hvf: refactor cpuid code
hvf: implement vga dirty page tracking
hvf: refactor event injection code for hvf
hvf: inject General Protection Fault when vmexit through vmcallconfigure | 38 + cpus.c | 86 ++ hw/intc/apic.c | 12 + include/hw/i386/apic.h | 1 + include/qom/cpu.h | 2 + include/sysemu/hvf.h | 107 ++ qemu-options.hx | 10 +- target/i386/Makefile.objs | 1 + target/i386/cpu-qom.h | 4 +- target/i386/cpu.c | 79 +- target/i386/cpu.h | 38 +- target/i386/hvf-all.c | 963 +++++++++++++++ target/i386/hvf-i386.h | 48 + target/i386/hvf-utils/Makefile.objs | 1 + target/i386/hvf-utils/README.md | 7 + target/i386/hvf-utils/vmcs.h | 371 ++++++ target/i386/hvf-utils/vmx.h | 222 ++++ target/i386/hvf-utils/x86.c | 184 +++ target/i386/hvf-utils/x86.h | 476 ++++++++ target/i386/hvf-utils/x86_cpuid.c | 417 +++++++ target/i386/hvf-utils/x86_cpuid.h | 52 + target/i386/hvf-utils/x86_decode.c | 2186 ++++++++++++++++++++++++++++++ +++++ target/i386/hvf-utils/x86_decode.h | 325 ++++++ target/i386/hvf-utils/x86_descr.c | 124 ++ target/i386/hvf-utils/x86_descr.h | 55 + target/i386/hvf-utils/x86_emu.c | 1536 ++++++++++++++++++++++++ target/i386/hvf-utils/x86_emu.h | 49 + target/i386/hvf-utils/x86_flags.c | 333 ++++++ target/i386/hvf-utils/x86_flags.h | 243 ++++ target/i386/hvf-utils/x86_gen.h | 53 + target/i386/hvf-utils/x86_mmu.c | 273 +++++ target/i386/hvf-utils/x86_mmu.h | 45 + target/i386/hvf-utils/x86_task.c | 201 ++++ target/i386/hvf-utils/x86_task.h | 18 + target/i386/hvf-utils/x86hvf.c | 463 ++++++++ target/i386/hvf-utils/x86hvf.h | 39 + target/i386/kvm.c | 2 - 37 files changed, 9031 insertions(+), 33 deletions(-) create mode 100644 include/sysemu/hvf.h create mode 100644 target/i386/hvf-all.c create mode 100644 target/i386/hvf-i386.h create mode 100644 target/i386/hvf-utils/Makefile.objs create mode 100644 target/i386/hvf-utils/README.md create mode 100644 target/i386/hvf-utils/vmcs.h create mode 100644 target/i386/hvf-utils/vmx.h create mode 100644 target/i386/hvf-utils/x86.c create mode 100644 target/i386/hvf-utils/x86.h create mode 100644 target/i386/hvf-utils/x86_cpuid.c create mode 100644 target/i386/hvf-utils/x86_cpuid.h create mode 100644 target/i386/hvf-utils/x86_decode.c create mode 100644 target/i386/hvf-utils/x86_decode.h create mode 100644 target/i386/hvf-utils/x86_descr.c create mode 100644 target/i386/hvf-utils/x86_descr.h create mode 100644 target/i386/hvf-utils/x86_emu.c create mode 100644 target/i386/hvf-utils/x86_emu.h create mode 100644 target/i386/hvf-utils/x86_flags.c create mode 100644 target/i386/hvf-utils/x86_flags.h create mode 100644 target/i386/hvf-utils/x86_gen.h create mode 100644 target/i386/hvf-utils/x86_mmu.c create mode 100644 target/i386/hvf-utils/x86_mmu.h create mode 100644 target/i386/hvf-utils/x86_task.c create mode 100644 target/i386/hvf-utils/x86_task.h create mode 100644 target/i386/hvf-utils/x86hvf.c create mode 100644 target/i386/hvf-utils/x86hvf.h--
2.14.1
Quoted 2 lines · Sergio Andrés Gómez del Real
This patchset didn't address every issue, so it won't be the definite version.
This series is fairly large and I don't want to review the same unresolved issues multiple times. I'll skip this revision and review again once outstanding issues have been addressed.
Now would be a good time for someone familiar with VMX and x86 emulation to review the meat of this.
Stefan