Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2219163/?format=api
{ "id": 2219163, "url": "http://patchwork.ozlabs.org/api/patches/2219163/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260402-mshv_accel_arm64_supp-v2-5-754895c15e9e@linux.microsoft.com/", "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": "<20260402-mshv_accel_arm64_supp-v2-5-754895c15e9e@linux.microsoft.com>", "list_archive_url": null, "date": "2026-04-02T12:52:32", "name": "[v2,05/14] target/arm/mshv: implement -cpu host for MSHV", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "280179483e908b988ae7fea2713471a1fc3a2bf6", "submitter": { "id": 92925, "url": "http://patchwork.ozlabs.org/api/people/92925/?format=api", "name": "Aastha Rawat", "email": "aastharawat@linux.microsoft.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260402-mshv_accel_arm64_supp-v2-5-754895c15e9e@linux.microsoft.com/mbox/", "series": [ { "id": 498484, "url": "http://patchwork.ozlabs.org/api/series/498484/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=498484", "date": "2026-04-02T12:52:39", "name": "Add ARM64 support for MSHV accelerator", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/498484/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2219163/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2219163/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@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=linux.microsoft.com header.i=@linux.microsoft.com\n header.a=rsa-sha256 header.s=default header.b=BD1sLZkH;\n\tdkim-atps=neutral", "legolas.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=patchwork.ozlabs.org)" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fmjxn6tXsz1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 03 Apr 2026 00:53:49 +1100 (AEDT)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1w8ILH-0008NK-Sr; Thu, 02 Apr 2026 09:44:15 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <aastharawat@linux.microsoft.com>)\n id 1w8IKu-0005fW-2X; Thu, 02 Apr 2026 09:43:53 -0400", "from linux.microsoft.com ([13.77.154.182])\n by eggs.gnu.org with esmtp (Exim 4.90_1)\n (envelope-from <aastharawat@linux.microsoft.com>)\n id 1w8HXu-0008SD-LC; Thu, 02 Apr 2026 08:53:17 -0400", "from localhost (unknown [131.107.147.136])\n by linux.microsoft.com (Postfix) with ESMTPSA id 64D8820B713B;\n Thu, 2 Apr 2026 05:53:01 -0700 (PDT)" ], "DKIM-Filter": "OpenDKIM Filter v2.11.0 linux.microsoft.com 64D8820B713B", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com;\n s=default; t=1775134381;\n bh=TY7n33ExJIL0Bw0UIsz8p5ZQFgxMQ47a5Q5d1DVObQA=;\n h=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n b=BD1sLZkHdf8eweQ1tpQmiksrEnFpDs2ChJjXdttdc0gcH/wqtRfWHi6FZeCOORWon\n ZQEjcce70peIeuWr7rbD/xBbP9UROl3iSS7djjZOkdjLBNc0cG24vJB7ncX5T5giww\n SxrhkBjPqcNcSlbSSkMjerjcArTbfZXXBl9+hd7g=", "From": "Aastha Rawat <aastharawat@linux.microsoft.com>", "Date": "Thu, 02 Apr 2026 12:52:32 +0000", "Subject": "[PATCH v2 05/14] target/arm/mshv: implement -cpu host for MSHV", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "\n <20260402-mshv_accel_arm64_supp-v2-5-754895c15e9e@linux.microsoft.com>", "References": "\n <20260402-mshv_accel_arm64_supp-v2-0-754895c15e9e@linux.microsoft.com>", "In-Reply-To": "\n <20260402-mshv_accel_arm64_supp-v2-0-754895c15e9e@linux.microsoft.com>", "To": "qemu-devel@nongnu.org", "Cc": "Magnus Kulke <magnuskulke@linux.microsoft.com>,\n Wei Liu <wei.liu@kernel.org>, Paolo Bonzini <pbonzini@redhat.com>,\n\t=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>,\n\t=?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= <berrange@redhat.com>, =?utf-8?q?Phil?=\n\t=?utf-8?q?ippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org>,\n Peter Maydell <peter.maydell@linaro.org>,\n Anirudh Rayabharam <anirudh@anirudhrb.com>,\n Aastha Rawat <aastharawat@linux.microsoft.com>,\n Magnus Kulke <magnus.kulke@linux.microsoft.com>, qemu-arm@nongnu.org,\n Alexander Graf <agraf@csgraf.de>, Pedro Barbuda <pbarbuda@microsoft.com>,\n Mohamed Mediouni <mohamed@unpredictable.fr>", "X-Mailer": "b4 0.15.1", "Received-SPF": "pass client-ip=13.77.154.182;\n envelope-from=aastharawat@linux.microsoft.com; helo=linux.microsoft.com", "X-Spam_score_int": "-42", "X-Spam_score": "-4.3", "X-Spam_bar": "----", "X-Spam_report": "(-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3,\n RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001,\n SPF_HELO_PASS=-0.001, 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.29", "Precedence": "list", "List-Id": "qemu development <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>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "This commit enables support for the `-cpu host` option with MSHV\naccelerator on ARM64. The implementation queries the partition's CPU's\nID registers and features via hypervisor interface, allowing to pass all\nCPU capabilities for the host CPU to the guest.\n\nReplace preprocessor config checks with runtime calls to mshv_enabled(),\nkvm_enabled(), etc. This ensures that the correct accelerator is\nselected at runtime when both MSHV and KVM are enabled.\n\nSigned-off-by: Aastha Rawat <aastharawat@linux.microsoft.com>\n---\n accel/mshv/mshv-all.c | 3 +-\n hw/arm/virt.c | 3 +-\n include/hw/hyperv/hvgdk_mini.h | 17 ++++\n include/hw/hyperv/hvhdk.h | 10 ++\n include/system/hw_accel.h | 3 +-\n target/arm/cpu.c | 6 +-\n target/arm/cpu64.c | 24 +++--\n target/arm/mshv/mshv-all.c | 204 +++++++++++++++++++++++++++++++++++++++++\n target/arm/mshv_arm.h | 18 ++++\n 9 files changed, 273 insertions(+), 15 deletions(-)", "diff": "diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c\nindex d4cc7f5371..44f35a1463 100644\n--- a/accel/mshv/mshv-all.c\n+++ b/accel/mshv/mshv-all.c\n@@ -400,13 +400,14 @@ static int mshv_init_vcpu(CPUState *cpu)\n int ret;\n \n cpu->accel = g_new0(AccelCPUState, 1);\n- mshv_arch_init_vcpu(cpu);\n \n ret = mshv_create_vcpu(vm_fd, vp_index, &cpu->accel->cpufd);\n if (ret < 0) {\n return -1;\n }\n \n+ mshv_arch_init_vcpu(cpu);\n+\n cpu->accel->dirty = true;\n \n return 0;\ndiff --git a/hw/arm/virt.c b/hw/arm/virt.c\nindex 7456614d05..34eb5248a9 100644\n--- a/hw/arm/virt.c\n+++ b/hw/arm/virt.c\n@@ -50,6 +50,7 @@\n #include \"system/kvm.h\"\n #include \"system/hvf.h\"\n #include \"system/whpx.h\"\n+#include \"system/mshv.h\"\n #include \"system/qtest.h\"\n #include \"system/system.h\"\n #include \"hw/core/loader.h\"\n@@ -3450,7 +3451,7 @@ static GPtrArray *virt_get_valid_cpu_types(const MachineState *ms)\n if (target_aarch64()) {\n g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME(\"cortex-a53\")));\n g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME(\"cortex-a57\")));\n- if (kvm_enabled() || hvf_enabled()) {\n+ if (kvm_enabled() || hvf_enabled() || mshv_enabled()) {\n g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME(\"host\")));\n }\n }\ndiff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h\nindex dfe94050f4..d56be0d70f 100644\n--- a/include/hw/hyperv/hvgdk_mini.h\n+++ b/include/hw/hyperv/hvgdk_mini.h\n@@ -48,6 +48,20 @@ typedef enum hv_register_name {\n HV_ARM64_REGISTER_LR = 0x0002001E,\n HV_ARM64_REGISTER_PC = 0x00020022,\n \n+ /* AArch64 System Register Descriptions: ID Registers */\n+ HV_ARM64_REGISTER_ID_MIDR_EL1 = 0x00022000,\n+ HV_ARM64_REGISTER_ID_MPIDR_EL1 = 0x00022005,\n+ HV_ARM64_REGISTER_ID_AA64_PFR0_EL1 = 0x00022020,\n+ HV_ARM64_REGISTER_ID_AA64_PFR1_EL1 = 0x00022021,\n+ HV_ARM64_REGISTER_ID_AA64_ISAR0_EL1 = 0x00022030,\n+ HV_ARM64_REGISTER_ID_AA64_ISAR1_EL1 = 0x00022031,\n+ HV_ARM64_REGISTER_ID_AA64_ISAR2_EL1 = 0x00022032,\n+ HV_ARM64_REGISTER_ID_AA64_MMFR0_EL1 = 0x00022038,\n+ HV_ARM64_REGISTER_ID_AA64_MMFR1_EL1 = 0x00022039,\n+ HV_ARM64_REGISTER_ID_AA64_MMFR2_EL1 = 0x0002203a,\n+ HV_ARM64_REGISTER_ID_AA64_DFR0_EL1 = 0x00022028,\n+ HV_ARM64_REGISTER_ID_AA64_DFR1_EL1 = 0x00022029,\n+\n /* AArch64 System Register Descriptions: General system control registers */\n HV_ARM64_REGISTER_MIDR_EL1 = 0x00040051,\n HV_ARM64_REGISTER_MPIDR_EL1 = 0x00040001,\n@@ -841,6 +855,9 @@ struct hv_cpuid {\n #define HV_HYP_PAGE_SIZE BIT(HV_HYP_PAGE_SHIFT)\n #define HV_HYP_PAGE_MASK (~(HV_HYP_PAGE_SIZE - 1))\n \n+#define HV_ANY_VP ((uint32_t)-1)\n+#define HV_VTL_ALL 0xF\n+\n #define HVCALL_GET_PARTITION_PROPERTY 0x0044\n #define HVCALL_SET_PARTITION_PROPERTY 0x0045\n #define HVCALL_GET_VP_REGISTERS 0x0050\ndiff --git a/include/hw/hyperv/hvhdk.h b/include/hw/hyperv/hvhdk.h\nindex 866c8211bf..2e1ef80972 100644\n--- a/include/hw/hyperv/hvhdk.h\n+++ b/include/hw/hyperv/hvhdk.h\n@@ -18,6 +18,16 @@ struct hv_input_set_partition_property {\n uint64_t property_value;\n };\n \n+struct hv_input_get_partition_property {\n+ uint64_t partition_id;\n+ uint32_t property_code; /* enum hv_partition_property_code */\n+ uint32_t padding;\n+};\n+\n+struct hv_output_get_partition_property {\n+ uint64_t property_value;\n+};\n+\n union hv_partition_synthetic_processor_features {\n uint64_t as_uint64[HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS];\n \ndiff --git a/include/system/hw_accel.h b/include/system/hw_accel.h\nindex f0c10b6d80..614ea60be3 100644\n--- a/include/system/hw_accel.h\n+++ b/include/system/hw_accel.h\n@@ -51,7 +51,8 @@ static inline bool hwaccel_enabled(void)\n return hvf_enabled()\n || kvm_enabled()\n || nvmm_enabled()\n- || whpx_enabled();\n+ || whpx_enabled()\n+ || mshv_enabled();\n }\n \n #endif /* QEMU_HW_ACCEL_H */\ndiff --git a/target/arm/cpu.c b/target/arm/cpu.c\nindex 7e3e84b4bb..8aa22747ff 100644\n--- a/target/arm/cpu.c\n+++ b/target/arm/cpu.c\n@@ -46,6 +46,7 @@\n #include \"system/tcg.h\"\n #include \"system/qtest.h\"\n #include \"system/hw_accel.h\"\n+#include \"system/mshv.h\"\n #include \"kvm_arm.h\"\n #include \"disas/capstone.h\"\n #include \"fpu/softfloat.h\"\n@@ -1629,8 +1630,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)\n * this is the first point where we can report it.\n */\n if (cpu->host_cpu_probe_failed) {\n- if (!kvm_enabled() && !hvf_enabled()) {\n- error_setg(errp, \"The 'host' CPU type can only be used with KVM or HVF\");\n+ if (!kvm_enabled() && !hvf_enabled() && !mshv_enabled()) {\n+ error_setg(errp,\n+ \"The 'host' CPU type can only be used with KVM, HVF, or MSHV\");\n } else {\n error_setg(errp, \"Failed to retrieve host CPU features\");\n }\ndiff --git a/target/arm/cpu64.c b/target/arm/cpu64.c\nindex d6feba220e..59cb23dd99 100644\n--- a/target/arm/cpu64.c\n+++ b/target/arm/cpu64.c\n@@ -26,12 +26,14 @@\n #include \"qemu/units.h\"\n #include \"system/kvm.h\"\n #include \"system/hvf.h\"\n+#include \"system/mshv.h\"\n #include \"system/whpx.h\"\n #include \"system/hw_accel.h\"\n #include \"system/qtest.h\"\n #include \"system/tcg.h\"\n #include \"kvm_arm.h\"\n #include \"hvf_arm.h\"\n+#include \"mshv_arm.h\"\n #include \"whpx_arm.h\"\n #include \"qapi/visitor.h\"\n #include \"hw/core/qdev-properties.h\"\n@@ -821,16 +823,18 @@ static void aarch64_host_initfn(Object *obj)\n }\n #endif\n \n-#if defined(CONFIG_KVM)\n- kvm_arm_set_cpu_features_from_host(cpu);\n- aarch64_add_sve_properties(obj);\n-#elif defined(CONFIG_HVF)\n- hvf_arm_set_cpu_features_from_host(cpu);\n-#elif defined(CONFIG_WHPX)\n- whpx_arm_set_cpu_features_from_host(cpu);\n-#else\n- g_assert_not_reached();\n-#endif\n+ if (mshv_enabled()) {\n+ mshv_arm_set_cpu_features_from_host(cpu);\n+ } else if (kvm_enabled()) {\n+ kvm_arm_set_cpu_features_from_host(cpu);\n+ aarch64_add_sve_properties(obj);\n+ } else if (hvf_enabled()) {\n+ hvf_arm_set_cpu_features_from_host(cpu);\n+ } else if (whpx_enabled()) {\n+ whpx_arm_set_cpu_features_from_host(cpu);\n+ } else {\n+ g_assert_not_reached();\n+ }\n if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {\n aarch64_add_pauth_properties(obj);\n }\ndiff --git a/target/arm/mshv/mshv-all.c b/target/arm/mshv/mshv-all.c\nindex ad9cb267a8..db1174b444 100644\n--- a/target/arm/mshv/mshv-all.c\n+++ b/target/arm/mshv/mshv-all.c\n@@ -18,10 +18,23 @@\n \n #include \"system/cpus.h\"\n #include \"target/arm/cpu.h\"\n+#include \"target/arm/internals.h\"\n+#include \"target/arm/mshv_arm.h\"\n \n #include \"system/mshv.h\"\n #include \"system/mshv_int.h\"\n #include \"hw/hyperv/hvgdk_mini.h\"\n+#include \"hw/hyperv/hvhdk_mini.h\"\n+\n+typedef struct ARMHostCPUFeatures {\n+ ARMISARegisters isar;\n+ uint64_t features;\n+ uint64_t midr;\n+ uint32_t reset_sctlr;\n+ const char *dtb_compatible;\n+} ARMHostCPUFeatures;\n+\n+static ARMHostCPUFeatures arm_host_cpu_features;\n \n static enum hv_register_name STANDARD_REGISTER_NAMES[32] = {\n HV_ARM64_REGISTER_X0,\n@@ -190,3 +203,194 @@ int mshv_arch_post_init_vm(int vm_fd)\n {\n return 0;\n }\n+\n+static uint32_t mshv_arm_get_ipa_bit_size(int mshv_fd)\n+{\n+ int ret;\n+ struct hv_input_get_partition_property in = {0};\n+ struct hv_output_get_partition_property out = {0};\n+ struct mshv_root_hvcall args = {0};\n+\n+ in.property_code = HV_PARTITION_PROPERTY_PHYSICAL_ADDRESS_WIDTH;\n+\n+ args.code = HVCALL_GET_PARTITION_PROPERTY;\n+ args.in_sz = sizeof(in);\n+ args.in_ptr = (uint64_t)∈\n+ args.out_sz = sizeof(out);\n+ args.out_ptr = (uint64_t)&out;\n+\n+ ret = mshv_hvcall(mshv_fd, &args);\n+\n+ if (ret < 0) {\n+ error_report(\"Failed to get IPA size\");\n+ exit(1);\n+ }\n+\n+ return out.property_value;\n+}\n+\n+static void clamp_id_aa64mmfr0_parange_to_ipa_size(int mshv_fd,\n+ ARMISARegisters *isar)\n+{\n+ uint32_t ipa_size = mshv_arm_get_ipa_bit_size(mshv_fd);\n+ uint64_t id_aa64mmfr0;\n+\n+ /* Clamp down the PARange to the IPA size the kernel supports. */\n+ uint8_t index = round_down_to_parange_index(ipa_size);\n+ id_aa64mmfr0 = GET_IDREG(isar, ID_AA64MMFR0);\n+ id_aa64mmfr0 = (id_aa64mmfr0 & ~R_ID_AA64MMFR0_PARANGE_MASK) | index;\n+ SET_IDREG(isar, ID_AA64MMFR0, id_aa64mmfr0);\n+}\n+\n+static int mshv_get_partition_regs(int vm_fd, hv_register_name *names,\n+ hv_register_value *values, size_t n_regs)\n+{\n+ int ret = 0;\n+ size_t in_sz, names_sz, values_sz;\n+ void *in_buffer = qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE);\n+ void *out_buffer = qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE);\n+ hv_input_get_vp_registers *in = in_buffer;\n+\n+ struct mshv_root_hvcall args = {0};\n+\n+ names_sz = n_regs * sizeof(hv_register_name);\n+ in_sz = sizeof(hv_input_get_vp_registers) + names_sz;\n+\n+ memset(in, 0, HV_HYP_PAGE_SIZE);\n+\n+ in->vp_index = HV_ANY_VP;\n+ in->input_vtl.target_vtl = HV_VTL_ALL;\n+ in->input_vtl.use_target_vtl = 1;\n+\n+ for (int i = 0; i < n_regs; i++) {\n+ in->names[i] = names[i];\n+ }\n+\n+ values_sz = n_regs * sizeof(hv_register_value);\n+\n+ args.code = HVCALL_GET_VP_REGISTERS;\n+ args.in_sz = in_sz;\n+ args.in_ptr = (uintptr_t)(in_buffer);\n+ args.out_sz = values_sz;\n+ args.out_ptr = (uintptr_t)(out_buffer);\n+ args.reps = (uint16_t) n_regs;\n+\n+ ret = mshv_hvcall(vm_fd, &args);\n+\n+ if (ret == 0) {\n+ memcpy(values, out_buffer, values_sz);\n+ }\n+\n+ qemu_vfree(in_buffer);\n+ qemu_vfree(out_buffer);\n+\n+ return ret;\n+}\n+\n+static bool mshv_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)\n+{\n+ int mshv_fd = mshv_state->fd;\n+ int vm_fd = mshv_state->vm;\n+ int i, ret;\n+ bool success = true;\n+ uint64_t pfr0, pfr1;\n+ gchar *contents = NULL;\n+\n+ const struct {\n+ hv_register_name name;\n+ int isar_idx;\n+ } regs[] = {\n+ { HV_ARM64_REGISTER_ID_AA64_PFR0_EL1, ID_AA64PFR0_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_PFR1_EL1, ID_AA64PFR1_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_ISAR0_EL1, ID_AA64ISAR0_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_ISAR1_EL1, ID_AA64ISAR1_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_ISAR2_EL1, ID_AA64ISAR2_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_MMFR0_EL1, ID_AA64MMFR0_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_MMFR1_EL1, ID_AA64MMFR1_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_MMFR2_EL1, ID_AA64MMFR2_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_DFR0_EL1, ID_AA64DFR0_EL1_IDX },\n+ { HV_ARM64_REGISTER_ID_AA64_DFR1_EL1, ID_AA64DFR1_EL1_IDX },\n+ };\n+\n+ size_t n_regs = ARRAY_SIZE(regs);\n+ hv_register_name *reg_names = g_new(hv_register_name, n_regs);\n+ hv_register_value *reg_values = g_new(hv_register_value, n_regs);\n+\n+ for (i = 0; i < n_regs; i++) {\n+ reg_names[i] = regs[i].name;\n+ }\n+\n+ ret = mshv_get_partition_regs(vm_fd, reg_names, reg_values, n_regs);\n+\n+ if (ret < 0) {\n+ error_report(\"Failed to get host ID registers\");\n+ success = false;\n+ goto out;\n+ }\n+\n+ for (i = 0; i < n_regs; i++) {\n+ ahcf->isar.idregs[regs[i].isar_idx] = reg_values[i].reg64;\n+ }\n+\n+ /* Read MIDR_EL1 from sysfs */\n+ if (g_file_get_contents(\n+ \"/sys/devices/system/cpu/cpu0/regs/identification/midr_el1\",\n+ &contents, NULL, NULL)) {\n+ ahcf->midr = g_ascii_strtoull(contents, NULL, 0);\n+ } else {\n+ error_report(\"Failed to read MIDR_EL1 from sysfs\");\n+ success = false;\n+ goto out;\n+ }\n+\n+ ahcf->dtb_compatible = \"arm,armv8\";\n+ ahcf->features = (1ULL << ARM_FEATURE_V8) |\n+ (1ULL << ARM_FEATURE_AARCH64) |\n+ (1ULL << ARM_FEATURE_PMU) |\n+ (1ULL << ARM_FEATURE_GENERIC_TIMER) |\n+ (1ULL << ARM_FEATURE_NEON);\n+\n+ clamp_id_aa64mmfr0_parange_to_ipa_size(mshv_fd, &ahcf->isar);\n+\n+ /*\n+ * SVE (Scalable Vector Extension) and SME (Scalable Matrix Extension)\n+ * require specific context switch logic in the accelerator.\n+ * Mask them out for now to ensure stability.\n+ */\n+ /* Mask SVE in PFR0 */\n+ pfr0 = GET_IDREG(&ahcf->isar, ID_AA64PFR0);\n+ pfr0 &= ~R_ID_AA64PFR0_SVE_MASK;\n+ SET_IDREG(&ahcf->isar, ID_AA64PFR0, pfr0);\n+\n+ /* Mask SME in PFR1 */\n+ pfr1 = GET_IDREG(&ahcf->isar, ID_AA64PFR1);\n+ pfr1 &= ~R_ID_AA64PFR1_SME_MASK;\n+ SET_IDREG(&ahcf->isar, ID_AA64PFR1, pfr1);\n+\n+out:\n+ g_free(contents);\n+ g_free(reg_names);\n+ g_free(reg_values);\n+ return success;\n+}\n+\n+void mshv_arm_set_cpu_features_from_host(ARMCPU *cpu)\n+{\n+ if (!arm_host_cpu_features.dtb_compatible) {\n+ if (!mshv_enabled() ||\n+ !mshv_arm_get_host_cpu_features(&arm_host_cpu_features)) {\n+ /*\n+ * We can't report this error yet, so flag that we need to\n+ * in arm_cpu_realizefn().\n+ */\n+ cpu->host_cpu_probe_failed = true;\n+ return;\n+ }\n+ }\n+\n+ cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;\n+ cpu->isar = arm_host_cpu_features.isar;\n+ cpu->env.features = arm_host_cpu_features.features;\n+ cpu->midr = arm_host_cpu_features.midr;\n+ cpu->reset_sctlr = arm_host_cpu_features.reset_sctlr;\n+}\ndiff --git a/target/arm/mshv_arm.h b/target/arm/mshv_arm.h\nnew file mode 100644\nindex 0000000000..a03f9a4405\n--- /dev/null\n+++ b/target/arm/mshv_arm.h\n@@ -0,0 +1,18 @@\n+/*\n+ * QEMU MSHV support\n+ *\n+ * Copyright Microsoft, Corp. 2026\n+ *\n+ * Authors: Aastha Rawat <aastharawat@linux.microsoft.com>\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#ifndef QEMU_MSHV_ARM_H\n+#define QEMU_MSHV_ARM_H\n+\n+#include \"target/arm/cpu.h\"\n+\n+void mshv_arm_set_cpu_features_from_host(ARMCPU *cpu);\n+\n+#endif\n", "prefixes": [ "v2", "05/14" ] }