Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2219137/?format=api
{ "id": 2219137, "url": "http://patchwork.ozlabs.org/api/patches/2219137/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260402-mshv_accel_arm64_supp-v2-2-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-2-754895c15e9e@linux.microsoft.com>", "list_archive_url": null, "date": "2026-04-02T12:52:29", "name": "[v2,02/14] accel/mshv: extract common CPU register helpers", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "f178f79d9bb92d1b00fd690d0fc8d06cdab77ee3", "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-2-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/2219137/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2219137/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=SCHwIjL6;\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 4fmjmx4LhLz1yGH\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 03 Apr 2026 00:46:09 +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 1w8ILI-0008P4-Sn; Thu, 02 Apr 2026 09:44:16 -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 1w8IKw-0004lE-8H; Thu, 02 Apr 2026 09:43:55 -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 1w8HXl-0008QM-JN; Thu, 02 Apr 2026 08:53:09 -0400", "from localhost (unknown [131.107.147.136])\n by linux.microsoft.com (Postfix) with ESMTPSA id 5803620B7135;\n Thu, 2 Apr 2026 05:52:59 -0700 (PDT)" ], "DKIM-Filter": "OpenDKIM Filter v2.11.0 linux.microsoft.com 5803620B7135", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com;\n s=default; t=1775134379;\n bh=HJT/I+bbATbzpZa7IFBQev2FeK1wmUQopVue49jowBM=;\n h=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n b=SCHwIjL692COZw/8pbjnMyFLcDEBqUgjJxhYYbB2tMutNb0ass7XBrDxmTE9R2Rq+\n S9la6TDwxEvlbT8HBds/MXENFavkTnF37TXsPiuXFDRSNP8TWFwlup3XfyjMdcKeuQ\n +apmEAUZ82TEGl37mFZ0vmoXhNKhqyrp8XU4315s=", "From": "Aastha Rawat <aastharawat@linux.microsoft.com>", "Date": "Thu, 02 Apr 2026 12:52:29 +0000", "Subject": "[PATCH v2 02/14] accel/mshv: extract common CPU register helpers", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "\n <20260402-mshv_accel_arm64_supp-v2-2-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": "Move arch-independent MSHV CPU register handling functions into\naccel/mshv/mshv-cpu-common.c. Update x86 MSHV backends to use these\nshared helpers.\n\nPrefix get_generic_regs() with mshv_ for proper namespacing since it\nis now public.\n\nSigned-off-by: Aastha Rawat <aastharawat@linux.microsoft.com>\n---\n accel/mshv/meson.build | 3 +-\n accel/mshv/mshv-cpu-common.c | 151 +++++++++++++++++++++++++++++++++++++++++++\n include/system/mshv_int.h | 3 +\n target/i386/mshv/mshv-cpu.c | 130 +------------------------------------\n 4 files changed, 159 insertions(+), 128 deletions(-)", "diff": "diff --git a/accel/mshv/meson.build b/accel/mshv/meson.build\nindex e433187cde..ebe32921b3 100644\n--- a/accel/mshv/meson.build\n+++ b/accel/mshv/meson.build\n@@ -1,5 +1,6 @@\n system_ss.add(when: 'CONFIG_MSHV', if_true: files(\n 'irq.c',\n 'mem.c',\n- 'mshv-all.c'\n+ 'mshv-all.c',\n+ 'mshv-cpu-common.c'\n ))\ndiff --git a/accel/mshv/mshv-cpu-common.c b/accel/mshv/mshv-cpu-common.c\nnew file mode 100644\nindex 0000000000..b104720161\n--- /dev/null\n+++ b/accel/mshv/mshv-cpu-common.c\n@@ -0,0 +1,151 @@\n+/*\n+ * QEMU MSHV common CPU register helpers\n+ *\n+ * Copyright Microsoft, Corp. 2026\n+ *\n+ * Authors: Ziqiao Zhou <ziqiaozhou@microsoft.com>\n+ * Magnus Kulke <magnuskulke@microsoft.com>\n+ * Jinank Jain <jinankjain@microsoft.com>\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+#include \"qemu/osdep.h\"\n+#include \"qemu/error-report.h\"\n+#include \"qemu/memalign.h\"\n+\n+#include \"system/mshv.h\"\n+#include \"system/mshv_int.h\"\n+\n+#include \"hw/core/cpu.h\"\n+#include \"linux/mshv.h\"\n+\n+#include <sys/ioctl.h>\n+\n+int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,\n+ size_t n_regs)\n+{\n+ int cpu_fd = mshv_vcpufd(cpu);\n+ int vp_index = cpu->cpu_index;\n+ size_t in_sz, assocs_sz;\n+ hv_input_set_vp_registers *in = cpu->accel->hvcall_args.input_page;\n+ struct mshv_root_hvcall args = {0};\n+ int ret;\n+\n+ /* find out the size of the struct w/ a flexible array at the tail */\n+ assocs_sz = n_regs * sizeof(hv_register_assoc);\n+ in_sz = sizeof(hv_input_set_vp_registers) + assocs_sz;\n+\n+ /* fill the input struct */\n+ memset(in, 0, sizeof(hv_input_set_vp_registers));\n+ in->vp_index = vp_index;\n+ memcpy(in->elements, assocs, assocs_sz);\n+\n+ /* create the hvcall envelope */\n+ args.code = HVCALL_SET_VP_REGISTERS;\n+ args.in_sz = in_sz;\n+ args.in_ptr = (uint64_t) in;\n+ args.reps = (uint16_t) n_regs;\n+\n+ /* perform the call */\n+ ret = mshv_hvcall(cpu_fd, &args);\n+ if (ret < 0) {\n+ error_report(\"Failed to set registers\");\n+ return -1;\n+ }\n+\n+ /* assert we set all registers */\n+ if (args.reps != n_regs) {\n+ error_report(\"Failed to set registers: expected %zu elements\"\n+ \", got %u\", n_regs, args.reps);\n+ return -1;\n+ }\n+\n+ return 0;\n+}\n+\n+int mshv_get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,\n+ size_t n_regs)\n+{\n+ int cpu_fd = mshv_vcpufd(cpu);\n+ int vp_index = cpu->cpu_index;\n+ hv_input_get_vp_registers *in = cpu->accel->hvcall_args.input_page;\n+ hv_register_value *values = cpu->accel->hvcall_args.output_page;\n+ size_t in_sz, names_sz, values_sz;\n+ int i, ret;\n+ struct mshv_root_hvcall args = {0};\n+\n+ /* find out the size of the struct w/ a flexible array at the tail */\n+ names_sz = n_regs * sizeof(hv_register_name);\n+ in_sz = sizeof(hv_input_get_vp_registers) + names_sz;\n+\n+ /* fill the input struct */\n+ memset(in, 0, sizeof(hv_input_get_vp_registers));\n+ in->vp_index = vp_index;\n+ for (i = 0; i < n_regs; i++) {\n+ in->names[i] = assocs[i].name;\n+ }\n+\n+ /* determine size of value output buffer */\n+ values_sz = n_regs * sizeof(union hv_register_value);\n+\n+ /* create the hvcall envelope */\n+ args.code = HVCALL_GET_VP_REGISTERS;\n+ args.in_sz = in_sz;\n+ args.in_ptr = (uint64_t) in;\n+ args.out_sz = values_sz;\n+ args.out_ptr = (uint64_t) values;\n+ args.reps = (uint16_t) n_regs;\n+\n+ /* perform the call */\n+ ret = mshv_hvcall(cpu_fd, &args);\n+ if (ret < 0) {\n+ error_report(\"Failed to retrieve registers\");\n+ return -1;\n+ }\n+\n+ /* assert we got all registers */\n+ if (args.reps != n_regs) {\n+ error_report(\"Failed to retrieve registers: expected %zu elements\"\n+ \", got %u\", n_regs, args.reps);\n+ return -1;\n+ }\n+\n+ /* copy values into assoc */\n+ for (i = 0; i < n_regs; i++) {\n+ assocs[i].value = values[i];\n+ }\n+\n+ return 0;\n+}\n+\n+int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd)\n+{\n+ int ret;\n+ struct mshv_create_vp vp_arg = {\n+ .vp_index = vp_index,\n+ };\n+\n+ ret = ioctl(vm_fd, MSHV_CREATE_VP, &vp_arg);\n+ if (ret < 0) {\n+ error_report(\"failed to create mshv vcpu: %s\", strerror(errno));\n+ return -1;\n+ }\n+\n+ *cpu_fd = ret;\n+\n+ return 0;\n+}\n+\n+void mshv_remove_vcpu(int vm_fd, int cpu_fd)\n+{\n+ close(cpu_fd);\n+}\n+\n+void mshv_setup_hvcall_args(AccelCPUState *state)\n+{\n+ void *mem = qemu_memalign(HV_HYP_PAGE_SIZE, 2 * HV_HYP_PAGE_SIZE);\n+\n+ state->hvcall_args.base = mem;\n+ state->hvcall_args.input_page = mem;\n+ state->hvcall_args.output_page = (uint8_t *)mem + HV_HYP_PAGE_SIZE;\n+}\ndiff --git a/include/system/mshv_int.h b/include/system/mshv_int.h\nindex 35386c422f..ff3ab957b5 100644\n--- a/include/system/mshv_int.h\n+++ b/include/system/mshv_int.h\n@@ -89,12 +89,15 @@ int mshv_load_regs(CPUState *cpu);\n int mshv_store_regs(CPUState *cpu);\n int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,\n size_t n_regs);\n+int mshv_get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,\n+ size_t n_regs);\n int mshv_arch_put_registers(const CPUState *cpu);\n void mshv_arch_init_vcpu(CPUState *cpu);\n void mshv_arch_destroy_vcpu(CPUState *cpu);\n void mshv_arch_amend_proc_features(\n union hv_partition_synthetic_processor_features *features);\n int mshv_arch_post_init_vm(int vm_fd);\n+void mshv_setup_hvcall_args(AccelCPUState *state);\n \n typedef struct mshv_root_hvcall mshv_root_hvcall;\n int mshv_hvcall(int fd, const mshv_root_hvcall *args);\ndiff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c\nindex 2bc978deb2..9a80dc34d0 100644\n--- a/target/i386/mshv/mshv-cpu.c\n+++ b/target/i386/mshv/mshv-cpu.c\n@@ -148,103 +148,6 @@ static int translate_gva(const CPUState *cpu, uint64_t gva, uint64_t *gpa,\n return 0;\n }\n \n-int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,\n- size_t n_regs)\n-{\n- int cpu_fd = mshv_vcpufd(cpu);\n- int vp_index = cpu->cpu_index;\n- size_t in_sz, assocs_sz;\n- hv_input_set_vp_registers *in = cpu->accel->hvcall_args.input_page;\n- struct mshv_root_hvcall args = {0};\n- int ret;\n-\n- /* find out the size of the struct w/ a flexible array at the tail */\n- assocs_sz = n_regs * sizeof(hv_register_assoc);\n- in_sz = sizeof(hv_input_set_vp_registers) + assocs_sz;\n-\n- /* fill the input struct */\n- memset(in, 0, sizeof(hv_input_set_vp_registers));\n- in->vp_index = vp_index;\n- memcpy(in->elements, assocs, assocs_sz);\n-\n- /* create the hvcall envelope */\n- args.code = HVCALL_SET_VP_REGISTERS;\n- args.in_sz = in_sz;\n- args.in_ptr = (uint64_t) in;\n- args.reps = (uint16_t) n_regs;\n-\n- /* perform the call */\n- ret = mshv_hvcall(cpu_fd, &args);\n- if (ret < 0) {\n- error_report(\"Failed to set registers\");\n- return -1;\n- }\n-\n- /* assert we set all registers */\n- if (args.reps != n_regs) {\n- error_report(\"Failed to set registers: expected %zu elements\"\n- \", got %u\", n_regs, args.reps);\n- return -1;\n- }\n-\n- return 0;\n-}\n-\n-static int get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,\n- size_t n_regs)\n-{\n- int cpu_fd = mshv_vcpufd(cpu);\n- int vp_index = cpu->cpu_index;\n- hv_input_get_vp_registers *in = cpu->accel->hvcall_args.input_page;\n- hv_register_value *values = cpu->accel->hvcall_args.output_page;\n- size_t in_sz, names_sz, values_sz;\n- int i, ret;\n- struct mshv_root_hvcall args = {0};\n-\n- /* find out the size of the struct w/ a flexible array at the tail */\n- names_sz = n_regs * sizeof(hv_register_name);\n- in_sz = sizeof(hv_input_get_vp_registers) + names_sz;\n-\n- /* fill the input struct */\n- memset(in, 0, sizeof(hv_input_get_vp_registers));\n- in->vp_index = vp_index;\n- for (i = 0; i < n_regs; i++) {\n- in->names[i] = assocs[i].name;\n- }\n-\n- /* determine size of value output buffer */\n- values_sz = n_regs * sizeof(union hv_register_value);\n-\n- /* create the hvcall envelope */\n- args.code = HVCALL_GET_VP_REGISTERS;\n- args.in_sz = in_sz;\n- args.in_ptr = (uint64_t) in;\n- args.out_sz = values_sz;\n- args.out_ptr = (uint64_t) values;\n- args.reps = (uint16_t) n_regs;\n-\n- /* perform the call */\n- ret = mshv_hvcall(cpu_fd, &args);\n- if (ret < 0) {\n- error_report(\"Failed to retrieve registers\");\n- return -1;\n- }\n-\n- /* assert we got all registers */\n- if (args.reps != n_regs) {\n- error_report(\"Failed to retrieve registers: expected %zu elements\"\n- \", got %u\", n_regs, args.reps);\n- return -1;\n- }\n-\n- /* copy values into assoc */\n- for (i = 0; i < n_regs; i++) {\n- assocs[i].value = values[i];\n- }\n-\n- return 0;\n-}\n-\n static int set_standard_regs(const CPUState *cpu)\n {\n X86CPU *x86cpu = X86_CPU(cpu);\n@@ -334,7 +237,7 @@ int mshv_get_standard_regs(CPUState *cpu)\n for (size_t i = 0; i < n_regs; i++) {\n assocs[i].name = STANDARD_REGISTER_NAMES[i];\n }\n- ret = get_generic_regs(cpu, assocs, n_regs);\n+ ret = mshv_get_generic_regs(cpu, assocs, n_regs);\n if (ret < 0) {\n error_report(\"failed to get standard registers\");\n return -1;\n@@ -412,7 +315,7 @@ int mshv_get_special_regs(CPUState *cpu)\n for (size_t i = 0; i < n_regs; i++) {\n assocs[i].name = SPECIAL_REGISTER_NAMES[i];\n }\n- ret = get_generic_regs(cpu, assocs, n_regs);\n+ ret = mshv_get_generic_regs(cpu, assocs, n_regs);\n if (ret < 0) {\n error_report(\"failed to get special registers\");\n return -errno;\n@@ -1525,29 +1428,6 @@ int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit)\n return 0;\n }\n \n-void mshv_remove_vcpu(int vm_fd, int cpu_fd)\n-{\n- close(cpu_fd);\n-}\n-\n-\n-int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd)\n-{\n- int ret;\n- struct mshv_create_vp vp_arg = {\n- .vp_index = vp_index,\n- };\n- ret = ioctl(vm_fd, MSHV_CREATE_VP, &vp_arg);\n- if (ret < 0) {\n- error_report(\"failed to create mshv vcpu: %s\", strerror(errno));\n- return -1;\n- }\n-\n- *cpu_fd = ret;\n-\n- return 0;\n-}\n-\n static void read_segment_descriptor(CPUState *cpu,\n struct x86_segment_descriptor *desc,\n enum X86Seg seg_idx)\n@@ -1580,8 +1460,6 @@ void mshv_arch_init_vcpu(CPUState *cpu)\n X86CPU *x86_cpu = X86_CPU(cpu);\n CPUX86State *env = &x86_cpu->env;\n AccelCPUState *state = cpu->accel;\n- size_t page = HV_HYP_PAGE_SIZE;\n- void *mem = qemu_memalign(page, 2 * page);\n \n /* sanity check, to make sure we don't overflow the page */\n QEMU_BUILD_BUG_ON((MAX_REGISTER_COUNT\n@@ -1589,9 +1467,7 @@ void mshv_arch_init_vcpu(CPUState *cpu)\n + sizeof(hv_input_get_vp_registers)\n > HV_HYP_PAGE_SIZE));\n \n- state->hvcall_args.base = mem;\n- state->hvcall_args.input_page = mem;\n- state->hvcall_args.output_page = (uint8_t *)mem + page;\n+ mshv_setup_hvcall_args(state);\n \n env->emu_mmio_buf = g_new(char, 4096);\n }\n", "prefixes": [ "v2", "02/14" ] }