get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/1429470/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "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"
    ]
}