From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274315; cv=none; d=zohomail.com; s=zohoarc; b=Q8fETttnc3UjzLGS5GK2caH3FwhQlW2T5kPynHoKoa83ny47c3b7WvVC1d1WWK5JouPpwffHxQ8aYHfJ4akjo0KVK3xp3Oi3/CUK0jOQdJ2X8dVkz+F69bwQveFERPg+s0gDMd6IFZ5RY0nm6hMc1nAysRwXoBdN+UVzOwI7a9A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274315; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Vlb84NjCXw4NOONm0D1TCpsCilPuQF2CzdK3RJxUGA0=; b=jDTlsDSjQR5RfOxdNsF87TAXcZGIQnCBUZ7k6KlwVewJdI7HiuDfSlUzUCppEHMstU62sLHbD6YGdIaYedWPB7nebKqQ8B0b5eUBivSJdVLys808Em6DotgLOoxIzLwLbUB39eonZS1+V2diXrja72Q6DWa8FPGFnqAFO0c2OR0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274315651213.2008100914428; Mon, 23 Mar 2026 06:58:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnZ-0007dT-Ag; Mon, 23 Mar 2026 09:58:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fnU-0007Up-W1 for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:25 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnT-0006lI-B7 for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:24 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 48FE420B7128; Mon, 23 Mar 2026 06:58:19 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 48FE420B7128 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274302; bh=Vlb84NjCXw4NOONm0D1TCpsCilPuQF2CzdK3RJxUGA0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hMPwTB+rYS5v/mRxV8PZQqytZJKtgPFLB5uyyMkOElN7y1+GgbwuXj22di95cyzbK K4lxBjyhTOiK1hIm75uulI37nhlfaPPR57GBaNVHD72uJ03LSUxPdMQ42wwPysoTg6 WLQM3ODL2djcSElZW33m4Qaglx/h+FlI1JlyWIZw= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 01/32] target/i386/mshv: use arch_load/store_reg fns Date: Mon, 23 Mar 2026 14:57:41 +0100 Message-Id: <20260323135812.383509-2-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274317573158501 Content-Type: text/plain; charset="utf-8" Improved consistency around the naming of load/store register fn's. this is required since we want to roundtrip more registers in a migration than what's currently required for MMIO emulation. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 2 +- include/system/mshv_int.h | 6 ++--- target/i386/mshv/mshv-cpu.c | 52 ++++++++++++++----------------------- 3 files changed, 23 insertions(+), 37 deletions(-) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index d4cc7f5371..7c0eb68a5b 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -650,7 +650,7 @@ static void mshv_cpu_synchronize_pre_loadvm(CPUState *c= pu) static void do_mshv_cpu_synchronize(CPUState *cpu, run_on_cpu_data arg) { if (!cpu->accel->dirty) { - int ret =3D mshv_load_regs(cpu); + int ret =3D mshv_arch_load_regs(cpu); if (ret < 0) { error_report("Failed to load registers for vcpu %d", cpu->cpu_index); diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 35386c422f..a142dd241a 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -82,11 +82,9 @@ void mshv_init_mmio_emu(void); int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd); void mshv_remove_vcpu(int vm_fd, int cpu_fd); int mshv_configure_vcpu(const CPUState *cpu, const MshvFPU *fpu, uint64_t = xcr0); -int mshv_get_standard_regs(CPUState *cpu); -int mshv_get_special_regs(CPUState *cpu); int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *e= xit); -int mshv_load_regs(CPUState *cpu); -int mshv_store_regs(CPUState *cpu); +int mshv_arch_load_regs(CPUState *cpu); +int mshv_arch_store_regs(CPUState *cpu); int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *as= socs, size_t n_regs); int mshv_arch_put_registers(const CPUState *cpu); diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 2bc978deb2..9456e75277 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -107,6 +107,8 @@ static enum hv_register_name FPU_REGISTER_NAMES[26] =3D= { HV_X64_REGISTER_XMM_CONTROL_STATUS, }; =20 +static int set_special_regs(const CPUState *cpu); + static int translate_gva(const CPUState *cpu, uint64_t gva, uint64_t *gpa, uint64_t flags) { @@ -285,7 +287,7 @@ static int set_standard_regs(const CPUState *cpu) return 0; } =20 -int mshv_store_regs(CPUState *cpu) +int mshv_arch_store_regs(CPUState *cpu) { int ret; =20 @@ -295,6 +297,12 @@ int mshv_store_regs(CPUState *cpu) return -1; } =20 + ret =3D set_special_regs(cpu); + if (ret < 0) { + error_report("Failed to store speical registers"); + return ret; + } + return 0; } =20 @@ -323,7 +331,7 @@ static void populate_standard_regs(const hv_register_as= soc *assocs, rflags_to_lflags(env); } =20 -int mshv_get_standard_regs(CPUState *cpu) +static int get_standard_regs(CPUState *cpu) { struct hv_register_assoc assocs[ARRAY_SIZE(STANDARD_REGISTER_NAMES)]; int ret; @@ -401,8 +409,7 @@ static void populate_special_regs(const hv_register_ass= oc *assocs, cpu_set_apic_base(x86cpu->apic_state, assocs[16].value.reg64); } =20 - -int mshv_get_special_regs(CPUState *cpu) +static int get_special_regs(CPUState *cpu) { struct hv_register_assoc assocs[ARRAY_SIZE(SPECIAL_REGISTER_NAMES)]; int ret; @@ -422,17 +429,17 @@ int mshv_get_special_regs(CPUState *cpu) return 0; } =20 -int mshv_load_regs(CPUState *cpu) +int mshv_arch_load_regs(CPUState *cpu) { int ret; =20 - ret =3D mshv_get_standard_regs(cpu); + ret =3D get_standard_regs(cpu); if (ret < 0) { error_report("Failed to load standard registers"); return -1; } =20 - ret =3D mshv_get_special_regs(cpu); + ret =3D get_special_regs(cpu); if (ret < 0) { error_report("Failed to load special registers"); return -1; @@ -1103,16 +1110,16 @@ static int emulate_instruction(CPUState *cpu, int ret; x86_insn_stream stream =3D { .bytes =3D insn_bytes, .len =3D insn_len = }; =20 - ret =3D mshv_load_regs(cpu); + ret =3D mshv_arch_load_regs(cpu); if (ret < 0) { - error_report("failed to load registers"); + error_report("Failed to load registers"); return -1; } =20 decode_instruction_stream(env, &decode, &stream); exec_instruction(env, &decode); =20 - ret =3D mshv_store_regs(cpu); + ret =3D mshv_arch_store_regs(cpu); if (ret < 0) { error_report("failed to store registers"); return -1; @@ -1291,25 +1298,6 @@ static int handle_pio_non_str(const CPUState *cpu, return 0; } =20 -static int fetch_guest_state(CPUState *cpu) -{ - int ret; - - ret =3D mshv_get_standard_regs(cpu); - if (ret < 0) { - error_report("Failed to get standard registers"); - return -1; - } - - ret =3D mshv_get_special_regs(cpu); - if (ret < 0) { - error_report("Failed to get special registers"); - return -1; - } - - return 0; -} - static int read_memory(const CPUState *cpu, uint64_t initial_gva, uint64_t initial_gpa, uint64_t gva, uint8_t *data, size_t len) @@ -1429,9 +1417,9 @@ static int handle_pio_str(CPUState *cpu, hv_x64_io_po= rt_intercept_message *info) X86CPU *x86_cpu =3D X86_CPU(cpu); CPUX86State *env =3D &x86_cpu->env; =20 - ret =3D fetch_guest_state(cpu); + ret =3D mshv_arch_load_regs(cpu); if (ret < 0) { - error_report("Failed to fetch guest state"); + error_report("Failed to load registers"); return -1; } =20 @@ -1462,7 +1450,7 @@ static int handle_pio_str(CPUState *cpu, hv_x64_io_po= rt_intercept_message *info) =20 ret =3D set_x64_registers(cpu, reg_names, reg_values); if (ret < 0) { - error_report("Failed to set x64 registers"); + error_report("Failed to set RIP and RAX registers"); return -1; } =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274339; cv=none; d=zohomail.com; s=zohoarc; b=JiC1mM6PJxuCoyQ/9bKyVnWjlSVgHrhZbxbEDD3szZvJDtJRIJEOTEEf/jJu/TV8n7Iv2tGGFFqjYiGSnygLXWckxBzHolOKN4sGpcZFfFheOojM9kcemEmyTusQm6eBhWWfGQTXum1sA/fa2Qi8IXotMggLUEG23J7bvJVI/co= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274339; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=YCyjkeVZjehmvMqQkFEvROL42xs/v9qbwCcFiaYqzZg=; b=ZTfnFhtSqbmW/TSH/4TtWpcm0e3+bk812fp47rOWqceNJSxNl3X/5dFs17ZxZzWFfWt9k34Um10Cxe9J8m+Etem5IAxg7jaWiGz3Fa5cBftl7N1pX6jOAOQthG1m/gLuo6OAqnUydOKuxyac99FjaaP+uxXd5RgN3lUooWG+qrg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274339499647.5859111986429; Mon, 23 Mar 2026 06:58:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnd-0007m1-Je; Mon, 23 Mar 2026 09:58:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fna-0007ey-9s for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:30 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnW-0006ld-S3 for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:28 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id E81B720B7129; Mon, 23 Mar 2026 06:58:22 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com E81B720B7129 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274305; bh=YCyjkeVZjehmvMqQkFEvROL42xs/v9qbwCcFiaYqzZg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bNNnk4MMJ4vbAAJ2OXqT59mNqJKnUAZxhosxCIavInExD+4F65zTbDkNgopkDPB6K KY+mrlZr3rKPFY10z1h2XF0RWQotir9tHdsmjgbbO1OyZ+y8DhdvLHemRL/vOTQ2YN urxPXNOr1gN1l0e9CWXA6gsHzxzDa4wCNAD9cQxA= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 02/32] target/i386/mshv: use generic FPU/xcr0 state Date: Mon, 23 Mar 2026 14:57:42 +0100 Message-Id: <20260323135812.383509-3-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274340096154100 Content-Type: text/plain; charset="utf-8" Instead of using an mshv-specific FPU state representation we switch to the generic i386 representation of the registers. Signed-off-by: Magnus Kulke --- include/system/mshv_int.h | 15 +------- target/i386/mshv/mshv-cpu.c | 76 ++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index a142dd241a..e3d1867a77 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -58,19 +58,6 @@ typedef struct MshvMsiControl { #define mshv_vcpufd(cpu) (cpu->accel->cpufd) =20 /* cpu */ -typedef struct MshvFPU { - uint8_t fpr[8][16]; - uint16_t fcw; - uint16_t fsw; - uint8_t ftwx; - uint8_t pad1; - uint16_t last_opcode; - uint64_t last_ip; - uint64_t last_dp; - uint8_t xmm[16][16]; - uint32_t mxcsr; - uint32_t pad2; -} MshvFPU; =20 typedef enum MshvVmExit { MshvVmExitIgnore =3D 0, @@ -81,7 +68,7 @@ typedef enum MshvVmExit { void mshv_init_mmio_emu(void); int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd); void mshv_remove_vcpu(int vm_fd, int cpu_fd); -int mshv_configure_vcpu(const CPUState *cpu, const MshvFPU *fpu, uint64_t = xcr0); +int mshv_configure_vcpu(const CPUState *cpu); int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *e= xit); int mshv_arch_load_regs(CPUState *cpu); int mshv_arch_store_regs(CPUState *cpu); diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 9456e75277..78b218e596 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -108,6 +108,9 @@ static enum hv_register_name FPU_REGISTER_NAMES[26] =3D= { }; =20 static int set_special_regs(const CPUState *cpu); +static int get_generic_regs(CPUState *cpu, + struct hv_register_assoc *assocs, + size_t n_regs); =20 static int translate_gva(const CPUState *cpu, uint64_t gva, uint64_t *gpa, uint64_t flags) @@ -717,48 +720,65 @@ static int set_special_regs(const CPUState *cpu) return 0; } =20 -static int set_fpu(const CPUState *cpu, const struct MshvFPU *regs) +static int set_fpu(const CPUState *cpu) { struct hv_register_assoc assocs[ARRAY_SIZE(FPU_REGISTER_NAMES)]; union hv_register_value *value; - size_t fp_i; union hv_x64_fp_control_status_register *ctrl_status; union hv_x64_xmm_control_status_register *xmm_ctrl_status; int ret; size_t n_regs =3D ARRAY_SIZE(FPU_REGISTER_NAMES); + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + size_t i, fp_i; + bool valid; =20 /* first 16 registers are xmm0-xmm15 */ - for (size_t i =3D 0; i < 16; i++) { + for (i =3D 0; i < 16; i++) { assocs[i].name =3D FPU_REGISTER_NAMES[i]; value =3D &assocs[i].value; - memcpy(&value->reg128, ®s->xmm[i], 16); + value->reg128.low_part =3D env->xmm_regs[i].ZMM_Q(0); + value->reg128.high_part =3D env->xmm_regs[i].ZMM_Q(1); } =20 /* next 8 registers are fp_mmx0-fp_mmx7 */ - for (size_t i =3D 16; i < 24; i++) { - assocs[i].name =3D FPU_REGISTER_NAMES[i]; + for (i =3D 16; i < 24; i++) { fp_i =3D (i - 16); + assocs[i].name =3D FPU_REGISTER_NAMES[i]; value =3D &assocs[i].value; - memcpy(&value->reg128, ®s->fpr[fp_i], 16); + value->fp.mantissa =3D env->fpregs[fp_i].d.low; + value->fp.biased_exponent =3D env->fpregs[fp_i].d.high & 0x7FFF; + value->fp.sign =3D (env->fpregs[fp_i].d.high >> 15) & 0= x1; + value->fp.reserved =3D 0; } =20 /* last two registers are fp_control_status and xmm_control_status */ assocs[24].name =3D FPU_REGISTER_NAMES[24]; value =3D &assocs[24].value; ctrl_status =3D &value->fp_control_status; - ctrl_status->fp_control =3D regs->fcw; - ctrl_status->fp_status =3D regs->fsw; - ctrl_status->fp_tag =3D regs->ftwx; + + ctrl_status->fp_control =3D env->fpuc; + /* bits 11,12,13 are the top of stack pointer */ + ctrl_status->fp_status =3D (env->fpus & ~0x3800) | ((env->fpstt & 0x7)= << 11); + + ctrl_status->fp_tag =3D 0; + for (i =3D 0; i < 8; i++) { + valid =3D (env->fptags[i] =3D=3D 0); + if (valid) { + ctrl_status->fp_tag |=3D (1u << i); + } + } + ctrl_status->reserved =3D 0; - ctrl_status->last_fp_op =3D regs->last_opcode; - ctrl_status->last_fp_rip =3D regs->last_ip; + ctrl_status->last_fp_op =3D env->fpop; + ctrl_status->last_fp_rip =3D env->fpip; =20 assocs[25].name =3D FPU_REGISTER_NAMES[25]; value =3D &assocs[25].value; xmm_ctrl_status =3D &value->xmm_control_status; - xmm_ctrl_status->xmm_status_control =3D regs->mxcsr; - xmm_ctrl_status->xmm_status_control_mask =3D 0; - xmm_ctrl_status->last_fp_rdp =3D regs->last_dp; + xmm_ctrl_status->xmm_status_control =3D env->mxcsr; + xmm_ctrl_status->xmm_status_control_mask =3D 0x0000ffff; + xmm_ctrl_status->last_fp_rdp =3D env->fpdp; =20 ret =3D mshv_set_generic_regs(cpu, assocs, n_regs); if (ret < 0) { @@ -769,12 +789,15 @@ static int set_fpu(const CPUState *cpu, const struct = MshvFPU *regs) return 0; } =20 -static int set_xc_reg(const CPUState *cpu, uint64_t xcr0) +static int set_xc_reg(const CPUState *cpu) { int ret; + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + struct hv_register_assoc assoc =3D { .name =3D HV_X64_REGISTER_XFEM, - .value.reg64 =3D xcr0, + .value.reg64 =3D env->xcr0, }; =20 ret =3D mshv_set_generic_regs(cpu, &assoc, 1); @@ -785,8 +808,7 @@ static int set_xc_reg(const CPUState *cpu, uint64_t xcr= 0) return 0; } =20 -static int set_cpu_state(const CPUState *cpu, const MshvFPU *fpu_regs, - uint64_t xcr0) +static int set_cpu_state(const CPUState *cpu) { int ret; =20 @@ -798,11 +820,11 @@ static int set_cpu_state(const CPUState *cpu, const M= shvFPU *fpu_regs, if (ret < 0) { return ret; } - ret =3D set_fpu(cpu, fpu_regs); + ret =3D set_fpu(cpu); if (ret < 0) { return ret; } - ret =3D set_xc_reg(cpu, xcr0); + ret =3D set_xc_reg(cpu); if (ret < 0) { return ret; } @@ -951,8 +973,7 @@ static int setup_msrs(const CPUState *cpu) * CPUX86State *env =3D &x86cpu->env; * X86CPUTopoInfo *topo_info =3D &env->topo_info; */ -int mshv_configure_vcpu(const CPUState *cpu, const struct MshvFPU *fpu, - uint64_t xcr0) +int mshv_configure_vcpu(const CPUState *cpu) { int ret; int cpu_fd =3D mshv_vcpufd(cpu); @@ -969,7 +990,7 @@ int mshv_configure_vcpu(const CPUState *cpu, const stru= ct MshvFPU *fpu, return -1; } =20 - ret =3D set_cpu_state(cpu, fpu, xcr0); + ret =3D set_cpu_state(cpu); if (ret < 0) { error_report("failed to set cpu state"); return -1; @@ -986,14 +1007,9 @@ int mshv_configure_vcpu(const CPUState *cpu, const st= ruct MshvFPU *fpu, =20 static int put_regs(const CPUState *cpu) { - X86CPU *x86cpu =3D X86_CPU(cpu); - CPUX86State *env =3D &x86cpu->env; - MshvFPU fpu =3D {0}; int ret; =20 - memset(&fpu, 0, sizeof(fpu)); - - ret =3D mshv_configure_vcpu(cpu, &fpu, env->xcr0); + ret =3D mshv_configure_vcpu(cpu); if (ret < 0) { error_report("failed to configure vcpu"); return ret; --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274340; cv=none; d=zohomail.com; s=zohoarc; b=OaILlwJ2TczRQqRGIJmiHzTb2EqpQ6q9h4m0PQu+CvoOJkdruppGtPyw9fdl5jHFmRWy7PFG9leI6blQUyX4Cwb4Na94XGIEHRg3lvgaOLfj8OZEKzRBCrX1NB0YFPmJm86JGF5NhbeVFI2u9c3JlnG0Mp3aur6m+RhDfmShqCU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274340; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=A8uL1r6Og/T/HGwRnV+r8ObS1E2Hjxpnf4cpXNnVOek=; b=fQeWasXV5HgKnh419v6e9xUmMySQDdL0iicIbaPtWlfE9Tlm5i1zkHNODp0pdT0dxmkCxwoXOU2lPy4F3bj/HJMiC0kgg96ueB2agfYiDXmPsNv55iSAjuFI/jaBpHCIU6mpcIAo5gTQ5z60P+Kd6yOhClNelxVj2bTdd3YN3zQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17742743401171.7023767441222617; Mon, 23 Mar 2026 06:59:00 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fng-0007rq-PI; Mon, 23 Mar 2026 09:58:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fnf-0007pl-Hg for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:35 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnb-0006mA-4Z for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:35 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 92B6420B712B; Mon, 23 Mar 2026 06:58:26 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 92B6420B712B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274309; bh=A8uL1r6Og/T/HGwRnV+r8ObS1E2Hjxpnf4cpXNnVOek=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Io70UxoQxEhc3ZV0ykVSmvYb+5K5SxS+UXZMrDYxNiQXMkjGtPS2LBBZ1KsIc3gwB 3Cs8KAib48xVZGIZPaICMIPpViIlpG89iPoE3n6zcPwWr+mTU2sAQH50YEk3cXHZuc ZXexjAyfRY1r3dB1eNpf/xhXFQlBUkKDA1LLpof4= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 03/32] target/i386/mshv: impl init/load/store_vcpu_state Date: Mon, 23 Mar 2026 14:57:43 +0100 Message-Id: <20260323135812.383509-4-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274341983158500 Content-Type: text/plain; charset="utf-8" In migration we will handle more than registers, so we rework the routines that were used to load & store CPU registers from/to the hypervisor into more explicit init/load/store_vcpu_state() functions that can be called from the appropriate hooks. load/store_regs() still exists for the purpose of MMIO emulation, but it will only address standard and special x86 registers. Functions to retrieve FPU and XCR0 state from the hypervsisor have been introduced. MSR and APIC state covered are covered only as part of init_vcpu(). They are not yet part of the load/store routines. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 10 +- include/system/mshv_int.h | 5 +- target/i386/mshv/mshv-cpu.c | 354 ++++++++++++++++++------------------ 3 files changed, 185 insertions(+), 184 deletions(-) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 7c0eb68a5b..04d248fe1d 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -400,13 +400,13 @@ static int mshv_init_vcpu(CPUState *cpu) int ret; =20 cpu->accel =3D g_new0(AccelCPUState, 1); - mshv_arch_init_vcpu(cpu); =20 ret =3D mshv_create_vcpu(vm_fd, vp_index, &cpu->accel->cpufd); if (ret < 0) { return -1; } =20 + mshv_arch_init_vcpu(cpu); cpu->accel->dirty =3D true; =20 return 0; @@ -488,7 +488,7 @@ static int mshv_cpu_exec(CPUState *cpu) =20 do { if (cpu->accel->dirty) { - ret =3D mshv_arch_put_registers(cpu); + ret =3D mshv_arch_store_vcpu_state(cpu); if (ret) { error_report("Failed to put registers after init: %s", strerror(-ret)); @@ -610,7 +610,7 @@ static void mshv_start_vcpu_thread(CPUState *cpu) static void do_mshv_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) { - int ret =3D mshv_arch_put_registers(cpu); + int ret =3D mshv_arch_store_vcpu_state(cpu); if (ret < 0) { error_report("Failed to put registers after init: %s", strerror(-r= et)); abort(); @@ -626,7 +626,7 @@ static void mshv_cpu_synchronize_post_init(CPUState *cp= u) =20 static void mshv_cpu_synchronize_post_reset(CPUState *cpu) { - int ret =3D mshv_arch_put_registers(cpu); + int ret =3D mshv_arch_store_vcpu_state(cpu); if (ret) { error_report("Failed to put registers after reset: %s", strerror(-ret)); @@ -650,7 +650,7 @@ static void mshv_cpu_synchronize_pre_loadvm(CPUState *c= pu) static void do_mshv_cpu_synchronize(CPUState *cpu, run_on_cpu_data arg) { if (!cpu->accel->dirty) { - int ret =3D mshv_arch_load_regs(cpu); + int ret =3D mshv_arch_load_vcpu_state(cpu); if (ret < 0) { error_report("Failed to load registers for vcpu %d", cpu->cpu_index); diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index e3d1867a77..70631ca6ba 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -70,11 +70,10 @@ int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *= cpu_fd); void mshv_remove_vcpu(int vm_fd, int cpu_fd); int mshv_configure_vcpu(const CPUState *cpu); int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *e= xit); -int mshv_arch_load_regs(CPUState *cpu); -int mshv_arch_store_regs(CPUState *cpu); int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *as= socs, size_t n_regs); -int mshv_arch_put_registers(const CPUState *cpu); +int mshv_arch_store_vcpu_state(const CPUState *cpu); +int mshv_arch_load_vcpu_state(CPUState *cpu); void mshv_arch_init_vcpu(CPUState *cpu); void mshv_arch_destroy_vcpu(CPUState *cpu); void mshv_arch_amend_proc_features( diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 78b218e596..56656ac0b0 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -112,6 +112,92 @@ static int get_generic_regs(CPUState *cpu, struct hv_register_assoc *assocs, size_t n_regs); =20 +static void populate_fpu(const hv_register_assoc *assocs, X86CPU *x86cpu) +{ + union hv_register_value value; + const union hv_x64_fp_control_status_register *ctrl_status; + const union hv_x64_xmm_control_status_register *xmm_ctrl; + CPUX86State *env =3D &x86cpu->env; + size_t i, fp_i; + bool valid; + + /* first 16 registers are xmm0-xmm15 */ + for (i =3D 0; i < 16; i++) { + value =3D assocs[i].value; + env->xmm_regs[i].ZMM_Q(0) =3D value.reg128.low_part; + env->xmm_regs[i].ZMM_Q(1) =3D value.reg128.high_part; + } + + /* next 8 registers are fp_mmx0-fp_mmx7 */ + for (i =3D 16; i < 24; i++) { + fp_i =3D i - 16; + value =3D assocs[i].value; + env->fpregs[fp_i].d.low =3D value.fp.mantissa; + env->fpregs[fp_i].d.high =3D (value.fp.sign << 15) + | (value.fp.biased_exponent & 0x7FFF); + } + + /* last two registers are fp_control_status and xmm_control_status */ + ctrl_status =3D &assocs[24].value.fp_control_status; + env->fpuc =3D ctrl_status->fp_control; + + env->fpus =3D ctrl_status->fp_status & ~0x3800; + /* bits 11,12,13 are the top of stack pointer */ + env->fpstt =3D (ctrl_status->fp_status >> 11) & 0x7; + + for (i =3D 0; i < 8; i++) { + valid =3D ctrl_status->fp_tag & (1 << i); + env->fptags[i] =3D valid ? 0 : 1; + } + + env->fpop =3D ctrl_status->last_fp_op; + env->fpip =3D ctrl_status->last_fp_rip; + + xmm_ctrl =3D &assocs[25].value.xmm_control_status; + env->mxcsr =3D xmm_ctrl->xmm_status_control; + env->fpdp =3D xmm_ctrl->last_fp_rdp; +} + +static int get_fpu(CPUState *cpu) +{ + struct hv_register_assoc assocs[ARRAY_SIZE(FPU_REGISTER_NAMES)]; + int ret; + X86CPU *x86cpu =3D X86_CPU(cpu); + size_t n_regs =3D ARRAY_SIZE(FPU_REGISTER_NAMES); + + for (size_t i =3D 0; i < n_regs; i++) { + assocs[i].name =3D FPU_REGISTER_NAMES[i]; + } + ret =3D get_generic_regs(cpu, assocs, n_regs); + if (ret < 0) { + error_report("failed to get special registers"); + return -errno; + } + + populate_fpu(assocs, x86cpu); + + return 0; +} + +static int get_xc_reg(CPUState *cpu) +{ + int ret; + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + struct hv_register_assoc assocs[1]; + + assocs[0].name =3D HV_X64_REGISTER_XFEM; + + ret =3D get_generic_regs(cpu, assocs, 1); + if (ret < 0) { + error_report("failed to get xcr0"); + return -1; + } + env->xcr0 =3D assocs[0].value.reg64; + + return 0; +} + static int translate_gva(const CPUState *cpu, uint64_t gva, uint64_t *gpa, uint64_t flags) { @@ -290,7 +376,7 @@ static int set_standard_regs(const CPUState *cpu) return 0; } =20 -int mshv_arch_store_regs(CPUState *cpu) +static int store_regs(CPUState *cpu) { int ret; =20 @@ -432,20 +518,45 @@ static int get_special_regs(CPUState *cpu) return 0; } =20 -int mshv_arch_load_regs(CPUState *cpu) +static int load_regs(CPUState *cpu) { int ret; =20 ret =3D get_standard_regs(cpu); if (ret < 0) { - error_report("Failed to load standard registers"); - return -1; + return ret; } =20 ret =3D get_special_regs(cpu); if (ret < 0) { - error_report("Failed to load special registers"); - return -1; + return ret; + } + + return 0; +} + +int mshv_arch_load_vcpu_state(CPUState *cpu) +{ + int ret; + + ret =3D get_standard_regs(cpu); + if (ret < 0) { + return ret; + } + + ret =3D get_special_regs(cpu); + if (ret < 0) { + return ret; + } + + ret =3D get_xc_reg(cpu); + if (ret < 0) { + return ret; + } + + ret =3D get_fpu(cpu); + if (ret < 0) { + return ret; } =20 return 0; @@ -617,7 +728,7 @@ static int register_intercept_result_cpuid(const CPUSta= te *cpu, return ret; } =20 -static int set_cpuid2(const CPUState *cpu) +static int init_cpuid2(const CPUState *cpu) { int ret; size_t n_entries, cpuid_size; @@ -808,29 +919,6 @@ static int set_xc_reg(const CPUState *cpu) return 0; } =20 -static int set_cpu_state(const CPUState *cpu) -{ - int ret; - - ret =3D set_standard_regs(cpu); - if (ret < 0) { - return ret; - } - ret =3D set_special_regs(cpu); - if (ret < 0) { - return ret; - } - ret =3D set_fpu(cpu); - if (ret < 0) { - return ret; - } - ret =3D set_xc_reg(cpu); - if (ret < 0) { - return ret; - } - return 0; -} - static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state) { int ret; @@ -844,7 +932,7 @@ static int get_vp_state(int cpu_fd, struct mshv_get_set= _vp_state *state) return 0; } =20 -static int get_lapic(int cpu_fd, +static int get_lapic(const CPUState *cpu, struct hv_local_interrupt_controller_state *state) { int ret; @@ -852,6 +940,7 @@ static int get_lapic(int cpu_fd, /* buffer aligned to 4k, as *state requires that */ void *buffer =3D qemu_memalign(size, size); struct mshv_get_set_vp_state mshv_state =3D { 0 }; + int cpu_fd =3D mshv_vcpufd(cpu); =20 mshv_state.buf_ptr =3D (uint64_t) buffer; mshv_state.buf_sz =3D size; @@ -888,7 +977,7 @@ static int set_vp_state(int cpu_fd, const struct mshv_g= et_set_vp_state *state) return 0; } =20 -static int set_lapic(int cpu_fd, +static int set_lapic(const CPUState *cpu, const struct hv_local_interrupt_controller_state *sta= te) { int ret; @@ -896,6 +985,7 @@ static int set_lapic(int cpu_fd, /* buffer aligned to 4k, as *state requires that */ void *buffer =3D qemu_memalign(size, size); struct mshv_get_set_vp_state mshv_state =3D { 0 }; + int cpu_fd =3D mshv_vcpufd(cpu); =20 if (!state) { error_report("lapic state is NULL"); @@ -917,13 +1007,13 @@ static int set_lapic(int cpu_fd, return 0; } =20 -static int set_lint(int cpu_fd) +static int init_lint(const CPUState *cpu) { int ret; uint32_t *lvt_lint0, *lvt_lint1; =20 struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; - ret =3D get_lapic(cpu_fd, &lapic_state); + ret =3D get_lapic(cpu, &lapic_state); if (ret < 0) { return ret; } @@ -936,161 +1026,31 @@ static int set_lint(int cpu_fd) =20 /* TODO: should we skip setting lapic if the values are the same? */ =20 - return set_lapic(cpu_fd, &lapic_state); + return set_lapic(cpu, &lapic_state); } =20 -static int setup_msrs(const CPUState *cpu) -{ - int ret; - uint64_t default_type =3D MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB; - - /* boot msr entries */ - MshvMsrEntry msrs[9] =3D { - { .index =3D IA32_MSR_SYSENTER_CS, .data =3D 0x0, }, - { .index =3D IA32_MSR_SYSENTER_ESP, .data =3D 0x0, }, - { .index =3D IA32_MSR_SYSENTER_EIP, .data =3D 0x0, }, - { .index =3D IA32_MSR_STAR, .data =3D 0x0, }, - { .index =3D IA32_MSR_CSTAR, .data =3D 0x0, }, - { .index =3D IA32_MSR_LSTAR, .data =3D 0x0, }, - { .index =3D IA32_MSR_KERNEL_GS_BASE, .data =3D 0x0, }, - { .index =3D IA32_MSR_SFMASK, .data =3D 0x0, }, - { .index =3D IA32_MSR_MTRR_DEF_TYPE, .data =3D default_type, }, - }; - - ret =3D mshv_configure_msr(cpu, msrs, 9); - if (ret < 0) { - error_report("failed to setup msrs"); - return -1; - } - - return 0; -} - -/* - * TODO: populate topology info: - * - * X86CPU *x86cpu =3D X86_CPU(cpu); - * CPUX86State *env =3D &x86cpu->env; - * X86CPUTopoInfo *topo_info =3D &env->topo_info; - */ -int mshv_configure_vcpu(const CPUState *cpu) +int mshv_arch_store_vcpu_state(const CPUState *cpu) { int ret; - int cpu_fd =3D mshv_vcpufd(cpu); - - ret =3D set_cpuid2(cpu); - if (ret < 0) { - error_report("failed to set cpuid"); - return -1; - } - - ret =3D setup_msrs(cpu); - if (ret < 0) { - error_report("failed to setup msrs"); - return -1; - } - - ret =3D set_cpu_state(cpu); - if (ret < 0) { - error_report("failed to set cpu state"); - return -1; - } =20 - ret =3D set_lint(cpu_fd); + ret =3D set_standard_regs(cpu); if (ret < 0) { - error_report("failed to set lpic int"); - return -1; + return ret; } =20 - return 0; -} - -static int put_regs(const CPUState *cpu) -{ - int ret; - - ret =3D mshv_configure_vcpu(cpu); + ret =3D set_special_regs(cpu); if (ret < 0) { - error_report("failed to configure vcpu"); return ret; } =20 - return 0; -} - -struct MsrPair { - uint32_t index; - uint64_t value; -}; - -static int put_msrs(const CPUState *cpu) -{ - int ret =3D 0; - X86CPU *x86cpu =3D X86_CPU(cpu); - CPUX86State *env =3D &x86cpu->env; - MshvMsrEntries *msrs =3D g_malloc0(sizeof(MshvMsrEntries)); - - struct MsrPair pairs[] =3D { - { MSR_IA32_SYSENTER_CS, env->sysenter_cs }, - { MSR_IA32_SYSENTER_ESP, env->sysenter_esp }, - { MSR_IA32_SYSENTER_EIP, env->sysenter_eip }, - { MSR_EFER, env->efer }, - { MSR_PAT, env->pat }, - { MSR_STAR, env->star }, - { MSR_CSTAR, env->cstar }, - { MSR_LSTAR, env->lstar }, - { MSR_KERNELGSBASE, env->kernelgsbase }, - { MSR_FMASK, env->fmask }, - { MSR_MTRRdefType, env->mtrr_deftype }, - { MSR_VM_HSAVE_PA, env->vm_hsave }, - { MSR_SMI_COUNT, env->msr_smi_count }, - { MSR_IA32_PKRS, env->pkrs }, - { MSR_IA32_BNDCFGS, env->msr_bndcfgs }, - { MSR_IA32_XSS, env->xss }, - { MSR_IA32_UMWAIT_CONTROL, env->umwait }, - { MSR_IA32_TSX_CTRL, env->tsx_ctrl }, - { MSR_AMD64_TSC_RATIO, env->amd_tsc_scale_msr }, - { MSR_TSC_AUX, env->tsc_aux }, - { MSR_TSC_ADJUST, env->tsc_adjust }, - { MSR_IA32_SMBASE, env->smbase }, - { MSR_IA32_SPEC_CTRL, env->spec_ctrl }, - { MSR_VIRT_SSBD, env->virt_ssbd }, - }; - - if (ARRAY_SIZE(pairs) > MSHV_MSR_ENTRIES_COUNT) { - error_report("MSR entries exceed maximum size"); - g_free(msrs); - return -1; - } - - for (size_t i =3D 0; i < ARRAY_SIZE(pairs); i++) { - MshvMsrEntry *entry =3D &msrs->entries[i]; - entry->index =3D pairs[i].index; - entry->reserved =3D 0; - entry->data =3D pairs[i].value; - msrs->nmsrs++; - } - - ret =3D mshv_configure_msr(cpu, &msrs->entries[0], msrs->nmsrs); - g_free(msrs); - return ret; -} - - -int mshv_arch_put_registers(const CPUState *cpu) -{ - int ret; - - ret =3D put_regs(cpu); + ret =3D set_xc_reg(cpu); if (ret < 0) { - error_report("Failed to put registers"); - return -1; + return ret; } =20 - ret =3D put_msrs(cpu); + ret =3D set_fpu(cpu); if (ret < 0) { - error_report("Failed to put msrs"); - return -1; + return ret; } =20 return 0; @@ -1126,7 +1086,7 @@ static int emulate_instruction(CPUState *cpu, int ret; x86_insn_stream stream =3D { .bytes =3D insn_bytes, .len =3D insn_len = }; =20 - ret =3D mshv_arch_load_regs(cpu); + ret =3D load_regs(cpu); if (ret < 0) { error_report("Failed to load registers"); return -1; @@ -1135,7 +1095,7 @@ static int emulate_instruction(CPUState *cpu, decode_instruction_stream(env, &decode, &stream); exec_instruction(env, &decode); =20 - ret =3D mshv_arch_store_regs(cpu); + ret =3D store_regs(cpu); if (ret < 0) { error_report("failed to store registers"); return -1; @@ -1433,7 +1393,7 @@ static int handle_pio_str(CPUState *cpu, hv_x64_io_po= rt_intercept_message *info) X86CPU *x86_cpu =3D X86_CPU(cpu); CPUX86State *env =3D &x86_cpu->env; =20 - ret =3D mshv_arch_load_regs(cpu); + ret =3D load_regs(cpu); if (ret < 0) { error_report("Failed to load registers"); return -1; @@ -1579,6 +1539,33 @@ void mshv_init_mmio_emu(void) init_emu(&mshv_x86_emul_ops); } =20 +static int init_msrs(const CPUState *cpu) +{ + int ret; + uint64_t d_t =3D MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB; + + const struct hv_register_assoc assocs[] =3D { + { .name =3D HV_X64_REGISTER_SYSENTER_CS, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_SYSENTER_ESP, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_SYSENTER_EIP, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_STAR, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_CSTAR, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_LSTAR, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_KERNEL_GS_BASE, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_SFMASK, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_MSR_MTRR_DEF_TYPE, .value.reg64 =3D d_= t }, + }; + QEMU_BUILD_BUG_ON(ARRAY_SIZE(assocs) > MSHV_MSR_ENTRIES_COUNT); + + ret =3D mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs)); + if (ret < 0) { + error_report("failed to put msrs"); + return -1; + } + + return 0; +} + void mshv_arch_init_vcpu(CPUState *cpu) { X86CPU *x86_cpu =3D X86_CPU(cpu); @@ -1586,6 +1573,7 @@ void mshv_arch_init_vcpu(CPUState *cpu) AccelCPUState *state =3D cpu->accel; size_t page =3D HV_HYP_PAGE_SIZE; void *mem =3D qemu_memalign(page, 2 * page); + int ret; =20 /* sanity check, to make sure we don't overflow the page */ QEMU_BUILD_BUG_ON((MAX_REGISTER_COUNT @@ -1598,6 +1586,20 @@ void mshv_arch_init_vcpu(CPUState *cpu) state->hvcall_args.output_page =3D (uint8_t *)mem + page; =20 env->emu_mmio_buf =3D g_new(char, 4096); + + /* + * TODO: populate topology info: + * X86CPUTopoInfo *topo_info =3D &env->topo_info; + */ + + ret =3D init_cpuid2(cpu); + assert(ret =3D=3D 0); + + ret =3D init_msrs(cpu); + assert(ret =3D=3D 0); + + ret =3D init_lint(cpu); + assert(ret =3D=3D 0); } =20 void mshv_arch_destroy_vcpu(CPUState *cpu) --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274344; cv=none; d=zohomail.com; s=zohoarc; b=fyxax+zcA1RDrdBqA6C60xeJVja8hXgyYhfVRy4mbp6u3j/wV8aq2Fb/nV4/qo/ARBVzGzVSM0EaDUI3/nrSdqizjfUkulT/TvVNxk4m9ZVhRDzpfJHnXKPbFCAlRi1XDDnQ3aetfcd8cjwsDKbS5HrLuWv2iy+pzCI9Ty7WDqU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274344; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=VJNxhxOOFiPusHtx5YENFOefg54G1/K9ab3YYZ75Ulo=; b=cne2i9FcFu7L4UraWkdxmg7NBYkb0k5TafYpub8YoL26H3VzXBjCwLO2WzbXsQaPLnF0OkWP4RggSCmgtJeTwTZhON7mQqayKKf7j5bKUz3CEPU5sqBlMGuZmQNm8io7g6R1DO3cudlttrc+1L9LJnEq/t9a9Svq33P/wLQ7Q3Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274344523377.62265122005465; Mon, 23 Mar 2026 06:59:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnj-0007un-8i; Mon, 23 Mar 2026 09:58:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fnh-0007sH-6d for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:37 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnf-0006mc-6u for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:36 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id DC20120B712D; Mon, 23 Mar 2026 06:58:30 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com DC20120B712D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274313; bh=VJNxhxOOFiPusHtx5YENFOefg54G1/K9ab3YYZ75Ulo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kmLJXyhgRN7R5+fu7zGEnJLXHa4wEDaa2chbJr+BTysKWKE32jzQpMyi9TvaR4F3s 3CTfZBxZH23X+i5hi30IYA8Yof4RusN+Y1SUL3IfKe79MBXRW8+f/iJA8cGZstC5rw aUaEiec25ejvOs1ONncNOT25Ui6WWm9H2edoPwTc= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 04/32] accel/accel-irq: add AccelRouteChange abstraction Date: Mon, 23 Mar 2026 14:57:44 +0100 Message-Id: <20260323135812.383509-5-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274346429154100 Content-Type: text/plain; charset="utf-8" The accelerated irqchip routines use a record of changes to batch changes when programming routes. Currently this mechanism is coupled to the KVM accelerator, this change introduces an abstraction that replaces KVMRouteChange and keeps a pointer to an abstract AccelState instead of the concrete type, converting the state where necessary. This is done to further align the irqchip programming in the MSHV accelerator with the existing KVM code in QEMU. Subsequent commits will introduce AccelRouteChange to the MSHV accelerator code. Signed-off-by: Magnus Kulke --- accel/accel-irq.c | 4 ++-- accel/kvm/kvm-all.c | 6 +++--- accel/stubs/kvm-stub.c | 2 +- hw/misc/ivshmem-pci.c | 2 +- hw/vfio/pci.c | 2 +- hw/virtio/virtio-pci.c | 3 +-- include/accel/accel-route.h | 17 +++++++++++++++++ include/system/accel-irq.h | 5 +++-- include/system/kvm.h | 21 ++++++++++----------- include/system/mshv.h | 1 + target/i386/kvm/kvm.c | 2 +- 11 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 include/accel/accel-route.h diff --git a/accel/accel-irq.c b/accel/accel-irq.c index 7f864e35c4..0aa04c033d 100644 --- a/accel/accel-irq.c +++ b/accel/accel-irq.c @@ -16,7 +16,7 @@ #include "system/mshv.h" #include "system/accel-irq.h" =20 -int accel_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *= dev) +int accel_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice= *dev) { #ifdef CONFIG_MSHV_IS_POSSIBLE if (mshv_msi_via_irqfd_enabled()) { @@ -42,7 +42,7 @@ int accel_irqchip_update_msi_route(int vector, MSIMessage= msg, PCIDevice *dev) return -ENOSYS; } =20 -void accel_irqchip_commit_route_changes(KVMRouteChange *c) +void accel_irqchip_commit_route_changes(AccelRouteChange *c) { #ifdef CONFIG_MSHV_IS_POSSIBLE if (mshv_msi_via_irqfd_enabled()) { diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 774499d34f..0979545744 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2359,11 +2359,11 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage ms= g) return kvm_vm_ioctl(s, KVM_SIGNAL_MSI, &msi); } =20 -int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *de= v) +int kvm_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice *= dev) { struct kvm_irq_routing_entry kroute =3D {}; int virq; - KVMState *s =3D c->s; + KVMState *s =3D KVM_STATE(c->accel); MSIMessage msg =3D {0, 0}; =20 if (pci_available && dev) { @@ -2506,7 +2506,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg) abort(); } =20 -int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *de= v) +int kvm_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice *= dev) { return -ENOSYS; } diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index c4617caac6..32b4b07403 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -44,7 +44,7 @@ int kvm_on_sigbus(int code, void *addr) return 1; } =20 -int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *de= v) +int kvm_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice *= dev) { return -ENOSYS; } diff --git a/hw/misc/ivshmem-pci.c b/hw/misc/ivshmem-pci.c index c987eebb98..aa8f271755 100644 --- a/hw/misc/ivshmem-pci.c +++ b/hw/misc/ivshmem-pci.c @@ -424,7 +424,7 @@ static void ivshmem_add_kvm_msi_virq(IVShmemState *s, i= nt vector, Error **errp) { PCIDevice *pdev =3D PCI_DEVICE(s); - KVMRouteChange c; + AccelRouteChange c; int ret; =20 IVSHMEM_DPRINTF("ivshmem_add_kvm_msi_virq vector:%d\n", vector); diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 94c174a773..e48f4add4e 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -51,7 +51,7 @@ #include "vfio-helpers.h" =20 /* Protected by BQL */ -static KVMRouteChange vfio_route_change; +static AccelRouteChange vfio_route_change; =20 static void vfio_disable_interrupts(VFIOPCIDevice *vdev); static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index bcab2d18b8..5010572784 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -869,7 +869,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy = *proxy, int ret; =20 if (irqfd->users =3D=3D 0) { - KVMRouteChange c =3D kvm_irqchip_begin_route_changes(kvm_state); + AccelRouteChange c =3D kvm_irqchip_begin_route_changes(kvm_state); ret =3D accel_irqchip_add_msi_route(&c, vector, &proxy->pci_dev); if (ret < 0) { return ret; @@ -2695,4 +2695,3 @@ static void virtio_pci_register_types(void) } =20 type_init(virtio_pci_register_types) - diff --git a/include/accel/accel-route.h b/include/accel/accel-route.h new file mode 100644 index 0000000000..07fac27e2a --- /dev/null +++ b/include/accel/accel-route.h @@ -0,0 +1,17 @@ +/* + * Accelerator MSI route change tracking + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef ACCEL_ROUTE_H +#define ACCEL_ROUTE_H + +#include "qemu/accel.h" + +typedef struct AccelRouteChange { + AccelState *accel; + int changes; +} AccelRouteChange; + +#endif /* ACCEL_ROUTE_H */ diff --git a/include/system/accel-irq.h b/include/system/accel-irq.h index a2caa06f54..a148920711 100644 --- a/include/system/accel-irq.h +++ b/include/system/accel-irq.h @@ -25,9 +25,10 @@ static inline bool accel_irqchip_is_split(void) return mshv_msi_via_irqfd_enabled() || kvm_irqchip_is_split(); } =20 -int accel_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *= dev); +int accel_irqchip_add_msi_route(AccelRouteChange *c, int vector, + PCIDevice *dev); int accel_irqchip_update_msi_route(int vector, MSIMessage msg, PCIDevice *= dev); -void accel_irqchip_commit_route_changes(KVMRouteChange *c); +void accel_irqchip_commit_route_changes(AccelRouteChange *c); void accel_irqchip_commit_routes(void); void accel_irqchip_release_virq(int virq); int accel_irqchip_add_irqfd_notifier_gsi(EventNotifier *n, EventNotifier *= rn, diff --git a/include/system/kvm.h b/include/system/kvm.h index 5fa33eddda..ccf90b8341 100644 --- a/include/system/kvm.h +++ b/include/system/kvm.h @@ -18,6 +18,7 @@ =20 #include "exec/memattrs.h" #include "qemu/accel.h" +#include "accel/accel-route.h" #include "qom/object.h" =20 #ifdef COMPILING_PER_TARGET @@ -183,11 +184,6 @@ extern KVMState *kvm_state; typedef struct Notifier Notifier; typedef struct NotifierWithReturn NotifierWithReturn; =20 -typedef struct KVMRouteChange { - KVMState *s; - int changes; -} KVMRouteChange; - /* external API */ =20 unsigned int kvm_get_max_memslots(void); @@ -466,7 +462,7 @@ void kvm_init_cpu_signals(CPUState *cpu); =20 /** * kvm_irqchip_add_msi_route - Add MSI route for specific vector - * @c: KVMRouteChange instance. + * @c: AccelRouteChange instance. * @vector: which vector to add. This can be either MSI/MSIX * vector. The function will automatically detect whether * MSI/MSIX is enabled, and fetch corresponding MSI @@ -475,20 +471,23 @@ void kvm_init_cpu_signals(CPUState *cpu); * as @NULL, an empty MSI message will be inited. * @return: virq (>=3D0) when success, errno (<0) when failed. */ -int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *de= v); +int kvm_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice *= dev); int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg, PCIDevice *dev); void kvm_irqchip_commit_routes(KVMState *s); =20 -static inline KVMRouteChange kvm_irqchip_begin_route_changes(KVMState *s) +static inline AccelRouteChange kvm_irqchip_begin_route_changes(KVMState *s) { - return (KVMRouteChange) { .s =3D s, .changes =3D 0 }; + return (AccelRouteChange) { + .accel =3D ACCEL(s), + .changes =3D 0, + }; } =20 -static inline void kvm_irqchip_commit_route_changes(KVMRouteChange *c) +static inline void kvm_irqchip_commit_route_changes(AccelRouteChange *c) { if (c->changes) { - kvm_irqchip_commit_routes(c->s); + kvm_irqchip_commit_routes(KVM_STATE(c->accel)); c->changes =3D 0; } } diff --git a/include/system/mshv.h b/include/system/mshv.h index 75286baf16..1e96b3a606 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -21,6 +21,7 @@ #include "qapi/qapi-types-common.h" #include "system/memory.h" #include "accel/accel-ops.h" +#include "accel/accel-route.h" =20 #ifdef COMPILING_PER_TARGET #ifdef CONFIG_MSHV diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index a29f757c16..9cc41758d7 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -6680,7 +6680,7 @@ void kvm_arch_init_irq_routing(KVMState *s) kvm_gsi_routing_allowed =3D true; =20 if (kvm_irqchip_is_split()) { - KVMRouteChange c =3D kvm_irqchip_begin_route_changes(s); + AccelRouteChange c =3D kvm_irqchip_begin_route_changes(s); int i; =20 /* If the ioapic is in QEMU and the lapics are in KVM, reserve --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274362; cv=none; d=zohomail.com; s=zohoarc; b=TSzrjeD3RcSIN3rRz3aQOqJHvBcdWHJ5SqV7mysE5F/weY02LBul+tbTCi+UIvVVKl5yTm5r49vrV7i8Yr0IZU2BnBcIPWK3A84upghI6xuSyO1KeVZyhy0fAsHkOEMzuTj3OQIQ20rBjMZ/yGnhdBqj4B37NY24sG9wH3Tllo0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274362; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ZUck8KRzAIHOJZRjiz7XUC9sA5Upd2lSR/QGThC5/Zk=; b=ep603/7QEAh9TPPVA+eEDFAq5wRPKp7uiNq6fIOzV+9rpu01kkPUfnnrW5X+3+OPdQpa96379UWSddP3TKdqdifWsRyUz4nwYZq1fL3eFlRnrIILOlaTy43Xac2DUGGWsH4HlYZyym676KgJ+K7uGOf4+exLklDzIwtNiE3llWI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274362275922.2615658783573; Mon, 23 Mar 2026 06:59:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnm-0007yf-6K; Mon, 23 Mar 2026 09:58:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fnk-0007wA-GC for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:40 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fni-0006nH-NY for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:40 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id AA6F320B7135; Mon, 23 Mar 2026 06:58:34 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com AA6F320B7135 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274317; bh=ZUck8KRzAIHOJZRjiz7XUC9sA5Upd2lSR/QGThC5/Zk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G66Phg8ZIRSknyuAf6SxTBhuI7Pa5PEEyhu4NG/DulcV27GFe6HTGv6wcij1P98mk vA5QBuFi2l6cojr9xpbtuo6jIBPhFiYk6A2H6Ciu+/LZjrsJsVXlfbyhla9BEkzzMP SqsxJcmqAq2f7SVl87GjNXfYTHwHOs07dSnros5U= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 05/32] accel/accel-irq: add generic begin_route_changes Date: Mon, 23 Mar 2026 14:57:45 +0100 Message-Id: <20260323135812.383509-6-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274364002158500 Content-Type: text/plain; charset="utf-8" A generic accel_irqchip_begin_route_change() fn has been introduced for usage in the MSHV accelerator. It replaces the respective kvm_ fn. Signed-off-by: Magnus Kulke --- accel/accel-irq.c | 21 +++++++++++++++++++++ hw/misc/ivshmem-pci.c | 4 ++-- hw/vfio/pci.c | 5 +++-- hw/virtio/virtio-pci.c | 2 +- include/system/accel-irq.h | 1 + include/system/kvm.h | 8 -------- target/i386/kvm/kvm.c | 3 ++- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/accel/accel-irq.c b/accel/accel-irq.c index 0aa04c033d..3815f6727c 100644 --- a/accel/accel-irq.c +++ b/accel/accel-irq.c @@ -10,6 +10,7 @@ */ =20 #include "qemu/osdep.h" +#include "qemu/error-report.h" #include "hw/pci/msi.h" =20 #include "system/kvm.h" @@ -104,3 +105,23 @@ int accel_irqchip_remove_irqfd_notifier_gsi(EventNotif= ier *n, int virq) } return -ENOSYS; } + +inline AccelRouteChange accel_irqchip_begin_route_changes(void) +{ +#ifdef CONFIG_MSHV_IS_POSSIBLE + if (mshv_msi_via_irqfd_enabled()) { + return (AccelRouteChange) { + .accel =3D ACCEL(mshv_state), + .changes =3D 0, + }; + } +#endif + if (kvm_enabled()) { + return (AccelRouteChange) { + .accel =3D ACCEL(kvm_state), + .changes =3D 0, + }; + } + error_report("can't initiate route change, no accel irqchip available"= ); + abort(); +} diff --git a/hw/misc/ivshmem-pci.c b/hw/misc/ivshmem-pci.c index aa8f271755..fa23562886 100644 --- a/hw/misc/ivshmem-pci.c +++ b/hw/misc/ivshmem-pci.c @@ -26,7 +26,7 @@ #include "hw/core/qdev-properties-system.h" #include "hw/pci/msi.h" #include "hw/pci/msix.h" -#include "system/kvm.h" +#include "system/accel-irq.h" #include "migration/blocker.h" #include "migration/vmstate.h" #include "qemu/error-report.h" @@ -430,7 +430,7 @@ static void ivshmem_add_kvm_msi_virq(IVShmemState *s, i= nt vector, IVSHMEM_DPRINTF("ivshmem_add_kvm_msi_virq vector:%d\n", vector); assert(!s->msi_vectors[vector].pdev); =20 - c =3D kvm_irqchip_begin_route_changes(kvm_state); + c =3D accel_irqchip_begin_route_changes(); ret =3D kvm_irqchip_add_msi_route(&c, vector, pdev); if (ret < 0) { error_setg(errp, "kvm_irqchip_add_msi_route failed"); diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index e48f4add4e..6768523147 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -39,6 +39,7 @@ #include "qemu/module.h" #include "qemu/range.h" #include "qemu/units.h" +#include "system/accel-irq.h" #include "system/kvm.h" #include "system/runstate.h" #include "pci.h" @@ -692,7 +693,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, uns= igned int nr, if (vdev->defer_kvm_irq_routing) { vfio_pci_add_kvm_msi_virq(vdev, vector, nr, true); } else { - vfio_route_change =3D kvm_irqchip_begin_route_changes(kvm_= state); + vfio_route_change =3D accel_irqchip_begin_route_changes(); vfio_pci_add_kvm_msi_virq(vdev, vector, nr, true); kvm_irqchip_commit_route_changes(&vfio_route_change); vfio_connect_kvm_msi_virq(vector, nr); @@ -793,7 +794,7 @@ void vfio_pci_prepare_kvm_msi_virq_batch(VFIOPCIDevice = *vdev) { assert(!vdev->defer_kvm_irq_routing); vdev->defer_kvm_irq_routing =3D true; - vfio_route_change =3D kvm_irqchip_begin_route_changes(kvm_state); + vfio_route_change =3D accel_irqchip_begin_route_changes(); } =20 void vfio_pci_commit_kvm_msi_virq_batch(VFIOPCIDevice *vdev) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 5010572784..faa4a41cca 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -869,7 +869,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy = *proxy, int ret; =20 if (irqfd->users =3D=3D 0) { - AccelRouteChange c =3D kvm_irqchip_begin_route_changes(kvm_state); + AccelRouteChange c =3D accel_irqchip_begin_route_changes(); ret =3D accel_irqchip_add_msi_route(&c, vector, &proxy->pci_dev); if (ret < 0) { return ret; diff --git a/include/system/accel-irq.h b/include/system/accel-irq.h index a148920711..fc94c54264 100644 --- a/include/system/accel-irq.h +++ b/include/system/accel-irq.h @@ -25,6 +25,7 @@ static inline bool accel_irqchip_is_split(void) return mshv_msi_via_irqfd_enabled() || kvm_irqchip_is_split(); } =20 +AccelRouteChange accel_irqchip_begin_route_changes(void); int accel_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice *dev); int accel_irqchip_update_msi_route(int vector, MSIMessage msg, PCIDevice *= dev); diff --git a/include/system/kvm.h b/include/system/kvm.h index ccf90b8341..fec24d2135 100644 --- a/include/system/kvm.h +++ b/include/system/kvm.h @@ -476,14 +476,6 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq= , MSIMessage msg, PCIDevice *dev); void kvm_irqchip_commit_routes(KVMState *s); =20 -static inline AccelRouteChange kvm_irqchip_begin_route_changes(KVMState *s) -{ - return (AccelRouteChange) { - .accel =3D ACCEL(s), - .changes =3D 0, - }; -} - static inline void kvm_irqchip_commit_route_changes(AccelRouteChange *c) { if (c->changes) { diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 9cc41758d7..dc7c495f9c 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -32,6 +32,7 @@ #include "vmsr_energy.h" #include "system/system.h" #include "system/hw_accel.h" +#include "system/accel-irq.h" #include "system/kvm_int.h" #include "system/runstate.h" #include "system/ramblock.h" @@ -6680,7 +6681,7 @@ void kvm_arch_init_irq_routing(KVMState *s) kvm_gsi_routing_allowed =3D true; =20 if (kvm_irqchip_is_split()) { - AccelRouteChange c =3D kvm_irqchip_begin_route_changes(s); + AccelRouteChange c =3D accel_irqchip_begin_route_changes(); int i; =20 /* If the ioapic is in QEMU and the lapics are in KVM, reserve --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274346; cv=none; d=zohomail.com; s=zohoarc; b=Wbmv/UrjxWDYXKVplbbs60KWpiAzbLDrItOIH3AmenmI9tJlrJ8fiRGL4Bnr6/tcujg9mBuWqlDaU2Xhbmty3xD5MAPAHaxyZYnCNDkd4MAjjqGzuCSPHz4PdE9vNlLrhksaZLx2yqn4LFIzt5/xsbq87W4Do6yALCNXUp9EOCw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274346; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=5f5lBzYNJXSQHl9L3phyPddlzD4DT+ukgAveanWx3Z4=; b=oABjnemKo3DeJBPjXT7w77TrU4vKsxGUdAFLWPTglXTWw/NUGgIndBjUu9BUUcu018HbE+kDRGlPiitP0Iffhf1sETTyPqvC0rQtQ8Q77LimROuMQQrPRkWfywQpNq7HDMYwzFGtip1yXc9ZNY34Q4jh8GfsFM4wSqmfelKE+5Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274346957389.30082012429796; Mon, 23 Mar 2026 06:59:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnt-00089X-9A; Mon, 23 Mar 2026 09:58:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fno-00082e-RH for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:45 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnm-0006nT-CU for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:43 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 5719F20B7136; Mon, 23 Mar 2026 06:58:38 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 5719F20B7136 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274321; bh=5f5lBzYNJXSQHl9L3phyPddlzD4DT+ukgAveanWx3Z4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nDlUuqEn44ECZzdbgOTVV2eqEPp/xykd4mfUDlDV/yjrXhWX3yYgXkpvBQ3IviHMK T6Iffl179PzLwnbtL3ewwffHUrLKt8rKTrgAmTrbztCUfWOfXbo1SSVrlujNQI0aTz pXYZ///WQnWppFBugbcCKUqZMcp5wyv0OedoeusQ= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 06/32] accel/accel-irq: add generic commit_route_changes Date: Mon, 23 Mar 2026 14:57:46 +0100 Message-Id: <20260323135812.383509-7-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274348182154100 Content-Type: text/plain; charset="utf-8" A generic accel_irqchip_commit_route_changes() fn has been introduced for usage in the MSHV accelerator. The respective kvm_ fn can be removed since we handle the commit op in a generic way. Signed-off-by: Magnus Kulke --- accel/accel-irq.c | 10 +++------- hw/misc/ivshmem-pci.c | 2 +- hw/vfio/pci.c | 4 ++-- include/system/kvm.h | 8 -------- target/i386/kvm/kvm.c | 2 +- 5 files changed, 7 insertions(+), 19 deletions(-) diff --git a/accel/accel-irq.c b/accel/accel-irq.c index 3815f6727c..7e71b52555 100644 --- a/accel/accel-irq.c +++ b/accel/accel-irq.c @@ -45,13 +45,9 @@ int accel_irqchip_update_msi_route(int vector, MSIMessag= e msg, PCIDevice *dev) =20 void accel_irqchip_commit_route_changes(AccelRouteChange *c) { -#ifdef CONFIG_MSHV_IS_POSSIBLE - if (mshv_msi_via_irqfd_enabled()) { - mshv_irqchip_commit_routes(); - } -#endif - if (kvm_enabled()) { - kvm_irqchip_commit_route_changes(c); + if (c->changes) { + accel_irqchip_commit_routes(); + c->changes =3D 0; } } =20 diff --git a/hw/misc/ivshmem-pci.c b/hw/misc/ivshmem-pci.c index fa23562886..536475e9de 100644 --- a/hw/misc/ivshmem-pci.c +++ b/hw/misc/ivshmem-pci.c @@ -436,7 +436,7 @@ static void ivshmem_add_kvm_msi_virq(IVShmemState *s, i= nt vector, error_setg(errp, "kvm_irqchip_add_msi_route failed"); return; } - kvm_irqchip_commit_route_changes(&c); + accel_irqchip_commit_route_changes(&c); =20 s->msi_vectors[vector].virq =3D ret; s->msi_vectors[vector].pdev =3D pdev; diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 6768523147..d1807888d5 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -695,7 +695,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, uns= igned int nr, } else { vfio_route_change =3D accel_irqchip_begin_route_changes(); vfio_pci_add_kvm_msi_virq(vdev, vector, nr, true); - kvm_irqchip_commit_route_changes(&vfio_route_change); + accel_irqchip_commit_route_changes(&vfio_route_change); vfio_connect_kvm_msi_virq(vector, nr); } } @@ -804,7 +804,7 @@ void vfio_pci_commit_kvm_msi_virq_batch(VFIOPCIDevice *= vdev) assert(vdev->defer_kvm_irq_routing); vdev->defer_kvm_irq_routing =3D false; =20 - kvm_irqchip_commit_route_changes(&vfio_route_change); + accel_irqchip_commit_route_changes(&vfio_route_change); =20 for (i =3D 0; i < vdev->nr_vectors; i++) { vfio_connect_kvm_msi_virq(&vdev->msi_vectors[i], i); diff --git a/include/system/kvm.h b/include/system/kvm.h index fec24d2135..cdd1856ac5 100644 --- a/include/system/kvm.h +++ b/include/system/kvm.h @@ -476,14 +476,6 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq= , MSIMessage msg, PCIDevice *dev); void kvm_irqchip_commit_routes(KVMState *s); =20 -static inline void kvm_irqchip_commit_route_changes(AccelRouteChange *c) -{ - if (c->changes) { - kvm_irqchip_commit_routes(KVM_STATE(c->accel)); - c->changes =3D 0; - } -} - int kvm_irqchip_get_virq(KVMState *s); void kvm_irqchip_release_virq(KVMState *s, int virq); =20 diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index dc7c495f9c..b132e986f9 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -6692,7 +6692,7 @@ void kvm_arch_init_irq_routing(KVMState *s) exit(1); } } - kvm_irqchip_commit_route_changes(&c); + accel_irqchip_commit_route_changes(&c); } } =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274354; cv=none; d=zohomail.com; s=zohoarc; b=Mce380mBuIDlb5FQCBjuhFOOTNPE3B2bwxJJ+aW+bvtodUbf122WDcDzmXWYI3vnCceraDG70/njfKyDOgKgSg4KLYGc9ybjFhNZpjPIk7jRcIdGCGJZFgrD0wtQ/UlET58wrlM+DcZ9Heb07WvVEhmfNd6q+mRg1dhanZFvPXI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274354; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Q99VB31zJMe+kwy7P7q526bcuOKPTBKL3PaUmcduhVg=; b=TEshM6XnrFqXB+dnLEoiW6gOwQWHwVbyJfKWf2VThNghvn+cTlSQtZWSwqWla8mql0wIeMO4KZO/yHv5ZRmhuwATaDKN3egetRMUwXMtkHMchL69KeZTLGEgwR5ghZ1CHGJ7Ibdlun6qFc8wXP1YuhIyoLdsbhHAXNVeW9tuuHE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274354772140.99525921824193; Mon, 23 Mar 2026 06:59:14 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnw-0008DE-7W; Mon, 23 Mar 2026 09:58:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fnr-000885-7S for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:48 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnp-0006nf-OV for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:47 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 108DA20B7138; Mon, 23 Mar 2026 06:58:41 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 108DA20B7138 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274324; bh=Q99VB31zJMe+kwy7P7q526bcuOKPTBKL3PaUmcduhVg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UMugpAwPlir5DpKO9i8Us7blVSXe4E05zoCjdDxYfujRpzKhOP+wMH9RrbRjxoRfl +/sLmlCFC+M7Yscfn0ou5YM1nneprBNHqAFcP41oByX5dsdslcXwPesGVg76Cr/z25 KCR+5wXkiJV8WnAvEwOMM23oRtTMJ4oHDKwxeRG0= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 07/32] accel/mshv: add irq_routes to state Date: Mon, 23 Mar 2026 14:57:47 +0100 Message-Id: <20260323135812.383509-8-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274355755158500 Content-Type: text/plain; charset="utf-8" This change adds fields related to irq routing to the MSHV state, following similar fields in the KVM implementation. So far the fields are only initialized, they will be used in subsequent commits for bookkeeping purposes and storing uncommitted interrupt routes. The TYPE_MSHV_ACCEL defines have been moved to the header. Signed-off-by: Magnus Kulke --- accel/mshv/irq.c | 10 ++++++++++ accel/mshv/mshv-all.c | 6 ++---- include/system/mshv.h | 7 +++++++ include/system/mshv_int.h | 5 +++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/accel/mshv/irq.c b/accel/mshv/irq.c index 3c238c33c3..82f2022c7c 100644 --- a/accel/mshv/irq.c +++ b/accel/mshv/irq.c @@ -396,3 +396,13 @@ int mshv_reserve_ioapic_msi_routes(int vm_fd) =20 return 0; } + +void mshv_init_irq_routing(MshvState *s) +{ + int gsi_count =3D MSHV_MAX_MSI_ROUTES; + + s->irq_routes =3D g_malloc0(sizeof(*s->irq_routes)); + s->nr_allocated_irq_routes =3D 0; + s->gsi_count =3D gsi_count; + s->used_gsi_bitmap =3D bitmap_new(gsi_count); +} diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 04d248fe1d..8acb080db1 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -43,10 +43,6 @@ #include #include =20 -#define TYPE_MSHV_ACCEL ACCEL_CLASS_NAME("mshv") - -DECLARE_INSTANCE_CHECKER(MshvState, MSHV_STATE, TYPE_MSHV_ACCEL) - bool mshv_allowed; =20 MshvState *mshv_state; @@ -457,6 +453,8 @@ static int mshv_init(AccelState *as, MachineState *ms) =20 mshv_state =3D s; =20 + mshv_init_irq_routing(s); + register_mshv_memory_listener(s, &s->memory_listener, &address_space_m= emory, 0, "mshv-memory"); memory_listener_register(&mshv_io_listener, &address_space_io); diff --git a/include/system/mshv.h b/include/system/mshv.h index 1e96b3a606..0d1745315b 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -45,7 +45,13 @@ extern bool mshv_allowed; #define mshv_msi_via_irqfd_enabled() mshv_enabled() #endif =20 +#define TYPE_MSHV_ACCEL ACCEL_CLASS_NAME("mshv") + typedef struct MshvState MshvState; + +DECLARE_INSTANCE_CHECKER(MshvState, MSHV_STATE, + TYPE_MSHV_ACCEL) + extern MshvState *mshv_state; =20 /* interrupt */ @@ -60,5 +66,6 @@ void mshv_irqchip_release_virq(int virq); int mshv_irqchip_add_irqfd_notifier_gsi(const EventNotifier *n, const EventNotifier *rn, int virq); int mshv_irqchip_remove_irqfd_notifier_gsi(const EventNotifier *n, int vir= q); +void mshv_init_irq_routing(MshvState *s); =20 #endif diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 70631ca6ba..56fda76a9c 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -48,6 +48,11 @@ struct MshvState { int nr_as; MshvAddressSpace *as; int fd; + /* irqchip routing */ + struct mshv_user_irq_table *irq_routes; + int nr_allocated_irq_routes; + unsigned long *used_gsi_bitmap; + unsigned int gsi_count; }; =20 typedef struct MshvMsiControl { --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274365; cv=none; d=zohomail.com; s=zohoarc; b=AJSN3pCoY5KekTLIC+Z3fsXh62Qhy6xuCpZGztIPLXf40bRZRn1jNpwcQseLgwiUGfLARdeoCEgUl4v+qbf/lrz0RAcK9ChTE5RqkIIipr/3HHMb50a8uFZGROivxr/iQNdorLk8I+lio9h0emRXx/UF+BlkWKCESrX5mMo25Jw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274365; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=VSt5BsFgnJsvC8WsZFKT0zrQ9CBJAd3GXCR4xVichT0=; b=ZAwjzsPL1nuooh5fyi1gzUuXJMarqZzhB2cRNvd+YMQB3eHFJ1cn1KZyUutG9EjiBs5S/wUKtbs4fKks5ntLxr7ntec/sQfciT77TjPqIAn5++0VWvvh2Re2kTK6ZWo0KzGc6bitd3Qh0h5bEWYyWtAgTLDT1UREe1Y674tVn90= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274365313488.4484054401288; Mon, 23 Mar 2026 06:59:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fo9-0008GZ-2N; Mon, 23 Mar 2026 09:59:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fnv-0008DR-RB for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:52 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnu-0006nz-0E for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:51 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 940BF20B713B; Mon, 23 Mar 2026 06:58:45 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 940BF20B713B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274328; bh=VSt5BsFgnJsvC8WsZFKT0zrQ9CBJAd3GXCR4xVichT0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oz74KWORamCB4RpfWr9zrTaZQAfh1RNHwhhpmrbmrDW+LGCg+Z6OJPn5VB0HGCLSO r1ad5GomT/DuWmXPrvXhrDUwWhKS0NcrUcWpKuIhm6e6Y7wj4oWenmGk5KlMXG1PEA tIcKikz8XuPXkjI8cQBcud1kj+lqrNxmdc2vr8do= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 08/32] accel/mshv: update s->irq_routes in add_msi_route Date: Mon, 23 Mar 2026 14:57:48 +0100 Message-Id: <20260323135812.383509-9-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274365988158500 Content-Type: text/plain; charset="utf-8" The irq_routes field of the state is populated with native mshv irq route entries. The allocation logic is modelled after the KVM implementation: we will always allocate a minumum of 64 entries and use a bitmask to find/set/clear GSIs. The old implementation of add_msi_routes will be removed in a subsequent commit. Signed-off-by: Magnus Kulke --- accel/accel-irq.c | 2 +- accel/mshv/irq.c | 87 +++++++++++++++++++++++++++++++++++++---- accel/stubs/mshv-stub.c | 2 +- include/system/mshv.h | 3 +- 4 files changed, 84 insertions(+), 10 deletions(-) diff --git a/accel/accel-irq.c b/accel/accel-irq.c index 7e71b52555..5a97a345b2 100644 --- a/accel/accel-irq.c +++ b/accel/accel-irq.c @@ -21,7 +21,7 @@ int accel_irqchip_add_msi_route(AccelRouteChange *c, int = vector, PCIDevice *dev) { #ifdef CONFIG_MSHV_IS_POSSIBLE if (mshv_msi_via_irqfd_enabled()) { - return mshv_irqchip_add_msi_route(vector, dev); + return mshv_irqchip_add_msi_route(c, vector, dev); } #endif if (kvm_enabled()) { diff --git a/accel/mshv/irq.c b/accel/mshv/irq.c index 82f2022c7c..9d6bdde27a 100644 --- a/accel/mshv/irq.c +++ b/accel/mshv/irq.c @@ -278,18 +278,91 @@ static int irqchip_update_irqfd_notifier_gsi(const Ev= entNotifier *event, return register_irqfd(vm_fd, fd, virq); } =20 +static int irqchip_allocate_gsi(MshvState *s, int *gsi) +{ + int next_gsi; + + /* Return the lowest unused GSI in the bitmap */ + next_gsi =3D find_first_zero_bit(s->used_gsi_bitmap, s->gsi_count); + if (next_gsi >=3D s->gsi_count) { + return -ENOSPC; + } + + *gsi =3D next_gsi; + + return 0; +} + +static void irqchip_release_gsi(MshvState *s, int gsi) +{ + clear_bit(gsi, s->used_gsi_bitmap); +} + +static void add_routing_entry(MshvState *s, struct mshv_user_irq_entry *en= try) +{ + struct mshv_user_irq_entry *new; + int n, size; + + if (s->irq_routes->nr =3D=3D s->nr_allocated_irq_routes) { + n =3D s->nr_allocated_irq_routes * 2; + if (n < MSHV_MIN_ALLOCATED_MSI_ROUTES) { + n =3D MSHV_MIN_ALLOCATED_MSI_ROUTES; + } + size =3D sizeof(struct mshv_user_irq_table); + size +=3D n * sizeof(*new); + s->irq_routes =3D g_realloc(s->irq_routes, size); + s->nr_allocated_irq_routes =3D n; + } + + n =3D s->irq_routes->nr; + s->irq_routes->nr++; + new =3D &s->irq_routes->entries[n]; + + *new =3D *entry; + + set_bit(entry->gsi, s->used_gsi_bitmap); =20 -int mshv_irqchip_add_msi_route(int vector, PCIDevice *dev) + trace_mshv_add_msi_routing(entry->address_lo | entry->address_hi, + entry->data); +} + +int mshv_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice = *dev) { - MSIMessage msg =3D { 0, 0 }; - int virq =3D 0; + struct mshv_user_irq_entry entry =3D { 0 }; + MSIMessage msg =3D { 0 }; + uint32_t data, high_addr, low_addr; + int gsi, ret; + MshvState *s =3D MSHV_STATE(c->accel); + + if (!pci_available || !dev) { + return 0; + } =20 - if (pci_available && dev) { - msg =3D pci_get_msi_message(dev, vector); - virq =3D add_msi_routing(msg.address, le32_to_cpu(msg.data)); + msg =3D pci_get_msi_message(dev, vector); + + ret =3D irqchip_allocate_gsi(mshv_state, &gsi); + if (ret < 0) { + error_report("Could not allocate GSI for MSI route"); + return -1; + } + high_addr =3D msg.address >> 32; + low_addr =3D msg.address & 0xFFFFFFFF; + data =3D le32_to_cpu(msg.data); + + entry.gsi =3D gsi; + entry.address_hi =3D high_addr; + entry.address_lo =3D low_addr; + entry.data =3D data; + + if (s->irq_routes->nr < s->gsi_count) { + add_routing_entry(s, &entry); + c->changes++; + } else { + irqchip_release_gsi(s, gsi); + return -ENOSPC; } =20 - return virq; + return gsi; } =20 void mshv_irqchip_release_virq(int virq) diff --git a/accel/stubs/mshv-stub.c b/accel/stubs/mshv-stub.c index e499b199d9..998c9e2fc6 100644 --- a/accel/stubs/mshv-stub.c +++ b/accel/stubs/mshv-stub.c @@ -14,7 +14,7 @@ =20 bool mshv_allowed; =20 -int mshv_irqchip_add_msi_route(int vector, PCIDevice *dev) +int mshv_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice = *dev) { return -ENOSYS; } diff --git a/include/system/mshv.h b/include/system/mshv.h index 0d1745315b..7f60aba308 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -33,6 +33,7 @@ #endif =20 #define MSHV_MAX_MSI_ROUTES 4096 +#define MSHV_MIN_ALLOCATED_MSI_ROUTES 64 =20 #define MSHV_PAGE_SHIFT 12 =20 @@ -59,7 +60,7 @@ int mshv_request_interrupt(MshvState *mshv_state, uint32_= t interrupt_type, uint3 uint32_t vp_index, bool logical_destination_mod= e, bool level_triggered); =20 -int mshv_irqchip_add_msi_route(int vector, PCIDevice *dev); +int mshv_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice = *dev); int mshv_irqchip_update_msi_route(int virq, MSIMessage msg, PCIDevice *dev= ); void mshv_irqchip_commit_routes(void); void mshv_irqchip_release_virq(int virq); --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274666; cv=none; d=zohomail.com; s=zohoarc; b=frz+WbAjyKHkBpycu5ODtTKrRDvra1J+BP0PdEcoSoisbs1Wp8YSxadPvxrQjn70QoYGrjDJawCNNGTcSLRPd3o8BAKKjC+VAx5iWumKkShVTn7CPWY5D1oB4pDQ5gno16fV9X5WmbrFGCm7tdS2W/m4PHeptQgG1VxTjDDMKZU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274666; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=DLb4Xz56FicxDJh1EcJd2k8Rmdkqnc0+6TN1HYuGNCw=; b=eUuTidwGgupwDugjqGhx2tdrKga9Qp4dseBB7+opxYROOHbApC//8bdd2Sa7U1jCy4iDn2N5nOD04GPia5WhqfomSJ/WClhTlL43WLqFwkxBt2Am95+6L7bivXscCgIGe+NiI/22qlm8yL0TfXpplvEzlwQgV7tflA3XVClQRy0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274666439983.7785932289405; Mon, 23 Mar 2026 07:04:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foR-0008V3-9c; Mon, 23 Mar 2026 09:59:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fnz-0008FH-7a for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:57 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fnx-0006q3-2I for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:54 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 49F1920B7001; Mon, 23 Mar 2026 06:58:49 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 49F1920B7001 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274332; bh=DLb4Xz56FicxDJh1EcJd2k8Rmdkqnc0+6TN1HYuGNCw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bNpHuoI0CjuyVef9jXpvTbtEeEGAcU8V6+voQWSnxvzYoYAe1H/VJIzj8oOayT3f3 6rghs2smdRVgvJmDwsQjzOTF+NA6k+okOLNQG2Rv7LPFCp1wzNKwmDJ+LzwXbEKvp1 WSASlAQ7AyQKpktO6WM7d7hUo2JyWSUh2o98P9VQ= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 09/32] accel/mshv: update s->irq_routes in update_msi_route Date: Mon, 23 Mar 2026 14:57:49 +0100 Message-Id: <20260323135812.383509-10-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274669337154100 Content-Type: text/plain; charset="utf-8" The state's irq_routes field will be updated when an irqchip's gsi is requested to be updated with a new dest/vector. The old set_msi_routing() fn is redundant and can be removed. Signed-off-by: Magnus Kulke --- accel/mshv/irq.c | 87 +++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/accel/mshv/irq.c b/accel/mshv/irq.c index 9d6bdde27a..b5a047b367 100644 --- a/accel/mshv/irq.c +++ b/accel/mshv/irq.c @@ -36,52 +36,6 @@ void mshv_init_msicontrol(void) msi_control->updated =3D false; } =20 -static int set_msi_routing(uint32_t gsi, uint64_t addr, uint32_t data) -{ - struct mshv_user_irq_entry *entry; - uint32_t high_addr =3D addr >> 32; - uint32_t low_addr =3D addr & 0xFFFFFFFF; - GHashTable *gsi_routes; - - trace_mshv_set_msi_routing(gsi, addr, data); - - if (gsi >=3D MSHV_MAX_MSI_ROUTES) { - error_report("gsi >=3D MSHV_MAX_MSI_ROUTES"); - return -1; - } - - assert(msi_control); - - WITH_QEMU_LOCK_GUARD(&msi_control_mutex) { - gsi_routes =3D msi_control->gsi_routes; - entry =3D g_hash_table_lookup(gsi_routes, GINT_TO_POINTER(gsi)); - - if (entry - && entry->address_hi =3D=3D high_addr - && entry->address_lo =3D=3D low_addr - && entry->data =3D=3D data) - { - /* nothing to update */ - return 0; - } - - /* free old entry */ - g_free(entry); - - /* create new entry */ - entry =3D g_new0(struct mshv_user_irq_entry, 1); - entry->gsi =3D gsi; - entry->address_hi =3D high_addr; - entry->address_lo =3D low_addr; - entry->data =3D data; - - g_hash_table_insert(gsi_routes, GINT_TO_POINTER(gsi), entry); - msi_control->updated =3D true; - } - - return 0; -} - static int add_msi_routing(uint64_t addr, uint32_t data) { struct mshv_user_irq_entry *route_entry; @@ -370,16 +324,51 @@ void mshv_irqchip_release_virq(int virq) remove_msi_routing(virq); } =20 +static int update_routing_entry(MshvState *s, + struct mshv_user_irq_entry *new_entry) +{ + struct mshv_user_irq_entry *entry; + int n; + + for (n =3D 0; n < s->irq_routes->nr; n++) { + entry =3D &s->irq_routes->entries[n]; + if (entry->gsi !=3D new_entry->gsi) { + continue; + } + + if (!memcmp(entry, new_entry, sizeof *entry)) { + return 0; + } + + *entry =3D *new_entry; + + return 0; + } + + return -ESRCH; +} + int mshv_irqchip_update_msi_route(int virq, MSIMessage msg, PCIDevice *dev) { + uint32_t addr_hi =3D msg.address >> 32; + uint32_t addr_lo =3D msg.address & 0xFFFFFFFF; + uint32_t data =3D le32_to_cpu(msg.data); + struct mshv_user_irq_entry entry =3D { + .gsi =3D virq, + .address_hi =3D addr_hi, + .address_lo =3D addr_lo, + .data =3D data, + }; int ret; =20 - ret =3D set_msi_routing(virq, msg.address, le32_to_cpu(msg.data)); + ret =3D update_routing_entry(mshv_state, &entry); if (ret < 0) { - error_report("Failed to set msi routing"); - return -1; + error_report("Failed to set msi routing for gsi %d", virq); + abort(); } =20 + trace_mshv_set_msi_routing(virq, msg.address, data); + return 0; } =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274710; cv=none; d=zohomail.com; s=zohoarc; b=Ktz4tplIVnqdB2M9jb4E7Cpx40ei79DW7pcVLOZvo7YFnUvyM/mUxZqZBqehntN9Hg9Hrkjg18+2gumWxLcdhsT2melCTbKGhrJMT+cnNXRAu6qY+ngVZ204F9v28wXHSk85yre7ymoaExwv7tTADJlP2r6Wz9MYggx0zdTMl1Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274710; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4H6AOTHbSt4M6umhyzila9t2EZwbHKhGHm3APiPWRFc=; b=VMxjwi12ToNTmmGWGqKauw8lIJyXxya4JT0UUztHsByImwp2zdbWhGftyHy/8BTmL8rjz5w3XvdwPULhXNbbu0o/7buHHAmcX92GGrB6gDqmpO+lpkfzSZOpGuo+cB1q0uqOI0TsEthPOjBD1ruqzsDzTlVvU7hA0WKrR/a7j9Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274710258707.0098617749159; Mon, 23 Mar 2026 07:05:10 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foa-0000CD-CZ; Mon, 23 Mar 2026 09:59:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fo2-0008Ga-Hl for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:02 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fo0-0006s9-SB for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:58:58 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 00BCF20B700D; Mon, 23 Mar 2026 06:58:52 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 00BCF20B700D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274335; bh=4H6AOTHbSt4M6umhyzila9t2EZwbHKhGHm3APiPWRFc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ogk3+hhNAmK2F2D7EZqoy8Tq5JUjReQ2gcuNfVMHJuOvIOJBookBdOcNZ/oiD6uQ7 pZNAEfNs9TU0yj+qMZNmbuIkdwaGgEtUiBGw5TlBHZ4wzXEjeH84SAjov+N7uDi8UU PO+qfdmZxDZsSycV4/hVnpBU/dOQU5RFCMPdnIv4= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 10/32] accel/mshv: update s->irq_routes in release_virq Date: Mon, 23 Mar 2026 14:57:50 +0100 Message-Id: <20260323135812.383509-11-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274711308158500 Content-Type: text/plain; charset="utf-8" The state's irq_routes field will be updated when an irqchip's gsi is requested to be released. The old remove_msi_routing() fn is redundant and can be removed. Signed-off-by: Magnus Kulke --- accel/accel-irq.c | 2 +- accel/mshv/irq.c | 43 ++++++++++++++--------------------------- accel/stubs/mshv-stub.c | 2 +- include/system/mshv.h | 2 +- 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/accel/accel-irq.c b/accel/accel-irq.c index 5a97a345b2..0cb3ef78d3 100644 --- a/accel/accel-irq.c +++ b/accel/accel-irq.c @@ -67,7 +67,7 @@ void accel_irqchip_release_virq(int virq) { #ifdef CONFIG_MSHV_IS_POSSIBLE if (mshv_msi_via_irqfd_enabled()) { - mshv_irqchip_release_virq(virq); + mshv_irqchip_release_virq(mshv_state, virq); } #endif if (kvm_enabled()) { diff --git a/accel/mshv/irq.c b/accel/mshv/irq.c index b5a047b367..990ce34620 100644 --- a/accel/mshv/irq.c +++ b/accel/mshv/irq.c @@ -123,33 +123,6 @@ static int commit_msi_routing_table(int vm_fd) return 0; } =20 -static int remove_msi_routing(uint32_t gsi) -{ - struct mshv_user_irq_entry *route_entry; - GHashTable *gsi_routes; - - trace_mshv_remove_msi_routing(gsi); - - if (gsi >=3D MSHV_MAX_MSI_ROUTES) { - error_report("Invalid GSI: %u", gsi); - return -1; - } - - assert(msi_control); - - WITH_QEMU_LOCK_GUARD(&msi_control_mutex) { - gsi_routes =3D msi_control->gsi_routes; - route_entry =3D g_hash_table_lookup(gsi_routes, GINT_TO_POINTER(gs= i)); - if (route_entry) { - g_hash_table_remove(gsi_routes, GINT_TO_POINTER(gsi)); - g_free(route_entry); - msi_control->updated =3D true; - } - } - - return 0; -} - /* Pass an eventfd which is to be used for injecting interrupts from userl= and */ static int irqfd(int vm_fd, int fd, int resample_fd, uint32_t gsi, uint32_t flags) @@ -319,9 +292,21 @@ int mshv_irqchip_add_msi_route(AccelRouteChange *c, in= t vector, PCIDevice *dev) return gsi; } =20 -void mshv_irqchip_release_virq(int virq) +void mshv_irqchip_release_virq(MshvState *s, int virq) { - remove_msi_routing(virq); + struct mshv_user_irq_entry *e; + int i; + + for (i =3D 0; i < s->irq_routes->nr; i++) { + e =3D &s->irq_routes->entries[i]; + if (e->gsi =3D=3D virq) { + s->irq_routes->nr--; + *e =3D s->irq_routes->entries[s->irq_routes->nr]; + } + } + irqchip_release_gsi(s, virq); + + trace_mshv_remove_msi_routing(virq); } =20 static int update_routing_entry(MshvState *s, diff --git a/accel/stubs/mshv-stub.c b/accel/stubs/mshv-stub.c index 998c9e2fc6..dadf05511a 100644 --- a/accel/stubs/mshv-stub.c +++ b/accel/stubs/mshv-stub.c @@ -19,7 +19,7 @@ int mshv_irqchip_add_msi_route(AccelRouteChange *c, int v= ector, PCIDevice *dev) return -ENOSYS; } =20 -void mshv_irqchip_release_virq(int virq) +void mshv_irqchip_release_virq(MshvState *s, int virq) { } =20 diff --git a/include/system/mshv.h b/include/system/mshv.h index 7f60aba308..2033beed70 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -63,7 +63,7 @@ int mshv_request_interrupt(MshvState *mshv_state, uint32_= t interrupt_type, uint3 int mshv_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice = *dev); int mshv_irqchip_update_msi_route(int virq, MSIMessage msg, PCIDevice *dev= ); void mshv_irqchip_commit_routes(void); -void mshv_irqchip_release_virq(int virq); +void mshv_irqchip_release_virq(MshvState *s, int virq); int mshv_irqchip_add_irqfd_notifier_gsi(const EventNotifier *n, const EventNotifier *rn, int virq); int mshv_irqchip_remove_irqfd_notifier_gsi(const EventNotifier *n, int vir= q); --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274704; cv=none; d=zohomail.com; s=zohoarc; b=OBxHF4etxaDBju/ydl5vAlhYAdRO9thZJuyieC+d+RmnImCpVIIA0I4ShviflgCrOwEhWngMKLZaBrOg1fHQeww16PtzlrPQW54qdZdCFT4MkVh0W4nrFnxbhn7Otx0Lf6tcJUuFrpXAfRDzo1wx2U2qGLjcRyV/YzsrTHM0qZ0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274704; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=+449kqpsT3rs/26cTO+xTXYI56NYmCzZVttigepvBaE=; b=m5NZwyvXf6ucUyPd5C75zXmOLN7ziBq3MANVxpdhC5z0aRii4M0J6Z3dvwav5yOEIbc1azoS0YfdT5frRLaJq2p/0xL09kGJQHkihtbSG3/mQiP5hsacJhkNPLBHoxalbE+Ikn5HTVbuE0DjoYgyqrGrDBhO/rA0+xfQjXNprcM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274704945736.3018276918614; Mon, 23 Mar 2026 07:05:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foa-0000CZ-CV; Mon, 23 Mar 2026 09:59:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fo5-0008Jg-PG for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:03 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fo4-0006tE-C6 for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:01 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 8649420B7007; Mon, 23 Mar 2026 06:58:56 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8649420B7007 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274339; bh=+449kqpsT3rs/26cTO+xTXYI56NYmCzZVttigepvBaE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o73bjwCv1M6bmGMltUPwyi9QAIV+9orQPu8JdvTulptPQu+OYOS/eYdweG9gWS8MK BCLIxFKwQi2/TGqoLCre1iGiIanPEfphanY1iJmVbs/FYp5lYzVFDcZiGTOpcLMeGv dzUJ0apeVV4YTV/rYUgk3fRG0aXlrH1fJP6IdmKo= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 11/32] accel/mshv: use s->irq_routes in commit_routes Date: Mon, 23 Mar 2026 14:57:51 +0100 Message-Id: <20260323135812.383509-12-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274705354158500 Content-Type: text/plain; charset="utf-8" In mshv_irqchip_commit_routes() the entries that have been accumulated in s->irq_routes are committed directly to MSHV's irqchip. The old commit_msi_routing_table() fn will be removed in a subsquent commit. Signed-off-by: Magnus Kulke --- accel/accel-irq.c | 2 +- accel/mshv/irq.c | 7 ++++--- accel/stubs/mshv-stub.c | 2 +- include/system/mshv.h | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/accel/accel-irq.c b/accel/accel-irq.c index 0cb3ef78d3..4303e10e40 100644 --- a/accel/accel-irq.c +++ b/accel/accel-irq.c @@ -55,7 +55,7 @@ void accel_irqchip_commit_routes(void) { #ifdef CONFIG_MSHV_IS_POSSIBLE if (mshv_msi_via_irqfd_enabled()) { - mshv_irqchip_commit_routes(); + mshv_irqchip_commit_routes(mshv_state); } #endif if (kvm_enabled()) { diff --git a/accel/mshv/irq.c b/accel/mshv/irq.c index 990ce34620..9ba837f0e2 100644 --- a/accel/mshv/irq.c +++ b/accel/mshv/irq.c @@ -394,16 +394,17 @@ int mshv_request_interrupt(MshvState *mshv_state, uin= t32_t interrupt_type, uint3 return 0; } =20 -void mshv_irqchip_commit_routes(void) +void mshv_irqchip_commit_routes(MshvState *s) { int ret; - int vm_fd =3D mshv_state->vm; + int vm_fd =3D s->vm; =20 - ret =3D commit_msi_routing_table(vm_fd); + ret =3D ioctl(vm_fd, MSHV_SET_MSI_ROUTING, s->irq_routes); if (ret < 0) { error_report("Failed to commit msi routing table"); abort(); } + trace_mshv_commit_msi_routing_table(vm_fd, s->irq_routes->nr); } =20 int mshv_irqchip_add_irqfd_notifier_gsi(const EventNotifier *event, diff --git a/accel/stubs/mshv-stub.c b/accel/stubs/mshv-stub.c index dadf05511a..8b69539a85 100644 --- a/accel/stubs/mshv-stub.c +++ b/accel/stubs/mshv-stub.c @@ -28,7 +28,7 @@ int mshv_irqchip_update_msi_route(int virq, MSIMessage ms= g, PCIDevice *dev) return -ENOSYS; } =20 -void mshv_irqchip_commit_routes(void) +void mshv_irqchip_commit_routes(MshvState *s) { } =20 diff --git a/include/system/mshv.h b/include/system/mshv.h index 2033beed70..0c9a4f927c 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -62,8 +62,8 @@ int mshv_request_interrupt(MshvState *mshv_state, uint32_= t interrupt_type, uint3 =20 int mshv_irqchip_add_msi_route(AccelRouteChange *c, int vector, PCIDevice = *dev); int mshv_irqchip_update_msi_route(int virq, MSIMessage msg, PCIDevice *dev= ); -void mshv_irqchip_commit_routes(void); void mshv_irqchip_release_virq(MshvState *s, int virq); +void mshv_irqchip_commit_routes(MshvState *s); int mshv_irqchip_add_irqfd_notifier_gsi(const EventNotifier *n, const EventNotifier *rn, int virq); int mshv_irqchip_remove_irqfd_notifier_gsi(const EventNotifier *n, int vir= q); --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274537; cv=none; d=zohomail.com; s=zohoarc; b=By30ibB5h5LtiGSzNovRu8dTWP5YHx69kliak7V9UJ90wg88lsDRlWOIbfBXV+LDU4FhY7R2v7psdJxUNhIDBpsMYvCERS+P/4QxD+WA7Kz5NDwsLaVKk6SyO0ZiA+S1fl9tJaxKOweUVjnZJ2W4IeLvyP8LLa/0dPECFiZBj70= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274537; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=apZ0c23LEobuYLV/xQNkaE00YRO3wUE05eRvWn9R9qc=; b=Z0J1Fa8XqN5wiQ1X0etyPhCwrAWUDaJ6bo8NLrTefaAw2D2soutd50SKX+p02XkF6s8yD/L6y/TcpySa80oJhCFtwlM3vyS8Unm275u7vvBzfupu7FveCFoAOgsqRS4+zx506XoBopEKbXJ0wGdbTzfWMme1T+DUVfKrVu2qz6w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274537536730.9181548832593; Mon, 23 Mar 2026 07:02:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpD-0000dy-Cy; Mon, 23 Mar 2026 10:00:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4foE-0008Sb-DO for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:15 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fo8-0006wM-Mv for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:06 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 1650820B7017; Mon, 23 Mar 2026 06:58:59 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 1650820B7017 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274342; bh=apZ0c23LEobuYLV/xQNkaE00YRO3wUE05eRvWn9R9qc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G5MhR6qGe8Pl+TzUfI7xQZZt0ZGF6hUb9To/EUYKelrzr4B8KKbnEz6ecpGSCCbcs j5nsuXuljRYPXWE9f9tSZvwBU6ovuM/H/Zl/V570sCJ6tuyjei4rvyiDrFYkVJJl29 bUiV6feNjPyLCPcfxQf+ByMz25s9oJyjd1vJYCts= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 12/32] accel/mshv: reserve ioapic routes on s->irq_routes Date: Mon, 23 Mar 2026 14:57:52 +0100 Message-Id: <20260323135812.383509-13-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274537760158500 Content-Type: text/plain; charset="utf-8" We reserve 24 ioapic routes using the new functions that operate on the mshv apic state. commit/add_msi_routing() fn's can be removed now. Signed-off-by: Magnus Kulke --- accel/mshv/irq.c | 115 ++++++-------------------------------- accel/mshv/mshv-all.c | 5 -- include/system/mshv_int.h | 1 - 3 files changed, 18 insertions(+), 103 deletions(-) diff --git a/accel/mshv/irq.c b/accel/mshv/irq.c index 9ba837f0e2..52b8ac9479 100644 --- a/accel/mshv/irq.c +++ b/accel/mshv/irq.c @@ -36,93 +36,6 @@ void mshv_init_msicontrol(void) msi_control->updated =3D false; } =20 -static int add_msi_routing(uint64_t addr, uint32_t data) -{ - struct mshv_user_irq_entry *route_entry; - uint32_t high_addr =3D addr >> 32; - uint32_t low_addr =3D addr & 0xFFFFFFFF; - int gsi; - GHashTable *gsi_routes; - - trace_mshv_add_msi_routing(addr, data); - - assert(msi_control); - - WITH_QEMU_LOCK_GUARD(&msi_control_mutex) { - /* find an empty slot */ - gsi =3D 0; - gsi_routes =3D msi_control->gsi_routes; - while (gsi < MSHV_MAX_MSI_ROUTES) { - route_entry =3D g_hash_table_lookup(gsi_routes, GINT_TO_POINTE= R(gsi)); - if (!route_entry) { - break; - } - gsi++; - } - if (gsi >=3D MSHV_MAX_MSI_ROUTES) { - error_report("No empty gsi slot available"); - return -1; - } - - /* create new entry */ - route_entry =3D g_new0(struct mshv_user_irq_entry, 1); - route_entry->gsi =3D gsi; - route_entry->address_hi =3D high_addr; - route_entry->address_lo =3D low_addr; - route_entry->data =3D data; - - g_hash_table_insert(gsi_routes, GINT_TO_POINTER(gsi), route_entry); - msi_control->updated =3D true; - } - - return gsi; -} - -static int commit_msi_routing_table(int vm_fd) -{ - guint len; - int i, ret; - size_t table_size; - struct mshv_user_irq_table *table; - GHashTableIter iter; - gpointer key, value; - - assert(msi_control); - - WITH_QEMU_LOCK_GUARD(&msi_control_mutex) { - if (!msi_control->updated) { - /* nothing to update */ - return 0; - } - - /* Calculate the size of the table */ - len =3D g_hash_table_size(msi_control->gsi_routes); - table_size =3D sizeof(struct mshv_user_irq_table) - + len * sizeof(struct mshv_user_irq_entry); - table =3D g_malloc0(table_size); - - g_hash_table_iter_init(&iter, msi_control->gsi_routes); - i =3D 0; - while (g_hash_table_iter_next(&iter, &key, &value)) { - struct mshv_user_irq_entry *entry =3D value; - table->entries[i] =3D *entry; - i++; - } - table->nr =3D i; - - trace_mshv_commit_msi_routing_table(vm_fd, len); - - ret =3D ioctl(vm_fd, MSHV_SET_MSI_ROUTING, table); - g_free(table); - if (ret < 0) { - error_report("Failed to commit msi routing table"); - return -1; - } - msi_control->updated =3D false; - } - return 0; -} - /* Pass an eventfd which is to be used for injecting interrupts from userl= and */ static int irqfd(int vm_fd, int fd, int resample_fd, uint32_t gsi, uint32_t flags) @@ -420,37 +333,45 @@ int mshv_irqchip_remove_irqfd_notifier_gsi(const Even= tNotifier *event, return irqchip_update_irqfd_notifier_gsi(event, NULL, virq, false); } =20 -int mshv_reserve_ioapic_msi_routes(int vm_fd) +static int mshv_reserve_ioapic_msi_routes(MshvState *s) { - int ret, gsi; + int ret, i; + int gsi =3D 0; + struct mshv_user_irq_entry blank_entry =3D { 0 }; =20 /* * Reserve GSI 0-23 for IOAPIC pins, to avoid conflicts of legacy * peripherals with MSI-X devices */ - for (gsi =3D 0; gsi < IOAPIC_NUM_PINS; gsi++) { - ret =3D add_msi_routing(0, 0); + for (i =3D 0; i < IOAPIC_NUM_PINS; i++) { + /* ret =3D add_msi_routing(0, 0); */ + ret =3D irqchip_allocate_gsi(s, &gsi); if (ret < 0) { - error_report("Failed to reserve GSI %d", gsi); + error_report("Failed to reserve GSI %d: %s", gsi, strerror(-re= t)); return -1; } + blank_entry.gsi =3D gsi; + add_routing_entry(s, &blank_entry); } =20 - ret =3D commit_msi_routing_table(vm_fd); - if (ret < 0) { - error_report("Failed to commit reserved IOAPIC MSI routes"); - return -1; - } + mshv_irqchip_commit_routes(s); =20 return 0; } =20 void mshv_init_irq_routing(MshvState *s) { + int ret; int gsi_count =3D MSHV_MAX_MSI_ROUTES; =20 s->irq_routes =3D g_malloc0(sizeof(*s->irq_routes)); s->nr_allocated_irq_routes =3D 0; s->gsi_count =3D gsi_count; s->used_gsi_bitmap =3D bitmap_new(gsi_count); + + ret =3D mshv_reserve_ioapic_msi_routes(s); + if (ret < 0) { + error_report("Failed to reserve IOAPIC MSI routes"); + abort(); + } } diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 8acb080db1..08bc26713f 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -200,11 +200,6 @@ static int create_vm(int mshv_fd, int *vm_fd) return -1; } =20 - ret =3D mshv_reserve_ioapic_msi_routes(*vm_fd); - if (ret < 0) { - return -1; - } - ret =3D mshv_arch_post_init_vm(*vm_fd); if (ret < 0) { return -1; diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 56fda76a9c..9bc56e70cf 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -120,6 +120,5 @@ int mshv_configure_msr(const CPUState *cpu, const MshvM= srEntry *msrs, =20 /* interrupt */ void mshv_init_msicontrol(void); -int mshv_reserve_ioapic_msi_routes(int vm_fd); =20 #endif --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274587; cv=none; d=zohomail.com; s=zohoarc; b=GS6AwQl59o/k5XUW+afjj24DepbAi2eWK4EYUe0WXQJ9Z66KcuRZ4HlhDiQC4OnFGgzvqQCVBaBshAVbZB9sNfX8BD8lvTIbNYU3Q3agrxMabyHMZs7U8BWHE+k/MaVshvIxeXw+GmljMwpFRolsN7x1w/qXVCa+DMO+iDwWNXg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274587; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=57Nxf0HUrehtTgIAOHD4gvpLgPO803KCA3BRX10c6L0=; b=QYEAO5ZJvUAZWiWX9gUW8siQuKTCDQJlVHDqFdeKdRvLj/Q46nksB9X1ULGeDatX/SuG5tjalk9FVb/IQKFi3iu/Bd4MnbVcLwEiRzGKSbCSfP/kBOD/lGY7EtZXduehXbRaIBSl67yDAThYgfgfyQ/ZZB2rOaFULOkZbVsH8EY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274587938410.43522204850626; Mon, 23 Mar 2026 07:03:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fop-0000TY-77; Mon, 23 Mar 2026 09:59:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4foG-0008St-25 for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:16 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foD-0006wZ-Gf for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:11 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id ABB9020B703B; Mon, 23 Mar 2026 06:59:03 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com ABB9020B703B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274346; bh=57Nxf0HUrehtTgIAOHD4gvpLgPO803KCA3BRX10c6L0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k6q8KWt76IFtPQRx4EoxjLyHAczwTAFAwykWgBnbrySJ5CVrdRKhDXqe6Cew6CL3U ni4M+EKnPKg5GVjHoRek7pE+EXgM93XwPqSJrr/ujI+4kQykNENxVPRIsWFJecihSi oztEOE7VsjSEq7kc9185RWpDVYSXqE1oC9zJLSdE= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 13/32] accel/mshv: remove redundant msi controller Date: Mon, 23 Mar 2026 14:57:53 +0100 Message-Id: <20260323135812.383509-14-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274590140154102 Content-Type: text/plain; charset="utf-8" The remaining MsiControl infrastructure can be removed now Signed-off-by: Magnus Kulke --- accel/mshv/irq.c | 11 ----------- accel/mshv/mshv-all.c | 2 -- include/system/mshv_int.h | 3 --- 3 files changed, 16 deletions(-) diff --git a/accel/mshv/irq.c b/accel/mshv/irq.c index 52b8ac9479..4828ac51ac 100644 --- a/accel/mshv/irq.c +++ b/accel/mshv/irq.c @@ -25,17 +25,6 @@ #define MSHV_IRQFD_RESAMPLE_FLAG (1 << MSHV_IRQFD_BIT_RESAMPLE) #define MSHV_IRQFD_BIT_DEASSIGN_FLAG (1 << MSHV_IRQFD_BIT_DEASSIGN) =20 -static MshvMsiControl *msi_control; -static QemuMutex msi_control_mutex; - -void mshv_init_msicontrol(void) -{ - qemu_mutex_init(&msi_control_mutex); - msi_control =3D g_new0(MshvMsiControl, 1); - msi_control->gsi_routes =3D g_hash_table_new(g_direct_hash, g_direct_e= qual); - msi_control->updated =3D false; -} - /* Pass an eventfd which is to be used for injecting interrupts from userl= and */ static int irqfd(int vm_fd, int fd, int resample_fd, uint32_t gsi, uint32_t flags) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 08bc26713f..056b19b3b8 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -426,8 +426,6 @@ static int mshv_init(AccelState *as, MachineState *ms) =20 mshv_init_mmio_emu(); =20 - mshv_init_msicontrol(); - ret =3D create_vm(mshv_fd, &vm_fd); if (ret < 0) { close(mshv_fd); diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 9bc56e70cf..7af5bcf022 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -118,7 +118,4 @@ typedef struct MshvMsrEntries { int mshv_configure_msr(const CPUState *cpu, const MshvMsrEntry *msrs, size_t n_msrs); =20 -/* interrupt */ -void mshv_init_msicontrol(void); - #endif --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274708; cv=none; d=zohomail.com; s=zohoarc; b=KShjYrTIIMNjX7NwtZNN7O9xuQN+egnxISCM0V0pCPcRrBpmK8jI9PM62RIF0HMbD5AwuCb784jxvpt7U6dBKTWcOFgUk4W5vcltp3UAYvW9K+kE6Xbf5z3TLItfW2Lhy4IPPcw9diYCjqVxlZannju3sfNzIPvhQ8EjDGv3azk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274708; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=jJHde85rrqP4JFlhsgAekskobRmJMJo3MVNFcALWQys=; b=Q3ubeGmvJaz+3ramZk2e45bnBiZ4DECAhOzxMaTibU3lt/tdBZ9WPRWeysiLNtqj0Sjf3b0i+Y196nPV/Dmhpuv7Ieapeol7i+/gWu6WberlvKhSY6AgHKaSxuO8xTOz2+YN0sLsWkUF5UGLV+GCeZm8aaFGzlNcYknxrTTr4mQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274708635183.5407215836583; Mon, 23 Mar 2026 07:05:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpt-00017z-Jz; Mon, 23 Mar 2026 10:00:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4foH-0008TA-Oj for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:20 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foF-0006wl-QZ for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:13 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 93A7A20B6F01; Mon, 23 Mar 2026 06:59:07 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 93A7A20B6F01 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274350; bh=jJHde85rrqP4JFlhsgAekskobRmJMJo3MVNFcALWQys=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jZX5ekNXnuKDmViDKWeLe6jPJW1ZxH4BagMdEbQpl9FVooJfy4oELFciJEKl/fD9N r+HeF1+fyAGCc3DgLc/1h0q7baBYN2anFR+F+rJkawuEcIX5uwLavbaT+EqUHESexU 320eLM+0Fm/ybrVMxVA9wZAb6AXSpJpc7mBvTRrk= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 14/32] target/i386/mshv: move apic logic into own file Date: Mon, 23 Mar 2026 14:57:54 +0100 Message-Id: <20260323135812.383509-15-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274709358158500 Content-Type: text/plain; charset="utf-8" Use a new file to unclutter the vcpu code gradually from APIC related logic. Signed-off-by: Magnus Kulke --- include/system/mshv_int.h | 8 ++++ target/i386/mshv/meson.build | 1 + target/i386/mshv/mshv-apic.c | 78 ++++++++++++++++++++++++++++++++++++ target/i386/mshv/mshv-cpu.c | 66 +++--------------------------- 4 files changed, 92 insertions(+), 61 deletions(-) create mode 100644 target/i386/mshv/mshv-apic.c diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 7af5bcf022..f86c7a3be6 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -16,6 +16,8 @@ =20 #define MSHV_MSR_ENTRIES_COUNT 64 =20 +struct mshv_get_set_vp_state; + typedef struct hyperv_message hv_message; =20 typedef struct MshvHvCallArgs { @@ -84,6 +86,12 @@ void mshv_arch_destroy_vcpu(CPUState *cpu); void mshv_arch_amend_proc_features( union hv_partition_synthetic_processor_features *features); int mshv_arch_post_init_vm(int vm_fd); +int mshv_set_lapic(int cpu_fd, + const struct hv_local_interrupt_controller_state *state= ); +int mshv_get_lapic(int cpu_fd, + struct hv_local_interrupt_controller_state *state); +int mshv_get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state); +int mshv_set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *stat= e); =20 typedef struct mshv_root_hvcall mshv_root_hvcall; int mshv_hvcall(int fd, const mshv_root_hvcall *args); diff --git a/target/i386/mshv/meson.build b/target/i386/mshv/meson.build index 49f28d4a5b..5eb6e833a6 100644 --- a/target/i386/mshv/meson.build +++ b/target/i386/mshv/meson.build @@ -1,6 +1,7 @@ i386_mshv_ss =3D ss.source_set() =20 i386_mshv_ss.add(files( + 'mshv-apic.c', 'mshv-cpu.c', )) =20 diff --git a/target/i386/mshv/mshv-apic.c b/target/i386/mshv/mshv-apic.c new file mode 100644 index 0000000000..e0e8b8cacf --- /dev/null +++ b/target/i386/mshv/mshv-apic.c @@ -0,0 +1,78 @@ +/* + * QEMU MSHV support + * + * Copyright Microsoft, Corp. 2026 + * + * Authors: Magnus Kulke + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/memalign.h" +#include "qemu/error-report.h" + +#include "system/mshv.h" +#include "system/mshv_int.h" + +#include "linux/mshv.h" +#include "hw/hyperv/hvgdk.h" +#include "hw/hyperv/hvhdk_mini.h" +#include "hw/hyperv/hvgdk_mini.h" + +#include + +int mshv_get_lapic(int cpu_fd, + struct hv_local_interrupt_controller_state *state) +{ + int ret; + size_t size =3D 4096; + /* buffer aligned to 4k, as *state requires that */ + void *buffer =3D qemu_memalign(size, size); + struct mshv_get_set_vp_state mshv_state =3D { 0 }; + + mshv_state.buf_ptr =3D (uint64_t) buffer; + mshv_state.buf_sz =3D size; + mshv_state.type =3D MSHV_VP_STATE_LAPIC; + + ret =3D mshv_get_vp_state(cpu_fd, &mshv_state); + if (ret =3D=3D 0) { + memcpy(state, buffer, sizeof(*state)); + } + qemu_vfree(buffer); + if (ret < 0) { + error_report("failed to get lapic"); + return -1; + } + + return 0; +} + +int mshv_set_lapic(int cpu_fd, + const struct hv_local_interrupt_controller_state *state) +{ + int ret; + size_t size =3D 4096; + /* buffer aligned to 4k, as *state requires that */ + void *buffer =3D qemu_memalign(size, size); + struct mshv_get_set_vp_state mshv_state =3D { 0 }; + + if (!state) { + error_report("lapic state is NULL"); + return -1; + } + memcpy(buffer, state, sizeof(*state)); + + mshv_state.buf_ptr =3D (uint64_t) buffer; + mshv_state.buf_sz =3D size; + mshv_state.type =3D MSHV_VP_STATE_LAPIC; + + ret =3D mshv_set_vp_state(cpu_fd, &mshv_state); + qemu_vfree(buffer); + if (ret < 0) { + error_report("failed to set lapic: %s", strerror(errno)); + return -1; + } + + return 0; +} diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 56656ac0b0..54c262d8bc 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -919,7 +919,7 @@ static int set_xc_reg(const CPUState *cpu) return 0; } =20 -static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state) +int mshv_get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state) { int ret; =20 @@ -932,39 +932,12 @@ static int get_vp_state(int cpu_fd, struct mshv_get_s= et_vp_state *state) return 0; } =20 -static int get_lapic(const CPUState *cpu, - struct hv_local_interrupt_controller_state *state) -{ - int ret; - size_t size =3D 4096; - /* buffer aligned to 4k, as *state requires that */ - void *buffer =3D qemu_memalign(size, size); - struct mshv_get_set_vp_state mshv_state =3D { 0 }; - int cpu_fd =3D mshv_vcpufd(cpu); - - mshv_state.buf_ptr =3D (uint64_t) buffer; - mshv_state.buf_sz =3D size; - mshv_state.type =3D MSHV_VP_STATE_LAPIC; - - ret =3D get_vp_state(cpu_fd, &mshv_state); - if (ret =3D=3D 0) { - memcpy(state, buffer, sizeof(*state)); - } - qemu_vfree(buffer); - if (ret < 0) { - error_report("failed to get lapic"); - return -1; - } - - return 0; -} - static uint32_t set_apic_delivery_mode(uint32_t reg, uint32_t mode) { return ((reg) & ~0x700) | ((mode) << 8); } =20 -static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *st= ate) +int mshv_set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *stat= e) { int ret; =20 @@ -977,43 +950,14 @@ static int set_vp_state(int cpu_fd, const struct mshv= _get_set_vp_state *state) return 0; } =20 -static int set_lapic(const CPUState *cpu, - const struct hv_local_interrupt_controller_state *sta= te) -{ - int ret; - size_t size =3D 4096; - /* buffer aligned to 4k, as *state requires that */ - void *buffer =3D qemu_memalign(size, size); - struct mshv_get_set_vp_state mshv_state =3D { 0 }; - int cpu_fd =3D mshv_vcpufd(cpu); - - if (!state) { - error_report("lapic state is NULL"); - return -1; - } - memcpy(buffer, state, sizeof(*state)); - - mshv_state.buf_ptr =3D (uint64_t) buffer; - mshv_state.buf_sz =3D size; - mshv_state.type =3D MSHV_VP_STATE_LAPIC; - - ret =3D set_vp_state(cpu_fd, &mshv_state); - qemu_vfree(buffer); - if (ret < 0) { - error_report("failed to set lapic: %s", strerror(errno)); - return -1; - } - - return 0; -} - static int init_lint(const CPUState *cpu) { int ret; uint32_t *lvt_lint0, *lvt_lint1; + int cpu_fd =3D mshv_vcpufd(cpu); =20 struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; - ret =3D get_lapic(cpu, &lapic_state); + ret =3D mshv_get_lapic(cpu_fd, &lapic_state); if (ret < 0) { return ret; } @@ -1026,7 +970,7 @@ static int init_lint(const CPUState *cpu) =20 /* TODO: should we skip setting lapic if the values are the same? */ =20 - return set_lapic(cpu, &lapic_state); + return mshv_set_lapic(cpu_fd, &lapic_state); } =20 int mshv_arch_store_vcpu_state(const CPUState *cpu) --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274707; cv=none; d=zohomail.com; s=zohoarc; b=VGI6xZhZE9ot/XQEmLmQtnYIzL9Uq2PEXbACbEKMOoFd304REkMyFFYvQNypvsknbdfCbFbQ6LeM/KFT+p7+5PkRuaQ5vvzSVtKyjlj/xnLNs2syyGGnlzbNSKFiWctQsiSgdty2SvgCVq726NGg8W9oEwB7tdHEl2r4p9YgHnk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274707; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=5zQbl0qaIrXlqH8wQsSR333IBJGZhs7tX9K2NiD0c5Y=; b=MBIbIXYGoQ9mbDycAHh3UH6b1b2uxJIcoR76LcKLfjvJ6S+XdajQiQQJTLXnyzNT3u6tvIwuwTlCTk53qKRRqPRabT5sCr3WqE1E0Ol9cBOpWGMrY7h1YuwQ8Ls9EeJdWF8aKK8n87GFNA31r5MtJn35aAy0HSXp1jYM0Iu7M+0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274707721916.4969142192962; Mon, 23 Mar 2026 07:05:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fqh-0001M5-9U; Mon, 23 Mar 2026 10:01:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4foW-0000KK-O1 for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:32 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foT-0006x8-CG for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:26 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 630D820B6F08; Mon, 23 Mar 2026 06:59:11 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 630D820B6F08 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274354; bh=5zQbl0qaIrXlqH8wQsSR333IBJGZhs7tX9K2NiD0c5Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q/ZRDX2XBm1qEzol0kfD+91lpBhi58V1oP9IFaZNPqfjB+VpBfxr4CFDE7GSxiFec ZuhS/USARHValeySyaF3TDKcDCniH5Wfq7Oh/Roq8fGlrNZwrsHeBV9WeBOF7k1wKN MOA0Jg1yGStijV4but70LbvZ1eZCWD8EiIqc1KeM= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 15/32] target/i386/mshv: migrate LAPIC state Date: Mon, 23 Mar 2026 14:57:55 +0100 Message-Id: <20260323135812.383509-16-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274710053154100 Content-Type: text/plain; charset="utf-8" This change implements loading and storing the hyperv lapic state as part of the load/store routines for a vcpu. The HyperV LAPIC is similar to the the split-irqchip in KVM, it will only handle MSI/X interrupts. PIC and IOAPIC have to be handled in userland. An opaque blob is added to the APICCommonState, guarded behind a flag, hence it will be covered by a migration, as we declare VMSTATE_BUFFER for the hv_lapic_state field. In the future we might want to introduce a dedicated class for MSHV, that would require us to wire up an IOAPIC delivery path to QEMU's userland emulation. Signed-off-by: Magnus Kulke --- hw/intc/apic_common.c | 3 ++ include/hw/i386/apic_internal.h | 5 +++ target/i386/mshv/mshv-cpu.c | 61 +++++++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index bf4abc21d7..a7df870f1a 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -380,6 +380,9 @@ static const VMStateDescription vmstate_apic_common =3D= { VMSTATE_INT64(next_time, APICCommonState), VMSTATE_INT64(timer_expiry, APICCommonState), /* open-coded timer state */ +#ifdef CONFIG_MSHV + VMSTATE_BUFFER(hv_lapic_state, APICCommonState), +#endif VMSTATE_END_OF_LIST() }, .subsections =3D (const VMStateDescription * const []) { diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_interna= l.h index 0cb06bbc76..6d4ccca4e8 100644 --- a/include/hw/i386/apic_internal.h +++ b/include/hw/i386/apic_internal.h @@ -23,6 +23,7 @@ =20 #include "cpu.h" #include "hw/i386/apic.h" +#include "hw/hyperv/hvgdk_mini.h" #include "system/memory.h" #include "qemu/timer.h" #include "target/i386/cpu-qom.h" @@ -188,6 +189,10 @@ struct APICCommonState { DeviceState *vapic; hwaddr vapic_paddr; /* note: persistence via kvmvapic */ uint32_t extended_log_dest; + +#ifdef CONFIG_MSHV + uint8_t hv_lapic_state[sizeof(struct hv_local_interrupt_controller_sta= te)]; +#endif }; =20 typedef struct VAPICState { diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 54c262d8bc..906f5b0c3d 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -112,6 +112,25 @@ static int get_generic_regs(CPUState *cpu, struct hv_register_assoc *assocs, size_t n_regs); =20 +static int get_lapic(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + APICCommonState *apic =3D APIC_COMMON(x86cpu->apic_state); + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; + + ret =3D mshv_get_lapic(cpu_fd, &lapic_state); + if (ret < 0) { + error_report("failed to get lapic state"); + return -1; + } + + memcpy(&apic->hv_lapic_state, &lapic_state, sizeof(lapic_state)); + + return 0; +} + static void populate_fpu(const hv_register_assoc *assocs, X86CPU *x86cpu) { union hv_register_value value; @@ -559,6 +578,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D get_lapic(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 @@ -952,9 +976,11 @@ int mshv_set_vp_state(int cpu_fd, const struct mshv_ge= t_set_vp_state *state) =20 static int init_lint(const CPUState *cpu) { - int ret; + X86CPU *x86cpu =3D X86_CPU(cpu); + APICCommonState *apic =3D APIC_COMMON(x86cpu->apic_state); uint32_t *lvt_lint0, *lvt_lint1; int cpu_fd =3D mshv_vcpufd(cpu); + int ret; =20 struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; ret =3D mshv_get_lapic(cpu_fd, &lapic_state); @@ -970,7 +996,32 @@ static int init_lint(const CPUState *cpu) =20 /* TODO: should we skip setting lapic if the values are the same? */ =20 - return mshv_set_lapic(cpu_fd, &lapic_state); + ret =3D mshv_set_lapic(cpu_fd, &lapic_state); + if (ret < 0) { + return -1; + } + + memcpy(apic->hv_lapic_state, &lapic_state, sizeof(lapic_state)); + + return 0; +} + +static int set_lapic(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + APICCommonState *apic =3D APIC_COMMON(x86cpu->apic_state); + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + + struct hv_local_interrupt_controller_state lapic_state =3D { 0 }; + memcpy(&lapic_state, &apic->hv_lapic_state, sizeof(lapic_state)); + ret =3D mshv_set_lapic(cpu_fd, &lapic_state); + if (ret < 0) { + error_report("failed to set lapic"); + return -1; + } + + return 0; } =20 int mshv_arch_store_vcpu_state(const CPUState *cpu) @@ -997,6 +1048,12 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 + /* INVARIANT: special regs (APIC_BASE) must be restored before LAPIC */ + ret =3D set_lapic(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274717; cv=none; d=zohomail.com; s=zohoarc; b=kM4QVx43BdH66mgXMbgaXewz+E4XrkL+79FyL0y+YTq9+XoKhnA9VxvLvKjEFAlpBqOnbapDNS5bSuVMSFrdTfOfJatgyPcU6MBj+HKnWbgBv4SMLApyx8/DLqBBndKqcrmS35ViY+F2PIx/GlAtu6g5gENLpj9JddXAz61hAv0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274717; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=JjZO2/X3lUM54v7gEfoxaHgi6BZofDR2FWQNRjmIZ3g=; b=cXTGBzOP1C5c1se2rS0BzVYd/HVQevkOh/d+MzfA/XZco6qSlOKbSXcN1HR7A5vlNIbkzR9LHs0fIGKGslkDu5jGyhWEdGbnkMTtn4IOfd1QGLTZ1IRQgwTSnztZxZ2PajTI3JNlkPWNMkSPFzGbb96/fv03+ulgOMdMu1wxFGk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274717736636.7819816009114; Mon, 23 Mar 2026 07:05:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4frg-00031z-TE; Mon, 23 Mar 2026 10:02:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4foZ-0000RL-0Q for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:40 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foW-0006xI-HO for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:29 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 01C4720B6F12; Mon, 23 Mar 2026 06:59:14 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 01C4720B6F12 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274357; bh=JjZO2/X3lUM54v7gEfoxaHgi6BZofDR2FWQNRjmIZ3g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EdTpaejezyNCqSnBHdwFIFM4AsUnJFV6TB9ExJskiAIaH2I/xiWhRE4gcvppAbvkD OvbDelpoc+sNVyggAWiHp3Vpj5sm6fb+J+iD6MuaLub0HMX3QBgcxqlDRkven0BVrn FjGit/rrNlDterxKu/jRGDcqzhWk91DeO1Po6G9c= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 16/32] target/i386/mshv: move msr code to arch Date: Mon, 23 Mar 2026 14:57:56 +0100 Message-Id: <20260323135812.383509-17-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274719312158500 Content-Type: text/plain; charset="utf-8" The MSR code is x86 specific, hence it's better suited in the arch tree. Signed-off-by: Magnus Kulke --- accel/mshv/meson.build | 1 - target/i386/mshv/meson.build | 1 + {accel =3D> target/i386}/mshv/msr.c | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {accel =3D> target/i386}/mshv/msr.c (100%) diff --git a/accel/mshv/meson.build b/accel/mshv/meson.build index c1b1787c5e..e433187cde 100644 --- a/accel/mshv/meson.build +++ b/accel/mshv/meson.build @@ -1,6 +1,5 @@ system_ss.add(when: 'CONFIG_MSHV', if_true: files( 'irq.c', 'mem.c', - 'msr.c', 'mshv-all.c' )) diff --git a/target/i386/mshv/meson.build b/target/i386/mshv/meson.build index 5eb6e833a6..f44e84688d 100644 --- a/target/i386/mshv/meson.build +++ b/target/i386/mshv/meson.build @@ -3,6 +3,7 @@ i386_mshv_ss =3D ss.source_set() i386_mshv_ss.add(files( 'mshv-apic.c', 'mshv-cpu.c', + 'msr.c', )) =20 i386_system_ss.add_all(when: 'CONFIG_MSHV', if_true: i386_mshv_ss) diff --git a/accel/mshv/msr.c b/target/i386/mshv/msr.c similarity index 100% rename from accel/mshv/msr.c rename to target/i386/mshv/msr.c --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274667; cv=none; d=zohomail.com; s=zohoarc; b=M0aayI4lA3XoJGLjxOtzVmRQ01HNeHjodZg8IkwmdepgMMWZvnX3J3eFNZPkC4AeK9WuWaI7s6eYB01YMd0PxMQQWGc8nuoi1jpqSlqSaX3SUrrqrDbCfbCzSj4ROfFtILkEKJmflAhgmiRzk7pHLCLH1hCDkSb03Z4YbAfRKT8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274667; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=OQujwAZOqX2qQUO+ZXBx8ttJK+qeeuCMDCt1NJaHUSw=; b=hECfmsbFbpeOWZ+O/Op6TvfrrKJA1smva3AnxBRYzrxyJCGoaBpL5vjOw+68CuJV1AzoIf1/JKoqbwXUPSRkhvd4NGpIVkDI3JbBOFCPThjI5U6RcWVrBzcTnrF+WnBoXs6RHpLOXLnktm5eZ/Dxhvfi+1tRP1aChps4ALRYZpI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274667331155.6661015595945; Mon, 23 Mar 2026 07:04:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4frz-0003PF-N2; Mon, 23 Mar 2026 10:03:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fof-0000SI-EP for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:42 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foa-0006xR-UM for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:34 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 85EFE20B6F0C; Mon, 23 Mar 2026 06:59:18 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 85EFE20B6F0C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274361; bh=OQujwAZOqX2qQUO+ZXBx8ttJK+qeeuCMDCt1NJaHUSw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NoeyWSSt+dIrj8giZcWklm+Y9AptfNIcDh8IOcnaYBjlz5Os9MWvifc/MfDlJ29xE 1U6QdD+eGy8pAQSzsQjA1zNioIvm4UtPVnSdocmj22vfxbgUE+4TmSvsu8x2jRHVhH 4ek9uRGWcPr65VVRYi/ADaI3h2tL3iahMSUwYZ8w= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 17/32] accel/mshv: store partition proc features Date: Mon, 23 Mar 2026 14:57:57 +0100 Message-Id: <20260323135812.383509-18-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274669283154100 Content-Type: text/plain; charset="utf-8" We retrieve and store processor features on the state, so we can query them later when deciding which MSRs to migrate. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 57 +++++++++++++++ include/hw/hyperv/hvhdk.h | 149 ++++++++++++++++++++++++++++++++++++++ include/system/mshv_int.h | 2 + 3 files changed, 208 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 056b19b3b8..d1bf148bb8 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -106,6 +106,57 @@ static int resume_vm(int vm_fd) return 0; } =20 +static int get_partition_property(int vm_fd, uint32_t property_code, + uint64_t *value) +{ + struct hv_input_get_partition_property in =3D {0}; + struct hv_output_get_partition_property out =3D {0}; + struct mshv_root_hvcall args =3D {0}; + int ret; + + in.property_code =3D property_code; + + args.code =3D HVCALL_GET_PARTITION_PROPERTY; + args.in_sz =3D sizeof(in); + args.in_ptr =3D (uint64_t)∈ + args.out_sz =3D sizeof(out); + args.out_ptr =3D (uint64_t)&out; + + ret =3D ioctl(vm_fd, MSHV_ROOT_HVCALL, &args); + if (ret < 0) { + error_report("Failed to get guest partition property bank: %s", + strerror(errno)); + return -1; + } + + *value =3D out.property_value; + return 0; +} + +static int get_proc_features(int vm_fd, + union hv_partition_processor_features *featur= es) +{ + int ret; + + ret =3D get_partition_property(vm_fd, + HV_PARTITION_PROPERTY_PROCESSOR_FEATURES0, + features[0].as_uint64); + if (ret < 0) { + error_report("Failed to get processor features bank 0"); + return -1; + } + + ret =3D get_partition_property(vm_fd, + HV_PARTITION_PROPERTY_PROCESSOR_FEATURES1, + features[0].as_uint64); + if (ret < 0) { + error_report("Failed to get processor features bank 1"); + return -1; + } + + return 0; +} + static int create_partition(int mshv_fd, int *vm_fd) { int ret; @@ -441,6 +492,12 @@ static int mshv_init(AccelState *as, MachineState *ms) =20 s->vm =3D vm_fd; s->fd =3D mshv_fd; + + ret =3D get_proc_features(vm_fd, &s->processor_features); + if (ret < 0) { + return -1; + } + s->nr_as =3D 1; s->as =3D g_new0(MshvAddressSpace, s->nr_as); =20 diff --git a/include/hw/hyperv/hvhdk.h b/include/hw/hyperv/hvhdk.h index 866c8211bf..5177cfa7e5 100644 --- a/include/hw/hyperv/hvhdk.h +++ b/include/hw/hyperv/hvhdk.h @@ -11,6 +11,16 @@ =20 #define HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS 1 =20 +struct hv_input_get_partition_property { + uint64_t partition_id; + uint32_t property_code; /* enum hv_partition_property_code */ + uint32_t padding; +} QEMU_PACKED; + +struct hv_output_get_partition_property { + uint64_t property_value; +} QEMU_PACKED; + struct hv_input_set_partition_property { uint64_t partition_id; uint32_t property_code; /* enum hv_partition_property_code */ @@ -246,4 +256,143 @@ typedef struct hv_input_register_intercept_result { union hv_register_intercept_result_parameters parameters; } hv_input_register_intercept_result; =20 +#define HV_PARTITION_PROCESSOR_FEATURES_BANKS 2 +#define HV_PARTITION_PROCESSOR_FEATURES_RESERVEDBANK1_BITFIELD_COUNT 4 + +union hv_partition_processor_features { + uint64_t as_uint64[HV_PARTITION_PROCESSOR_FEATURES_BANKS]; + struct { + uint64_t sse3_support:1; + uint64_t lahf_sahf_support:1; + uint64_t ssse3_support:1; + uint64_t sse4_1_support:1; + uint64_t sse4_2_support:1; + uint64_t sse4a_support:1; + uint64_t xop_support:1; + uint64_t pop_cnt_support:1; + uint64_t cmpxchg16b_support:1; + uint64_t altmovcr8_support:1; + uint64_t lzcnt_support:1; + uint64_t mis_align_sse_support:1; + uint64_t mmx_ext_support:1; + uint64_t amd3dnow_support:1; + uint64_t extended_amd3dnow_support:1; + uint64_t page_1gb_support:1; + uint64_t aes_support:1; + uint64_t pclmulqdq_support:1; + uint64_t pcid_support:1; + uint64_t fma4_support:1; + uint64_t f16c_support:1; + uint64_t rd_rand_support:1; + uint64_t rd_wr_fs_gs_support:1; + uint64_t smep_support:1; + uint64_t enhanced_fast_string_support:1; + uint64_t bmi1_support:1; + uint64_t bmi2_support:1; + uint64_t hle_support_deprecated:1; + uint64_t rtm_support_deprecated:1; + uint64_t movbe_support:1; + uint64_t npiep1_support:1; + uint64_t dep_x87_fpu_save_support:1; + uint64_t rd_seed_support:1; + uint64_t adx_support:1; + uint64_t intel_prefetch_support:1; + uint64_t smap_support:1; + uint64_t hle_support:1; + uint64_t rtm_support:1; + uint64_t rdtscp_support:1; + uint64_t clflushopt_support:1; + uint64_t clwb_support:1; + uint64_t sha_support:1; + uint64_t x87_pointers_saved_support:1; + uint64_t invpcid_support:1; + uint64_t ibrs_support:1; + uint64_t stibp_support:1; + uint64_t ibpb_support:1; + uint64_t unrestricted_guest_support:1; + uint64_t mdd_support:1; + uint64_t fast_short_rep_mov_support:1; + uint64_t l1dcache_flush_support:1; + uint64_t rdcl_no_support:1; + uint64_t ibrs_all_support:1; + uint64_t skip_l1df_support:1; + uint64_t ssb_no_support:1; + uint64_t rsb_a_no_support:1; + uint64_t virt_spec_ctrl_support:1; + uint64_t rd_pid_support:1; + uint64_t umip_support:1; + uint64_t mbs_no_support:1; + uint64_t mb_clear_support:1; + uint64_t taa_no_support:1; + uint64_t tsx_ctrl_support:1; + uint64_t reserved_bank0:1; + + /* N.B. Begin bank 1 processor features. */ + uint64_t a_count_m_count_support:1; + uint64_t tsc_invariant_support:1; + uint64_t cl_zero_support:1; + uint64_t rdpru_support:1; + uint64_t la57_support:1; + uint64_t mbec_support:1; + uint64_t nested_virt_support:1; + uint64_t psfd_support:1; + uint64_t cet_ss_support:1; + uint64_t cet_ibt_support:1; + uint64_t vmx_exception_inject_support:1; + uint64_t enqcmd_support:1; + uint64_t umwait_tpause_support:1; + uint64_t movdiri_support:1; + uint64_t movdir64b_support:1; + uint64_t cldemote_support:1; + uint64_t serialize_support:1; + uint64_t tsc_deadline_tmr_support:1; + uint64_t tsc_adjust_support:1; + uint64_t fzl_rep_movsb:1; + uint64_t fs_rep_stosb:1; + uint64_t fs_rep_cmpsb:1; + uint64_t tsx_ld_trk_support:1; + uint64_t vmx_ins_outs_exit_info_support:1; + uint64_t hlat_support:1; + uint64_t sbdr_ssdp_no_support:1; + uint64_t fbsdp_no_support:1; + uint64_t psdp_no_support:1; + uint64_t fb_clear_support:1; + uint64_t btc_no_support:1; + uint64_t ibpb_rsb_flush_support:1; + uint64_t stibp_always_on_support:1; + uint64_t perf_global_ctrl_support:1; + uint64_t npt_execute_only_support:1; + uint64_t npt_ad_flags_support:1; + uint64_t npt1_gb_page_support:1; + uint64_t amd_processor_topology_node_id_support:1; + uint64_t local_machine_check_support:1; + uint64_t extended_topology_leaf_fp256_amd_support:1; + uint64_t gds_no_support:1; + uint64_t cmpccxadd_support:1; + uint64_t tsc_aux_virtualization_support:1; + uint64_t rmp_query_support:1; + uint64_t bhi_no_support:1; + uint64_t bhi_dis_support:1; + uint64_t prefetch_i_support:1; + uint64_t sha512_support:1; + uint64_t mitigation_ctrl_support:1; + uint64_t rfds_no_support:1; + uint64_t rfds_clear_support:1; + uint64_t sm3_support:1; + uint64_t sm4_support:1; + uint64_t secure_avic_support:1; + uint64_t guest_intercept_ctrl_support:1; + uint64_t sbpb_supported:1; + uint64_t ibpb_br_type_supported:1; + uint64_t srso_no_supported:1; + uint64_t srso_user_kernel_no_supported:1; + uint64_t vrew_clear_supported:1; + uint64_t tsa_l1_no_supported:1; + uint64_t tsa_sq_no_supported:1; + uint64_t lass_support:1; + uint64_t idle_hlt_intercept_support:1; + uint64_t msr_list_support:1; + } QEMU_PACKED; +}; + #endif /* HW_HYPERV_HVHDK_H */ diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index f86c7a3be6..2b6d7b2f35 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -15,6 +15,7 @@ #define QEMU_MSHV_INT_H =20 #define MSHV_MSR_ENTRIES_COUNT 64 +#include "hw/hyperv/hvhdk.h" =20 struct mshv_get_set_vp_state; =20 @@ -55,6 +56,7 @@ struct MshvState { int nr_allocated_irq_routes; unsigned long *used_gsi_bitmap; unsigned int gsi_count; + union hv_partition_processor_features processor_features; }; =20 typedef struct MshvMsiControl { --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274558; cv=none; d=zohomail.com; s=zohoarc; b=YOG5LwYalWIq8DFaMXqhyVpRFDGzWANu6/SUhPeemtk4lFWAsNlQXnNSGK3fKA5rK3Wouwq6vvQcZ7H5LIGb9MyE/M59wIWOpCXy1QSX59hOdp94vpmZsaz21fSq5ndSZ5WJNFqQPNxZhEKwxbi/wNa6p4ipZ+8Y2pXBIaafj+I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274558; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ASHwIUqJhX6VXNhjtPjQt2QC4yNFkvq7Vac2whkLBwE=; b=KVAzMOyAMrMfaeVSxkDHTS/7QNXROX+j+NwvPnzxqK2QNqnyV4EmVP3cjYCIhtVeW86YGnz3Bx61TcrJMWBUEAVk1Anj/HhXRqsd/8pfIMxN+wi2kB80DQnm2vXIV3DId3aAJ00YYJf1v8jHScQp+i6AuWpTANWc5dlHIaRDgY8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274558614528.3591066330786; Mon, 23 Mar 2026 07:02:38 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fqs-0001aL-1L; Mon, 23 Mar 2026 10:02:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fog-0000Sx-Op for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:42 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fod-0006xu-RP for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:38 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 4AD4820B6F1F; Mon, 23 Mar 2026 06:59:22 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 4AD4820B6F1F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274365; bh=ASHwIUqJhX6VXNhjtPjQt2QC4yNFkvq7Vac2whkLBwE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AEtv4OcTVKomZFVNK/kGBko1z4d0IDgkNtbtPVl/n7a9C/U4RgbmeMHzA3L53fdpy n+T0JSs5ZkVnVDg3u0KUJDwGSPdjtQmD6HS0CIXxU5EgywxL8v2H5RAWwYdtwz+hG/ layGbJuszzJhBQ9zC2SFfpMvc5bxICZWPAQzBwMY= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 18/32] target/i386/mshv: expose msvh_get_generic_regs Date: Mon, 23 Mar 2026 14:57:58 +0100 Message-Id: <20260323135812.383509-19-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274559856154100 Content-Type: text/plain; charset="utf-8" We expose the fn, so we can call them from the other source files (msr.c). Signed-off-by: Magnus Kulke --- include/system/mshv_int.h | 2 ++ target/i386/mshv/mshv-cpu.c | 15 ++++++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 2b6d7b2f35..2c5d16bf9a 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -81,6 +81,8 @@ int mshv_configure_vcpu(const CPUState *cpu); int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *e= xit); int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *as= socs, size_t n_regs); +int mshv_get_generic_regs(CPUState *cpu, hv_register_assoc *assocs, + size_t n_regs); int mshv_arch_store_vcpu_state(const CPUState *cpu); int mshv_arch_load_vcpu_state(CPUState *cpu); void mshv_arch_init_vcpu(CPUState *cpu); diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 906f5b0c3d..ecb4711b95 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -108,9 +108,6 @@ static enum hv_register_name FPU_REGISTER_NAMES[26] =3D= { }; =20 static int set_special_regs(const CPUState *cpu); -static int get_generic_regs(CPUState *cpu, - struct hv_register_assoc *assocs, - size_t n_regs); =20 static int get_lapic(CPUState *cpu) { @@ -187,7 +184,7 @@ static int get_fpu(CPUState *cpu) for (size_t i =3D 0; i < n_regs; i++) { assocs[i].name =3D FPU_REGISTER_NAMES[i]; } - ret =3D get_generic_regs(cpu, assocs, n_regs); + ret =3D mshv_get_generic_regs(cpu, assocs, n_regs); if (ret < 0) { error_report("failed to get special registers"); return -errno; @@ -207,7 +204,7 @@ static int get_xc_reg(CPUState *cpu) =20 assocs[0].name =3D HV_X64_REGISTER_XFEM; =20 - ret =3D get_generic_regs(cpu, assocs, 1); + ret =3D mshv_get_generic_regs(cpu, assocs, 1); if (ret < 0) { error_report("failed to get xcr0"); return -1; @@ -300,8 +297,8 @@ int mshv_set_generic_regs(const CPUState *cpu, const hv= _register_assoc *assocs, return 0; } =20 -static int get_generic_regs(CPUState *cpu, hv_register_assoc *assocs, - size_t n_regs) +int mshv_get_generic_regs(CPUState *cpu, hv_register_assoc *assocs, + size_t n_regs) { int cpu_fd =3D mshv_vcpufd(cpu); int vp_index =3D cpu->cpu_index; @@ -450,7 +447,7 @@ static int get_standard_regs(CPUState *cpu) for (size_t i =3D 0; i < n_regs; i++) { assocs[i].name =3D STANDARD_REGISTER_NAMES[i]; } - ret =3D get_generic_regs(cpu, assocs, n_regs); + ret =3D mshv_get_generic_regs(cpu, assocs, n_regs); if (ret < 0) { error_report("failed to get standard registers"); return -1; @@ -527,7 +524,7 @@ static int get_special_regs(CPUState *cpu) for (size_t i =3D 0; i < n_regs; i++) { assocs[i].name =3D SPECIAL_REGISTER_NAMES[i]; } - ret =3D get_generic_regs(cpu, assocs, n_regs); + ret =3D mshv_get_generic_regs(cpu, assocs, n_regs); if (ret < 0) { error_report("failed to get special registers"); return -errno; --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274750; cv=none; d=zohomail.com; s=zohoarc; b=Rh6kZpKcrAgD1ksme6I1DmHOOJJxLYLsLaXN+tBOSoveIePaRJ/ppMcSZqLeBDR8/fDKVkNVCh08KsdQdgyOeC9gKG/rU4rxAyES/fvxzFn4z5fKV9oswSqnF7/oNXE2165+8j7PN8x3NoqW9IT7iGSqxofsnoNFcXvBO/NLlEk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274750; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=bqX1LydjjPPSm4vkKSG85SPs6GNqTLaHe3QD+pYtxEM=; b=J9aZQO4UiVErTxgcTQp2h8edC9AaomyCvTGBklCcVcQrNo566zW2zsrrv0VrY8Trn7SDlT05bZA1FWnG929WSD31uNHzZbWjbo6gCtUb1AtbaMqxr0t0eaALaAJM2ktBDqxjOSXGXbae2caKOIDPHsRsUDClwCrmcJCGT40MDbs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274750720749.0005686364694; Mon, 23 Mar 2026 07:05:50 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4frY-000257-DW; Mon, 23 Mar 2026 10:02:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4foo-0000WN-6J for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:49 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foi-0006yl-QI for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:44 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id D42B020B6F15; Mon, 23 Mar 2026 06:59:25 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D42B020B6F15 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274369; bh=bqX1LydjjPPSm4vkKSG85SPs6GNqTLaHe3QD+pYtxEM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=puH5ODnmgAuUdppLRIXyKpxP0HYMgSkz+Y7oAsxBX7avzDaND9N0DF7mjoA2LFm5n rOHnJP8Q18PSsmOLx7VMC4zWeOFcNAn+Po7pF91stUKKm6V//Rwg4YOi3KsaZq/3OS pVGPFWLBgUVzol+p41fFeOP40s6R2MV5JEFmgOKk= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 19/32] target/i386/mshv: migrate MSRs Date: Mon, 23 Mar 2026 14:57:59 +0100 Message-Id: <20260323135812.383509-20-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274752635154100 Content-Type: text/plain; charset="utf-8" In this change the we rewrite the existing MSR logic to make MSRs migratable: - we map them on existing QEMU fields in the CPU. A table and a macro MSHV_ENV_FIELD is used to associate a HV register name to the their msr index and their offset in the cpu state struct. The list is not exhaustive and will be extended in follow-up commits. - mshv_set/get_msrs() fns are called in the arch_load/store_vcpu_state() fns. they use use generic registers ioctl's and map the input/output via load/store_to/from_env() from/to the hv register content to the cpu state representation. - init_msrs() has been moved from mshv-vcpu to the msr source file - we need to perform some filtering of MSR because before writing and reading, because the hvcalls will fail if the partition doesn't support a given MSRs. - Some MSRs are partition-wide and so we will only write the to on the BSP. Signed-off-by: Magnus Kulke --- include/hw/hyperv/hvgdk_mini.h | 16 + include/system/mshv_int.h | 17 +- target/i386/mshv/mshv-cpu.c | 40 +-- target/i386/mshv/msr.c | 549 +++++++++++++-------------------- 4 files changed, 254 insertions(+), 368 deletions(-) diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h index cb52cc9de2..a47bc6212e 100644 --- a/include/hw/hyperv/hvgdk_mini.h +++ b/include/hw/hyperv/hvgdk_mini.h @@ -9,6 +9,19 @@ =20 #define MSHV_IOCTL 0xB8 =20 +/* Hyper-V specific model specific registers (MSRs) */ + +/* HV_X64_SYNTHETIC_MSR */ +#define HV_X64_MSR_GUEST_OS_ID 0x40000000 +#define HV_X64_MSR_HYPERCALL 0x40000001 +#define HV_X64_MSR_VP_INDEX 0x40000002 +#define HV_X64_MSR_RESET 0x40000003 +#define HV_X64_MSR_VP_RUNTIME 0x40000010 +#define HV_X64_MSR_TIME_REF_COUNT 0x40000020 +#define HV_X64_MSR_REFERENCE_TSC 0x40000021 +#define HV_X64_MSR_TSC_FREQUENCY 0x40000022 +#define HV_X64_MSR_APIC_FREQUENCY 0x40000023 + typedef enum hv_register_name { /* Pending Interruption Register */ HV_REGISTER_PENDING_INTERRUPTION =3D 0x00010002, @@ -152,12 +165,14 @@ typedef enum hv_register_name { /* Available */ =20 HV_X64_REGISTER_SPEC_CTRL =3D 0x00080084, + HV_X64_REGISTER_TSC_DEADLINE =3D 0x00080095, HV_X64_REGISTER_TSC_ADJUST =3D 0x00080096, =20 /* Other MSRs */ HV_X64_REGISTER_MSR_IA32_MISC_ENABLE =3D 0x000800A0, =20 /* Misc */ + HV_X64_REGISTER_HYPERCALL =3D 0x00090001, HV_REGISTER_GUEST_OS_ID =3D 0x00090002, HV_REGISTER_REFERENCE_TSC =3D 0x00090017, =20 @@ -788,6 +803,7 @@ struct hv_cpuid { #define IA32_MSR_DEBUG_CTL 0x1D9 #define IA32_MSR_SPEC_CTRL 0x00000048 #define IA32_MSR_TSC_ADJUST 0x0000003b +#define IA32_MSR_TSC_DEADLINE 0x000006e0 =20 #define IA32_MSR_MISC_ENABLE 0x000001a0 =20 diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 2c5d16bf9a..29b363e73e 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -14,7 +14,6 @@ #ifndef QEMU_MSHV_INT_H #define QEMU_MSHV_INT_H =20 -#define MSHV_MSR_ENTRIES_COUNT 64 #include "hw/hyperv/hvhdk.h" =20 struct mshv_get_set_vp_state; @@ -116,18 +115,8 @@ void mshv_set_phys_mem(MshvMemoryListener *mml, Memory= RegionSection *section, bool add); =20 /* msr */ -typedef struct MshvMsrEntry { - uint32_t index; - uint32_t reserved; - uint64_t data; -} MshvMsrEntry; - -typedef struct MshvMsrEntries { - MshvMsrEntry entries[MSHV_MSR_ENTRIES_COUNT]; - uint32_t nmsrs; -} MshvMsrEntries; - -int mshv_configure_msr(const CPUState *cpu, const MshvMsrEntry *msrs, - size_t n_msrs); +int mshv_init_msrs(const CPUState *cpu); +int mshv_get_msrs(CPUState *cpu); +int mshv_set_msrs(const CPUState *cpu); =20 #endif diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index ecb4711b95..0d4721582a 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -580,6 +580,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D mshv_get_msrs(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 @@ -1051,6 +1056,12 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 + /* INVARIANT: LAPIC must be restored before MSRs (TSC_DEADLINE) */ + ret =3D mshv_set_msrs(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 @@ -1537,33 +1548,6 @@ void mshv_init_mmio_emu(void) init_emu(&mshv_x86_emul_ops); } =20 -static int init_msrs(const CPUState *cpu) -{ - int ret; - uint64_t d_t =3D MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB; - - const struct hv_register_assoc assocs[] =3D { - { .name =3D HV_X64_REGISTER_SYSENTER_CS, .value.reg64 =3D 0x= 0 }, - { .name =3D HV_X64_REGISTER_SYSENTER_ESP, .value.reg64 =3D 0x= 0 }, - { .name =3D HV_X64_REGISTER_SYSENTER_EIP, .value.reg64 =3D 0x= 0 }, - { .name =3D HV_X64_REGISTER_STAR, .value.reg64 =3D 0x= 0 }, - { .name =3D HV_X64_REGISTER_CSTAR, .value.reg64 =3D 0x= 0 }, - { .name =3D HV_X64_REGISTER_LSTAR, .value.reg64 =3D 0x= 0 }, - { .name =3D HV_X64_REGISTER_KERNEL_GS_BASE, .value.reg64 =3D 0x= 0 }, - { .name =3D HV_X64_REGISTER_SFMASK, .value.reg64 =3D 0x= 0 }, - { .name =3D HV_X64_REGISTER_MSR_MTRR_DEF_TYPE, .value.reg64 =3D d_= t }, - }; - QEMU_BUILD_BUG_ON(ARRAY_SIZE(assocs) > MSHV_MSR_ENTRIES_COUNT); - - ret =3D mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs)); - if (ret < 0) { - error_report("failed to put msrs"); - return -1; - } - - return 0; -} - void mshv_arch_init_vcpu(CPUState *cpu) { X86CPU *x86_cpu =3D X86_CPU(cpu); @@ -1593,7 +1577,7 @@ void mshv_arch_init_vcpu(CPUState *cpu) ret =3D init_cpuid2(cpu); assert(ret =3D=3D 0); =20 - ret =3D init_msrs(cpu); + ret =3D mshv_init_msrs(cpu); assert(ret =3D=3D 0); =20 ret =3D init_lint(cpu); diff --git a/target/i386/mshv/msr.c b/target/i386/mshv/msr.c index e6e5baef50..6e53874787 100644 --- a/target/i386/mshv/msr.c +++ b/target/i386/mshv/msr.c @@ -14,362 +14,259 @@ #include "hw/hyperv/hvgdk_mini.h" #include "linux/mshv.h" #include "qemu/error-report.h" +#include "cpu.h" =20 -static uint32_t supported_msrs[64] =3D { - IA32_MSR_TSC, - IA32_MSR_EFER, - IA32_MSR_KERNEL_GS_BASE, - IA32_MSR_APIC_BASE, - IA32_MSR_PAT, - IA32_MSR_SYSENTER_CS, - IA32_MSR_SYSENTER_ESP, - IA32_MSR_SYSENTER_EIP, - IA32_MSR_STAR, - IA32_MSR_LSTAR, - IA32_MSR_CSTAR, - IA32_MSR_SFMASK, - IA32_MSR_MTRR_DEF_TYPE, - IA32_MSR_MTRR_PHYSBASE0, - IA32_MSR_MTRR_PHYSMASK0, - IA32_MSR_MTRR_PHYSBASE1, - IA32_MSR_MTRR_PHYSMASK1, - IA32_MSR_MTRR_PHYSBASE2, - IA32_MSR_MTRR_PHYSMASK2, - IA32_MSR_MTRR_PHYSBASE3, - IA32_MSR_MTRR_PHYSMASK3, - IA32_MSR_MTRR_PHYSBASE4, - IA32_MSR_MTRR_PHYSMASK4, - IA32_MSR_MTRR_PHYSBASE5, - IA32_MSR_MTRR_PHYSMASK5, - IA32_MSR_MTRR_PHYSBASE6, - IA32_MSR_MTRR_PHYSMASK6, - IA32_MSR_MTRR_PHYSBASE7, - IA32_MSR_MTRR_PHYSMASK7, - IA32_MSR_MTRR_FIX64K_00000, - IA32_MSR_MTRR_FIX16K_80000, - IA32_MSR_MTRR_FIX16K_A0000, - IA32_MSR_MTRR_FIX4K_C0000, - IA32_MSR_MTRR_FIX4K_C8000, - IA32_MSR_MTRR_FIX4K_D0000, - IA32_MSR_MTRR_FIX4K_D8000, - IA32_MSR_MTRR_FIX4K_E0000, - IA32_MSR_MTRR_FIX4K_E8000, - IA32_MSR_MTRR_FIX4K_F0000, - IA32_MSR_MTRR_FIX4K_F8000, - IA32_MSR_TSC_AUX, - IA32_MSR_DEBUG_CTL, - HV_X64_MSR_GUEST_OS_ID, - HV_X64_MSR_SINT0, - HV_X64_MSR_SINT1, - HV_X64_MSR_SINT2, - HV_X64_MSR_SINT3, - HV_X64_MSR_SINT4, - HV_X64_MSR_SINT5, - HV_X64_MSR_SINT6, - HV_X64_MSR_SINT7, - HV_X64_MSR_SINT8, - HV_X64_MSR_SINT9, - HV_X64_MSR_SINT10, - HV_X64_MSR_SINT11, - HV_X64_MSR_SINT12, - HV_X64_MSR_SINT13, - HV_X64_MSR_SINT14, - HV_X64_MSR_SINT15, - HV_X64_MSR_SCONTROL, - HV_X64_MSR_SIEFP, - HV_X64_MSR_SIMP, - HV_X64_MSR_REFERENCE_TSC, - HV_X64_MSR_EOM, +#define MSHV_ENV_FIELD(env, offset) (*(uint64_t *)((char *)(env) + (offset= ))) + +typedef struct MshvMsrEnvMap { + uint32_t msr_index; + uint32_t hv_name; + ptrdiff_t env_offset; +} MshvMsrEnvMap; + +/* Those MSRs have a direct mapping to fields in CPUX86State */ +static const MshvMsrEnvMap msr_env_map[] =3D { + /* Architectural */ + { IA32_MSR_EFER, HV_X64_REGISTER_EFER, offsetof(CPUX86State, efer) }, + { IA32_MSR_PAT, HV_X64_REGISTER_PAT, offsetof(CPUX86State, pat) }, + + /* Syscall */ + { IA32_MSR_SYSENTER_CS, HV_X64_REGISTER_SYSENTER_CS, + offsetof(CPUX86State, sysenter_cs) }, + { IA32_MSR_SYSENTER_ESP, HV_X64_REGISTER_SYSENTER_ESP, + offsetof(CPUX86State, sysenter_esp) }, + { IA32_MSR_SYSENTER_EIP, HV_X64_REGISTER_SYSENTER_EIP, + offsetof(CPUX86State, sysenter_eip) }, + { IA32_MSR_STAR, HV_X64_REGISTER_STAR, + offsetof(CPUX86State, star) }, + { IA32_MSR_LSTAR, HV_X64_REGISTER_LSTAR, + offsetof(CPUX86State, lstar) }, + { IA32_MSR_CSTAR, HV_X64_REGISTER_CSTAR, + offsetof(CPUX86State, cstar) }, + { IA32_MSR_SFMASK, HV_X64_REGISTER_SFMASK, + offsetof(CPUX86State, fmask) }, + { IA32_MSR_KERNEL_GS_BASE, HV_X64_REGISTER_KERNEL_GS_BASE, + offsetof(CPUX86State, kernelgsbase) }, + + /* TSC-related */ + { IA32_MSR_TSC, HV_X64_REGISTER_TSC, + offsetof(CPUX86State, tsc) }, + { IA32_MSR_TSC_AUX, HV_X64_REGISTER_TSC_AUX, + offsetof(CPUX86State, tsc_aux) }, + { IA32_MSR_TSC_ADJUST, HV_X64_REGISTER_TSC_ADJUST, + offsetof(CPUX86State, tsc_adjust) }, + { IA32_MSR_TSC_DEADLINE, HV_X64_REGISTER_TSC_DEADLINE, + offsetof(CPUX86State, tsc_deadline) }, + + /* Hyper-V per-partition MSRs */ + { HV_X64_MSR_HYPERCALL, HV_X64_REGISTER_HYPERCALL, + offsetof(CPUX86State, msr_hv_hypercall) }, + { HV_X64_MSR_GUEST_OS_ID, HV_REGISTER_GUEST_OS_ID, + offsetof(CPUX86State, msr_hv_guest_os_id) = }, + { HV_X64_MSR_REFERENCE_TSC, HV_REGISTER_REFERENCE_TSC, + offsetof(CPUX86State, msr_hv_tsc) }, + + /* Hyper-V MSRs (non-SINT) */ + { HV_X64_MSR_SCONTROL, HV_REGISTER_SCONTROL, + offsetof(CPUX86State, msr_hv_synic_control) }, + { HV_X64_MSR_SIEFP, HV_REGISTER_SIEFP, + offsetof(CPUX86State, msr_hv_synic_evt_page) }, + { HV_X64_MSR_SIMP, HV_REGISTER_SIMP, + offsetof(CPUX86State, msr_hv_synic_msg_page) }, + + /* Other */ + + /* TODO: find out processor features that correlate to unsupported MSR= s. */ + /* { IA32_MSR_MISC_ENABLE, HV_X64_REGISTER_MSR_IA32_MISC_ENABLE, */ + /* offsetof(CPUX86State, msr_ia32_misc_enable)= }, */ + /* { IA32_MSR_BNDCFGS, HV_X64_REGISTER_BNDCFGS, */ + /* offsetof(CPUX86State, msr_bndcfgs) }, */ + { IA32_MSR_SPEC_CTRL, HV_X64_REGISTER_SPEC_CTRL, + offsetof(CPUX86State, spec_ctrl) }, }; -static const size_t msr_count =3D ARRAY_SIZE(supported_msrs); =20 -static int compare_msr_index(const void *a, const void *b) +int mshv_init_msrs(const CPUState *cpu) { - return *(uint32_t *)a - *(uint32_t *)b; + int ret; + uint64_t d_t =3D MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB; + + const struct hv_register_assoc assocs[] =3D { + { .name =3D HV_X64_REGISTER_SYSENTER_CS, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_SYSENTER_ESP, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_SYSENTER_EIP, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_STAR, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_CSTAR, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_LSTAR, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_KERNEL_GS_BASE, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_SFMASK, .value.reg64 =3D 0x= 0 }, + { .name =3D HV_X64_REGISTER_MSR_MTRR_DEF_TYPE, .value.reg64 =3D d_= t }, + }; + + ret =3D mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs)); + if (ret < 0) { + error_report("failed to put msrs"); + return -1; + } + + return 0; } =20 -__attribute__((constructor)) -static void init_sorted_msr_map(void) + +/* + * INVARIANT: this fn expects assocs in the same order as they appear in + * msr_env_map. + */ +static void store_in_env(CPUState *cpu, const struct hv_register_assoc *as= socs, + size_t n_assocs) { - qsort(supported_msrs, msr_count, sizeof(uint32_t), compare_msr_index); + X86CPU *x86_cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86_cpu->env; + size_t i, j; + const MshvMsrEnvMap *mapping; + union hv_register_value hv_value; + ptrdiff_t offset; + uint32_t hv_name; + + assert(n_assocs <=3D (ARRAY_SIZE(msr_env_map))); + + for (i =3D 0, j =3D 0; i < ARRAY_SIZE(msr_env_map); i++) { + hv_name =3D assocs[j].name; + mapping =3D &msr_env_map[i]; + if (hv_name !=3D mapping->hv_name) { + continue; + } + + hv_value =3D assocs[j].value; + offset =3D mapping->env_offset; + MSHV_ENV_FIELD(env, offset) =3D hv_value.reg64; + j++; + } } =20 -static int mshv_is_supported_msr(uint32_t msr) +static void set_hv_name_in_assocs(struct hv_register_assoc *assocs, + size_t n_assocs) { - return bsearch(&msr, supported_msrs, msr_count, sizeof(uint32_t), - compare_msr_index) !=3D NULL; + size_t i; + + assert(n_assocs =3D=3D ARRAY_SIZE(msr_env_map)); + for (i =3D 0; i < ARRAY_SIZE(msr_env_map); i++) { + assocs[i].name =3D msr_env_map[i].hv_name; + } } =20 -static int mshv_msr_to_hv_reg_name(uint32_t msr, uint32_t *hv_reg) +static bool msr_supported(uint32_t name) { - switch (msr) { - case IA32_MSR_TSC: - *hv_reg =3D HV_X64_REGISTER_TSC; - return 0; - case IA32_MSR_EFER: - *hv_reg =3D HV_X64_REGISTER_EFER; - return 0; - case IA32_MSR_KERNEL_GS_BASE: - *hv_reg =3D HV_X64_REGISTER_KERNEL_GS_BASE; - return 0; - case IA32_MSR_APIC_BASE: - *hv_reg =3D HV_X64_REGISTER_APIC_BASE; - return 0; - case IA32_MSR_PAT: - *hv_reg =3D HV_X64_REGISTER_PAT; - return 0; - case IA32_MSR_SYSENTER_CS: - *hv_reg =3D HV_X64_REGISTER_SYSENTER_CS; - return 0; - case IA32_MSR_SYSENTER_ESP: - *hv_reg =3D HV_X64_REGISTER_SYSENTER_ESP; - return 0; - case IA32_MSR_SYSENTER_EIP: - *hv_reg =3D HV_X64_REGISTER_SYSENTER_EIP; - return 0; - case IA32_MSR_STAR: - *hv_reg =3D HV_X64_REGISTER_STAR; - return 0; - case IA32_MSR_LSTAR: - *hv_reg =3D HV_X64_REGISTER_LSTAR; - return 0; - case IA32_MSR_CSTAR: - *hv_reg =3D HV_X64_REGISTER_CSTAR; - return 0; - case IA32_MSR_SFMASK: - *hv_reg =3D HV_X64_REGISTER_SFMASK; - return 0; - case IA32_MSR_MTRR_CAP: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_CAP; - return 0; - case IA32_MSR_MTRR_DEF_TYPE: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_DEF_TYPE; - return 0; - case IA32_MSR_MTRR_PHYSBASE0: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0; - return 0; - case IA32_MSR_MTRR_PHYSMASK0: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0; - return 0; - case IA32_MSR_MTRR_PHYSBASE1: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE1; - return 0; - case IA32_MSR_MTRR_PHYSMASK1: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK1; - return 0; - case IA32_MSR_MTRR_PHYSBASE2: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE2; - return 0; - case IA32_MSR_MTRR_PHYSMASK2: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK2; - return 0; - case IA32_MSR_MTRR_PHYSBASE3: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE3; - return 0; - case IA32_MSR_MTRR_PHYSMASK3: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK3; - return 0; - case IA32_MSR_MTRR_PHYSBASE4: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE4; - return 0; - case IA32_MSR_MTRR_PHYSMASK4: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK4; - return 0; - case IA32_MSR_MTRR_PHYSBASE5: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE5; - return 0; - case IA32_MSR_MTRR_PHYSMASK5: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK5; - return 0; - case IA32_MSR_MTRR_PHYSBASE6: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE6; - return 0; - case IA32_MSR_MTRR_PHYSMASK6: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK6; - return 0; - case IA32_MSR_MTRR_PHYSBASE7: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE7; - return 0; - case IA32_MSR_MTRR_PHYSMASK7: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK7; - return 0; - case IA32_MSR_MTRR_FIX64K_00000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX64K00000; - return 0; - case IA32_MSR_MTRR_FIX16K_80000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX16K80000; - return 0; - case IA32_MSR_MTRR_FIX16K_A0000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX16KA0000; - return 0; - case IA32_MSR_MTRR_FIX4K_C0000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX4KC0000; - return 0; - case IA32_MSR_MTRR_FIX4K_C8000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX4KC8000; - return 0; - case IA32_MSR_MTRR_FIX4K_D0000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX4KD0000; - return 0; - case IA32_MSR_MTRR_FIX4K_D8000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX4KD8000; - return 0; - case IA32_MSR_MTRR_FIX4K_E0000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX4KE0000; - return 0; - case IA32_MSR_MTRR_FIX4K_E8000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX4KE8000; - return 0; - case IA32_MSR_MTRR_FIX4K_F0000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX4KF0000; - return 0; - case IA32_MSR_MTRR_FIX4K_F8000: - *hv_reg =3D HV_X64_REGISTER_MSR_MTRR_FIX4KF8000; - return 0; - case IA32_MSR_TSC_AUX: - *hv_reg =3D HV_X64_REGISTER_TSC_AUX; - return 0; - case IA32_MSR_BNDCFGS: - *hv_reg =3D HV_X64_REGISTER_BNDCFGS; - return 0; - case IA32_MSR_DEBUG_CTL: - *hv_reg =3D HV_X64_REGISTER_DEBUG_CTL; - return 0; - case IA32_MSR_TSC_ADJUST: - *hv_reg =3D HV_X64_REGISTER_TSC_ADJUST; - return 0; - case IA32_MSR_SPEC_CTRL: - *hv_reg =3D HV_X64_REGISTER_SPEC_CTRL; - return 0; - case HV_X64_MSR_GUEST_OS_ID: - *hv_reg =3D HV_REGISTER_GUEST_OS_ID; - return 0; - case HV_X64_MSR_SINT0: - *hv_reg =3D HV_REGISTER_SINT0; - return 0; - case HV_X64_MSR_SINT1: - *hv_reg =3D HV_REGISTER_SINT1; - return 0; - case HV_X64_MSR_SINT2: - *hv_reg =3D HV_REGISTER_SINT2; - return 0; - case HV_X64_MSR_SINT3: - *hv_reg =3D HV_REGISTER_SINT3; - return 0; - case HV_X64_MSR_SINT4: - *hv_reg =3D HV_REGISTER_SINT4; - return 0; - case HV_X64_MSR_SINT5: - *hv_reg =3D HV_REGISTER_SINT5; - return 0; - case HV_X64_MSR_SINT6: - *hv_reg =3D HV_REGISTER_SINT6; - return 0; - case HV_X64_MSR_SINT7: - *hv_reg =3D HV_REGISTER_SINT7; - return 0; - case HV_X64_MSR_SINT8: - *hv_reg =3D HV_REGISTER_SINT8; - return 0; - case HV_X64_MSR_SINT9: - *hv_reg =3D HV_REGISTER_SINT9; - return 0; - case HV_X64_MSR_SINT10: - *hv_reg =3D HV_REGISTER_SINT10; - return 0; - case HV_X64_MSR_SINT11: - *hv_reg =3D HV_REGISTER_SINT11; - return 0; - case HV_X64_MSR_SINT12: - *hv_reg =3D HV_REGISTER_SINT12; - return 0; - case HV_X64_MSR_SINT13: - *hv_reg =3D HV_REGISTER_SINT13; - return 0; - case HV_X64_MSR_SINT14: - *hv_reg =3D HV_REGISTER_SINT14; - return 0; - case HV_X64_MSR_SINT15: - *hv_reg =3D HV_REGISTER_SINT15; - return 0; - case IA32_MSR_MISC_ENABLE: - *hv_reg =3D HV_X64_REGISTER_MSR_IA32_MISC_ENABLE; - return 0; - case HV_X64_MSR_SCONTROL: - *hv_reg =3D HV_REGISTER_SCONTROL; - return 0; - case HV_X64_MSR_SIEFP: - *hv_reg =3D HV_REGISTER_SIEFP; - return 0; - case HV_X64_MSR_SIMP: - *hv_reg =3D HV_REGISTER_SIMP; - return 0; - case HV_X64_MSR_REFERENCE_TSC: - *hv_reg =3D HV_REGISTER_REFERENCE_TSC; - return 0; - case HV_X64_MSR_EOM: - *hv_reg =3D HV_REGISTER_EOM; - return 0; - default: - error_report("failed to map MSR %u to HV register name", msr); - return -1; + /* + * This check is not done comprehensively, it's meant to avoid hvcall + * failures for certain MSRs on architectures that don't support them. + */ + + switch (name) { + case HV_X64_REGISTER_SPEC_CTRL: + return mshv_state->processor_features.ibrs_support; + case HV_X64_REGISTER_TSC_ADJUST: + return mshv_state->processor_features.tsc_adjust_support; + case HV_X64_REGISTER_TSC_DEADLINE: + return mshv_state->processor_features.tsc_deadline_tmr_support; } + + return true; } =20 -static int set_msrs(const CPUState *cpu, GList *msrs) +int mshv_get_msrs(CPUState *cpu) { - size_t n_msrs; - GList *entries; - MshvMsrEntry *entry; - enum hv_register_name name; - struct hv_register_assoc *assoc; - int ret; - size_t i =3D 0; - - n_msrs =3D g_list_length(msrs); - hv_register_assoc *assocs =3D g_new0(hv_register_assoc, n_msrs); - - entries =3D msrs; - for (const GList *elem =3D entries; elem !=3D NULL; elem =3D elem->nex= t) { - entry =3D elem->data; - ret =3D mshv_msr_to_hv_reg_name(entry->index, &name); - if (ret < 0) { - g_free(assocs); - return ret; + int ret =3D 0; + size_t n_assocs =3D ARRAY_SIZE(msr_env_map); + struct hv_register_assoc assocs[ARRAY_SIZE(msr_env_map)]; + size_t i, j; + uint32_t name; + + set_hv_name_in_assocs(assocs, n_assocs); + + /* Filter out MSRs that cannot be read */ + for (i =3D 0, j =3D 0; i < n_assocs; i++) { + name =3D assocs[i].name; + + if (!msr_supported(name)) { + continue; + } + + if (j !=3D i) { + assocs[j] =3D assocs[i]; } - assoc =3D &assocs[i]; - assoc->name =3D name; - /* the union has been initialized to 0 */ - assoc->value.reg64 =3D entry->data; - i++; + j++; } - ret =3D mshv_set_generic_regs(cpu, assocs, n_msrs); - g_free(assocs); + n_assocs =3D j; + + ret =3D mshv_get_generic_regs(cpu, assocs, n_assocs); if (ret < 0) { - error_report("failed to set msrs"); - return -1; + error_report("Failed to get MSRs"); + return -errno; } + + store_in_env(cpu, assocs, n_assocs); + return 0; } =20 +static void load_from_env(const CPUState *cpu, struct hv_register_assoc *a= ssocs, + size_t n_assocs) +{ + size_t i; + const MshvMsrEnvMap *mapping; + X86CPU *x86_cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86_cpu->env; + ptrdiff_t offset; + union hv_register_value *hv_value; + + assert(n_assocs =3D=3D ARRAY_SIZE(msr_env_map)); =20 -int mshv_configure_msr(const CPUState *cpu, const MshvMsrEntry *msrs, - size_t n_msrs) + for (i =3D 0; i < ARRAY_SIZE(msr_env_map); i++) { + mapping =3D &msr_env_map[i]; + offset =3D mapping->env_offset; + assocs[i].name =3D mapping->hv_name; + hv_value =3D &assocs[i].value; + hv_value->reg64 =3D MSHV_ENV_FIELD(env, offset); + } +} + +int mshv_set_msrs(const CPUState *cpu) { - GList *valid_msrs =3D NULL; - uint32_t msr_index; + size_t n_assocs =3D ARRAY_SIZE(msr_env_map); + struct hv_register_assoc assocs[ARRAY_SIZE(msr_env_map)]; int ret; + size_t i, j; =20 - for (size_t i =3D 0; i < n_msrs; i++) { - msr_index =3D msrs[i].index; - /* check whether index of msrs is in SUPPORTED_MSRS */ - if (mshv_is_supported_msr(msr_index)) { - valid_msrs =3D g_list_append(valid_msrs, (void *) &msrs[i]); + load_from_env(cpu, assocs, n_assocs); + + /* Filter out MSRs that cannot be written */ + for (i =3D 0, j =3D 0; i < n_assocs; i++) { + uint32_t name =3D assocs[i].name; + + /* Partition-wide MSRs: only write on vCPU 0 */ + if (cpu->cpu_index !=3D 0 && + (name =3D=3D HV_X64_REGISTER_HYPERCALL || + name =3D=3D HV_REGISTER_GUEST_OS_ID || + name =3D=3D HV_REGISTER_REFERENCE_TSC)) { + continue; } + + if (!msr_supported(name)) { + continue; + } + + if (j !=3D i) { + assocs[j] =3D assocs[i]; + } + j++; } + n_assocs =3D j; =20 - ret =3D set_msrs(cpu, valid_msrs); - g_list_free(valid_msrs); + ret =3D mshv_set_generic_regs(cpu, assocs, n_assocs); + if (ret < 0) { + error_report("Failed to set MSRs"); + return -errno; + } =20 - return ret; + return 0; } --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274605; cv=none; d=zohomail.com; s=zohoarc; b=UTw8FtTuLb+fFyN14q+2JGK3/5WzWFt1SaoNZ03PSZe85ZGhRHo/eKrapgq8HTmyVca8V/v4YDBcyJxuKQrZ+UgHwkRwWFVLvf1g3zmnIhZWU3VvdkS4dbi/0O5D9BVe1h2laP6EVmPLwv61IjgAxPLdU4Zc7AIFTDp6trCHvaI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274605; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kNzA8nCp9csQuvyKSQjGHIiPTieqMCR2YGTGwsfe1DM=; b=PXr7bWHqgrNBngA6vGi9EQfbTFdY5wyndf0SE3i4fLIdQtmdWnhgMAz7hx1YzfAH7FuIA0HTVTqIdcoRdIbL7gYijFgeyhH7iHcUqOnLSl7mafpNGhuhk1D5RdoUtvQ3TlsdmKmhY6ZQQU4xn9RLsyFQydZ2ooABc6yau+cqqLM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274605328438.7251170156959; Mon, 23 Mar 2026 07:03:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4frb-0002Zo-NV; Mon, 23 Mar 2026 10:02:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4for-0000YQ-6J for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:52 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fop-0006zc-5v for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:48 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 6E01F20B6F20; Mon, 23 Mar 2026 06:59:30 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 6E01F20B6F20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274373; bh=kNzA8nCp9csQuvyKSQjGHIiPTieqMCR2YGTGwsfe1DM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z2x/rK1YVfd43elLLTjnYxDtiCBArIejTnoZ+7DgMuO1eQsCj9aW3kqk31goAXghj OS+QnP9pdprlU9bqLtMyvuy6rsmfFIb8jgQOZhpwdpeXiZZIHjk1Wd8Z/ob3VT81IM LPpcpAJ0/g719Qzm260FRSb8TerQrWfgkNClk+Lo= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 20/32] target/i386/mshv: migrate MTRR MSRs Date: Mon, 23 Mar 2026 14:58:00 +0100 Message-Id: <20260323135812.383509-21-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274606465158500 Content-Type: text/plain; charset="utf-8" This change roundtrips memory access/caching MSRs. The mapping scheme is a bit more elaborate on these, so we have added a special handling instead of individual entries in the MSR mapping table. Signed-off-by: Magnus Kulke --- target/i386/mshv/msr.c | 136 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 7 deletions(-) diff --git a/target/i386/mshv/msr.c b/target/i386/mshv/msr.c index 6e53874787..240ee84447 100644 --- a/target/i386/mshv/msr.c +++ b/target/i386/mshv/msr.c @@ -74,6 +74,10 @@ static const MshvMsrEnvMap msr_env_map[] =3D { { HV_X64_MSR_SIMP, HV_REGISTER_SIMP, offsetof(CPUX86State, msr_hv_synic_msg_page) }, =20 + /* MTRR default type */ + { IA32_MSR_MTRR_DEF_TYPE, HV_X64_REGISTER_MSR_MTRR_DEF_TYPE, + offsetof(CPUX86State, mtrr_deftype) }, + /* Other */ =20 /* TODO: find out processor features that correlate to unsupported MSR= s. */ @@ -85,6 +89,98 @@ static const MshvMsrEnvMap msr_env_map[] =3D { offsetof(CPUX86State, spec_ctrl) }, }; =20 +/* + * The assocs have to be set according to this schema: + * 8 entries for 0-7 mtrr_base + * 8 entries for mtrr_mask 0-7 + * 11 entries for 1 x 64k, 2 x 16k, 8 x 4k fixed MTRR + * 27 total entries + */ + +#define MSHV_MTRR_MSR_COUNT 27 +#define MSHV_MSR_TOTAL_COUNT (ARRAY_SIZE(msr_env_map) + MSHV_MTRR_MSR_COUN= T) + +static void store_in_env_mtrr_phys(CPUState *cpu, + const struct hv_register_assoc *assocs, + size_t n_assocs) +{ + X86CPU *x86_cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86_cpu->env; + size_t i, fixed_offset; + hv_register_name hv_name; + uint64_t base, mask; + + assert(n_assocs =3D=3D MSHV_MTRR_MSR_COUNT); + + for (i =3D 0; i < MSR_MTRRcap_VCNT; i++) { + hv_name =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0 + i; + assert(assocs[i].name =3D=3D hv_name); + hv_name =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0 + i; + assert(assocs[i + MSR_MTRRcap_VCNT].name =3D=3D hv_name); + + base =3D assocs[i].value.reg64; + mask =3D assocs[i + MSR_MTRRcap_VCNT].value.reg64; + env->mtrr_var[i].base =3D base; + env->mtrr_var[i].mask =3D mask; + } + + /* fixed 1x 64, 2x 16, 8x 4 kB */ + fixed_offset =3D MSR_MTRRcap_VCNT * 2; + for (i =3D 0; i < 11; i++) { + hv_name =3D HV_X64_REGISTER_MSR_MTRR_FIX64K00000 + i; + assert(assocs[fixed_offset + i].name =3D=3D hv_name); + env->mtrr_fixed[i] =3D assocs[fixed_offset + i].value.reg64; + } +} + +/* + * The assocs have to be set according to this schema: + * 8 entries for 0-7 mtrr_base + * 8 entries for mtrr_mask 0-7 + * 11 entries for 1 x 64k, 2 x 16k, 8 x 4k fixed MTRR + * 27 total entries + */ +static void load_from_env_mtrr_phys(const CPUState *cpu, + struct hv_register_assoc *assocs, + size_t n_assocs) +{ + X86CPU *x86_cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86_cpu->env; + size_t i, fixed_offset; + uint64_t base, mask, fixed_value; + hv_register_name base_name, mask_name, fixed_name; + hv_register_assoc *assoc; + + assert(n_assocs =3D=3D MSHV_MTRR_MSR_COUNT); + + for (i =3D 0; i < MSR_MTRRcap_VCNT; i++) { + base =3D env->mtrr_var[i].base; + mask =3D env->mtrr_var[i].mask; + + base_name =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0 + i; + mask_name =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0 + i; + + assoc =3D &assocs[i]; + assoc->name =3D base_name; + assoc->value.reg64 =3D base; + + assoc =3D &assocs[i + MSR_MTRRcap_VCNT]; + assoc->name =3D mask_name; + assoc->value.reg64 =3D mask; + } + + /* fixed 1x 64, 2x 16, 8x 4 kB */ + fixed_offset =3D MSR_MTRRcap_VCNT * 2; + for (i =3D 0; i < 11; i++) { + fixed_name =3D HV_X64_REGISTER_MSR_MTRR_FIX64K00000 + i; + fixed_value =3D env->mtrr_fixed[i]; + + assoc =3D &assocs[fixed_offset + i]; + assoc->name =3D fixed_name; + assoc->value.reg64 =3D fixed_value; + } +} + int mshv_init_msrs(const CPUState *cpu) { int ret; @@ -126,8 +222,9 @@ static void store_in_env(CPUState *cpu, const struct hv= _register_assoc *assocs, union hv_register_value hv_value; ptrdiff_t offset; uint32_t hv_name; + size_t mtrr_index; =20 - assert(n_assocs <=3D (ARRAY_SIZE(msr_env_map))); + assert(n_assocs <=3D MSHV_MSR_TOTAL_COUNT); =20 for (i =3D 0, j =3D 0; i < ARRAY_SIZE(msr_env_map); i++) { hv_name =3D assocs[j].name; @@ -141,17 +238,38 @@ static void store_in_env(CPUState *cpu, const struct = hv_register_assoc *assocs, MSHV_ENV_FIELD(env, offset) =3D hv_value.reg64; j++; } + + mtrr_index =3D j; + store_in_env_mtrr_phys(cpu, &assocs[mtrr_index], MSHV_MTRR_MSR_COUNT); } =20 static void set_hv_name_in_assocs(struct hv_register_assoc *assocs, size_t n_assocs) { size_t i; + size_t mtrr_offset, mtrr_fixed_offset; + hv_register_name hv_name; + + assert(n_assocs =3D=3D MSHV_MSR_TOTAL_COUNT); =20 - assert(n_assocs =3D=3D ARRAY_SIZE(msr_env_map)); for (i =3D 0; i < ARRAY_SIZE(msr_env_map); i++) { assocs[i].name =3D msr_env_map[i].hv_name; } + + mtrr_offset =3D ARRAY_SIZE(msr_env_map); + for (i =3D 0; i < MSR_MTRRcap_VCNT; i++) { + hv_name =3D HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0 + i; + assocs[mtrr_offset + i].name =3D hv_name; + hv_name =3D HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0 + i; + assocs[mtrr_offset + MSR_MTRRcap_VCNT + i].name =3D hv_name; + } + + /* fixed 1x 64, 2x 16, 8x 4 kB */ + mtrr_fixed_offset =3D mtrr_offset + MSR_MTRRcap_VCNT * 2; + for (i =3D 0; i < 11; i++) { + hv_name =3D HV_X64_REGISTER_MSR_MTRR_FIX64K00000 + i; + assocs[mtrr_fixed_offset + i].name =3D hv_name; + } } =20 static bool msr_supported(uint32_t name) @@ -176,8 +294,8 @@ static bool msr_supported(uint32_t name) int mshv_get_msrs(CPUState *cpu) { int ret =3D 0; - size_t n_assocs =3D ARRAY_SIZE(msr_env_map); - struct hv_register_assoc assocs[ARRAY_SIZE(msr_env_map)]; + size_t n_assocs =3D MSHV_MSR_TOTAL_COUNT; + struct hv_register_assoc assocs[MSHV_MSR_TOTAL_COUNT]; size_t i, j; uint32_t name; =20 @@ -218,8 +336,9 @@ static void load_from_env(const CPUState *cpu, struct h= v_register_assoc *assocs, CPUX86State *env =3D &x86_cpu->env; ptrdiff_t offset; union hv_register_value *hv_value; + size_t mtrr_offset; =20 - assert(n_assocs =3D=3D ARRAY_SIZE(msr_env_map)); + assert(n_assocs =3D=3D MSHV_MSR_TOTAL_COUNT); =20 for (i =3D 0; i < ARRAY_SIZE(msr_env_map); i++) { mapping =3D &msr_env_map[i]; @@ -228,12 +347,15 @@ static void load_from_env(const CPUState *cpu, struct= hv_register_assoc *assocs, hv_value =3D &assocs[i].value; hv_value->reg64 =3D MSHV_ENV_FIELD(env, offset); } + + mtrr_offset =3D ARRAY_SIZE(msr_env_map); + load_from_env_mtrr_phys(cpu, &assocs[mtrr_offset], MSHV_MTRR_MSR_COUNT= ); } =20 int mshv_set_msrs(const CPUState *cpu) { - size_t n_assocs =3D ARRAY_SIZE(msr_env_map); - struct hv_register_assoc assocs[ARRAY_SIZE(msr_env_map)]; + size_t n_assocs =3D MSHV_MSR_TOTAL_COUNT; + struct hv_register_assoc assocs[MSHV_MSR_TOTAL_COUNT]; int ret; size_t i, j; =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274476; cv=none; d=zohomail.com; s=zohoarc; b=aMGS79aXmV6Gsl701Flyhkw3rOiHATh9n+R1vJ9jKVa5Ab6Mi/aP4103T2UbHPW+qpg0Lxa8ihBj8o26sv9rlf04x+908YSoMHJ468mFLHEEYTanxOGVPUnapBQLHBGyx5j4wdRYwk3o2Zd4PYMtdtSJMuZc2SGowEr5l+lqZs0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274476; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=fHGJO6oByr4zwjSDzga9p2/aohq98U3wlbaQ5tyzs2c=; b=mpNSVOs/d6dS92G+8QmcHZzxips7pdfp4ta1BTMQ1M2k9yaxAOdcjZpnAEFOS5H54Cw3MEfcSuHtuf2jknoXrg3fqXstVRFLUH+AcBxZEww3xfrgH1UuDSPnTkjhqqSFOcVNpXDUizIqAleLdZ4F9IGrkxFA0GQulfrnM3O1tYo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274476736543.3708645901319; Mon, 23 Mar 2026 07:01:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpX-0000wQ-Rw; Mon, 23 Mar 2026 10:00:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4for-0000YR-6d for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:50 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fop-000703-NX for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:48 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 2761C20B6F1B; Mon, 23 Mar 2026 06:59:33 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 2761C20B6F1B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274377; bh=fHGJO6oByr4zwjSDzga9p2/aohq98U3wlbaQ5tyzs2c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NUiTn1GaPrme945lxn1FyhsjFrYg/soTLtR90JhKsM+++6ZFoBGYjCUvRM6PH80VN qVHJdTTt6rrtd0hRBgCxIikxepI9cLhDnwq+1cmfr3nbamuhQIL2Pwk4TOcApdm0NR FOSQsCfFD9fWaq43SliFJL1QW3ZlCN6vYns6fUwU= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 21/32] target/i386/mshv: migrate Synic SINT MSRs Date: Mon, 23 Mar 2026 14:58:01 +0100 Message-Id: <20260323135812.383509-22-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274479134154100 Content-Type: text/plain; charset="utf-8" Migrate HyperV SynIC SINT MSRs. We can only read/write those if SCONTROL is enabled in the guest, hence we have to split the SINT MSR out and make reading/writing them dependent on that MSR. Signed-off-by: Magnus Kulke --- target/i386/mshv/msr.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/target/i386/mshv/msr.c b/target/i386/mshv/msr.c index 240ee84447..d19b79d729 100644 --- a/target/i386/mshv/msr.c +++ b/target/i386/mshv/msr.c @@ -298,6 +298,8 @@ int mshv_get_msrs(CPUState *cpu) struct hv_register_assoc assocs[MSHV_MSR_TOTAL_COUNT]; size_t i, j; uint32_t name; + X86CPU *x86cpu =3D X86_CPU(cpu); + bool synic_enabled; =20 set_hv_name_in_assocs(assocs, n_assocs); =20 @@ -324,6 +326,27 @@ int mshv_get_msrs(CPUState *cpu) =20 store_in_env(cpu, assocs, n_assocs); =20 + /* Read SINT MSRs only if SynIC is enabled */ + synic_enabled =3D x86cpu->env.msr_hv_synic_control & 1; + if (synic_enabled) { + QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT); + + for (i =3D 0; i < HV_SINT_COUNT; i++) { + assocs[i].name =3D HV_REGISTER_SINT0 + i; + } + + ret =3D mshv_get_generic_regs(cpu, assocs, HV_SINT_COUNT); + if (ret < 0) { + error_report("Failed to get SynIC SINT MSRs"); + return -errno; + } + + for (i =3D 0; i < HV_SINT_COUNT; i++) { + uint64_t hv_sint_value =3D assocs[i].value.reg64; + x86cpu->env.msr_hv_synic_sint[i] =3D hv_sint_value; + } + } + return 0; } =20 @@ -358,6 +381,8 @@ int mshv_set_msrs(const CPUState *cpu) struct hv_register_assoc assocs[MSHV_MSR_TOTAL_COUNT]; int ret; size_t i, j; + X86CPU *x86cpu =3D X86_CPU(cpu); + bool synic_enabled =3D x86cpu->env.msr_hv_synic_control & 1; =20 load_from_env(cpu, assocs, n_assocs); =20 @@ -390,5 +415,21 @@ int mshv_set_msrs(const CPUState *cpu) return -errno; } =20 + /* SINT MSRs can only be written if SCONTROL has been set, so we split= */ + if (synic_enabled) { + QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT); + + for (i =3D 0; i < HV_SINT_COUNT; i++) { + assocs[i].name =3D HV_REGISTER_SINT0 + i; + assocs[i].value.reg64 =3D x86cpu->env.msr_hv_synic_sint[i]; + } + + ret =3D mshv_set_generic_regs(cpu, assocs, HV_SINT_COUNT); + if (ret < 0) { + error_report("Failed to set SynIC SINT MSRs"); + return -errno; + } + } + return 0; } --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274705; cv=none; d=zohomail.com; s=zohoarc; b=eP715R0OZ7/HCfresjvQzVzMyyJzWusYiyQkYhgaXZCrdzSPYPg3gHYbrfS+FDx4LRXmXNphiB38HIjhmh7AvXxHspxiHz9+AqzxMvKfiYEXk3mAGFx2kHMxD4CxRYutehEhMQkzLdc6HHxTr+7teQbf2PzAQNJusExVx44yS3A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274705; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zOiXzpk6ZsOGpRIWUT9SZ7VhQlMkNvXloKqOzNfhXPM=; b=T3KMURB74SPWFkAQA8jzB+IYYSWyO8hkkwG8hL9Ha86XUomLdE7nlLN/c+F1LFopc29BHLJvZF4h5C+xEIHMAcNCex2f+AJY5f8QHbyH14H/hp/hPW2m8Qb8TVe2D63qeCjIclqGOepjaIAZRRjPvOT6o6F982S9bUE83E4mLwM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274705638431.18675999013976; Mon, 23 Mar 2026 07:05:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4ft1-0005aF-5p; Mon, 23 Mar 2026 10:04:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fow-0000av-9n for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:56 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fou-000710-2V for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:54 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id A05FF20B6F0C; Mon, 23 Mar 2026 06:59:37 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com A05FF20B6F0C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274380; bh=zOiXzpk6ZsOGpRIWUT9SZ7VhQlMkNvXloKqOzNfhXPM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S4LoVi6GMIfd5aBKX4+RBdvHCOaVeQcDrmNttz1aoQUupOjidR1hg6/U7EOoJQ27h YpPAn+Oe0f27T0ScMVgxdD1Wn5eJVkYD7TkW4VGHJeEXqeXJ8ixyMD9GSuof/PtntZ Im5RqEcAWKCXw4qN0Ht4tJsKwKr8i5TwtIo9+D90= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 22/32] target/i386/mshv: migrate SIMP and SIEFP state Date: Mon, 23 Mar 2026 14:58:02 +0100 Message-Id: <20260323135812.383509-23-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274707210158500 Content-Type: text/plain; charset="utf-8" This part SynIC state is retrieved from the hypervisor via aligned state pages: - Add new synic source file - Centralize the synic_enabled() check - r/w pages from the hyper via aligned pages - only handle pages when synic is enabled - add buffers for migration to VM state Signed-off-by: Magnus Kulke --- include/system/mshv_int.h | 7 ++ target/i386/cpu.h | 5 ++ target/i386/machine.c | 26 ++++++ target/i386/mshv/meson.build | 1 + target/i386/mshv/mshv-cpu.c | 64 +++++++++++++++ target/i386/mshv/msr.c | 7 +- target/i386/mshv/synic.c | 155 +++++++++++++++++++++++++++++++++++ 7 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 target/i386/mshv/synic.c diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 29b363e73e..80df4030c5 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -119,4 +119,11 @@ int mshv_init_msrs(const CPUState *cpu); int mshv_get_msrs(CPUState *cpu); int mshv_set_msrs(const CPUState *cpu); =20 +/* synic */ +int mshv_get_simp(int cpu_fd, uint8_t *page); +int mshv_set_simp(int cpu_fd, const uint8_t *page); +int mshv_get_siefp(int cpu_fd, uint8_t *page); +int mshv_set_siefp(int cpu_fd, const uint8_t *page); +bool mshv_synic_enabled(const CPUState *cpu); + #endif diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 0b539155c4..d010d26146 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -33,6 +33,7 @@ #include "qemu/cpu-float.h" #include "qemu/timer.h" #include "standard-headers/asm-x86/kvm_para.h" +#include "hw/hyperv/hvgdk_mini.h" =20 #define XEN_NR_VIRQS 24 =20 @@ -2291,6 +2292,10 @@ typedef struct CPUArchState { #if defined(CONFIG_HVF) || defined(CONFIG_MSHV) || defined(CONFIG_WHPX) void *emu_mmio_buf; #endif +#if defined(CONFIG_MSHV) + uint8_t hv_simp_page[HV_HYP_PAGE_SIZE]; + uint8_t hv_siefp_page[HV_HYP_PAGE_SIZE]; +#endif =20 uint64_t mcg_cap; uint64_t mcg_ctl; diff --git a/target/i386/machine.c b/target/i386/machine.c index 48a2a4b319..f94cc544b3 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -952,6 +952,29 @@ static const VMStateDescription vmstate_msr_hyperv_ree= nlightenment =3D { } }; =20 +#ifdef CONFIG_MSHV +static bool mshv_synic_vp_state_needed(void *opaque) +{ + X86CPU *cpu =3D opaque; + CPUX86State *env =3D &cpu->env; + + /* Only migrate SIMP/SIEFP if SynIC is enabled */ + return env->msr_hv_synic_control & 1; +} + +static const VMStateDescription vmstate_mshv_synic_vp_state =3D { + .name =3D "cpu/mshv_synic_vp_state", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D mshv_synic_vp_state_needed, + .fields =3D (const VMStateField[]) { + VMSTATE_BUFFER(env.hv_simp_page, X86CPU), + VMSTATE_BUFFER(env.hv_siefp_page, X86CPU), + VMSTATE_END_OF_LIST() + } +}; +#endif + static bool avx512_needed(void *opaque) { X86CPU *cpu =3D opaque; @@ -1916,6 +1939,9 @@ const VMStateDescription vmstate_x86_cpu =3D { &vmstate_cet, #ifdef TARGET_X86_64 &vmstate_apx, +#endif +#ifdef CONFIG_MSHV + &vmstate_mshv_synic_vp_state, #endif NULL } diff --git a/target/i386/mshv/meson.build b/target/i386/mshv/meson.build index f44e84688d..a847a6c74c 100644 --- a/target/i386/mshv/meson.build +++ b/target/i386/mshv/meson.build @@ -4,6 +4,7 @@ i386_mshv_ss.add(files( 'mshv-apic.c', 'mshv-cpu.c', 'msr.c', + 'synic.c', )) =20 i386_system_ss.add_all(when: 'CONFIG_MSHV', if_true: i386_mshv_ss) diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 0d4721582a..49f3f9c090 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -128,6 +128,33 @@ static int get_lapic(CPUState *cpu) return 0; } =20 +static int get_synic_state(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + + /* SIMP/SIEFP can only be read when SynIC is enabled */ + if (!mshv_synic_enabled(cpu)) { + return 0; + } + + ret =3D mshv_get_simp(cpu_fd, env->hv_simp_page); + if (ret < 0) { + error_report("failed to get simp state"); + return -1; + } + + ret =3D mshv_get_siefp(cpu_fd, env->hv_siefp_page); + if (ret < 0) { + error_report("failed to get siefp state"); + return -1; + } + + return 0; +} + static void populate_fpu(const hv_register_assoc *assocs, X86CPU *x86cpu) { union hv_register_value value; @@ -585,6 +612,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D get_synic_state(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 @@ -1026,6 +1058,33 @@ static int set_lapic(const CPUState *cpu) return 0; } =20 +static int set_synic_state(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + + /* SIMP/SIEFP can only be written when SynIC is enabled */ + if (!mshv_synic_enabled(cpu)) { + return 0; + } + + ret =3D mshv_set_simp(cpu_fd, env->hv_simp_page); + if (ret < 0) { + error_report("failed to set simp state"); + return -1; + } + + ret =3D mshv_set_siefp(cpu_fd, env->hv_siefp_page); + if (ret < 0) { + error_report("failed to set siefp state"); + return -1; + } + + return 0; +} + int mshv_arch_store_vcpu_state(const CPUState *cpu) { int ret; @@ -1062,6 +1121,11 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 + ret =3D set_synic_state(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 diff --git a/target/i386/mshv/msr.c b/target/i386/mshv/msr.c index d19b79d729..bfae4ed0d8 100644 --- a/target/i386/mshv/msr.c +++ b/target/i386/mshv/msr.c @@ -299,7 +299,6 @@ int mshv_get_msrs(CPUState *cpu) size_t i, j; uint32_t name; X86CPU *x86cpu =3D X86_CPU(cpu); - bool synic_enabled; =20 set_hv_name_in_assocs(assocs, n_assocs); =20 @@ -327,8 +326,7 @@ int mshv_get_msrs(CPUState *cpu) store_in_env(cpu, assocs, n_assocs); =20 /* Read SINT MSRs only if SynIC is enabled */ - synic_enabled =3D x86cpu->env.msr_hv_synic_control & 1; - if (synic_enabled) { + if (mshv_synic_enabled(cpu)) { QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT); =20 for (i =3D 0; i < HV_SINT_COUNT; i++) { @@ -382,7 +380,6 @@ int mshv_set_msrs(const CPUState *cpu) int ret; size_t i, j; X86CPU *x86cpu =3D X86_CPU(cpu); - bool synic_enabled =3D x86cpu->env.msr_hv_synic_control & 1; =20 load_from_env(cpu, assocs, n_assocs); =20 @@ -416,7 +413,7 @@ int mshv_set_msrs(const CPUState *cpu) } =20 /* SINT MSRs can only be written if SCONTROL has been set, so we split= */ - if (synic_enabled) { + if (mshv_synic_enabled(cpu)) { QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT); =20 for (i =3D 0; i < HV_SINT_COUNT; i++) { diff --git a/target/i386/mshv/synic.c b/target/i386/mshv/synic.c new file mode 100644 index 0000000000..8f9fee6ed7 --- /dev/null +++ b/target/i386/mshv/synic.c @@ -0,0 +1,155 @@ +/* + * QEMU MSHV SynIC support + * + * Copyright Microsoft, Corp. 2026 + * + * Authors: Magnus Kulke + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/memalign.h" +#include "qemu/error-report.h" + +#include "system/mshv.h" +#include "system/mshv_int.h" + +#include "linux/mshv.h" +#include "hw/hyperv/hvgdk_mini.h" +#include "cpu.h" + +#include + +bool mshv_synic_enabled(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + + return x86cpu->env.msr_hv_synic_control & 1; +} + +static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state) +{ + int ret; + + ret =3D ioctl(cpu_fd, MSHV_GET_VP_STATE, state); + if (ret < 0) { + error_report("failed to get vp state: %s", strerror(errno)); + return -1; + } + + return 0; +} + +static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *st= ate) +{ + int ret; + + ret =3D ioctl(cpu_fd, MSHV_SET_VP_STATE, state); + if (ret < 0) { + error_report("failed to set vp state: %s", strerror(errno)); + return -1; + } + + return 0; +} + +int mshv_get_simp(int cpu_fd, uint8_t *page) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SIMP; + + ret =3D get_vp_state(cpu_fd, &args); + + if (ret < 0) { + qemu_vfree(buffer); + error_report("failed to get simp"); + return -1; + } + + memcpy(page, buffer, HV_HYP_PAGE_SIZE); + qemu_vfree(buffer); + + return 0; +} + +int mshv_set_simp(int cpu_fd, const uint8_t *page) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SIMP; + + assert(page); + memcpy(buffer, page, HV_HYP_PAGE_SIZE); + + ret =3D set_vp_state(cpu_fd, &args); + qemu_vfree(buffer); + + if (ret < 0) { + error_report("failed to set simp"); + return -1; + } + + return 0; +} + +int mshv_get_siefp(int cpu_fd, uint8_t *page) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SIEFP, + + ret =3D get_vp_state(cpu_fd, &args); + + if (ret < 0) { + qemu_vfree(buffer); + error_report("failed to get siefp"); + return -1; + } + + memcpy(page, buffer, HV_HYP_PAGE_SIZE); + qemu_vfree(buffer); + + return 0; +} + +int mshv_set_siefp(int cpu_fd, const uint8_t *page) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SIEFP, + + assert(page); + memcpy(buffer, page, HV_HYP_PAGE_SIZE); + + ret =3D set_vp_state(cpu_fd, &args); + qemu_vfree(buffer); + + if (ret < 0) { + error_report("failed to set simp"); + return -1; + } + + return 0; +} --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274666; cv=none; d=zohomail.com; s=zohoarc; b=boIL6KfbvU1xKWuHMu3I0w+NxIYMSJS5iDR2pVO+sPyS/BLWNOC6BEu/40pG3OfpPUw4c8BPVRZWe7w6Pp4DdLNEto4KlS1QWIqkIPWTKYV9wRgXf99BTiYA611iV7aLVaskv7e7y71WYe1BN2OD99c+fVrqLCT6P30PM0PITU4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274666; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=yhITRCfVYpAj4mFPzBy0ptGSp7r7sjaGYtVDf189wk8=; b=f8jFp9sGg4YN1Aqxl9RqjdyXPbuVW0hIGmcsJe6Zp/YLIZirAh51lmG9nqqFz157j2yCsN9lRLFCJ4SRbLtsJ6/b44s+KpTiVAJsOcDKVol8GxWaOwt4vuwf1S3uKSQ9I7zm4qB+0+7eMKty2OzpoePy10743zvIo/9UNICZ3jg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274666138215.4471398234915; Mon, 23 Mar 2026 07:04:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fre-0002sg-QW; Mon, 23 Mar 2026 10:02:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4foz-0000eP-PN for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:04 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4foy-00071b-1m for qemu-devel@nongnu.org; Mon, 23 Mar 2026 09:59:57 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 7B26420B6F1F; Mon, 23 Mar 2026 06:59:41 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7B26420B6F1F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274384; bh=yhITRCfVYpAj4mFPzBy0ptGSp7r7sjaGYtVDf189wk8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qBpmZgjagkS2imgAQjvc11FGT9sV6RiIfquJjcSrHG9ocqn9+zCuhiXLhaN1swHnC 9Y/PRhjO3oZZX0s63dN0zmpR5lqHiwN/JWnFYxirW6hvoaImKPYUFO8ojtmvEcN5d3 H/dH8lOQ40Ge2/WzLtNX5gc3etC5Yjk65gQ7kKTs= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 23/32] target/i386/mshv: migrate STIMER state Date: Mon, 23 Mar 2026 14:58:03 +0100 Message-Id: <20260323135812.383509-24-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274669366154101 Content-Type: text/plain; charset="utf-8" This part of Synic state is retrieved via a mem-aligned page. We declare the required space (size reference: rust-vmm/mshv) as a buffer on the VM state struct for inclusion in a migration. Other than other SynIC features, STIMER doesn't depend on SCONTROL being set. Signed-off-by: Magnus Kulke --- include/system/mshv_int.h | 2 ++ target/i386/cpu.h | 5 ++++ target/i386/machine.c | 20 +++++++++++++++ target/i386/mshv/mshv-cpu.c | 12 +++++++++ target/i386/mshv/synic.c | 51 +++++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+) diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 80df4030c5..7d685fc647 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -125,5 +125,7 @@ int mshv_set_simp(int cpu_fd, const uint8_t *page); int mshv_get_siefp(int cpu_fd, uint8_t *page); int mshv_set_siefp(int cpu_fd, const uint8_t *page); bool mshv_synic_enabled(const CPUState *cpu); +int mshv_get_synthetic_timers(int cpu_fd, uint8_t *state); +int mshv_set_synthetic_timers(int cpu_fd, const uint8_t *state); =20 #endif diff --git a/target/i386/cpu.h b/target/i386/cpu.h index d010d26146..4ad4a35ce9 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -45,6 +45,10 @@ #define ELF_MACHINE_UNAME "i686" #endif =20 +#ifdef CONFIG_MSHV +#define MSHV_STIMERS_STATE_SIZE 200 +#endif + enum { R_EAX =3D 0, R_ECX =3D 1, @@ -2295,6 +2299,7 @@ typedef struct CPUArchState { #if defined(CONFIG_MSHV) uint8_t hv_simp_page[HV_HYP_PAGE_SIZE]; uint8_t hv_siefp_page[HV_HYP_PAGE_SIZE]; + uint8_t hv_synthetic_timers_state[MSHV_STIMERS_STATE_SIZE]; #endif =20 uint64_t mcg_cap; diff --git a/target/i386/machine.c b/target/i386/machine.c index f94cc544b3..38ccbbe19d 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -10,6 +10,7 @@ #include "exec/watchpoint.h" #include "system/kvm.h" #include "system/kvm_xen.h" +#include "system/mshv.h" #include "system/tcg.h" =20 #include "qemu/error-report.h" @@ -953,6 +954,24 @@ static const VMStateDescription vmstate_msr_hyperv_ree= nlightenment =3D { }; =20 #ifdef CONFIG_MSHV + +static bool mshv_synthetic_timers_needed(void *opaque) +{ + /* Always migrate synthetic timers */ + return mshv_enabled(); +} + +static const VMStateDescription vmstate_mshv_synthetic_timers =3D { + .name =3D "cpu/mshv_synthetic_timers", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D mshv_synthetic_timers_needed, + .fields =3D (const VMStateField[]) { + VMSTATE_BUFFER(env.hv_synthetic_timers_state, X86CPU), + VMSTATE_END_OF_LIST() + } +}; + static bool mshv_synic_vp_state_needed(void *opaque) { X86CPU *cpu =3D opaque; @@ -1942,6 +1961,7 @@ const VMStateDescription vmstate_x86_cpu =3D { #endif #ifdef CONFIG_MSHV &vmstate_mshv_synic_vp_state, + &vmstate_mshv_synthetic_timers, #endif NULL } diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 49f3f9c090..ec1caf4e7a 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -135,6 +135,12 @@ static int get_synic_state(CPUState *cpu) int cpu_fd =3D mshv_vcpufd(cpu); int ret; =20 + ret =3D mshv_get_synthetic_timers(cpu_fd, env->hv_synthetic_timers_sta= te); + if (ret < 0) { + error_report("failed to get synthetic timers"); + return -1; + } + /* SIMP/SIEFP can only be read when SynIC is enabled */ if (!mshv_synic_enabled(cpu)) { return 0; @@ -1065,6 +1071,12 @@ static int set_synic_state(const CPUState *cpu) int cpu_fd =3D mshv_vcpufd(cpu); int ret; =20 + ret =3D mshv_set_synthetic_timers(cpu_fd, env->hv_synthetic_timers_sta= te); + if (ret < 0) { + error_report("failed to set synthetic timers state"); + return -1; + } + /* SIMP/SIEFP can only be written when SynIC is enabled */ if (!mshv_synic_enabled(cpu)) { return 0; diff --git a/target/i386/mshv/synic.c b/target/i386/mshv/synic.c index 8f9fee6ed7..4c629adc3a 100644 --- a/target/i386/mshv/synic.c +++ b/target/i386/mshv/synic.c @@ -54,6 +54,57 @@ static int set_vp_state(int cpu_fd, const struct mshv_ge= t_set_vp_state *state) return 0; } =20 +int mshv_get_synthetic_timers(int cpu_fd, uint8_t *state) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SYNTHETIC_TIMERS; + + ret =3D get_vp_state(cpu_fd, &args); + + if (ret < 0) { + qemu_vfree(buffer); + error_report("failed to get synthetic timers"); + return -1; + } + + memcpy(state, buffer, MSHV_STIMERS_STATE_SIZE); + qemu_vfree(buffer); + + return 0; +} + +int mshv_set_synthetic_timers(int cpu_fd, const uint8_t *state) +{ + int ret; + void *buffer; + struct mshv_get_set_vp_state args =3D {0}; + + buffer =3D qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); + memset(buffer, 0, HV_HYP_PAGE_SIZE); + args.buf_ptr =3D (uint64_t)buffer; + args.buf_sz =3D HV_HYP_PAGE_SIZE; + args.type =3D MSHV_VP_STATE_SYNTHETIC_TIMERS; + + assert(state); + memcpy(buffer, state, MSHV_STIMERS_STATE_SIZE); + + ret =3D set_vp_state(cpu_fd, &args); + qemu_vfree(buffer); + + if (ret < 0) { + error_report("failed to set synthetic timers"); + return -1; + } + + return 0; +} + int mshv_get_simp(int cpu_fd, uint8_t *page) { int ret; --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274582; cv=none; d=zohomail.com; s=zohoarc; b=h+mkYKUKZ25++SD0XQbrC5pEZ16Qv6ztr3IkDKZ0hmKfs5iS6fuh+7JCZ7cerKM+vq9V899tLWWRB6y7w9FmaEN7rFRxFcT3OLY8EwD/pKFDx+7S+57wbAx1rOl6QBD2EUS+/N2sdOBCd1RmAIzyvLm1h1bcydEXjeQXFtEtEMI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274582; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=z5pOF/uzO+7evYgTyZgR0PS2QiZuE42WF+kRFN/Qu/4=; b=KQCKbeiPLjpbd6Jh1bxDtQtS9wzosBobT8BqZfOGZ2d5qVuoKdBWPFAx1XXnoAh/vAObToQXWmAvqyJwfA5uxDKZ7edKBCL8WTbZQggkVCyT5QIgfZLVAL25Dgq/tTPJitmQOnuF68kMYni//6cH4GFM3035RWHdLV9egNGd/C8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274582133276.51895634316736; Mon, 23 Mar 2026 07:03:02 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4frC-0001pF-KR; Mon, 23 Mar 2026 10:02:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fp4-0000jS-Gc for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:05 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fp0-00072n-Oo for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:00 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 263DA20B6F21; Mon, 23 Mar 2026 06:59:44 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 263DA20B6F21 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274388; bh=z5pOF/uzO+7evYgTyZgR0PS2QiZuE42WF+kRFN/Qu/4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MQP4it7X9kjqgaHAjWwpRdEqThg3YMJoToaoQvka51y29N8Ugk20eIlhJC5YTwPIM bxHknKSLeeuYASMTxJ1IgWzKolt5GcpPcNmBBgaTDQbGAfckyodyuJytvoBtHziXvn wbTt6GXiLKzkF9TPxqm1MJpyyEZXat0HH774cp/g= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 24/32] accel/mshv: introduce SaveVMHandler Date: Mon, 23 Mar 2026 14:58:04 +0100 Message-Id: <20260323135812.383509-25-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274584270158500 Content-Type: text/plain; charset="utf-8" This mechanism is used to handle more imperative partition-wide steps that have to be taken as part of a migration routine. Currently it's a skeleton that will just pause/resume the partition as part of a migration. It will later be extended with more specific steps like reference time and hypercall pages. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index d1bf148bb8..365288b901 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -39,6 +39,8 @@ #include "system/mshv.h" #include "system/mshv_int.h" #include "system/reset.h" +#include "migration/qemu-file-types.h" +#include "migration/register.h" #include "trace.h" #include #include @@ -47,6 +49,9 @@ bool mshv_allowed; =20 MshvState *mshv_state; =20 +static int pause_vm(int vm_fd); +static int resume_vm(int vm_fd); + static int init_mshv(int *mshv_fd) { int fd =3D open("/dev/mshv", O_RDWR | O_CLOEXEC); @@ -80,6 +85,64 @@ static int set_time_freeze(int vm_fd, int freeze) return 0; } =20 +static void mshv_save_state(QEMUFile *f, void *opaque) +{ + return; +} + +static int mshv_load_state(QEMUFile *f, void *opaque, int version_id) +{ + return 0; +} + +static int mshv_save_prepare(void *opaque, Error **errp) +{ + MshvState *s =3D opaque; + int ret; + + ret =3D pause_vm(s->vm); + if (ret < 0) { + error_setg(errp, "Failed to pause VM for migration"); + return -1; + } + + return 0; +} + +static void mshv_save_cleanup(void *opaque) +{ + MshvState *s =3D opaque; + int ret; + + ret =3D resume_vm(s->vm); + if (ret < 0) { + error_report("Failed to resme VM after migration"); + } +} + +static int mshv_load_setup(QEMUFile *f, void *opaque, Error **errp) +{ + MshvState *s =3D opaque; + int ret; + + ret =3D pause_vm(s->vm); + if (ret < 0) { + error_setg(errp, "Failed to pause VM for migration restore"); + return -1; + } + + return 0; +} + +static int mshv_load_cleanup(void *opaque) +{ + MshvState *s =3D opaque; + + resume_vm(s->vm); + + return 0; +} + static int pause_vm(int vm_fd) { int ret; @@ -454,6 +517,15 @@ static int mshv_init_vcpu(CPUState *cpu) return 0; } =20 +static SaveVMHandlers savevm_mshv =3D { + .save_prepare =3D mshv_save_prepare, + .save_state =3D mshv_save_state, + .save_cleanup =3D mshv_save_cleanup, + .load_setup =3D mshv_load_setup, + .load_state =3D mshv_load_state, + .load_cleanup =3D mshv_load_cleanup, +}; + static int mshv_init(AccelState *as, MachineState *ms) { MshvState *s; @@ -509,6 +581,9 @@ static int mshv_init(AccelState *as, MachineState *ms) 0, "mshv-memory"); memory_listener_register(&mshv_io_listener, &address_space_io); =20 + /* register custom handlers for migration events */ + register_savevm_live("mshv", 0, 1, &savevm_mshv, s); + return 0; } =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274502; cv=none; d=zohomail.com; s=zohoarc; b=KiPd6lTd4pVOPEoCKMX4sq5xO7q2NrkOs/E04Nulqfz95i7jEleeVtResfnEztty1/amFoexOrYCIeWfbkfFMgIR67eQTevY2+CeP9i7eVjJXve3gxYxfIWO3GfDCzF6lncNDyf/YebI+0oj4QR5Bz3V+eZ9ulr/WlYhEmS6x4Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274502; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/aJjVtv2N2HvKWYe9sJ5DIN7GG5pVPTEVn5pz5+VPjQ=; b=j+iiu77kjk4N0MMsa4WpcH3y1oQnLf0dzIN8e0OxlSP5Hpmj/x+jxUP4eh2uJHQkkCAxx0Vl+9lOaa2SBml9x8JhQe/HxGIu5l2xDVTfiPk0dCiZPTamgLOt1hbveT/n0vHGEd17Lgk8RP1aNZoc6zPZRySwOlQWo/5Lpvk0btE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274502495217.79679218686442; Mon, 23 Mar 2026 07:01:42 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpg-00010E-Pd; Mon, 23 Mar 2026 10:00:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fp7-0000kq-Bz for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:11 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fp4-00073O-Dp for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:04 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id AA00220B6F15; Mon, 23 Mar 2026 06:59:48 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com AA00220B6F15 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274391; bh=/aJjVtv2N2HvKWYe9sJ5DIN7GG5pVPTEVn5pz5+VPjQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dyeboFIJ2FdETlp6CR65ZWMlL/58/lM9WsOgz8YXa8ZdGCT4GFFQbhdVxXhGh3Zc4 xuNLnzXedjOIEom/ui2tP4fdkQwBPdtgkbgn+ZN/lKv10UleqbkEO3i563jq2ln8o0 gZLNOK8aRjvC8y4hsQ6pgG/8pRxphI88VyPINcHw= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 25/32] accel/mshv: write synthetic MSRs after migration Date: Mon, 23 Mar 2026 14:58:05 +0100 Message-Id: <20260323135812.383509-26-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274503307158500 Content-Type: text/plain; charset="utf-8" Write partition-wide synthetic MSRs. This ensures the hypercall page and SynIC facilities are set up before vCPUs attempt to use it. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 7 +++++++ include/hw/hyperv/hvgdk_mini.h | 3 +++ include/system/mshv_int.h | 1 + target/i386/mshv/mshv-cpu.c | 15 +++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 365288b901..22e838ede6 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -137,6 +137,13 @@ static int mshv_load_setup(QEMUFile *f, void *opaque, = Error **errp) static int mshv_load_cleanup(void *opaque) { MshvState *s =3D opaque; + int ret; + + ret =3D mshv_arch_set_partition_msrs(first_cpu); + if (ret < 0) { + error_report("Failed to set partition MSRs: %s", strerror(-ret)); + return -1; + } =20 resume_vm(s->vm); =20 diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h index a47bc6212e..00daac0431 100644 --- a/include/hw/hyperv/hvgdk_mini.h +++ b/include/hw/hyperv/hvgdk_mini.h @@ -23,6 +23,9 @@ #define HV_X64_MSR_APIC_FREQUENCY 0x40000023 =20 typedef enum hv_register_name { + /* VP Management Registers */ + HV_REGISTER_INTERNAL_ACTIVITY_STATE =3D 0x00000004, + /* Pending Interruption Register */ HV_REGISTER_PENDING_INTERRUPTION =3D 0x00010002, =20 diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 7d685fc647..7052f20a00 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -84,6 +84,7 @@ int mshv_get_generic_regs(CPUState *cpu, hv_register_asso= c *assocs, size_t n_regs); int mshv_arch_store_vcpu_state(const CPUState *cpu); int mshv_arch_load_vcpu_state(CPUState *cpu); +int mshv_arch_set_partition_msrs(const CPUState *cpu); void mshv_arch_init_vcpu(CPUState *cpu); void mshv_arch_destroy_vcpu(CPUState *cpu); void mshv_arch_amend_proc_features( diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index ec1caf4e7a..0b08f478ce 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -1141,6 +1141,21 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return 0; } =20 +int mshv_arch_set_partition_msrs(const CPUState *cpu) +{ + CPUX86State *env =3D &X86_CPU(cpu)->env; + struct hv_register_assoc assocs[] =3D { + { .name =3D HV_REGISTER_GUEST_OS_ID, + .value.reg64 =3D env->msr_hv_guest_os_id }, + { .name =3D HV_REGISTER_REFERENCE_TSC, + .value.reg64 =3D env->msr_hv_tsc }, + { .name =3D HV_X64_REGISTER_HYPERCALL, + .value.reg64 =3D env->msr_hv_hypercall }, + }; + + return mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs)); +} + void mshv_arch_amend_proc_features( union hv_partition_synthetic_processor_features *features) { --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274704; cv=none; d=zohomail.com; s=zohoarc; b=lPYXjUtBOQq2Apg5tcZ6Q5Abc/h0acxFvp3kpb8XBkQYeu7ith27yDO6GNm5iHEYJ5KVguv+ctU5HYb1F+C5Vjyw2m301cz6KMGIxn/lEgSbVJM9MV5VgR1WYx5636eqxSYooGDcYxfTTmboQ9CBMGXXq53uz+iMKZFGGT9hWmg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274704; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=+GcfDGF+p4TwuNzdDU1vHppWDYVvy/FB9/c/HXYoevs=; b=V4+vCah+zs0ow5RqvCmSYAn8yzP8NUNgszRcH3Yuoa9BRQMnM9njZl7/7se+EOh0D7LtcNJK9bqUfqO0ndlF0jPrL1T/Td2OCW5qsQyrkvhp1Cws7CLz/zol44+pqZmS1GBK2ybY00kd1nH4WSsbqSB1t4FYCKc6WTmaZzdghgY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274704133865.1159804838366; Mon, 23 Mar 2026 07:05:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4ft9-00060N-Uu; Mon, 23 Mar 2026 10:04:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fp9-0000pD-OP for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:15 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fp8-00073m-1x for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:07 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 2F30720B6F1B; Mon, 23 Mar 2026 06:59:52 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 2F30720B6F1B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274395; bh=+GcfDGF+p4TwuNzdDU1vHppWDYVvy/FB9/c/HXYoevs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UVeLNgdI5nYWCu1OyAzf3VaXpB1gaFTPxadDDb6zHvYkUhmfNatrjByuo91FHcEXi AVJCN2Zt+lbprqjSuAah2EzDGjyvaOGFbM22H3Mt6XYwhgXiRwJB8tNALufhPHeiY2 unvfwFRqfmC6PGyPiibJHBt4ed0rqPMOcSd2D39s= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 26/32] accel/mshv: migrate REFERENCE_TIME Date: Mon, 23 Mar 2026 14:58:06 +0100 Message-Id: <20260323135812.383509-27-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274705944154100 Content-Type: text/plain; charset="utf-8" This is a partition-wide state that we use a dedicated handler for. It is stored as-is in the "mshv" savevm_live field. We might have to extend this later if we have more partition-wide state to roundtrip. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 70 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 22e838ede6..3927a82925 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -85,13 +85,81 @@ static int set_time_freeze(int vm_fd, int freeze) return 0; } =20 +static int get_reference_time(int vm_fd, uint64_t *ref_time) +{ + int ret; + struct hv_input_get_partition_property in =3D {0}; + struct hv_output_get_partition_property out =3D {0}; + struct mshv_root_hvcall args =3D {0}; + + in.property_code =3D HV_PARTITION_PROPERTY_REFERENCE_TIME; + + args.code =3D HVCALL_GET_PARTITION_PROPERTY; + args.in_sz =3D sizeof(in); + args.in_ptr =3D (uint64_t)∈ + args.out_sz =3D sizeof(out); + args.out_ptr =3D (uint64_t)&out; + + ret =3D mshv_hvcall(vm_fd, &args); + if (ret < 0) { + error_report("Failed to get reference time"); + return -1; + } + + *ref_time =3D out.property_value; + return 0; +} + static void mshv_save_state(QEMUFile *f, void *opaque) { - return; + MshvState *s =3D opaque; + uint64_t ref_time; + int ret; + + ret =3D get_reference_time(s->vm, &ref_time); + if (ret < 0) { + error_report("Failed to get reference time for migration"); + abort(); + } + + qemu_put_be64(f, ref_time); +} + +static int set_reference_time(int vm_fd, uint64_t ref_time) +{ + int ret; + struct hv_input_set_partition_property in =3D {0}; + struct mshv_root_hvcall args =3D {0}; + + in.property_code =3D HV_PARTITION_PROPERTY_REFERENCE_TIME; + in.property_value =3D ref_time; + + args.code =3D HVCALL_SET_PARTITION_PROPERTY; + args.in_sz =3D sizeof(in); + args.in_ptr =3D (uint64_t)∈ + + ret =3D mshv_hvcall(vm_fd, &args); + if (ret < 0) { + error_report("Failed to set reference time"); + return -1; + } + + return 0; } =20 static int mshv_load_state(QEMUFile *f, void *opaque, int version_id) { + MshvState *s =3D opaque; + uint64_t ref_time; + int ret; + + ref_time =3D qemu_get_be64(f); + + ret =3D set_reference_time(s->vm, ref_time); + if (ret < 0) { + error_report("Failed to set reference time after migration"); + return -1; + } return 0; } =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274697; cv=none; d=zohomail.com; s=zohoarc; b=kimxmmOyFCuFSFE1zlYLqqDbW/gL/YdotIs7NbGlbsakKKw/FW5yYV2SNHLElV63H2G7werL924TQfUcYQd+l6Pu7D8nTmyieSh4hIEVSwGOzOr5veYEEijv+YBx4XZXBxvMNRCbaUvSBYk517ZKeJtuBnaQGkVDxYVgvnCKgTI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274697; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=y5n6XcDjhdUcCeYhcYqonW1SGbx+ZfqghjHafqkUNaI=; b=Cf7grJy6L3eVeclCyyUWzYkHSFyzjy8vQug+rsjoxmOCeLf7mjl9EGzX3HDzjToXziAn7y7s0cbvrL4KEgQb2+uwMRnWDZt0iPgFVIHvhwig/L060sQ4gv7CiHz3pvkgIETvq5xG/YDluiChStEywaUhKmtS6cPjZaiPmh/rSNc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274697338678.3533024443559; Mon, 23 Mar 2026 07:04:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4frz-0003KL-9R; Mon, 23 Mar 2026 10:03:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fpE-0000qL-0f for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:17 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpB-00074K-Gs for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:11 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id C51A720B6F0C; Mon, 23 Mar 2026 06:59:55 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com C51A720B6F0C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274398; bh=y5n6XcDjhdUcCeYhcYqonW1SGbx+ZfqghjHafqkUNaI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rwms7er1i4rx+bIDzSkjhj8f3Yi4yf2DnOV4Ve4PgBWqy1b0o3Qrga5cwEz4KvVVh NOb5L5/myhhXAMBZA7FR+xWMBFIrwPcrxNrhlFiP44RW8i2rBbNMd8qmBUil3Esv70 v6BME3POxLDaMFlohJeDWwuViOE7ViTZ5W+zfF98= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 27/32] target/i386/mshv: migrate pending ints/excs Date: Mon, 23 Mar 2026 14:58:07 +0100 Message-Id: <20260323135812.383509-28-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274699905154100 Content-Type: text/plain; charset="utf-8" We use PENDING_INTERRUPTION, INTERRUPT_STATE, PENDING_EVENT hv registers to map and roundtrip from/to CPUX86State. We ignore HV_REGISTER_PENDING_EVENT1 which represent events for nested virt contexts, as we don't support nested virt with MSHV currently. Signed-off-by: Magnus Kulke --- include/hw/hyperv/hvgdk_mini.h | 3 + include/system/mshv_int.h | 13 +++ target/i386/mshv/mshv-cpu.c | 168 +++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+) diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h index 00daac0431..a88420fafe 100644 --- a/include/hw/hyperv/hvgdk_mini.h +++ b/include/hw/hyperv/hvgdk_mini.h @@ -28,6 +28,9 @@ typedef enum hv_register_name { =20 /* Pending Interruption Register */ HV_REGISTER_PENDING_INTERRUPTION =3D 0x00010002, + HV_REGISTER_INTERRUPT_STATE =3D 0x00010003, + HV_REGISTER_PENDING_EVENT0 =3D 0x00010004, + HV_REGISTER_PENDING_EVENT1 =3D 0x00010005, =20 /* X64 User-Mode Registers */ HV_X64_REGISTER_RAX =3D 0x00020000, diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 7052f20a00..bc16b794b2 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -18,6 +18,19 @@ =20 struct mshv_get_set_vp_state; =20 +/* + * Interruption-type encoding, used by the hypervisor in + * hv_x64_pending_interruption_register.interruption_type + * See TLFS 6.0 section 7.9.2, p55 + * https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlf= s/tlfs + */ +#define MSHV_HV_INTERRUPTION_TYPE_EXT_INT 0 +#define MSHV_HV_INTERRUPTION_TYPE_NMI 2 +#define MSHV_HV_INTERRUPTION_TYPE_HW_EXC 3 +#define MSHV_HV_INTERRUPTION_TYPE_SW_INT 4 +#define MSHV_HV_INTERRUPTION_TYPE_PRIV_SW_EXC 5 +#define MSHV_HV_INTERRUPTION_TYPE_SW_EXC 6 + typedef struct hyperv_message hv_message; =20 typedef struct MshvHvCallArgs { diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 0b08f478ce..746987d62b 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -584,6 +584,164 @@ static int load_regs(CPUState *cpu) return 0; } =20 +static int get_vcpu_events(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + struct hv_register_assoc assocs[] =3D { + { .name =3D HV_REGISTER_PENDING_INTERRUPTION }, + { .name =3D HV_REGISTER_INTERRUPT_STATE }, + { .name =3D HV_REGISTER_PENDING_EVENT0 }, + }; + union hv_x64_pending_interruption_register pending_int; + union hv_x64_interrupt_state_register int_state; + union hv_x64_pending_exception_event pending_exc; + int ret; + + ret =3D mshv_get_generic_regs(cpu, assocs, ARRAY_SIZE(assocs)); + if (ret < 0) { + error_report("failed to get vcpu event registers"); + return -1; + } + + pending_int.as_uint64 =3D assocs[0].value.reg64; + int_state.as_uint64 =3D assocs[1].value.reg64; + pending_exc =3D assocs[2].value.pending_exception_event; + + /* Clear previous state. injected ints/excs are blanked w/ -1 */ + env->interrupt_injected =3D -1; + env->soft_interrupt =3D 0; + env->exception_injected =3D 0; + env->exception_pending =3D 0; + env->exception_nr =3D -1; + env->has_error_code =3D 0; + env->error_code =3D 0; + env->exception_has_payload =3D 0; + env->exception_payload =3D 0; + env->nmi_injected =3D 0; + + if (pending_int.interruption_pending) { + switch (pending_int.interruption_type) { + case MSHV_HV_INTERRUPTION_TYPE_EXT_INT: + env->interrupt_injected =3D pending_int.interruption_vector; + break; + case MSHV_HV_INTERRUPTION_TYPE_NMI: + env->nmi_injected =3D 1; + break; + case MSHV_HV_INTERRUPTION_TYPE_HW_EXC: + env->exception_injected =3D 1; + env->exception_nr =3D pending_int.interruption_vector; + env->has_error_code =3D pending_int.deliver_error_code; + env->error_code =3D pending_int.error_code; + break; + case MSHV_HV_INTERRUPTION_TYPE_SW_INT: + env->interrupt_injected =3D pending_int.interruption_vector; + env->soft_interrupt =3D 1; + break; + case MSHV_HV_INTERRUPTION_TYPE_SW_EXC: + case MSHV_HV_INTERRUPTION_TYPE_PRIV_SW_EXC: + env->exception_injected =3D 1; + env->exception_nr =3D pending_int.interruption_vector; + env->has_error_code =3D pending_int.deliver_error_code; + env->error_code =3D pending_int.error_code; + break; + default: + error_report("unknown interruption type %u", + pending_int.interruption_type); + return -EINVAL; + } + } + + /* disabled for one instr after STI, MOV/POP SS, see hvf_store_events(= ) */ + if (int_state.interrupt_shadow) { + env->hflags |=3D HF_INHIBIT_IRQ_MASK; + } else { + env->hflags &=3D ~HF_INHIBIT_IRQ_MASK; + } + + /* see kvm_get_vcpu_events(), hvf_store_events() */ + if (int_state.nmi_masked) { + env->hflags2 |=3D HF2_NMI_MASK; + } else { + env->hflags2 &=3D ~HF2_NMI_MASK; + } + + /* HV_REGISTER_PENDING_EVENT0: pending exception not yet injected */ + if (pending_exc.event_pending) { + env->exception_pending =3D 1; + env->exception_nr =3D pending_exc.vector; + env->has_error_code =3D pending_exc.deliver_error_code; + env->error_code =3D pending_exc.error_code; + env->exception_has_payload =3D (pending_exc.exception_parameter != =3D 0); + env->exception_payload =3D pending_exc.exception_parameter; + } + + /* + * Ignoring HV_REGISTER_PENDING_EVENT1, virtualization fault events, M= SHV + * does not support nested virtualization. + */ + + return 0; +} + +static int set_vcpu_events(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + union hv_x64_pending_interruption_register pending_int =3D { 0 }; + union hv_x64_interrupt_state_register int_state =3D { 0 }; + union hv_x64_pending_exception_event pending_exc =3D { 0 }; + struct hv_register_assoc assocs[3]; + int ret; + + /* build pending_int from CPUX86State */ + if (env->exception_injected) { + pending_int.interruption_pending =3D 1; + pending_int.interruption_type =3D MSHV_HV_INTERRUPTION_TYPE_HW_= EXC; + pending_int.interruption_vector =3D env->exception_nr; + pending_int.deliver_error_code =3D env->has_error_code; + pending_int.error_code =3D env->error_code; + } else if (env->nmi_injected) { + pending_int.interruption_pending =3D 1; + pending_int.interruption_type =3D MSHV_HV_INTERRUPTION_TYPE_NMI; + pending_int.interruption_vector =3D EXCP02_NMI; + } else if (env->interrupt_injected >=3D 0) { + pending_int.interruption_pending =3D 1; + pending_int.interruption_type =3D env->soft_interrupt + ? MSHV_HV_INTERRUPTION_TYPE_SW_INT + : MSHV_HV_INTERRUPTION_TYPE_EXT_INT; + pending_int.interruption_vector =3D env->interrupt_injected; + } + + /* build int_state, normalize to bool */ + int_state.interrupt_shadow =3D !!(env->hflags & HF_INHIBIT_IRQ_MASK); + int_state.nmi_masked =3D !!(env->hflags2 & HF2_NMI_MASK); + + /* build pending_exc */ + if (env->exception_pending) { + pending_exc.event_pending =3D 1; + pending_exc.vector =3D env->exception_nr; + pending_exc.deliver_error_code =3D env->has_error_code; + pending_exc.error_code =3D env->error_code; + pending_exc.exception_parameter =3D env->exception_payload; + } + + assocs[0].name =3D HV_REGISTER_PENDING_INTERRUPTION; + assocs[0].value.reg64 =3D pending_int.as_uint64; + assocs[1].name =3D HV_REGISTER_INTERRUPT_STATE; + assocs[1].value.reg64 =3D int_state.as_uint64; + assocs[2].name =3D HV_REGISTER_PENDING_EVENT0; + assocs[2].value.pending_exception_event =3D pending_exc; + + ret =3D mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs)); + if (ret < 0) { + error_report("failed to set vcpu event registers"); + return -1; + } + + return 0; +} + int mshv_arch_load_vcpu_state(CPUState *cpu) { int ret; @@ -623,6 +781,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D get_vcpu_events(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 @@ -1138,6 +1301,11 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 + ret =3D set_vcpu_events(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274786; cv=none; d=zohomail.com; s=zohoarc; b=Xh6P69WbUEoGZDyA7nJz2Uw6RV5W9aIe7ae8hwz6Vr2qhzaJxltfyLJ9E1ix5bqqOeo4v7ZWDZe79Gd8vUkGIja7aBBf8+y3dqBHPXJeTTX1K42U76MrDlXZcbVweE2TJ5DYNZ9eWYdE7rULbvEEbrmc6PWhZnCDGSUXgWTzTwY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274786; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=+vncmzL8fth993nkvLF4vJxsSvuXK42ECZb3oeQw0p4=; b=Lsp8rDs2vwSQupFt00jY+/X1hAA9InbklKf1hj5Sud3x3QXyEDKr41FF8r+XrGAdqsG7tHgY9mmvjTgN0CFDyQcDuao+f4gZikC02yM/vxrJ83x8uJGjwfrl3bG0uQ32bPLxpDJl3HHVzu/DHhXhdYsPdXW7Et8MzcVj7vFoUeA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274786201898.1127390955759; Mon, 23 Mar 2026 07:06:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fsE-0003jy-1A; Mon, 23 Mar 2026 10:03:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fpK-0000tP-HG for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:23 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpG-0007At-Ai for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:17 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 803C220B6F1F; Mon, 23 Mar 2026 06:59:59 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 803C220B6F1F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274402; bh=+vncmzL8fth993nkvLF4vJxsSvuXK42ECZb3oeQw0p4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VLfFYUZ0pSnR7atr85LKQAMWgQ/3Yv2GouJJR/SuwF7e5n7PfNhzXbwYQ+QyECsG5 jZoELpMOAtRKUKU8kyafANhOblvAn9TVJcMas7HivK+Gh5dkKI2Wd4AXgbrl0x8kKy XEDCvido95ixkYvl0PPIFYB2FUU2AgW/2er1CbAQ= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 28/32] target/i386: add de/compaction to xsave_helper Date: Mon, 23 Mar 2026 14:58:08 +0100 Message-Id: <20260323135812.383509-29-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274787428154100 Content-Type: text/plain; charset="utf-8" HyperV use XSAVES which stores extended state in compacted format in which components are packed contiguously, while QEMU's internal XSAVE representation use the standard format in which each component is places at a fixed offset. Hence for this purpose we add two conversion fn's to the xsave helper to roundtrip XSAVE state in a migration. - decompact_xsave_area(): converts compacted format to standard. XSTATE_BV is masked to host XCR0 since IA32_XSS is managed by the hypervisor. - compact_xsave_area(): converts standard format back to compacted format. XCOMP_BV is set from the host's CPUID 0xD.0 rather than the guest's XCR0, as this is what the hypervisor expects. Both functions use the host's CPUID leaf 0xD subleaves to determine compone= nt sizes, offsets, and alignment requirements. There are situations when the host advertises features that we want to disable for the guest, e.g. AMX TILE. In this case we cannot rely on the host's xcr0, but instead we use the feature mask that has been generated in as part of the CPU realization process (x86_cpu_expand_features). Signed-off-by: Magnus Kulke --- target/i386/cpu.h | 2 + target/i386/xsave_helper.c | 255 +++++++++++++++++++++++++++++++++++++ 2 files changed, 257 insertions(+) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 4ad4a35ce9..cd5d5a5369 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -3033,6 +3033,8 @@ void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void= *buf, uint32_t buflen); void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen); uint32_t xsave_area_size(uint64_t mask, bool compacted); void x86_update_hflags(CPUX86State* env); +int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env); +int compact_xsave_area(CPUX86State *env, void *buf, size_t buflen); =20 static inline bool hyperv_feat_enabled(X86CPU *cpu, int feat) { diff --git a/target/i386/xsave_helper.c b/target/i386/xsave_helper.c index bab2258732..2272b83f5f 100644 --- a/target/i386/xsave_helper.c +++ b/target/i386/xsave_helper.c @@ -3,6 +3,7 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" +#include "qemu/error-report.h" =20 #include "cpu.h" =20 @@ -293,3 +294,257 @@ void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void= *buf, uint32_t buflen) } #endif } + +#define XSTATE_BV_IN_HDR offsetof(X86XSaveHeader, xstate_bv) +#define XCOMP_BV_IN_HDR offsetof(X86XSaveHeader, xcomp_bvo) + +typedef struct X86XSaveAreaView { + /* 512 bytes */ + X86LegacyXSaveArea legacy; + /* 64 bytes */ + X86XSaveHeader header; + /* ...followed by individual xsave areas */ +} X86XSaveAreaView; + +#define XSAVE_XSTATE_BV_OFFSET offsetof(X86XSaveAreaView, header.xstate_b= v) +#define XSAVE_XCOMP_BV_OFFSET offsetof(X86XSaveAreaView, header.xcomp_bv) +#define XSAVE_EXT_OFFSET (sizeof(X86LegacyXSaveArea) + \ + sizeof(X86XSaveHeader)) + +/** + * decompact_xsave_area - Convert compacted XSAVE format to standard format + * @buf: Source buffer containing compacted XSAVE data + * @buflen: Size of source buffer + * @env: CPU state where the standard format buffer will be written to + * + * Accelerator backends like MSHV might return XSAVE state in compacted fo= rmat + * (XSAVEC). The state components have to be packed contiguously without g= aps. + * The XSAVE qemu buffers are in standard format where each component has a + * fixed offset. + * + * Returns: 0 on success, negative errno on failure + */ +int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env) +{ + uint64_t compacted_xstate_bv, compacted_xcomp_bv, compacted_layout_bv; + uint64_t xsave_offset, *xcomp_bv; + size_t i; + uint32_t eax, ebx, ecx, edx; + uint32_t size, dst_off; + bool align64; + uint64_t guest_xcr0, *xstate_bv; + + compacted_xstate_bv =3D *(uint64_t *)(buf + XSAVE_XSTATE_BV_OFFSET); + compacted_xcomp_bv =3D *(uint64_t *)(buf + XSAVE_XCOMP_BV_OFFSET); + + /* This function only handles compacted format (bit 63 set) */ + assert((compacted_xcomp_bv >> 63) & 1); + + /* Low bits of XCOMP_BV describe which components are in the layout */ + compacted_layout_bv =3D compacted_xcomp_bv & ~(1ULL << 63); + + /* Zero out buffer, then copy legacy region (FP + SSE) and header as-i= s */ + memset(env->xsave_buf, 0, env->xsave_buf_len); + memcpy(env->xsave_buf, buf, XSAVE_EXT_OFFSET); + + /* + * We mask XSTATE_BV with the guest's supported XCR0 because: + * 1. Supervisor state (IA32_XSS) is hypervisor-managed, we don't use + * this state for migration. + * 2. Features disabled at partition creation (e.g. AMX) must be exclu= ded + */ + guest_xcr0 =3D ((uint64_t)env->features[FEAT_XSAVE_XCR0_HI] << 32) | + env->features[FEAT_XSAVE_XCR0_LO]; + xstate_bv =3D (uint64_t *)(env->xsave_buf + XSAVE_XSTATE_BV_OFFSET); + *xstate_bv &=3D guest_xcr0; + + /* Clear bit 63 - output is standard format, not compacted */ + xcomp_bv =3D (uint64_t *)(env->xsave_buf + XSAVE_XCOMP_BV_OFFSET); + *xcomp_bv =3D *xcomp_bv & ~(1ULL << 63); + + /* + * Process each extended state component in the compacted layout. + * Components 0 and 1 (FP and SSE) are in the legacy region, so we + * start at component 2. For each component: + * - Calculate its offset in the compacted source (contiguous layout) + * - Get its fixed offset in the standard destination from CPUID + * - Copy if the component has non-init state (bit set in XSTATE_BV) + */ + xsave_offset =3D XSAVE_EXT_OFFSET; + for (i =3D 2; i < 63; i++) { + if (((compacted_layout_bv >> i) & 1) =3D=3D 0) { + continue; + } + + /* Query guest CPUID for this component's size and standard offset= */ + cpu_x86_cpuid(env, 0xD, i, &eax, &ebx, &ecx, &edx); + + size =3D eax; + dst_off =3D ebx; + align64 =3D (ecx & (1u << 1)) !=3D 0; + + /* Component is in the layout but unknown to the guest CPUID model= */ + if (size =3D=3D 0) { + /* + * The hypervisor might expose a component that has no + * representation in the guest CPUID model. We query the host = to + * retrieve the size of the component, so we can skip over it. + */ + host_cpuid(0xD, i, &eax, &ebx, &ecx, &edx); + size =3D eax; + align64 =3D (ecx & (1u << 1)) !=3D 0; + if (size =3D=3D 0) { + error_report("xsave component %zu: size unknown to both " + "guest and host CPUID", i); + return -EINVAL; + } + + if (align64) { + xsave_offset =3D QEMU_ALIGN_UP(xsave_offset, 64); + } + + if (xsave_offset + size > buflen) { + error_report("xsave component %zu overruns source buffer: " + "offset=3D%zu size=3D%u buflen=3D%zu", + i, xsave_offset, size, buflen); + return -E2BIG; + } + + xsave_offset +=3D size; + continue; + } + + if (align64) { + xsave_offset =3D QEMU_ALIGN_UP(xsave_offset, 64); + } + + if ((xsave_offset + size) > buflen) { + error_report("xsave component %zu overruns source buffer: " + "offset=3D%zu size=3D%u buflen=3D%zu", + i, xsave_offset, size, buflen); + return -E2BIG; + } + + if ((dst_off + size) > env->xsave_buf_len) { + error_report("xsave component %zu overruns destination buffer:= " + "offset=3D%u size=3D%u buflen=3D%zu", + i, dst_off, size, (size_t)env->xsave_buf_len); + return -E2BIG; + } + + /* Copy components marked present in XSTATE_BV to guest model */ + if (((compacted_xstate_bv >> i) & 1) !=3D 0) { + memcpy(env->xsave_buf + dst_off, buf + xsave_offset, size); + } + + xsave_offset +=3D size; + } + + return 0; +} + +/** + * compact_xsave_area - Convert standard XSAVE format to compacted format + * @env: CPU state containing the standard format XSAVE buffer + * @buf: Destination buffer for compacted XSAVE data (to send to hyperviso= r) + * @buflen: Size of destination buffer + * + * Accelerator backends like MSHV might expect XSAVE state in compacted fo= rmat + * (XSAVEC). The state components are packed contiguously without gaps. + * The XSAVE qemu buffers are in standard format where each component has a + * fixed offset. + * + * This function converts from standard to compacted format, it accepts a + * pre-allocated destination buffer of sufficient size, it is the + * responsibility of the caller to ensure the buffer is big enough. + * + * Returns: total size of compacted XSAVE data written to @buf + */ +int compact_xsave_area(CPUX86State *env, void *buf, size_t buflen) +{ + uint64_t *xcomp_bv; + size_t i; + uint32_t eax, ebx, ecx, edx; + uint32_t size, src_off; + bool align64; + size_t compact_offset; + uint64_t host_xcr0_mask, guest_xcr0; + + /* Zero out buffer, then copy legacy region (FP + SSE) and header as-i= s */ + memset(buf, 0, buflen); + memcpy(buf, env->xsave_buf, XSAVE_EXT_OFFSET); + + /* + * Set XCOMP_BV to indicate compacted format (bit 63) and which + * components are in the layout. + * + * We must explicitly set XCOMP_BV because x86_cpu_xsave_all_areas() + * produces standard format with XCOMP_BV=3D0 (buffer is zeroed and on= ly + * XSTATE_BV is set in the header). + * + * XCOMP_BV must reflect the partition's XSAVE capability, not the + * guest's current XCR0 (env->xcr0). These differ b/c: + * - A guest's XCR0 is what the guest OS has enabled via XSETBV + * - The partition's XCR0 mask is the hypervisor's save/restore capabi= lity + * + * The hypervisor uses XSAVES which saves based on its capability, so = the + * XCOMP_BV value in the buffer we send back must match that capabilit= y. + * + * We intersect the host XCR0 with the guest's supported XCR0 features + * (FEAT_XSAVE_XCR0_*) so that features disabled at partition creation + * (e.g. AMX) are excluded from the compacted layout. + */ + host_cpuid(0xD, 0, &eax, &ebx, &ecx, &edx); + host_xcr0_mask =3D ((uint64_t)edx << 32) | eax; + guest_xcr0 =3D ((uint64_t)env->features[FEAT_XSAVE_XCR0_HI] << 32) | + env->features[FEAT_XSAVE_XCR0_LO]; + host_xcr0_mask &=3D guest_xcr0; + xcomp_bv =3D buf + XSAVE_XCOMP_BV_OFFSET; + *xcomp_bv =3D host_xcr0_mask | (1ULL << 63); + + /* + * Process each extended state component in the host's XCR0. + * The compacted layout must match XCOMP_BV (host capability). + * + * For each component: + * - Get its size and standard offset from host CPUID + * - Apply 64-byte alignment if required + * - Copy data only if guest has this component (bit set in env->xcr0) + * - Always advance offset to maintain correct layout + */ + compact_offset =3D XSAVE_EXT_OFFSET; + for (i =3D 2; i < 63; i++) { + if (!((host_xcr0_mask >> i) & 1)) { + continue; + } + + /* Query host CPUID for this component's size and standard offset = */ + host_cpuid(0xD, i, &eax, &ebx, &ecx, &edx); + size =3D eax; + src_off =3D ebx; + align64 =3D (ecx >> 1) & 1; + + if (size =3D=3D 0) { + /* Component in host xcr0 but unknown - shouldn't happen */ + continue; + } + + /* Apply 64-byte alignment if required by this component */ + if (align64) { + compact_offset =3D QEMU_ALIGN_UP(compact_offset, 64); + } + + /* + * Only copy data if guest has this component enabled in XCR0. + * Otherwise the component remains zeroed (init state), but we + * still advance the offset to maintain the correct layout. + */ + if ((env->xcr0 >> i) & 1) { + memcpy(buf + compact_offset, env->xsave_buf + src_off, size); + } + + compact_offset +=3D size; + } + + return compact_offset; +} --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274754; cv=none; d=zohomail.com; s=zohoarc; b=aNrypkRupLMjuRXfIcNtTlKSIM0AekDlLIpzQ/6xM3rXpaiudmBQlQR+//lHhRZrekcDQFH5kFRSR3e5E8ExvDu85ayHOmGVSgmrppa+rT4TMGOZvpQ9TV7cczUvvcNYpWLaUtw23pALSweX32Ztg9KeVPcrNWidAdgQG/8t4lA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274754; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=WL7aGhrD9h47rdLHpTc412OkLiLisXW3EZzyJTLGXtA=; b=XuLT86fogGmTEySxdeyGT7KqxE8DiZdHu/jZxvtL9EWRaEuHqC7wg7h3jYxC8iDFMaa/0O+XYD78R8jug22eIRgK+a0bvsnUq0tj5jiyy49AmCWtjPrT3X9+1N+TqmulxL+1QBLTP9ZMXSUNrz5ksQ8GDtGe7jbZ+1Vc4gsOdLo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274754605124.24874733547506; Mon, 23 Mar 2026 07:05:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fsJ-0004Ef-MZ; Mon, 23 Mar 2026 10:03:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fpP-0000vR-4W for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:27 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpK-0007IE-8R for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:20 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 7EACB20B6F20; Mon, 23 Mar 2026 07:00:03 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7EACB20B6F20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274406; bh=WL7aGhrD9h47rdLHpTc412OkLiLisXW3EZzyJTLGXtA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GBWvBSQvLoC3WBwWC0h45O+c/bU66/wvFs3nCeH9dOBaDh3MrqJbaMB0d/3twYolp qvvOrQRf4mxkubIxtdNXWQ89nWGQeQiEHfiBjm2tSgorfRLojL4M5nu+I0Yb4MmhCA QpG9cl4yELEpjCTar2KL9Xfg8mHIvHV2pMlhckrQ= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 29/32] target/i386/mshv: migrate XSAVE state Date: Mon, 23 Mar 2026 14:58:09 +0100 Message-Id: <20260323135812.383509-30-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274755660158500 Content-Type: text/plain; charset="utf-8" We implement fn's that roundtrip XSAVE state in migration. We are using the xsave_helper routines to move individual components from CPUX86State to an xsave_buf and then we have to compact the buffer to XSAVEC format, which is what the hypervisor expects. And the same applies in the other direction for restoring state from the hypervisor. Signed-off-by: Magnus Kulke --- target/i386/cpu.h | 2 +- target/i386/mshv/mshv-cpu.c | 100 +++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index cd5d5a5369..0f30f0dd5b 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2272,7 +2272,7 @@ typedef struct CPUArchState { int64_t user_tsc_khz; /* for sanity check only */ uint64_t apic_bus_freq; uint64_t tsc; -#if defined(CONFIG_KVM) || defined(CONFIG_HVF) +#if defined(CONFIG_KVM) || defined(CONFIG_HVF) || defined(CONFIG_MSHV) void *xsave_buf; uint32_t xsave_buf_len; #endif diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 746987d62b..dacc33674c 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -109,6 +109,78 @@ static enum hv_register_name FPU_REGISTER_NAMES[26] = =3D { =20 static int set_special_regs(const CPUState *cpu); =20 +static int get_xsave_state(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + void *xsavec_buf; + const size_t page =3D HV_HYP_PAGE_SIZE; + size_t xsavec_buf_len =3D page; + + /* TODO: should properly determine xsavec size based on CPUID */ + xsavec_buf =3D qemu_memalign(page, xsavec_buf_len); + memset(xsavec_buf, 0, xsavec_buf_len); + + struct mshv_get_set_vp_state args =3D { + .type =3D MSHV_VP_STATE_XSAVE, + .buf_sz =3D xsavec_buf_len, + .buf_ptr =3D (uintptr_t)xsavec_buf, + }; + + ret =3D ioctl(cpu_fd, MSHV_GET_VP_STATE, &args); + if (ret < 0) { + error_report("failed to get xsave state: %s", strerror(errno)); + return -errno; + } + + ret =3D decompact_xsave_area(xsavec_buf, xsavec_buf_len, env); + g_free(xsavec_buf); + if (ret < 0) { + error_report("failed to decompact xsave area"); + return ret; + } + x86_cpu_xrstor_all_areas(x86cpu, env->xsave_buf, env->xsave_buf_len); + + return 0; +} + +static int set_xsave_state(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + int cpu_fd =3D mshv_vcpufd(cpu); + int ret; + void *xsavec_buf; + size_t page =3D HV_HYP_PAGE_SIZE, xsavec_buf_len; + + /* allocate and populate compacted buffer */ + xsavec_buf =3D qemu_memalign(page, page); + xsavec_buf_len =3D page; + + /* save registers to standard format buffer */ + x86_cpu_xsave_all_areas(x86cpu, env->xsave_buf, env->xsave_buf_len); + + /* store compacted version of xsave area in xsavec_buf */ + compact_xsave_area(env, xsavec_buf, xsavec_buf_len); + + struct mshv_get_set_vp_state args =3D { + .type =3D MSHV_VP_STATE_XSAVE, + .buf_sz =3D xsavec_buf_len, + .buf_ptr =3D (uintptr_t)xsavec_buf, + }; + + ret =3D ioctl(cpu_fd, MSHV_SET_VP_STATE, &args); + g_free(xsavec_buf); + if (ret < 0) { + error_report("failed to set xsave state: %s", strerror(errno)); + return -errno; + } + + return 0; +} + static int get_lapic(CPUState *cpu) { X86CPU *x86cpu =3D X86_CPU(cpu); @@ -766,6 +838,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D get_xsave_state(cpu); + if (ret < 0) { + return ret; + } + ret =3D get_lapic(cpu); if (ret < 0) { return ret; @@ -1284,6 +1361,11 @@ int mshv_arch_store_vcpu_state(const CPUState *cpu) return ret; } =20 + ret =3D set_xsave_state(cpu); + if (ret < 0) { + return ret; + } + /* INVARIANT: special regs (APIC_BASE) must be restored before LAPIC */ ret =3D set_lapic(cpu); if (ret < 0) { @@ -1812,9 +1894,10 @@ void mshv_arch_init_vcpu(CPUState *cpu) X86CPU *x86_cpu =3D X86_CPU(cpu); CPUX86State *env =3D &x86_cpu->env; AccelCPUState *state =3D cpu->accel; - size_t page =3D HV_HYP_PAGE_SIZE; + size_t page =3D HV_HYP_PAGE_SIZE, xsave_len; void *mem =3D qemu_memalign(page, 2 * page); int ret; + X86XSaveHeader *header; =20 /* sanity check, to make sure we don't overflow the page */ QEMU_BUILD_BUG_ON((MAX_REGISTER_COUNT @@ -1828,6 +1911,17 @@ void mshv_arch_init_vcpu(CPUState *cpu) =20 env->emu_mmio_buf =3D g_new(char, 4096); =20 + /* Initialize XSAVE buffer page-aligned */ + /* TODO: pick proper size based on CPUID */ + xsave_len =3D page; + env->xsave_buf =3D qemu_memalign(page, xsave_len); + env->xsave_buf_len =3D xsave_len; + memset(env->xsave_buf, 0, env->xsave_buf_len); + + /* we need to set the compacted format bit in xsave header for mshv */ + header =3D (X86XSaveHeader *)(env->xsave_buf + sizeof(X86LegacyXSaveAr= ea)); + header->xcomp_bv =3D header->xstate_bv | (1ULL << 63); + /* * TODO: populate topology info: * X86CPUTopoInfo *topo_info =3D &env->topo_info; @@ -1852,6 +1946,10 @@ void mshv_arch_destroy_vcpu(CPUState *cpu) g_free(state->hvcall_args.base); state->hvcall_args =3D (MshvHvCallArgs){0}; g_clear_pointer(&env->emu_mmio_buf, g_free); + + qemu_vfree(env->xsave_buf); + env->xsave_buf =3D NULL; + env->xsave_buf_len =3D 0; } =20 /* --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274751; cv=none; d=zohomail.com; s=zohoarc; b=STlfhXvDFFvfMk7WY1/aMkqsWYa4hwjvbg9HTPq1ab6fw0qU/v6i4ivvuvh6Sy82JmB2v4TMPRRps60JBTWi65p6KXRSCurFryhOrhJAKsYxRfthpnyT+tCBtinMlHyCENUkfb8SHnsZBkAHAtUmreiAdDRf9WcNdaKGKMKj7Bk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274751; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=i1SaRdeL8nyaeXZZpzUNqErLAZluVvPxmogP/V/TiJQ=; b=Hje/D3ygU0rInCX2g65qziPVk14HKqJ5LDe5ukH17d/pC4iIrDWIWtHpJHpbPTilDw7CVYXMAqcR5EM56sT0oO81zCnYZd+wZb1MI0fa14BPVLdBbxF5zNHFNwcDuOVwWpfCB8QKErRFzUmMUfXRxNg55Y15XZ2c6nf/X0WJOXg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274751165325.95523669375757; Mon, 23 Mar 2026 07:05:51 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4frY-0002AW-Di; Mon, 23 Mar 2026 10:02:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fpQ-0000wg-J9 for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:28 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpO-0007Ii-3N for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:24 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id AD06220B6F15; Mon, 23 Mar 2026 07:00:07 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com AD06220B6F15 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274410; bh=i1SaRdeL8nyaeXZZpzUNqErLAZluVvPxmogP/V/TiJQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NnAdnNO0JkPCxghel2ozc28fvTtEn1BuZVgT0SHgDCMhWsoWNoHNtGTFtjkFC2tyG ma1lXudtzN9B1ql+G9K7y15vCNc7QMxg0+MVosPeW4zHaUWi/Lws7GbKsZ590ashrG IG4E2VAgl1qE9rljl1yM5La1Gt2cHJkzNGng4NN0= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 30/32] target/i386/mshv: reconstruct hflags after load Date: Mon, 23 Mar 2026 14:58:10 +0100 Message-Id: <20260323135812.383509-31-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274751557158500 Content-Type: text/plain; charset="utf-8" hflags is a cached bitmap derived from standard and special regs. We want to reconstruct this state after regs and sregs have been read from the hypervisor, similar to how it's one in other accelerators. Signed-off-by: Magnus Kulke --- target/i386/mshv/mshv-cpu.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index dacc33674c..80e5dd5a4b 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -814,6 +814,16 @@ static int set_vcpu_events(const CPUState *cpu) return 0; } =20 +static int update_hflags(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + + x86_update_hflags(env); + + return 0; +} + int mshv_arch_load_vcpu_state(CPUState *cpu) { int ret; @@ -828,6 +838,9 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + /* INVARIANT: hflags are derived from regs+sregs, need to get both fir= st */ + update_hflags(cpu); + ret =3D get_xc_reg(cpu); if (ret < 0) { return ret; --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274609; cv=none; d=zohomail.com; s=zohoarc; b=dPqUQSZNWTuLBg3ZftFXDK3mXz9oL0C+7Xj9nD8c/PAG7apPYJ2Mh+PgQmIJt5zD6j+Cm6p85JE210fooeDNVlr8EeTcOagbMAu5yLib8PBaPueINkueFMsAwc27WURvGiD1CHPK3YdqS9Zb1IxzTX40T8o+jQmCGFchDFdpxNQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274609; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=9BS8GXf6VR6ZaAFlkE7y0tvwO0EDUtmobElH9h7DNf8=; b=UpAPnxZ4ecx3H0FaHLny1JLk2oX5+y+Sg8rCKMX9I8X6SPvz9DF912k3Y4Ccv4XUeVaJ5dwzxU76xz+eg/ya8MrwyXMrgPR+N6fRsOcNZJHgQJc5Is4vwL+yTyctJo6gisnjb9P9pSR1ruvRTx2J7pktevQ48kAV/kvh1hrYG3E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274609697670.7118838019842; Mon, 23 Mar 2026 07:03:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fsH-0003mx-8b; Mon, 23 Mar 2026 10:03:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fpS-0000ws-Ly for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:29 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpR-0007JF-1i for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:26 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 25AB420B6F1B; Mon, 23 Mar 2026 07:00:10 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 25AB420B6F1B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274414; bh=9BS8GXf6VR6ZaAFlkE7y0tvwO0EDUtmobElH9h7DNf8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OIoGS9GKpf2Umk6z462NM92lu9gamDiTmGQtjQ/nKrxFTDphm8IElsq/7FcPNUMK9 L6SxxFIeWcR/ozR2uJ+v6ksidX1l1NfVLw88XDwip7QLRk7dV+MWttY2oVu83Cw/5M Y38sZ0w+b+uYSLl5FreenHD/iE8rXgbGOLN3Rix4= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 31/32] target/i386/mshv: migrate MP_STATE Date: Mon, 23 Mar 2026 14:58:11 +0100 Message-Id: <20260323135812.383509-32-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274610493158500 Content-Type: text/plain; charset="utf-8" MSHV's "internal activity state" roughly maps to QEMU's env->mp_state and cpu->halted states that describe state of APs in a guest. We don't invoke set_mp_state as part of store_vcpu_state() b/c we would put all BSP + APs in a RUNNABLE (0) state immediately, breaking SMP boot Instead we store the mp state as part of the load_cleanup() routine after a migration. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 10 +++++ include/system/mshv_int.h | 1 + target/i386/mshv/mshv-cpu.c | 80 +++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 3927a82925..45fe1ef468 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -205,6 +205,7 @@ static int mshv_load_setup(QEMUFile *f, void *opaque, E= rror **errp) static int mshv_load_cleanup(void *opaque) { MshvState *s =3D opaque; + CPUState *cpu; int ret; =20 ret =3D mshv_arch_set_partition_msrs(first_cpu); @@ -213,6 +214,15 @@ static int mshv_load_cleanup(void *opaque) return -1; } =20 + CPU_FOREACH(cpu) { + ret =3D mshv_arch_set_mp_state(cpu); + if (ret < 0) { + error_report("Failed to set mp state for vCPU %d: %s", + cpu->cpu_index, strerror(-ret)); + return -1; + } + } + resume_vm(s->vm); =20 return 0; diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index bc16b794b2..c24efc8675 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -98,6 +98,7 @@ int mshv_get_generic_regs(CPUState *cpu, hv_register_asso= c *assocs, int mshv_arch_store_vcpu_state(const CPUState *cpu); int mshv_arch_load_vcpu_state(CPUState *cpu); int mshv_arch_set_partition_msrs(const CPUState *cpu); +int mshv_arch_set_mp_state(const CPUState *cpu); void mshv_arch_init_vcpu(CPUState *cpu); void mshv_arch_destroy_vcpu(CPUState *cpu); void mshv_arch_amend_proc_features( diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 80e5dd5a4b..c2c217372a 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -33,6 +33,11 @@ =20 #include =20 +#define MSHV_MP_STATE_RUNNABLE 0 +#define MSHV_MP_STATE_UNINITIALIZED 1 +#define MSHV_MP_STATE_INIT_RECEIVED 2 +#define MSHV_MP_STATE_HALTED 3 + #define MAX_REGISTER_COUNT (MAX_CONST(ARRAY_SIZE(STANDARD_REGISTER_NAMES),= \ MAX_CONST(ARRAY_SIZE(SPECIAL_REGISTER_NAMES), \ ARRAY_SIZE(FPU_REGISTER_NAMES)))) @@ -814,6 +819,76 @@ static int set_vcpu_events(const CPUState *cpu) return 0; } =20 +static int get_mp_state(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + struct hv_register_assoc assoc =3D { + .name =3D HV_REGISTER_INTERNAL_ACTIVITY_STATE, + }; + union hv_internal_activity_register activity; + int ret; + + ret =3D mshv_get_generic_regs(cpu, &assoc, 1); + if (ret < 0) { + error_report("failed to get internal activity state"); + return -1; + } + + activity.as_uint64 =3D assoc.value.reg64; + + /* + * map MSHV activity state to KVM mp_state values, which are used as t= he + * shared representation in env->mp_state and serialized by vmstate_x8= 6_cpu. + */ + + if (activity.startup_suspend) { + env->mp_state =3D MSHV_MP_STATE_UNINITIALIZED; + } else if (activity.halt_suspend) { + env->mp_state =3D MSHV_MP_STATE_HALTED; + } else { + env->mp_state =3D MSHV_MP_STATE_RUNNABLE; + } + + cpu->halted =3D (env->mp_state =3D=3D MSHV_MP_STATE_HALTED); + + return 0; +} + +int mshv_arch_set_mp_state(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + union hv_internal_activity_register activity =3D { 0 }; + struct hv_register_assoc assoc =3D { + .name =3D HV_REGISTER_INTERNAL_ACTIVITY_STATE, + }; + int ret; + + switch (env->mp_state) { + case MSHV_MP_STATE_HALTED: + activity.halt_suspend =3D 1; + break; + case MSHV_MP_STATE_UNINITIALIZED: + case MSHV_MP_STATE_INIT_RECEIVED: + activity.startup_suspend =3D 1; + break; + case MSHV_MP_STATE_RUNNABLE: + default: + break; + } + + assoc.value.reg64 =3D activity.as_uint64; + + ret =3D mshv_set_generic_regs(cpu, &assoc, 1); + if (ret < 0) { + error_report("failed to set internal activity state"); + return -1; + } + + return 0; +} + static int update_hflags(CPUState *cpu) { X86CPU *x86cpu =3D X86_CPU(cpu); @@ -876,6 +951,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D get_mp_state(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 --=20 2.34.1 From nobody Fri Apr 3 20:54:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274607; cv=none; d=zohomail.com; s=zohoarc; b=CM50dssAeO1hDbNU6IgMNfP6r/E0eQBUsq/J8BfZkpMM7/k7DNGjVbPKV7ymskuy0pvtJ9/Y0ajUYLAkG2iZSO/v9XvOGUnkTbFumRTcRgfgqqE5L8w2bxdtWhFE95Ab1Lo68oQ9q6M8IY/KMV5ZE480kS2BeQ4SDu8qUy99CSg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274607; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ZOKMgpZvx3abEQdJCz++yqLR/8YcM3C1DO/6gvmwcn8=; b=YYS4DGiSeQuLzt+Mp8Wjbl5yblzYyRbIuZL7LSp1ja1naWA3IwglfMjb70Bm13+XLrtkIK9fw6+ItoQK+8hr/FHppPjXIV/3MzNeCTBhs47P3nvm5n5tnp6GpmIBn/bdQI/cmtstXX4KjkPQzyfjlS0rS0qGy43rk9BWwp0JlVw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274607882146.23880890952; Mon, 23 Mar 2026 07:03:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fry-0003G1-IZ; Mon, 23 Mar 2026 10:03:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fph-00017j-Oi for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:45 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpV-0007Jl-6Z for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:31 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id B723320B6F0C; Mon, 23 Mar 2026 07:00:14 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com B723320B6F0C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274417; bh=ZOKMgpZvx3abEQdJCz++yqLR/8YcM3C1DO/6gvmwcn8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RzbTvFBnANB0PBLvvjyPiezmuOZ8V87zlr4HkR+zgBsOkUCO+4NSdoFLwNOnhlyd9 JukQlPZtRvXBTWcxe3sxvaIxynSBnT7P2ehejkdWif5w2PYn3Rq1qDQFXG6EKU+WHf pwyw8Jj0V7csMTmyUH+AmQ8fCE2lCEGWIrUtbuyA= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 32/32] accel/mshv: enable dirty page tracking Date: Mon, 23 Mar 2026 14:58:12 +0100 Message-Id: <20260323135812.383509-33-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274608498158501 Content-Type: text/plain; charset="utf-8" This change introduces the functions required to perform dirty page tracking to speed up migrations. We are using the sync, global_start, and global_stop hooks. The sync is implemented in batches. Before we can disable the dirty page tracking we have to set all dirty bits. Signed-off-by: Magnus Kulke --- accel/mshv/mem.c | 211 ++++++++++++++++++++++++++++++++++++++ accel/mshv/mshv-all.c | 3 + include/system/mshv_int.h | 5 + 3 files changed, 219 insertions(+) diff --git a/accel/mshv/mem.c b/accel/mshv/mem.c index e55c38d4db..820f87ef0c 100644 --- a/accel/mshv/mem.c +++ b/accel/mshv/mem.c @@ -12,10 +12,13 @@ =20 #include "qemu/osdep.h" #include "qemu/error-report.h" +#include "qapi/error.h" #include "linux/mshv.h" #include "system/address-spaces.h" #include "system/mshv.h" #include "system/mshv_int.h" +#include "hw/hyperv/hvhdk_mini.h" +#include "system/physmem.h" #include "exec/memattrs.h" #include #include "trace.h" @@ -211,3 +214,211 @@ void mshv_set_phys_mem(MshvMemoryListener *mml, Memor= yRegionSection *section, abort(); } } + +static int enable_dirty_page_tracking(int vm_fd) +{ + int ret; + struct hv_input_set_partition_property in =3D {0}; + struct mshv_root_hvcall args =3D {0}; + + in.property_code =3D HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING; + in.property_value =3D 1; + + args.code =3D HVCALL_SET_PARTITION_PROPERTY; + args.in_sz =3D sizeof(in); + args.in_ptr =3D (uint64_t)∈ + + ret =3D mshv_hvcall(vm_fd, &args); + if (ret < 0) { + error_report("Failed to enable dirty page tracking: %s", + strerror(errno)); + return -1; + } + + return 0; +} + +/* + * Retrieve dirty page bitmap for a GPA range, clearing the dirty bits + * atomically. Large ranges are handled in batches. + */ +static int get_dirty_log(int vm_fd, uint64_t base_pfn, uint64_t page_count, + unsigned long *bitmap, size_t bitmap_size) +{ + uint64_t batch, bitmap_offset, completed =3D 0; + struct mshv_gpap_access_bitmap args =3D {0}; + int ret; + + QEMU_BUILD_BUG_ON(MSHV_DIRTY_PAGES_BATCH_SIZE % BITS_PER_LONG !=3D 0); + assert(bitmap_size >=3D ROUND_UP(page_count, BITS_PER_LONG) / 8); + + while (completed < page_count) { + batch =3D MIN(MSHV_DIRTY_PAGES_BATCH_SIZE, page_count - completed); + bitmap_offset =3D completed / BITS_PER_LONG; + + args.access_type =3D MSHV_GPAP_ACCESS_TYPE_DIRTY; + args.access_op =3D MSHV_GPAP_ACCESS_OP_CLEAR; + args.page_count =3D batch; + args.gpap_base =3D base_pfn + completed; + args.bitmap_ptr =3D (uint64_t)(bitmap + bitmap_offset); + + ret =3D ioctl(vm_fd, MSHV_GET_GPAP_ACCESS_BITMAP, &args); + if (ret < 0) { + error_report("Failed to get dirty log (base_pfn=3D0x%" PRIx64 + " batch=3D%" PRIu64 "): %s", + base_pfn + completed, batch, strerror(errno)); + return -1; + } + completed +=3D batch; + } + + return 0; +} + +bool mshv_log_global_start(MemoryListener *listener, Error **errp) +{ + int ret; + + ret =3D enable_dirty_page_tracking(mshv_state->vm); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to enable dirty page tracking= "); + return false; + } + return true; +} + +static int disable_dirty_page_tracking(int vm_fd) +{ + int ret; + struct hv_input_set_partition_property in =3D {0}; + struct mshv_root_hvcall args =3D {0}; + + in.property_code =3D HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING; + in.property_value =3D 0; + + args.code =3D HVCALL_SET_PARTITION_PROPERTY; + args.in_sz =3D sizeof(in); + args.in_ptr =3D (uint64_t)∈ + + ret =3D mshv_hvcall(vm_fd, &args); + if (ret < 0) { + error_report("Failed to disable dirty page tracking: %s", + strerror(errno)); + return -1; + } + + return 0; +} + +static int set_dirty_pages(int vm_fd, uint64_t base_pfn, uint64_t page_cou= nt) +{ + uint64_t batch, completed =3D 0; + unsigned long bitmap[MSHV_DIRTY_PAGES_BATCH_SIZE / BITS_PER_LONG]; + struct mshv_gpap_access_bitmap args =3D {0}; + int ret; + + while (completed < page_count) { + batch =3D MIN(MSHV_DIRTY_PAGES_BATCH_SIZE, page_count - completed); + + args.access_type =3D MSHV_GPAP_ACCESS_TYPE_DIRTY; + args.access_op =3D MSHV_GPAP_ACCESS_OP_SET; + args.page_count =3D batch; + args.gpap_base =3D base_pfn + completed; + args.bitmap_ptr =3D (uint64_t)bitmap; + + ret =3D ioctl(vm_fd, MSHV_GET_GPAP_ACCESS_BITMAP, &args); + if (ret < 0) { + error_report("Failed to set dirty pages (base_pfn=3D0x%" PRIx64 + " batch=3D%" PRIu64 "): %s", + base_pfn + completed, batch, strerror(errno)); + return -1; + } + completed +=3D batch; + } + + return 0; +} + +static bool set_dirty_bits_cb(Int128 start, Int128 len, const MemoryRegion= *mr, + hwaddr offset_in_region, void *opaque) +{ + int ret, *errp =3D opaque; + hwaddr gpa, size; + uint64_t page_count, base_pfn; + + gpa =3D int128_get64(start); + size =3D int128_get64(len); + page_count =3D size >> MSHV_PAGE_SHIFT; + base_pfn =3D gpa >> MSHV_PAGE_SHIFT; + + if (!mr->ram || mr->readonly) { + return false; + } + + if (page_count =3D=3D 0) { + return false; + } + + ret =3D set_dirty_pages(mshv_state->vm, base_pfn, page_count); + + /* true aborts the iteration, which is what we want if there's an erro= r */ + if (ret < 0) { + *errp =3D ret; + return true; + } + + return false; +} + +void mshv_log_global_stop(MemoryListener *listener) +{ + int err =3D 0; + /* MSHV requires all dirty bits to be set before disabling tracking. */ + FlatView *fv =3D address_space_to_flatview(&address_space_memory); + flatview_for_each_range(fv, set_dirty_bits_cb, &err); + + if (err < 0) { + error_report("Failed to set dirty bits before disabling tracking"); + } + + disable_dirty_page_tracking(mshv_state->vm); +} + +void mshv_log_sync(MemoryListener *listener, MemoryRegionSection *section) +{ + hwaddr size, start_addr, mr_offset; + uint64_t page_count, base_pfn; + size_t bitmap_size; + unsigned long *bitmap; + ram_addr_t ram_addr; + int ret; + MemoryRegion *mr =3D section->mr; + + if (!memory_region_is_ram(mr) || memory_region_is_rom(mr)) { + return; + } + + size =3D align_section(section, &start_addr); + if (!size) { + return; + } + + page_count =3D size >> MSHV_PAGE_SHIFT; + base_pfn =3D start_addr >> MSHV_PAGE_SHIFT; + bitmap_size =3D ROUND_UP(page_count, BITS_PER_LONG) / 8; + bitmap =3D g_malloc0(bitmap_size); + + ret =3D get_dirty_log(mshv_state->vm, base_pfn, page_count, bitmap, + bitmap_size); + if (ret < 0) { + g_free(bitmap); + return; + } + + mr_offset =3D section->offset_within_region + start_addr - + section->offset_within_address_space; + ram_addr =3D memory_region_get_ram_addr(mr) + mr_offset; + + physical_memory_set_dirty_lebitmap(bitmap, ram_addr, page_count); + g_free(bitmap); +} diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 45fe1ef468..87ed785302 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -546,6 +546,9 @@ static MemoryListener mshv_memory_listener =3D { .region_del =3D mem_region_del, .eventfd_add =3D mem_ioeventfd_add, .eventfd_del =3D mem_ioeventfd_del, + .log_sync =3D mshv_log_sync, + .log_global_start =3D mshv_log_global_start, + .log_global_stop =3D mshv_log_global_stop, }; =20 static MemoryListener mshv_io_listener =3D { diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index c24efc8675..ddbdd76076 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -31,6 +31,8 @@ struct mshv_get_set_vp_state; #define MSHV_HV_INTERRUPTION_TYPE_PRIV_SW_EXC 5 #define MSHV_HV_INTERRUPTION_TYPE_SW_EXC 6 =20 +#define MSHV_DIRTY_PAGES_BATCH_SIZE 0x10000 + typedef struct hyperv_message hv_message; =20 typedef struct MshvHvCallArgs { @@ -128,6 +130,9 @@ int mshv_guest_mem_write(uint64_t gpa, const uint8_t *d= ata, uintptr_t size, bool is_secure_mode); void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *secti= on, bool add); +void mshv_log_sync(MemoryListener *listener, MemoryRegionSection *section); +bool mshv_log_global_start(MemoryListener *listener, Error **errp); +void mshv_log_global_stop(MemoryListener *listener); =20 /* msr */ int mshv_init_msrs(const CPUState *cpu); --=20 2.34.1