Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1429470/?format=api
{ "id": 1429470, "url": "http://patchwork.ozlabs.org/api/patches/1429470/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20210120224444.71840-4-agraf@csgraf.de/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20210120224444.71840-4-agraf@csgraf.de>", "list_archive_url": null, "date": "2021-01-20T22:44:36", "name": "[v6,03/11] hvf: Move common code out", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "dd722b06acacee87f2ca96a47b4c31fb9f7a384f", "submitter": { "id": 65661, "url": "http://patchwork.ozlabs.org/api/people/65661/?format=api", "name": "Alexander Graf", "email": "agraf@csgraf.de" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20210120224444.71840-4-agraf@csgraf.de/mbox/", "series": [ { "id": 225556, "url": "http://patchwork.ozlabs.org/api/series/225556/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=225556", "date": "2021-01-20T22:44:33", "name": "hvf: Implement Apple Silicon Support", "version": 6, "mbox": "http://patchwork.ozlabs.org/series/225556/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1429470/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1429470/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=<UNKNOWN>)", "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 4DLggy5Cvtz9sT6\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 21 Jan 2021 09:49:34 +1100 (AEDT)", "from localhost ([::1]:44376 helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1l2MI8-0008Au-J7\n\tfor incoming@patchwork.ozlabs.org; Wed, 20 Jan 2021 17:49:32 -0500", "from eggs.gnu.org ([2001:470:142:3::10]:56614)\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <agraf@csgraf.de>)\n id 1l2MDj-0003up-8R; Wed, 20 Jan 2021 17:44:59 -0500", "from mail.csgraf.de ([188.138.100.120]:45118\n helo=zulu616.server4you.de) by eggs.gnu.org with esmtp (Exim 4.90_1)\n (envelope-from <agraf@csgraf.de>)\n id 1l2MDa-0001TW-P8; Wed, 20 Jan 2021 17:44:58 -0500", "from localhost.localdomain\n (dynamic-077-002-091-253.77.2.pool.telefonica.de [77.2.91.253])\n by csgraf.de (Postfix) with ESMTPSA id DC5E239004ED;\n Wed, 20 Jan 2021 23:44:47 +0100 (CET)" ], "From": "Alexander Graf <agraf@csgraf.de>", "To": "qemu-devel@nongnu.org", "Subject": "[PATCH v6 03/11] hvf: Move common code out", "Date": "Wed, 20 Jan 2021 23:44:36 +0100", "Message-Id": "<20210120224444.71840-4-agraf@csgraf.de>", "X-Mailer": "git-send-email 2.24.3 (Apple Git-128)", "In-Reply-To": "<20210120224444.71840-1-agraf@csgraf.de>", "References": "<20210120224444.71840-1-agraf@csgraf.de>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=188.138.100.120; envelope-from=agraf@csgraf.de;\n helo=zulu616.server4you.de", "X-Spam_score_int": "-18", "X-Spam_score": "-1.9", "X-Spam_bar": "-", "X-Spam_report": "(-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.23", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Cc": "Peter Maydell <peter.maydell@linaro.org>,\n Eduardo Habkost <ehabkost@redhat.com>,\n Richard Henderson <richard.henderson@linaro.org>,\n Cameron Esfahani <dirty@apple.com>, Roman Bolshakov <r.bolshakov@yadro.com>,\n qemu-arm@nongnu.org, Frank Yang <lfy@google.com>,\n Paolo Bonzini <pbonzini@redhat.com>, Peter Collingbourne <pcc@google.com>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "\"Qemu-devel\"\n <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>" }, "content": "Until now, Hypervisor.framework has only been available on x86_64 systems.\nWith Apple Silicon shipping now, it extends its reach to aarch64. To\nprepare for support for multiple architectures, let's move common code out\ninto its own accel directory.\n\nSigned-off-by: Alexander Graf <agraf@csgraf.de>\nReviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>\nTested-by: Roman Bolshakov <r.bolshakov@yadro.com>\n\n---\n\nv3 -> v4:\n\n - Use hv.h instead of Hypervisor.h for 10.15 compat\n - Remove manual inclusion of Hypervisor.h in common .c files\n---\n MAINTAINERS | 8 +\n accel/hvf/hvf-all.c | 54 +++++\n accel/hvf/hvf-cpus.c | 462 ++++++++++++++++++++++++++++++++++++\n accel/hvf/meson.build | 7 +\n accel/meson.build | 1 +\n include/sysemu/hvf_int.h | 54 +++++\n target/i386/hvf/hvf-cpus.c | 131 ----------\n target/i386/hvf/hvf-cpus.h | 25 --\n target/i386/hvf/hvf-i386.h | 33 +--\n target/i386/hvf/hvf.c | 360 +---------------------------\n target/i386/hvf/meson.build | 1 -\n target/i386/hvf/x86hvf.c | 11 +-\n target/i386/hvf/x86hvf.h | 2 -\n 13 files changed, 596 insertions(+), 553 deletions(-)\n create mode 100644 accel/hvf/hvf-all.c\n create mode 100644 accel/hvf/hvf-cpus.c\n create mode 100644 accel/hvf/meson.build\n create mode 100644 include/sysemu/hvf_int.h\n delete mode 100644 target/i386/hvf/hvf-cpus.c\n delete mode 100644 target/i386/hvf/hvf-cpus.h", "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 3216387521..e589ec02e0 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -448,7 +448,15 @@ M: Roman Bolshakov <r.bolshakov@yadro.com>\n W: https://wiki.qemu.org/Features/HVF\n S: Maintained\n F: target/i386/hvf/\n+\n+HVF\n+M: Cameron Esfahani <dirty@apple.com>\n+M: Roman Bolshakov <r.bolshakov@yadro.com>\n+W: https://wiki.qemu.org/Features/HVF\n+S: Maintained\n+F: accel/hvf/\n F: include/sysemu/hvf.h\n+F: include/sysemu/hvf_int.h\n \n WHPX CPUs\n M: Sunil Muthuswamy <sunilmut@microsoft.com>\ndiff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c\nnew file mode 100644\nindex 0000000000..5b415eb0ed\n--- /dev/null\n+++ b/accel/hvf/hvf-all.c\n@@ -0,0 +1,54 @@\n+/*\n+ * QEMU Hypervisor.framework support\n+ *\n+ * This work is licensed under the terms of the GNU GPL, version 2. See\n+ * the COPYING file in the top-level directory.\n+ *\n+ * Contributions after 2012-01-13 are licensed under the terms of the\n+ * GNU GPL, version 2 or (at your option) any later version.\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"qemu-common.h\"\n+#include \"qemu/error-report.h\"\n+#include \"sysemu/hvf.h\"\n+#include \"sysemu/hvf_int.h\"\n+#include \"sysemu/runstate.h\"\n+\n+#include \"qemu/main-loop.h\"\n+#include \"sysemu/accel.h\"\n+\n+bool hvf_allowed;\n+HVFState *hvf_state;\n+\n+void assert_hvf_ok(hv_return_t ret)\n+{\n+ if (ret == HV_SUCCESS) {\n+ return;\n+ }\n+\n+ switch (ret) {\n+ case HV_ERROR:\n+ error_report(\"Error: HV_ERROR\");\n+ break;\n+ case HV_BUSY:\n+ error_report(\"Error: HV_BUSY\");\n+ break;\n+ case HV_BAD_ARGUMENT:\n+ error_report(\"Error: HV_BAD_ARGUMENT\");\n+ break;\n+ case HV_NO_RESOURCES:\n+ error_report(\"Error: HV_NO_RESOURCES\");\n+ break;\n+ case HV_NO_DEVICE:\n+ error_report(\"Error: HV_NO_DEVICE\");\n+ break;\n+ case HV_UNSUPPORTED:\n+ error_report(\"Error: HV_UNSUPPORTED\");\n+ break;\n+ default:\n+ error_report(\"Unknown Error\");\n+ }\n+\n+ abort();\n+}\ndiff --git a/accel/hvf/hvf-cpus.c b/accel/hvf/hvf-cpus.c\nnew file mode 100644\nindex 0000000000..60f6d76bf3\n--- /dev/null\n+++ b/accel/hvf/hvf-cpus.c\n@@ -0,0 +1,462 @@\n+/*\n+ * Copyright 2008 IBM Corporation\n+ * 2008 Red Hat, Inc.\n+ * Copyright 2011 Intel Corporation\n+ * Copyright 2016 Veertu, Inc.\n+ * Copyright 2017 The Android Open Source Project\n+ *\n+ * QEMU Hypervisor.framework support\n+ *\n+ * This program is free software; you can redistribute it and/or\n+ * modify it under the terms of version 2 of the GNU General Public\n+ * License as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU General Public License\n+ * along with this program; if not, see <http://www.gnu.org/licenses/>.\n+ *\n+ * This file contain code under public domain from the hvdos project:\n+ * https://github.com/mist64/hvdos\n+ *\n+ * Parts Copyright (c) 2011 NetApp, Inc.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ * 1. Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in the\n+ * documentation and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND\n+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE\n+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n+ * SUCH DAMAGE.\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"qemu/error-report.h\"\n+#include \"qemu/main-loop.h\"\n+#include \"exec/address-spaces.h\"\n+#include \"exec/exec-all.h\"\n+#include \"sysemu/cpus.h\"\n+#include \"sysemu/hvf.h\"\n+#include \"sysemu/hvf_int.h\"\n+#include \"sysemu/runstate.h\"\n+#include \"qemu/guest-random.h\"\n+\n+/* Memory slots */\n+\n+struct mac_slot {\n+ int present;\n+ uint64_t size;\n+ uint64_t gpa_start;\n+ uint64_t gva;\n+};\n+\n+hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)\n+{\n+ hvf_slot *slot;\n+ int x;\n+ for (x = 0; x < hvf_state->num_slots; ++x) {\n+ slot = &hvf_state->slots[x];\n+ if (slot->size && start < (slot->start + slot->size) &&\n+ (start + size) > slot->start) {\n+ return slot;\n+ }\n+ }\n+ return NULL;\n+}\n+\n+struct mac_slot mac_slots[32];\n+\n+static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)\n+{\n+ struct mac_slot *macslot;\n+ hv_return_t ret;\n+\n+ macslot = &mac_slots[slot->slot_id];\n+\n+ if (macslot->present) {\n+ if (macslot->size != slot->size) {\n+ macslot->present = 0;\n+ ret = hv_vm_unmap(macslot->gpa_start, macslot->size);\n+ assert_hvf_ok(ret);\n+ }\n+ }\n+\n+ if (!slot->size) {\n+ return 0;\n+ }\n+\n+ macslot->present = 1;\n+ macslot->gpa_start = slot->start;\n+ macslot->size = slot->size;\n+ ret = hv_vm_map(slot->mem, slot->start, slot->size, flags);\n+ assert_hvf_ok(ret);\n+ return 0;\n+}\n+\n+static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)\n+{\n+ hvf_slot *mem;\n+ MemoryRegion *area = section->mr;\n+ bool writeable = !area->readonly && !area->rom_device;\n+ hv_memory_flags_t flags;\n+\n+ if (!memory_region_is_ram(area)) {\n+ if (writeable) {\n+ return;\n+ } else if (!memory_region_is_romd(area)) {\n+ /*\n+ * If the memory device is not in romd_mode, then we actually want\n+ * to remove the hvf memory slot so all accesses will trap.\n+ */\n+ add = false;\n+ }\n+ }\n+\n+ mem = hvf_find_overlap_slot(\n+ section->offset_within_address_space,\n+ int128_get64(section->size));\n+\n+ if (mem && add) {\n+ if (mem->size == int128_get64(section->size) &&\n+ mem->start == section->offset_within_address_space &&\n+ mem->mem == (memory_region_get_ram_ptr(area) +\n+ section->offset_within_region)) {\n+ return; /* Same region was attempted to register, go away. */\n+ }\n+ }\n+\n+ /* Region needs to be reset. set the size to 0 and remap it. */\n+ if (mem) {\n+ mem->size = 0;\n+ if (do_hvf_set_memory(mem, 0)) {\n+ error_report(\"Failed to reset overlapping slot\");\n+ abort();\n+ }\n+ }\n+\n+ if (!add) {\n+ return;\n+ }\n+\n+ if (area->readonly ||\n+ (!memory_region_is_ram(area) && memory_region_is_romd(area))) {\n+ flags = HV_MEMORY_READ | HV_MEMORY_EXEC;\n+ } else {\n+ flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;\n+ }\n+\n+ /* Now make a new slot. */\n+ int x;\n+\n+ for (x = 0; x < hvf_state->num_slots; ++x) {\n+ mem = &hvf_state->slots[x];\n+ if (!mem->size) {\n+ break;\n+ }\n+ }\n+\n+ if (x == hvf_state->num_slots) {\n+ error_report(\"No free slots\");\n+ abort();\n+ }\n+\n+ mem->size = int128_get64(section->size);\n+ mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;\n+ mem->start = section->offset_within_address_space;\n+ mem->region = area;\n+\n+ if (do_hvf_set_memory(mem, flags)) {\n+ error_report(\"Error registering new memory slot\");\n+ abort();\n+ }\n+}\n+\n+static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)\n+{\n+ hvf_slot *slot;\n+\n+ slot = hvf_find_overlap_slot(\n+ section->offset_within_address_space,\n+ int128_get64(section->size));\n+\n+ /* protect region against writes; begin tracking it */\n+ if (on) {\n+ slot->flags |= HVF_SLOT_LOG;\n+ hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,\n+ HV_MEMORY_READ);\n+ /* stop tracking region*/\n+ } else {\n+ slot->flags &= ~HVF_SLOT_LOG;\n+ hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,\n+ HV_MEMORY_READ | HV_MEMORY_WRITE);\n+ }\n+}\n+\n+static void hvf_log_start(MemoryListener *listener,\n+ MemoryRegionSection *section, int old, int new)\n+{\n+ if (old != 0) {\n+ return;\n+ }\n+\n+ hvf_set_dirty_tracking(section, 1);\n+}\n+\n+static void hvf_log_stop(MemoryListener *listener,\n+ MemoryRegionSection *section, int old, int new)\n+{\n+ if (new != 0) {\n+ return;\n+ }\n+\n+ hvf_set_dirty_tracking(section, 0);\n+}\n+\n+static void hvf_log_sync(MemoryListener *listener,\n+ MemoryRegionSection *section)\n+{\n+ /*\n+ * sync of dirty pages is handled elsewhere; just make sure we keep\n+ * tracking the region.\n+ */\n+ hvf_set_dirty_tracking(section, 1);\n+}\n+\n+static void hvf_region_add(MemoryListener *listener,\n+ MemoryRegionSection *section)\n+{\n+ hvf_set_phys_mem(section, true);\n+}\n+\n+static void hvf_region_del(MemoryListener *listener,\n+ MemoryRegionSection *section)\n+{\n+ hvf_set_phys_mem(section, false);\n+}\n+\n+static MemoryListener hvf_memory_listener = {\n+ .priority = 10,\n+ .region_add = hvf_region_add,\n+ .region_del = hvf_region_del,\n+ .log_start = hvf_log_start,\n+ .log_stop = hvf_log_stop,\n+ .log_sync = hvf_log_sync,\n+};\n+\n+static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)\n+{\n+ if (!cpu->vcpu_dirty) {\n+ hvf_get_registers(cpu);\n+ cpu->vcpu_dirty = true;\n+ }\n+}\n+\n+static void hvf_cpu_synchronize_state(CPUState *cpu)\n+{\n+ if (!cpu->vcpu_dirty) {\n+ run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);\n+ }\n+}\n+\n+static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,\n+ run_on_cpu_data arg)\n+{\n+ hvf_put_registers(cpu);\n+ cpu->vcpu_dirty = false;\n+}\n+\n+static void hvf_cpu_synchronize_post_reset(CPUState *cpu)\n+{\n+ run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);\n+}\n+\n+static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,\n+ run_on_cpu_data arg)\n+{\n+ hvf_put_registers(cpu);\n+ cpu->vcpu_dirty = false;\n+}\n+\n+static void hvf_cpu_synchronize_post_init(CPUState *cpu)\n+{\n+ run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);\n+}\n+\n+static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,\n+ run_on_cpu_data arg)\n+{\n+ cpu->vcpu_dirty = true;\n+}\n+\n+static void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)\n+{\n+ run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);\n+}\n+\n+static void hvf_vcpu_destroy(CPUState *cpu)\n+{\n+ hv_return_t ret = hv_vcpu_destroy(cpu->hvf_fd);\n+ assert_hvf_ok(ret);\n+\n+ hvf_arch_vcpu_destroy(cpu);\n+}\n+\n+static void dummy_signal(int sig)\n+{\n+}\n+\n+static int hvf_init_vcpu(CPUState *cpu)\n+{\n+ int r;\n+\n+ /* init cpu signals */\n+ sigset_t set;\n+ struct sigaction sigact;\n+\n+ memset(&sigact, 0, sizeof(sigact));\n+ sigact.sa_handler = dummy_signal;\n+ sigaction(SIG_IPI, &sigact, NULL);\n+\n+ pthread_sigmask(SIG_BLOCK, NULL, &set);\n+ sigdelset(&set, SIG_IPI);\n+\n+ r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);\n+ cpu->vcpu_dirty = 1;\n+ assert_hvf_ok(r);\n+\n+ return hvf_arch_init_vcpu(cpu);\n+}\n+\n+/*\n+ * The HVF-specific vCPU thread function. This one should only run when the host\n+ * CPU supports the VMX \"unrestricted guest\" feature.\n+ */\n+static void *hvf_cpu_thread_fn(void *arg)\n+{\n+ CPUState *cpu = arg;\n+\n+ int r;\n+\n+ assert(hvf_enabled());\n+\n+ rcu_register_thread();\n+\n+ qemu_mutex_lock_iothread();\n+ qemu_thread_get_self(cpu->thread);\n+\n+ cpu->thread_id = qemu_get_thread_id();\n+ cpu->can_do_io = 1;\n+ current_cpu = cpu;\n+\n+ hvf_init_vcpu(cpu);\n+\n+ /* signal CPU creation */\n+ cpu_thread_signal_created(cpu);\n+ qemu_guest_random_seed_thread_part2(cpu->random_seed);\n+\n+ do {\n+ if (cpu_can_run(cpu)) {\n+ r = hvf_vcpu_exec(cpu);\n+ if (r == EXCP_DEBUG) {\n+ cpu_handle_guest_debug(cpu);\n+ }\n+ }\n+ qemu_wait_io_event(cpu);\n+ } while (!cpu->unplug || cpu_can_run(cpu));\n+\n+ hvf_vcpu_destroy(cpu);\n+ cpu_thread_signal_destroyed(cpu);\n+ qemu_mutex_unlock_iothread();\n+ rcu_unregister_thread();\n+ return NULL;\n+}\n+\n+static void hvf_start_vcpu_thread(CPUState *cpu)\n+{\n+ char thread_name[VCPU_THREAD_NAME_SIZE];\n+\n+ /*\n+ * HVF currently does not support TCG, and only runs in\n+ * unrestricted-guest mode.\n+ */\n+ assert(hvf_enabled());\n+\n+ cpu->thread = g_malloc0(sizeof(QemuThread));\n+ cpu->halt_cond = g_malloc0(sizeof(QemuCond));\n+ qemu_cond_init(cpu->halt_cond);\n+\n+ snprintf(thread_name, VCPU_THREAD_NAME_SIZE, \"CPU %d/HVF\",\n+ cpu->cpu_index);\n+ qemu_thread_create(cpu->thread, thread_name, hvf_cpu_thread_fn,\n+ cpu, QEMU_THREAD_JOINABLE);\n+}\n+\n+static const CpusAccel hvf_cpus = {\n+ .create_vcpu_thread = hvf_start_vcpu_thread,\n+\n+ .synchronize_post_reset = hvf_cpu_synchronize_post_reset,\n+ .synchronize_post_init = hvf_cpu_synchronize_post_init,\n+ .synchronize_state = hvf_cpu_synchronize_state,\n+ .synchronize_pre_loadvm = hvf_cpu_synchronize_pre_loadvm,\n+};\n+\n+static int hvf_accel_init(MachineState *ms)\n+{\n+ int x;\n+ hv_return_t ret;\n+ HVFState *s;\n+\n+ ret = hv_vm_create(HV_VM_DEFAULT);\n+ assert_hvf_ok(ret);\n+\n+ s = g_new0(HVFState, 1);\n+\n+ s->num_slots = 32;\n+ for (x = 0; x < s->num_slots; ++x) {\n+ s->slots[x].size = 0;\n+ s->slots[x].slot_id = x;\n+ }\n+\n+ hvf_state = s;\n+ memory_listener_register(&hvf_memory_listener, &address_space_memory);\n+ cpus_register_accel(&hvf_cpus);\n+ return 0;\n+}\n+\n+static void hvf_accel_class_init(ObjectClass *oc, void *data)\n+{\n+ AccelClass *ac = ACCEL_CLASS(oc);\n+ ac->name = \"HVF\";\n+ ac->init_machine = hvf_accel_init;\n+ ac->allowed = &hvf_allowed;\n+}\n+\n+static const TypeInfo hvf_accel_type = {\n+ .name = TYPE_HVF_ACCEL,\n+ .parent = TYPE_ACCEL,\n+ .class_init = hvf_accel_class_init,\n+};\n+\n+static void hvf_type_init(void)\n+{\n+ type_register_static(&hvf_accel_type);\n+}\n+\n+type_init(hvf_type_init);\ndiff --git a/accel/hvf/meson.build b/accel/hvf/meson.build\nnew file mode 100644\nindex 0000000000..dfd6b68dc7\n--- /dev/null\n+++ b/accel/hvf/meson.build\n@@ -0,0 +1,7 @@\n+hvf_ss = ss.source_set()\n+hvf_ss.add(files(\n+ 'hvf-all.c',\n+ 'hvf-cpus.c',\n+))\n+\n+specific_ss.add_all(when: 'CONFIG_HVF', if_true: hvf_ss)\ndiff --git a/accel/meson.build b/accel/meson.build\nindex b26cca227a..6de12ce5d5 100644\n--- a/accel/meson.build\n+++ b/accel/meson.build\n@@ -1,5 +1,6 @@\n softmmu_ss.add(files('accel.c'))\n \n+subdir('hvf')\n subdir('qtest')\n subdir('kvm')\n subdir('tcg')\ndiff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h\nnew file mode 100644\nindex 0000000000..69de46db7d\n--- /dev/null\n+++ b/include/sysemu/hvf_int.h\n@@ -0,0 +1,54 @@\n+/*\n+ * QEMU Hypervisor.framework (HVF) support\n+ *\n+ * This work is licensed under the terms of the GNU GPL, version 2 or later.\n+ * See the COPYING file in the top-level directory.\n+ *\n+ */\n+\n+/* header to be included in HVF-specific code */\n+\n+#ifndef HVF_INT_H\n+#define HVF_INT_H\n+\n+#include <Hypervisor/hv.h>\n+\n+/* hvf_slot flags */\n+#define HVF_SLOT_LOG (1 << 0)\n+\n+typedef struct hvf_slot {\n+ uint64_t start;\n+ uint64_t size;\n+ uint8_t *mem;\n+ int slot_id;\n+ uint32_t flags;\n+ MemoryRegion *region;\n+} hvf_slot;\n+\n+typedef struct hvf_vcpu_caps {\n+ uint64_t vmx_cap_pinbased;\n+ uint64_t vmx_cap_procbased;\n+ uint64_t vmx_cap_procbased2;\n+ uint64_t vmx_cap_entry;\n+ uint64_t vmx_cap_exit;\n+ uint64_t vmx_cap_preemption_timer;\n+} hvf_vcpu_caps;\n+\n+struct HVFState {\n+ AccelState parent;\n+ hvf_slot slots[32];\n+ int num_slots;\n+\n+ hvf_vcpu_caps *hvf_caps;\n+};\n+extern HVFState *hvf_state;\n+\n+void assert_hvf_ok(hv_return_t ret);\n+int hvf_get_registers(CPUState *cpu);\n+int hvf_put_registers(CPUState *cpu);\n+int hvf_arch_init_vcpu(CPUState *cpu);\n+void hvf_arch_vcpu_destroy(CPUState *cpu);\n+int hvf_vcpu_exec(CPUState *cpu);\n+hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);\n+\n+#endif\ndiff --git a/target/i386/hvf/hvf-cpus.c b/target/i386/hvf/hvf-cpus.c\ndeleted file mode 100644\nindex 817b3d7452..0000000000\n--- a/target/i386/hvf/hvf-cpus.c\n+++ /dev/null\n@@ -1,131 +0,0 @@\n-/*\n- * Copyright 2008 IBM Corporation\n- * 2008 Red Hat, Inc.\n- * Copyright 2011 Intel Corporation\n- * Copyright 2016 Veertu, Inc.\n- * Copyright 2017 The Android Open Source Project\n- *\n- * QEMU Hypervisor.framework support\n- *\n- * This program is free software; you can redistribute it and/or\n- * modify it under the terms of version 2 of the GNU General Public\n- * License as published by the Free Software Foundation.\n- *\n- * This program is distributed in the hope that it will be useful,\n- * but WITHOUT ANY WARRANTY; without even the implied warranty of\n- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n- * General Public License for more details.\n- *\n- * You should have received a copy of the GNU General Public License\n- * along with this program; if not, see <http://www.gnu.org/licenses/>.\n- *\n- * This file contain code under public domain from the hvdos project:\n- * https://github.com/mist64/hvdos\n- *\n- * Parts Copyright (c) 2011 NetApp, Inc.\n- * All rights reserved.\n- *\n- * Redistribution and use in source and binary forms, with or without\n- * modification, are permitted provided that the following conditions\n- * are met:\n- * 1. Redistributions of source code must retain the above copyright\n- * notice, this list of conditions and the following disclaimer.\n- * 2. Redistributions in binary form must reproduce the above copyright\n- * notice, this list of conditions and the following disclaimer in the\n- * documentation and/or other materials provided with the distribution.\n- *\n- * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND\n- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n- * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE\n- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n- * SUCH DAMAGE.\n- */\n-\n-#include \"qemu/osdep.h\"\n-#include \"qemu/error-report.h\"\n-#include \"qemu/main-loop.h\"\n-#include \"sysemu/hvf.h\"\n-#include \"sysemu/runstate.h\"\n-#include \"target/i386/cpu.h\"\n-#include \"qemu/guest-random.h\"\n-\n-#include \"hvf-cpus.h\"\n-\n-/*\n- * The HVF-specific vCPU thread function. This one should only run when the host\n- * CPU supports the VMX \"unrestricted guest\" feature.\n- */\n-static void *hvf_cpu_thread_fn(void *arg)\n-{\n- CPUState *cpu = arg;\n-\n- int r;\n-\n- assert(hvf_enabled());\n-\n- rcu_register_thread();\n-\n- qemu_mutex_lock_iothread();\n- qemu_thread_get_self(cpu->thread);\n-\n- cpu->thread_id = qemu_get_thread_id();\n- cpu->can_do_io = 1;\n- current_cpu = cpu;\n-\n- hvf_init_vcpu(cpu);\n-\n- /* signal CPU creation */\n- cpu_thread_signal_created(cpu);\n- qemu_guest_random_seed_thread_part2(cpu->random_seed);\n-\n- do {\n- if (cpu_can_run(cpu)) {\n- r = hvf_vcpu_exec(cpu);\n- if (r == EXCP_DEBUG) {\n- cpu_handle_guest_debug(cpu);\n- }\n- }\n- qemu_wait_io_event(cpu);\n- } while (!cpu->unplug || cpu_can_run(cpu));\n-\n- hvf_vcpu_destroy(cpu);\n- cpu_thread_signal_destroyed(cpu);\n- qemu_mutex_unlock_iothread();\n- rcu_unregister_thread();\n- return NULL;\n-}\n-\n-static void hvf_start_vcpu_thread(CPUState *cpu)\n-{\n- char thread_name[VCPU_THREAD_NAME_SIZE];\n-\n- /*\n- * HVF currently does not support TCG, and only runs in\n- * unrestricted-guest mode.\n- */\n- assert(hvf_enabled());\n-\n- cpu->thread = g_malloc0(sizeof(QemuThread));\n- cpu->halt_cond = g_malloc0(sizeof(QemuCond));\n- qemu_cond_init(cpu->halt_cond);\n-\n- snprintf(thread_name, VCPU_THREAD_NAME_SIZE, \"CPU %d/HVF\",\n- cpu->cpu_index);\n- qemu_thread_create(cpu->thread, thread_name, hvf_cpu_thread_fn,\n- cpu, QEMU_THREAD_JOINABLE);\n-}\n-\n-const CpusAccel hvf_cpus = {\n- .create_vcpu_thread = hvf_start_vcpu_thread,\n-\n- .synchronize_post_reset = hvf_cpu_synchronize_post_reset,\n- .synchronize_post_init = hvf_cpu_synchronize_post_init,\n- .synchronize_state = hvf_cpu_synchronize_state,\n- .synchronize_pre_loadvm = hvf_cpu_synchronize_pre_loadvm,\n-};\ndiff --git a/target/i386/hvf/hvf-cpus.h b/target/i386/hvf/hvf-cpus.h\ndeleted file mode 100644\nindex ced31b82c0..0000000000\n--- a/target/i386/hvf/hvf-cpus.h\n+++ /dev/null\n@@ -1,25 +0,0 @@\n-/*\n- * Accelerator CPUS Interface\n- *\n- * Copyright 2020 SUSE LLC\n- *\n- * This work is licensed under the terms of the GNU GPL, version 2 or later.\n- * See the COPYING file in the top-level directory.\n- */\n-\n-#ifndef HVF_CPUS_H\n-#define HVF_CPUS_H\n-\n-#include \"sysemu/cpus.h\"\n-\n-extern const CpusAccel hvf_cpus;\n-\n-int hvf_init_vcpu(CPUState *);\n-int hvf_vcpu_exec(CPUState *);\n-void hvf_cpu_synchronize_state(CPUState *);\n-void hvf_cpu_synchronize_post_reset(CPUState *);\n-void hvf_cpu_synchronize_post_init(CPUState *);\n-void hvf_cpu_synchronize_pre_loadvm(CPUState *);\n-void hvf_vcpu_destroy(CPUState *);\n-\n-#endif /* HVF_CPUS_H */\ndiff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h\nindex e31938e5ff..f41f9444b4 100644\n--- a/target/i386/hvf/hvf-i386.h\n+++ b/target/i386/hvf/hvf-i386.h\n@@ -18,42 +18,11 @@\n \n #include \"sysemu/accel.h\"\n #include \"sysemu/hvf.h\"\n+#include \"sysemu/hvf_int.h\"\n #include \"cpu.h\"\n #include \"x86.h\"\n \n-/* hvf_slot flags */\n-#define HVF_SLOT_LOG (1 << 0)\n-\n-typedef struct hvf_slot {\n- uint64_t start;\n- uint64_t size;\n- uint8_t *mem;\n- int slot_id;\n- uint32_t flags;\n- MemoryRegion *region;\n-} hvf_slot;\n-\n-typedef struct hvf_vcpu_caps {\n- uint64_t vmx_cap_pinbased;\n- uint64_t vmx_cap_procbased;\n- uint64_t vmx_cap_procbased2;\n- uint64_t vmx_cap_entry;\n- uint64_t vmx_cap_exit;\n- uint64_t vmx_cap_preemption_timer;\n-} hvf_vcpu_caps;\n-\n-struct HVFState {\n- AccelState parent;\n- hvf_slot slots[32];\n- int num_slots;\n-\n- hvf_vcpu_caps *hvf_caps;\n-};\n-extern HVFState *hvf_state;\n-\n-void hvf_set_phys_mem(MemoryRegionSection *, bool);\n void hvf_handle_io(CPUArchState *, uint16_t, void *, int, int, int);\n-hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);\n \n #ifdef NEED_CPU_H\n /* Functions exported to host specific mode */\ndiff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c\nindex ed9356565c..8b96ecd619 100644\n--- a/target/i386/hvf/hvf.c\n+++ b/target/i386/hvf/hvf.c\n@@ -51,6 +51,7 @@\n #include \"qemu/error-report.h\"\n \n #include \"sysemu/hvf.h\"\n+#include \"sysemu/hvf_int.h\"\n #include \"sysemu/runstate.h\"\n #include \"hvf-i386.h\"\n #include \"vmcs.h\"\n@@ -72,171 +73,6 @@\n #include \"sysemu/accel.h\"\n #include \"target/i386/cpu.h\"\n \n-#include \"hvf-cpus.h\"\n-\n-HVFState *hvf_state;\n-\n-static void assert_hvf_ok(hv_return_t ret)\n-{\n- if (ret == HV_SUCCESS) {\n- return;\n- }\n-\n- switch (ret) {\n- case HV_ERROR:\n- error_report(\"Error: HV_ERROR\");\n- break;\n- case HV_BUSY:\n- error_report(\"Error: HV_BUSY\");\n- break;\n- case HV_BAD_ARGUMENT:\n- error_report(\"Error: HV_BAD_ARGUMENT\");\n- break;\n- case HV_NO_RESOURCES:\n- error_report(\"Error: HV_NO_RESOURCES\");\n- break;\n- case HV_NO_DEVICE:\n- error_report(\"Error: HV_NO_DEVICE\");\n- break;\n- case HV_UNSUPPORTED:\n- error_report(\"Error: HV_UNSUPPORTED\");\n- break;\n- default:\n- error_report(\"Unknown Error\");\n- }\n-\n- abort();\n-}\n-\n-/* Memory slots */\n-hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)\n-{\n- hvf_slot *slot;\n- int x;\n- for (x = 0; x < hvf_state->num_slots; ++x) {\n- slot = &hvf_state->slots[x];\n- if (slot->size && start < (slot->start + slot->size) &&\n- (start + size) > slot->start) {\n- return slot;\n- }\n- }\n- return NULL;\n-}\n-\n-struct mac_slot {\n- int present;\n- uint64_t size;\n- uint64_t gpa_start;\n- uint64_t gva;\n-};\n-\n-struct mac_slot mac_slots[32];\n-\n-static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)\n-{\n- struct mac_slot *macslot;\n- hv_return_t ret;\n-\n- macslot = &mac_slots[slot->slot_id];\n-\n- if (macslot->present) {\n- if (macslot->size != slot->size) {\n- macslot->present = 0;\n- ret = hv_vm_unmap(macslot->gpa_start, macslot->size);\n- assert_hvf_ok(ret);\n- }\n- }\n-\n- if (!slot->size) {\n- return 0;\n- }\n-\n- macslot->present = 1;\n- macslot->gpa_start = slot->start;\n- macslot->size = slot->size;\n- ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);\n- assert_hvf_ok(ret);\n- return 0;\n-}\n-\n-void hvf_set_phys_mem(MemoryRegionSection *section, bool add)\n-{\n- hvf_slot *mem;\n- MemoryRegion *area = section->mr;\n- bool writeable = !area->readonly && !area->rom_device;\n- hv_memory_flags_t flags;\n-\n- if (!memory_region_is_ram(area)) {\n- if (writeable) {\n- return;\n- } else if (!memory_region_is_romd(area)) {\n- /*\n- * If the memory device is not in romd_mode, then we actually want\n- * to remove the hvf memory slot so all accesses will trap.\n- */\n- add = false;\n- }\n- }\n-\n- mem = hvf_find_overlap_slot(\n- section->offset_within_address_space,\n- int128_get64(section->size));\n-\n- if (mem && add) {\n- if (mem->size == int128_get64(section->size) &&\n- mem->start == section->offset_within_address_space &&\n- mem->mem == (memory_region_get_ram_ptr(area) +\n- section->offset_within_region)) {\n- return; /* Same region was attempted to register, go away. */\n- }\n- }\n-\n- /* Region needs to be reset. set the size to 0 and remap it. */\n- if (mem) {\n- mem->size = 0;\n- if (do_hvf_set_memory(mem, 0)) {\n- error_report(\"Failed to reset overlapping slot\");\n- abort();\n- }\n- }\n-\n- if (!add) {\n- return;\n- }\n-\n- if (area->readonly ||\n- (!memory_region_is_ram(area) && memory_region_is_romd(area))) {\n- flags = HV_MEMORY_READ | HV_MEMORY_EXEC;\n- } else {\n- flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;\n- }\n-\n- /* Now make a new slot. */\n- int x;\n-\n- for (x = 0; x < hvf_state->num_slots; ++x) {\n- mem = &hvf_state->slots[x];\n- if (!mem->size) {\n- break;\n- }\n- }\n-\n- if (x == hvf_state->num_slots) {\n- error_report(\"No free slots\");\n- abort();\n- }\n-\n- mem->size = int128_get64(section->size);\n- mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;\n- mem->start = section->offset_within_address_space;\n- mem->region = area;\n-\n- if (do_hvf_set_memory(mem, flags)) {\n- error_report(\"Error registering new memory slot\");\n- abort();\n- }\n-}\n-\n void vmx_update_tpr(CPUState *cpu)\n {\n /* TODO: need integrate APIC handling */\n@@ -276,56 +112,6 @@ void hvf_handle_io(CPUArchState *env, uint16_t port, void *buffer,\n }\n }\n \n-static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)\n-{\n- if (!cpu->vcpu_dirty) {\n- hvf_get_registers(cpu);\n- cpu->vcpu_dirty = true;\n- }\n-}\n-\n-void hvf_cpu_synchronize_state(CPUState *cpu)\n-{\n- if (!cpu->vcpu_dirty) {\n- run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);\n- }\n-}\n-\n-static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,\n- run_on_cpu_data arg)\n-{\n- hvf_put_registers(cpu);\n- cpu->vcpu_dirty = false;\n-}\n-\n-void hvf_cpu_synchronize_post_reset(CPUState *cpu)\n-{\n- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);\n-}\n-\n-static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,\n- run_on_cpu_data arg)\n-{\n- hvf_put_registers(cpu);\n- cpu->vcpu_dirty = false;\n-}\n-\n-void hvf_cpu_synchronize_post_init(CPUState *cpu)\n-{\n- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);\n-}\n-\n-static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,\n- run_on_cpu_data arg)\n-{\n- cpu->vcpu_dirty = true;\n-}\n-\n-void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)\n-{\n- run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);\n-}\n-\n static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)\n {\n int read, write;\n@@ -370,109 +156,19 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)\n return false;\n }\n \n-static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)\n-{\n- hvf_slot *slot;\n-\n- slot = hvf_find_overlap_slot(\n- section->offset_within_address_space,\n- int128_get64(section->size));\n-\n- /* protect region against writes; begin tracking it */\n- if (on) {\n- slot->flags |= HVF_SLOT_LOG;\n- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,\n- HV_MEMORY_READ);\n- /* stop tracking region*/\n- } else {\n- slot->flags &= ~HVF_SLOT_LOG;\n- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,\n- HV_MEMORY_READ | HV_MEMORY_WRITE);\n- }\n-}\n-\n-static void hvf_log_start(MemoryListener *listener,\n- MemoryRegionSection *section, int old, int new)\n-{\n- if (old != 0) {\n- return;\n- }\n-\n- hvf_set_dirty_tracking(section, 1);\n-}\n-\n-static void hvf_log_stop(MemoryListener *listener,\n- MemoryRegionSection *section, int old, int new)\n-{\n- if (new != 0) {\n- return;\n- }\n-\n- hvf_set_dirty_tracking(section, 0);\n-}\n-\n-static void hvf_log_sync(MemoryListener *listener,\n- MemoryRegionSection *section)\n-{\n- /*\n- * sync of dirty pages is handled elsewhere; just make sure we keep\n- * tracking the region.\n- */\n- hvf_set_dirty_tracking(section, 1);\n-}\n-\n-static void hvf_region_add(MemoryListener *listener,\n- MemoryRegionSection *section)\n-{\n- hvf_set_phys_mem(section, true);\n-}\n-\n-static void hvf_region_del(MemoryListener *listener,\n- MemoryRegionSection *section)\n-{\n- hvf_set_phys_mem(section, false);\n-}\n-\n-static MemoryListener hvf_memory_listener = {\n- .priority = 10,\n- .region_add = hvf_region_add,\n- .region_del = hvf_region_del,\n- .log_start = hvf_log_start,\n- .log_stop = hvf_log_stop,\n- .log_sync = hvf_log_sync,\n-};\n-\n-void hvf_vcpu_destroy(CPUState *cpu)\n+void hvf_arch_vcpu_destroy(CPUState *cpu)\n {\n X86CPU *x86_cpu = X86_CPU(cpu);\n CPUX86State *env = &x86_cpu->env;\n \n- hv_return_t ret = hv_vcpu_destroy((hv_vcpuid_t)cpu->hvf_fd);\n g_free(env->hvf_mmio_buf);\n- assert_hvf_ok(ret);\n-}\n-\n-static void dummy_signal(int sig)\n-{\n }\n \n-int hvf_init_vcpu(CPUState *cpu)\n+int hvf_arch_init_vcpu(CPUState *cpu)\n {\n \n X86CPU *x86cpu = X86_CPU(cpu);\n CPUX86State *env = &x86cpu->env;\n- int r;\n-\n- /* init cpu signals */\n- sigset_t set;\n- struct sigaction sigact;\n-\n- memset(&sigact, 0, sizeof(sigact));\n- sigact.sa_handler = dummy_signal;\n- sigaction(SIG_IPI, &sigact, NULL);\n-\n- pthread_sigmask(SIG_BLOCK, NULL, &set);\n- sigdelset(&set, SIG_IPI);\n \n init_emu();\n init_decoder();\n@@ -480,10 +176,6 @@ int hvf_init_vcpu(CPUState *cpu)\n hvf_state->hvf_caps = g_new0(struct hvf_vcpu_caps, 1);\n env->hvf_mmio_buf = g_new(char, 4096);\n \n- r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);\n- cpu->vcpu_dirty = 1;\n- assert_hvf_ok(r);\n-\n if (hv_vmx_read_capability(HV_VMX_CAP_PINBASED,\n &hvf_state->hvf_caps->vmx_cap_pinbased)) {\n abort();\n@@ -865,49 +557,3 @@ int hvf_vcpu_exec(CPUState *cpu)\n \n return ret;\n }\n-\n-bool hvf_allowed;\n-\n-static int hvf_accel_init(MachineState *ms)\n-{\n- int x;\n- hv_return_t ret;\n- HVFState *s;\n-\n- ret = hv_vm_create(HV_VM_DEFAULT);\n- assert_hvf_ok(ret);\n-\n- s = g_new0(HVFState, 1);\n- \n- s->num_slots = 32;\n- for (x = 0; x < s->num_slots; ++x) {\n- s->slots[x].size = 0;\n- s->slots[x].slot_id = x;\n- }\n- \n- hvf_state = s;\n- memory_listener_register(&hvf_memory_listener, &address_space_memory);\n- cpus_register_accel(&hvf_cpus);\n- return 0;\n-}\n-\n-static void hvf_accel_class_init(ObjectClass *oc, void *data)\n-{\n- AccelClass *ac = ACCEL_CLASS(oc);\n- ac->name = \"HVF\";\n- ac->init_machine = hvf_accel_init;\n- ac->allowed = &hvf_allowed;\n-}\n-\n-static const TypeInfo hvf_accel_type = {\n- .name = TYPE_HVF_ACCEL,\n- .parent = TYPE_ACCEL,\n- .class_init = hvf_accel_class_init,\n-};\n-\n-static void hvf_type_init(void)\n-{\n- type_register_static(&hvf_accel_type);\n-}\n-\n-type_init(hvf_type_init);\ndiff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build\nindex 409c9a3f14..c8a43717ee 100644\n--- a/target/i386/hvf/meson.build\n+++ b/target/i386/hvf/meson.build\n@@ -1,6 +1,5 @@\n i386_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(\n 'hvf.c',\n- 'hvf-cpus.c',\n 'x86.c',\n 'x86_cpuid.c',\n 'x86_decode.c',\ndiff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c\nindex bbec412b6c..89b8e9d87a 100644\n--- a/target/i386/hvf/x86hvf.c\n+++ b/target/i386/hvf/x86hvf.c\n@@ -20,6 +20,9 @@\n #include \"qemu/osdep.h\"\n \n #include \"qemu-common.h\"\n+#include \"sysemu/hvf.h\"\n+#include \"sysemu/hvf_int.h\"\n+#include \"sysemu/hw_accel.h\"\n #include \"x86hvf.h\"\n #include \"vmx.h\"\n #include \"vmcs.h\"\n@@ -32,8 +35,6 @@\n #include <Hypervisor/hv.h>\n #include <Hypervisor/hv_vmx.h>\n \n-#include \"hvf-cpus.h\"\n-\n void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,\n SegmentCache *qseg, bool is_tr)\n {\n@@ -437,7 +438,7 @@ int hvf_process_events(CPUState *cpu_state)\n env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);\n \n if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {\n- hvf_cpu_synchronize_state(cpu_state);\n+ cpu_synchronize_state(cpu_state);\n do_cpu_init(cpu);\n }\n \n@@ -451,12 +452,12 @@ int hvf_process_events(CPUState *cpu_state)\n cpu_state->halted = 0;\n }\n if (cpu_state->interrupt_request & CPU_INTERRUPT_SIPI) {\n- hvf_cpu_synchronize_state(cpu_state);\n+ cpu_synchronize_state(cpu_state);\n do_cpu_sipi(cpu);\n }\n if (cpu_state->interrupt_request & CPU_INTERRUPT_TPR) {\n cpu_state->interrupt_request &= ~CPU_INTERRUPT_TPR;\n- hvf_cpu_synchronize_state(cpu_state);\n+ cpu_synchronize_state(cpu_state);\n apic_handle_tpr_access_report(cpu->apic_state, env->eip,\n env->tpr_access_type);\n }\ndiff --git a/target/i386/hvf/x86hvf.h b/target/i386/hvf/x86hvf.h\nindex 635ab0f34e..99ed8d608d 100644\n--- a/target/i386/hvf/x86hvf.h\n+++ b/target/i386/hvf/x86hvf.h\n@@ -21,8 +21,6 @@\n #include \"x86_descr.h\"\n \n int hvf_process_events(CPUState *);\n-int hvf_put_registers(CPUState *);\n-int hvf_get_registers(CPUState *);\n bool hvf_inject_interrupts(CPUState *);\n void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,\n SegmentCache *qseg, bool is_tr);\n", "prefixes": [ "v6", "03/11" ] }