* [PATCH 00/10] Support QEMU cpu models in MSHV accelerator
@ 2026-02-11 15:54 Magnus Kulke
2026-02-11 15:54 ` [PATCH 01/10] MAINTAINERS: fix magnuskulke email-address Magnus Kulke
` (10 more replies)
0 siblings, 11 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
Hey all,
In the current MSHV accelerator code passing CPU features via the -cpu
flag doesn't work as intended yet. When using the MSHV hypervisor we
either silently discard the specified model/features and leave it up
to the hypervisor to provide a sensible set of features or if the user
selects -cpu host, the hypervisor might refuse to create a partition.
This changeset introduces a more comprehensive support for passing
desired guest cpu features to the hypervisor. It's also a prerequisite
for Live Migration support, in which we have to roundtrip CPU State
explicitly
Known issues:
We will probably have to iterate a bit more on this, since recently
support for CET_U/CET_S xstate bits has been introduced in QEMU, which
doesn't harmonize with our current approach of configuring the
hypervisor with static responses to cpuid queries.
Drive-by fixes:
- tiny fix in MAINTAINERS
- adding packed attribute to inlined UAPI structs
best,
magnus
Magnus Kulke (10):
MAINTAINERS: fix magnuskulke email-address
include/hw/hyperv: add QEMU_PACKED to uapi structs
accel/mshv: use mshv_create_partition_v2 payload
target/i386/mshv: fix cpuid propagation bug
target/i386/mshv: fix various cpuid traversal bugs
target/i386/mshv: change cpuid mask to UINT32_MAX
target/i386/mshv: set cpu model name on -cpu host
target/i386: query mshv accel for supported cpuids
target/i386/mshv: populate xsave area offsets
target/i386/mshv: filter out CET bits in cpuid
MAINTAINERS | 4 +-
accel/mshv/mshv-all.c | 35 ++++--
include/hw/hyperv/hvgdk_mini.h | 39 ++++--
include/hw/hyperv/hvhdk.h | 199 ++++++++++++++++++++++++++++-
include/system/mshv.h | 3 +
target/i386/cpu.c | 8 ++
target/i386/mshv/mshv-cpu.c | 221 ++++++++++++++++++++++++++-------
7 files changed, 438 insertions(+), 71 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/10] MAINTAINERS: fix magnuskulke email-address
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-03-03 12:14 ` Peter Maydell
2026-02-11 15:54 ` [PATCH 02/10] include/hw/hyperv: add QEMU_PACKED to uapi structs Magnus Kulke
` (9 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
Consolidating email aliases.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
MAINTAINERS | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 29f88d48f3..6272d32ed4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -569,7 +569,7 @@ F: accel/stubs/whpx-stub.c
F: include/system/whpx.h
MSHV
-M: Magnus Kulke <magnus.kulke@linux.microsoft.com>
+M: Magnus Kulke <magnuskulke@linux.microsoft.com>
R: Wei Liu <wei.liu@kernel.org>
S: Supported
F: accel/mshv/
@@ -578,7 +578,7 @@ F: include/hw/hyperv/hvgdk*.h
F: include/hw/hyperv/hvhdk*.h
X86 MSHV CPUs
-M: Magnus Kulke <magnus.kulke@linux.microsoft.com>
+M: Magnus Kulke <magnuskulke@linux.microsoft.com>
R: Wei Liu <wei.liu@kernel.org>
S: Supported
F: target/i386/mshv/
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 02/10] include/hw/hyperv: add QEMU_PACKED to uapi structs
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
2026-02-11 15:54 ` [PATCH 01/10] MAINTAINERS: fix magnuskulke email-address Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-02-11 15:54 ` [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload Magnus Kulke
` (8 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
The uapi definitions are marked with __packed hints in the kernel
headers, since we want to keep the contract of the Microsoft Hypervisor
ABI explicit, we should also added them in our vendored files, with a
few notable exceptions where the attribute is a noop.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
include/hw/hyperv/hvgdk_mini.h | 37 ++++++++++++++++++++++------------
include/hw/hyperv/hvhdk.h | 14 +++++++------
2 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h
index cb52cc9de2..7d7b2e9b36 100644
--- a/include/hw/hyperv/hvgdk_mini.h
+++ b/include/hw/hyperv/hvgdk_mini.h
@@ -7,6 +7,8 @@
#ifndef HW_HYPERV_HVGDK_MINI_H
#define HW_HYPERV_HVGDK_MINI_H
+#include "qemu/compiler.h"
+
#define MSHV_IOCTL 0xB8
typedef enum hv_register_name {
@@ -211,7 +213,7 @@ enum hv_intercept_type {
struct hv_u128 {
uint64_t low_part;
uint64_t high_part;
-};
+} QEMU_PACKED;
union hv_x64_xmm_control_status_register {
struct hv_u128 as_uint128;
@@ -326,13 +328,13 @@ typedef struct hv_x64_segment_register {
};
uint16_t attributes;
};
-} hv_x64_segment_register;
+} QEMU_PACKED hv_x64_segment_register;
typedef struct hv_x64_table_register {
uint16_t pad[3];
uint16_t limit;
uint64_t base;
-} hv_x64_table_register;
+} QEMU_PACKED hv_x64_table_register;
union hv_x64_fp_control_status_register {
struct hv_u128 as_uint128;
@@ -416,6 +418,10 @@ typedef union hv_register_value {
union hv_x64_register_sev_control sev_control;
} hv_register_value;
+/*
+ * This struct is __packed in the kernel. Since all members are naturally
+ * aligned, we can omit QEMU_PACKED to avoid address-of-packed-member warnings.
+ */
typedef struct hv_register_assoc {
uint32_t name; /* enum hv_register_name */
uint32_t reserved1;
@@ -439,7 +445,7 @@ typedef struct hv_input_get_vp_registers {
uint8_t rsvd_z8;
uint16_t rsvd_z16;
uint32_t names[];
-} hv_input_get_vp_registers;
+} QEMU_PACKED hv_input_get_vp_registers;
typedef struct hv_input_set_vp_registers {
uint64_t partition_id;
@@ -448,7 +454,7 @@ typedef struct hv_input_set_vp_registers {
uint8_t rsvd_z8;
uint16_t rsvd_z16;
struct hv_register_assoc elements[];
-} hv_input_set_vp_registers;
+} QEMU_PACKED hv_input_set_vp_registers;
union hv_interrupt_control {
uint64_t as_uint64;
@@ -468,7 +474,7 @@ struct hv_input_assert_virtual_interrupt {
uint8_t target_vtl;
uint8_t rsvd_z0;
uint16_t rsvd_z1;
-};
+} QEMU_PACKED;
/* /dev/mshv */
#define MSHV_CREATE_PARTITION _IOW(MSHV_IOCTL, 0x00, struct mshv_create_partition)
@@ -487,6 +493,11 @@ struct hv_input_assert_virtual_interrupt {
********************************
*/
+/*
+ * This struct is __packed in the kernel, but since all members are naturally
+ * aligned, so we can omit QEMU_PACKED to avoid address-of-packed-member
+ * warnings.
+ */
struct hv_local_interrupt_controller_state {
/* HV_X64_INTERRUPT_CONTROLLER_STATE */
uint32_t apic_id;
@@ -644,7 +655,7 @@ struct hv_x64_intercept_message_header {
struct hv_x64_segment_register cs_segment;
uint64_t rip;
uint64_t rflags;
-};
+} QEMU_PACKED;
union hv_x64_io_port_access_info {
uint8_t as_uint8;
@@ -669,7 +680,7 @@ typedef struct hv_x64_io_port_intercept_message {
uint64_t rcx;
uint64_t rsi;
uint64_t rdi;
-} hv_x64_io_port_intercept_message;
+} QEMU_PACKED hv_x64_io_port_intercept_message;
union hv_x64_memory_access_info {
uint8_t as_uint8;
@@ -692,7 +703,7 @@ struct hv_x64_memory_intercept_message {
uint64_t guest_virtual_address;
uint64_t guest_physical_address;
uint8_t instruction_bytes[16];
-};
+} QEMU_PACKED;
union hv_message_flags {
uint8_t asu8;
@@ -711,14 +722,14 @@ struct hv_message_header {
uint64_t sender;
union hv_port_id port;
};
-};
+} QEMU_PACKED;
struct hv_message {
struct hv_message_header header;
union {
uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
} u;
-};
+} QEMU_PACKED;
/* From github.com/rust-vmm/mshv-bindings/src/x86_64/regs.rs */
@@ -731,13 +742,13 @@ struct hv_cpuid_entry {
uint32_t ecx;
uint32_t edx;
uint32_t padding[3];
-};
+} QEMU_PACKED;
struct hv_cpuid {
uint32_t nent;
uint32_t padding;
struct hv_cpuid_entry entries[0];
-};
+} QEMU_PACKED;
#define IA32_MSR_TSC 0x00000010
#define IA32_MSR_EFER 0xC0000080
diff --git a/include/hw/hyperv/hvhdk.h b/include/hw/hyperv/hvhdk.h
index 866c8211bf..bf2f8cbc27 100644
--- a/include/hw/hyperv/hvhdk.h
+++ b/include/hw/hyperv/hvhdk.h
@@ -9,6 +9,8 @@
#ifndef HW_HYPERV_HVHDK_H
#define HW_HYPERV_HVHDK_H
+#include "qemu/compiler.h"
+
#define HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS 1
struct hv_input_set_partition_property {
@@ -16,7 +18,7 @@ struct hv_input_set_partition_property {
uint32_t property_code; /* enum hv_partition_property_code */
uint32_t padding;
uint64_t property_value;
-};
+} QEMU_PACKED;
union hv_partition_synthetic_processor_features {
uint64_t as_uint64[HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS];
@@ -201,12 +203,12 @@ typedef struct hv_input_translate_virtual_address {
uint32_t padding;
uint64_t control_flags;
uint64_t gva_page;
-} hv_input_translate_virtual_address;
+} QEMU_PACKED hv_input_translate_virtual_address;
typedef struct hv_output_translate_virtual_address {
union hv_translate_gva_result translation_result;
uint64_t gpa_page;
-} hv_output_translate_virtual_address;
+} QEMU_PACKED hv_output_translate_virtual_address;
typedef struct hv_register_x64_cpuid_result_parameters {
struct {
@@ -226,13 +228,13 @@ typedef struct hv_register_x64_cpuid_result_parameters {
uint32_t edx;
uint32_t edx_mask;
} result;
-} hv_register_x64_cpuid_result_parameters;
+} QEMU_PACKED hv_register_x64_cpuid_result_parameters;
typedef struct hv_register_x64_msr_result_parameters {
uint32_t msr_index;
uint32_t access_type;
uint32_t action; /* enum hv_unimplemented_msr_action */
-} hv_register_x64_msr_result_parameters;
+} QEMU_PACKED hv_register_x64_msr_result_parameters;
union hv_register_intercept_result_parameters {
struct hv_register_x64_cpuid_result_parameters cpuid;
@@ -244,6 +246,6 @@ typedef struct hv_input_register_intercept_result {
uint32_t vp_index;
uint32_t intercept_type; /* enum hv_intercept_type */
union hv_register_intercept_result_parameters parameters;
-} hv_input_register_intercept_result;
+} QEMU_PACKED hv_input_register_intercept_result;
#endif /* HW_HYPERV_HVHDK_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
2026-02-11 15:54 ` [PATCH 01/10] MAINTAINERS: fix magnuskulke email-address Magnus Kulke
2026-02-11 15:54 ` [PATCH 02/10] include/hw/hyperv: add QEMU_PACKED to uapi structs Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-02-11 23:43 ` Mohamed Mediouni
2026-02-12 13:32 ` Anirudh Rayabharam
2026-02-11 15:54 ` [PATCH 04/10] target/i386/mshv: fix cpuid propagation bug Magnus Kulke
` (7 subsequent siblings)
10 siblings, 2 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
When using the extended request format we can instruct the hypervisor to
provision enough space for requested XSAVE features. This is required
for supporting QEMU models provided via the -cpu flag properly.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
accel/mshv/mshv-all.c | 35 +++++--
include/hw/hyperv/hvgdk_mini.h | 2 +
include/hw/hyperv/hvhdk.h | 185 +++++++++++++++++++++++++++++++++
3 files changed, 214 insertions(+), 8 deletions(-)
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
index bed0fa298e..8446f7128a 100644
--- a/accel/mshv/mshv-all.c
+++ b/accel/mshv/mshv-all.c
@@ -112,19 +112,38 @@ static int resume_vm(int vm_fd)
static int create_partition(int mshv_fd, int *vm_fd)
{
- int ret;
- struct mshv_create_partition args = {0};
+ int ret, i;
+ uint64_t pt_flags;
+ union hv_partition_processor_xsave_features disabled_xsave_features;
+ union hv_partition_processor_features disabled_processor_features;
+ struct mshv_create_partition_v2 args = {0};
/* Initialize pt_flags with the desired features */
- uint64_t pt_flags = (1ULL << MSHV_PT_BIT_LAPIC) |
- (1ULL << MSHV_PT_BIT_X2APIC) |
- (1ULL << MSHV_PT_BIT_GPA_SUPER_PAGES);
+ pt_flags = (1ULL << MSHV_PT_BIT_LAPIC) |
+ (1ULL << MSHV_PT_BIT_X2APIC) |
+ (1ULL << MSHV_PT_BIT_GPA_SUPER_PAGES) |
+ (1ULL << MSHV_PT_BIT_CPU_AND_XSAVE_FEATURES);
- /* Set default isolation type */
- uint64_t pt_isolation = MSHV_PT_ISOLATION_NONE;
+ /* enable all */
+ disabled_xsave_features.as_uint64 = 0;
+ /* Enable all proc features by default */
+ for (i = 0; i < MSHV_NUM_CPU_FEATURES_BANKS; i++) {
+ disabled_processor_features.as_uint64[i] = 0;
+ }
+ disabled_processor_features.reserved_bank0 = 1;
+ for (i = 0; i < MSHV_NUM_CPU_FEATURES_BANKS; i++) {
+ disabled_processor_features.as_uint64[i] = 0;
+ }
+
+ /* populate args structure */
args.pt_flags = pt_flags;
- args.pt_isolation = pt_isolation;
+ args.pt_isolation = MSHV_PT_ISOLATION_NONE;
+ args.pt_disabled_xsave = disabled_xsave_features.as_uint64;
+ args.pt_num_cpu_fbanks = MSHV_NUM_CPU_FEATURES_BANKS;
+ for (i = 0; i < MSHV_NUM_CPU_FEATURES_BANKS; i++) {
+ args.pt_cpu_fbanks[i] = disabled_processor_features.as_uint64[i];
+ }
ret = ioctl(mshv_fd, MSHV_CREATE_PARTITION, &args);
if (ret < 0) {
diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h
index 7d7b2e9b36..a8d4b2b2b1 100644
--- a/include/hw/hyperv/hvgdk_mini.h
+++ b/include/hw/hyperv/hvgdk_mini.h
@@ -456,6 +456,8 @@ typedef struct hv_input_set_vp_registers {
struct hv_register_assoc elements[];
} QEMU_PACKED hv_input_set_vp_registers;
+#define MSHV_VP_MAX_REGISTERS 128
+
union hv_interrupt_control {
uint64_t as_uint64;
struct {
diff --git a/include/hw/hyperv/hvhdk.h b/include/hw/hyperv/hvhdk.h
index bf2f8cbc27..83f12a8781 100644
--- a/include/hw/hyperv/hvhdk.h
+++ b/include/hw/hyperv/hvhdk.h
@@ -163,6 +163,191 @@ union hv_partition_synthetic_processor_features {
};
};
+union hv_partition_processor_xsave_features {
+ struct {
+ uint64_t xsave_support:1;
+ uint64_t xsaveopt_support:1;
+ uint64_t avx_support:1;
+ uint64_t avx2_support:1;
+ uint64_t fma_support:1;
+ uint64_t mpx_support:1;
+ uint64_t avx512_support:1;
+ uint64_t avx512_dq_support:1;
+ uint64_t avx512_cd_support:1;
+ uint64_t avx512_bw_support:1;
+ uint64_t avx512_vl_support:1;
+ uint64_t xsave_comp_support:1;
+ uint64_t xsave_supervisor_support:1;
+ uint64_t xcr1_support:1;
+ uint64_t avx512_bitalg_support:1;
+ uint64_t avx512_i_fma_support:1;
+ uint64_t avx512_v_bmi_support:1;
+ uint64_t avx512_v_bmi2_support:1;
+ uint64_t avx512_vnni_support:1;
+ uint64_t gfni_support:1;
+ uint64_t vaes_support:1;
+ uint64_t avx512_v_popcntdq_support:1;
+ uint64_t vpclmulqdq_support:1;
+ uint64_t avx512_bf16_support:1;
+ uint64_t avx512_vp2_intersect_support:1;
+ uint64_t avx512_fp16_support:1;
+ uint64_t xfd_support:1;
+ uint64_t amx_tile_support:1;
+ uint64_t amx_bf16_support:1;
+ uint64_t amx_int8_support:1;
+ uint64_t avx_vnni_support:1;
+ uint64_t avx_ifma_support:1;
+ uint64_t avx_ne_convert_support:1;
+ uint64_t avx_vnni_int8_support:1;
+ uint64_t avx_vnni_int16_support:1;
+ uint64_t avx10_1_256_support:1;
+ uint64_t avx10_1_512_support:1;
+ uint64_t amx_fp16_support:1;
+ uint64_t reserved1:26;
+ };
+ uint64_t as_uint64;
+};
+
+#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;
+ };
+};
+
enum hv_translate_gva_result_code {
HV_TRANSLATE_GVA_SUCCESS = 0,
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 04/10] target/i386/mshv: fix cpuid propagation bug
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
` (2 preceding siblings ...)
2026-02-11 15:54 ` [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-02-18 6:24 ` Wei Liu
2026-02-11 15:54 ` [PATCH 05/10] target/i386/mshv: fix various cpuid traversal bugs Magnus Kulke
` (6 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
The list argument was missing a pointer and hence e.g. -cpu qemu64 and
-cpu EPYC would produce the same of cpuid leaves.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
target/i386/mshv/mshv-cpu.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 586383b882..5c46cd67ec 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -441,7 +441,7 @@ int mshv_load_regs(CPUState *cpu)
return 0;
}
-static void add_cpuid_entry(GList *cpuid_entries,
+static void add_cpuid_entry(GList **cpuid_entries,
uint32_t function, uint32_t index,
uint32_t eax, uint32_t ebx,
uint32_t ecx, uint32_t edx)
@@ -456,10 +456,10 @@ static void add_cpuid_entry(GList *cpuid_entries,
entry->ecx = ecx;
entry->edx = edx;
- cpuid_entries = g_list_append(cpuid_entries, entry);
+ *cpuid_entries = g_list_append(*cpuid_entries, entry);
}
-static void collect_cpuid_entries(const CPUState *cpu, GList *cpuid_entries)
+static void collect_cpuid_entries(const CPUState *cpu, GList **cpuid_entries)
{
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
@@ -615,7 +615,7 @@ static int set_cpuid2(const CPUState *cpu)
struct hv_cpuid_entry *entry;
GList *entries = NULL;
- collect_cpuid_entries(cpu, entries);
+ collect_cpuid_entries(cpu, &entries);
n_entries = g_list_length(entries);
cpuid_size = sizeof(struct hv_cpuid)
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 05/10] target/i386/mshv: fix various cpuid traversal bugs
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
` (3 preceding siblings ...)
2026-02-11 15:54 ` [PATCH 04/10] target/i386/mshv: fix cpuid propagation bug Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-02-11 15:54 ` [PATCH 06/10] target/i386/mshv: change cpuid mask to UINT32_MAX Magnus Kulke
` (5 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
- Hardcoded max_leaf was not accurate. We query leaf 0x0 and 0x80000000 to
get the actual max leaves
- On all 0 zeroes on leaf 0x0d, we register 0-63 subleaves with zeros
indicating XSAVE is disabled
- Subleaf 0 was hardcoded, so the Hypervisor returned defaults for other
subleaves
- Subleaf 0 war hardcoded, so we were passing 0 instead of actual subleaf
when adding entries. We now pass the correct subleaf value to
add_cpuid_entry()
- Leaves 0x04,0x07,0d,0f,10 weren't marked as subleaf-specific
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
target/i386/mshv/mshv-cpu.c | 88 +++++++++++++++++++++++++------------
1 file changed, 61 insertions(+), 27 deletions(-)
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 5c46cd67ec..9fa93d2db1 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -465,14 +465,17 @@ static void collect_cpuid_entries(const CPUState *cpu, GList **cpuid_entries)
CPUX86State *env = &x86_cpu->env;
uint32_t eax, ebx, ecx, edx;
uint32_t leaf, subleaf;
- size_t max_leaf = 0x1F;
- size_t max_subleaf = 0x20;
-
- uint32_t leaves_with_subleaves[] = {0x4, 0x7, 0xD, 0xF, 0x10};
+ uint32_t max_basic_leaf, max_extended_leaf;
+ uint32_t max_subleaf = 0x20;
+ uint32_t leaves_with_subleaves[] = {0x04, 0x07, 0x0d, 0x0f, 0x10};
int n_subleaf_leaves = ARRAY_SIZE(leaves_with_subleaves);
- /* Regular leaves without subleaves */
- for (leaf = 0; leaf <= max_leaf; leaf++) {
+ /* Get maximum basic and and extended CPUID leaves */
+ cpu_x86_cpuid(env, 0, 0, &max_basic_leaf, &ebx, &ecx, &edx);
+ cpu_x86_cpuid(env, 0x80000000, 0, &max_extended_leaf, &ebx, &ecx, &edx);
+
+ /* Collect basic leaves (0x0 to max_basic_leaf) */
+ for (leaf = 0; leaf <= max_basic_leaf; leaf++) {
bool has_subleaves = false;
for (int i = 0; i < n_subleaf_leaves; i++) {
if (leaf == leaves_with_subleaves[i]) {
@@ -483,27 +486,40 @@ static void collect_cpuid_entries(const CPUState *cpu, GList **cpuid_entries)
if (!has_subleaves) {
cpu_x86_cpuid(env, leaf, 0, &eax, &ebx, &ecx, &edx);
- if (eax == 0 && ebx == 0 && ecx == 0 && edx == 0) {
- /* all zeroes indicates no more leaves */
- continue;
- }
-
add_cpuid_entry(cpuid_entries, leaf, 0, eax, ebx, ecx, edx);
continue;
}
+ /*
+ * Valid XSAVE components can exist at a higher index se we need to set
+ * all subleaves for leaf 0x0d, even if we encounter an empty one.
+ */
+ if (leaf == 0x0d) {
+ for (subleaf = 0; subleaf <= 63; subleaf++) {
+ cpu_x86_cpuid(env, leaf, subleaf, &eax, &ebx, &ecx, &edx);
+ add_cpuid_entry(cpuid_entries, leaf, subleaf,
+ eax, ebx, ecx, edx);
+ }
+ continue;
+ }
+
subleaf = 0;
while (subleaf < max_subleaf) {
cpu_x86_cpuid(env, leaf, subleaf, &eax, &ebx, &ecx, &edx);
if (eax == 0 && ebx == 0 && ecx == 0 && edx == 0) {
- /* all zeroes indicates no more leaves */
break;
}
- add_cpuid_entry(cpuid_entries, leaf, 0, eax, ebx, ecx, edx);
+ add_cpuid_entry(cpuid_entries, leaf, subleaf, eax, ebx, ecx, edx);
subleaf++;
}
}
+
+ /* Collect extended leaves (0x80000000 to max_extended_leaf) */
+ for (leaf = 0x80000000; leaf <= max_extended_leaf; leaf++) {
+ cpu_x86_cpuid(env, leaf, 0, &eax, &ebx, &ecx, &edx);
+ add_cpuid_entry(cpuid_entries, leaf, 0, eax, ebx, ecx, edx);
+ }
}
static int register_intercept_result_cpuid_entry(const CPUState *cpu,
@@ -576,22 +592,40 @@ static int register_intercept_result_cpuid(const CPUState *cpu,
subleaf_specific = 0;
always_override = 1;
- /* Intel */
- /* 0xb - Extended Topology Enumeration Leaf */
- /* 0x1f - V2 Extended Topology Enumeration Leaf */
- /* AMD */
- /* 0x8000_001e - Processor Topology Information */
- /* 0x8000_0026 - Extended CPU Topology */
- if (entry->function == 0xb
- || entry->function == 0x1f
- || entry->function == 0x8000001e
- || entry->function == 0x80000026) {
+ /*
+ * Intel
+ * 0xb - Extended Topology Enumeration Leaf
+ * 0x1f - V2 Extended Topology Enumeration Leaf
+ * AMD
+ * 0x8000_001e - Processor Topology Information
+ * 0x8000_0026 - Extended CPU Topology
+ */
+ if (entry->function == 0xb ||
+ entry->function == 0x1f ||
+ entry->function == 0x8000001e ||
+ entry->function == 0x80000026) {
+ subleaf_specific = 1;
+ always_override = 1;
+ /*
+ * Feature enumeration leaves (subleaf-specific)
+ * 0x04: Deterministic Cache Parameters
+ * 0x07: Structured Extended Feature Flags
+ * 0x0D: Processor Extended State Enumeration
+ * 0x0F: Platform QoS Monitoring
+ * 0x10: Platform QoS Enforcement
+ */
+ } else if (entry->function == 0x04 ||
+ entry->function == 0x07 ||
+ entry->function == 0x0d ||
+ entry->function == 0x0f ||
+ entry->function == 0x10) {
subleaf_specific = 1;
always_override = 1;
- } else if (entry->function == 0x00000001
- || entry->function == 0x80000000
- || entry->function == 0x80000001
- || entry->function == 0x80000008) {
+ /* Basic feature leaves (no subleaves) */
+ } else if (entry->function == 0x00000001 ||
+ entry->function == 0x80000000 ||
+ entry->function == 0x80000001 ||
+ entry->function == 0x80000008) {
subleaf_specific = 0;
always_override = 1;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 06/10] target/i386/mshv: change cpuid mask to UINT32_MAX
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
` (4 preceding siblings ...)
2026-02-11 15:54 ` [PATCH 05/10] target/i386/mshv: fix various cpuid traversal bugs Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-02-11 15:54 ` [PATCH 07/10] target/i386/mshv: set cpu model name on -cpu host Magnus Kulke
` (4 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
The current implementation would only override the feature bits that are
enabled, however we also want to consider disabled features, hence all
bits are set on the masks in the hypercall argument.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
target/i386/mshv/mshv-cpu.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 9fa93d2db1..b862a7ff6a 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -538,22 +538,17 @@ static int register_intercept_result_cpuid_entry(const CPUState *cpu,
.input.always_override = always_override,
.input.padding = 0,
/*
- * With regard to masks - these are to specify bits to be overwritten
- * The current CpuidEntry structure wouldn't allow to carry the masks
- * in addition to the actual register values. For this reason, the
- * masks are set to the exact values of the corresponding register bits
- * to be registered for an overwrite. To view resulting values the
- * hypervisor would return, HvCallGetVpCpuidValues hypercall can be
- * used.
+ * Masks specify which bits to override. Set to 0xFFFFFFFF to
+ * override all bits with the values from the QEMU CPU model.
*/
.result.eax = entry->eax,
- .result.eax_mask = entry->eax,
+ .result.eax_mask = 0xFFFFFFFF,
.result.ebx = entry->ebx,
- .result.ebx_mask = entry->ebx,
+ .result.ebx_mask = 0xFFFFFFFF,
.result.ecx = entry->ecx,
- .result.ecx_mask = entry->ecx,
+ .result.ecx_mask = 0xFFFFFFFF,
.result.edx = entry->edx,
- .result.edx_mask = entry->edx,
+ .result.edx_mask = 0xFFFFFFFF,
};
union hv_register_intercept_result_parameters parameters = {
.cpuid = cpuid_params,
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 07/10] target/i386/mshv: set cpu model name on -cpu host
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
` (5 preceding siblings ...)
2026-02-11 15:54 ` [PATCH 06/10] target/i386/mshv: change cpuid mask to UINT32_MAX Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-02-11 15:54 ` [PATCH 08/10] target/i386: query mshv accel for supported cpuids Magnus Kulke
` (3 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
By registering a cpu_accel_class for mshv, we can report an accurate
model name on -cpu host.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
target/i386/mshv/mshv-cpu.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index b862a7ff6a..38e0a045c2 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -24,10 +24,13 @@
#include "hw/i386/apic_internal.h"
#include "cpu.h"
+#include "host-cpu.h"
#include "emulate/x86_decode.h"
#include "emulate/x86_emu.h"
#include "emulate/x86_flags.h"
+#include "accel/accel-cpu-target.h"
+
#include "trace-accel_mshv.h"
#include "trace.h"
@@ -1793,3 +1796,31 @@ int mshv_arch_post_init_vm(int vm_fd)
return ret;
}
+
+static void mshv_cpu_instance_init(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+
+ host_cpu_instance_init(cpu);
+}
+
+static void mshv_cpu_accel_class_init(ObjectClass *oc, const void *data)
+{
+ AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
+
+ acc->cpu_instance_init = mshv_cpu_instance_init;
+}
+
+static const TypeInfo mshv_cpu_accel_type_info = {
+ .name = ACCEL_CPU_NAME("mshv"),
+ .parent = TYPE_ACCEL_CPU,
+ .class_init = mshv_cpu_accel_class_init,
+ .abstract = true,
+};
+
+static void mshv_cpu_accel_register_types(void)
+{
+ type_register_static(&mshv_cpu_accel_type_info);
+}
+
+type_init(mshv_cpu_accel_register_types);
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 08/10] target/i386: query mshv accel for supported cpuids
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
` (6 preceding siblings ...)
2026-02-11 15:54 ` [PATCH 07/10] target/i386/mshv: set cpu model name on -cpu host Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-02-11 23:35 ` Mohamed Mediouni
2026-02-11 15:54 ` [PATCH 09/10] target/i386/mshv: populate xsave area offsets Magnus Kulke
` (2 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
We implement mshv_get_supported_cpuid() and invoke it in
x86_cpu_get_supported_feature_word() retrieve the cpu features that the
host is supporting. Initially we mask the virtualization capabilitities
potentially we might need to mask more in the future.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
include/system/mshv.h | 3 +++
target/i386/cpu.c | 8 ++++++++
target/i386/mshv/mshv-cpu.c | 27 +++++++++++++++++++++++++++
3 files changed, 38 insertions(+)
diff --git a/include/system/mshv.h b/include/system/mshv.h
index 75286baf16..51b0420735 100644
--- a/include/system/mshv.h
+++ b/include/system/mshv.h
@@ -60,4 +60,7 @@ 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 virq);
+/* cpuid */
+uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg);
+
#endif
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0a7b884528..b611afc21a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -26,6 +26,7 @@
#include "tcg/helper-tcg.h"
#include "exec/translation-block.h"
#include "system/hvf.h"
+#include "system/mshv.h"
#include "hvf/hvf-i386.h"
#include "kvm/kvm_i386.h"
#include "kvm/tdx.h"
@@ -7958,6 +7959,13 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
r = hvf_get_supported_cpuid(wi->cpuid.eax,
wi->cpuid.ecx,
wi->cpuid.reg);
+ } else if (mshv_enabled()) {
+ if (wi->type != CPUID_FEATURE_WORD) {
+ return 0;
+ }
+ r = mshv_get_supported_cpuid(wi->cpuid.eax,
+ wi->cpuid.ecx,
+ wi->cpuid.reg);
} else if (tcg_enabled()) {
r = wi->tcg_features;
} else {
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 38e0a045c2..bbb58461a4 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -1757,6 +1757,33 @@ void mshv_arch_destroy_vcpu(CPUState *cpu)
g_clear_pointer(&env->emu_mmio_buf, g_free);
}
+uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg)
+{
+ uint32_t eax, ebx, ecx, edx;
+ uint32_t ret = 0;
+
+ host_cpuid(func, idx, &eax, &ebx, &ecx, &edx);
+ switch (reg) {
+ case R_EAX:
+ ret = eax; break;
+ case R_EBX:
+ ret = ebx; break;
+ case R_ECX:
+ ret = ecx; break;
+ case R_EDX:
+ ret = edx; break;
+ }
+
+ /* Disable nested virtualization features not yet supported by MSHV */
+ if (func == 0x80000001 && reg == R_ECX) {
+ ret &= ~CPUID_EXT3_SVM;
+ }
+ if (func == 0x01 && reg == R_ECX) {
+ ret &= ~CPUID_EXT_VMX;
+ }
+ return ret;
+}
+
/*
* Default Microsoft Hypervisor behavior for unimplemented MSR is to send a
* fault to the guest if it tries to access it. It is possible to override
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 09/10] target/i386/mshv: populate xsave area offsets
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
` (7 preceding siblings ...)
2026-02-11 15:54 ` [PATCH 08/10] target/i386: query mshv accel for supported cpuids Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-02-11 15:54 ` [PATCH 10/10] target/i386/mshv: filter out CET bits in cpuid Magnus Kulke
2026-03-02 18:34 ` [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Paolo Bonzini
10 siblings, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
This function is copied verbatim from kvm_cpu_xsave_init(), for MSHV we
need to populate the offsets similarly.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
target/i386/mshv/mshv-cpu.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index bbb58461a4..3a7d9237cd 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -1824,11 +1824,42 @@ int mshv_arch_post_init_vm(int vm_fd)
return ret;
}
+static void mshv_cpu_xsave_init(void)
+{
+ static bool first = true;
+ uint32_t eax, ebx, ecx, edx;
+ int i;
+
+ if (!first) {
+ return;
+ }
+ first = false;
+
+ /* x87 and SSE states are in the legacy region of the XSAVE area. */
+ x86_ext_save_areas[XSTATE_FP_BIT].offset = 0;
+ x86_ext_save_areas[XSTATE_SSE_BIT].offset = 0;
+
+ for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) {
+ ExtSaveArea *esa = &x86_ext_save_areas[i];
+
+ if (!esa->size) {
+ continue;
+ }
+ host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx);
+ if (eax != 0) {
+ assert(esa->size == eax);
+ esa->offset = ebx;
+ esa->ecx = ecx;
+ }
+ }
+}
+
static void mshv_cpu_instance_init(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
host_cpu_instance_init(cpu);
+ mshv_cpu_xsave_init();
}
static void mshv_cpu_accel_class_init(ObjectClass *oc, const void *data)
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 10/10] target/i386/mshv: filter out CET bits in cpuid
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
` (8 preceding siblings ...)
2026-02-11 15:54 ` [PATCH 09/10] target/i386/mshv: populate xsave area offsets Magnus Kulke
@ 2026-02-11 15:54 ` Magnus Kulke
2026-03-02 18:34 ` [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Paolo Bonzini
10 siblings, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-11 15:54 UTC (permalink / raw)
To: qemu-devel
Cc: Magnus Kulke, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
e46dcef1d0 introduced CET_U/CET_S xstate bits in the ExtSaveArea. The
response in EBX of a 0x4,1 cpuid query will contain a size contingent on
what the guest enabled in the IA32_XSS MSR (compacted xsave size).
Since the MSHV accelerator currently responds with static answers to
0x4d cpuid queries, we'll have to disable those bits, even if the host
supports them.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
target/i386/mshv/mshv-cpu.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 3a7d9237cd..4d64c54bc6 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -1781,6 +1781,25 @@ uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg)
if (func == 0x01 && reg == R_ECX) {
ret &= ~CPUID_EXT_VMX;
}
+
+ /*
+ * MSHV currently uses static CPUID intercept results for leaf 0xD.
+ * However there are feature-responses that are dynamic based on what a
+ * guest enables in XCR0 and XSS, such as CET shadow stack.
+ *
+ * A guest which doesn't know about those features yet would encounter an
+ * unexpcted CPUID[0xD,1].EBX (compactes XSAVE size) and either fail
+ * or gracefully degrade by not using XSAVE at all.
+ *
+ * To avoid this, we filter out supervisor xstate features.
+ */
+ if (func == 0x07 && idx == 0 && reg == R_ECX) {
+ ret &= ~CPUID_7_0_ECX_CET_SHSTK;
+ }
+ if (func == 0x07 && idx == 0 && reg == R_EDX) {
+ ret &= ~CPUID_7_0_EDX_CET_IBT;
+ }
+
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 08/10] target/i386: query mshv accel for supported cpuids
2026-02-11 15:54 ` [PATCH 08/10] target/i386: query mshv accel for supported cpuids Magnus Kulke
@ 2026-02-11 23:35 ` Mohamed Mediouni
2026-02-13 9:44 ` Magnus Kulke
2026-02-20 9:50 ` Paolo Bonzini
0 siblings, 2 replies; 27+ messages in thread
From: Mohamed Mediouni @ 2026-02-11 23:35 UTC (permalink / raw)
To: Magnus Kulke
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
> On 11. Feb 2026, at 16:54, Magnus Kulke <magnuskulke@linux.microsoft.com> wrote:
>
> We implement mshv_get_supported_cpuid() and invoke it in
> x86_cpu_get_supported_feature_word() retrieve the cpu features that the
> host is supporting. Initially we mask the virtualization capabilitities
> potentially we might need to mask more in the future.
>
> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Hi,
Interesting. For WHPX on Arm, what’s done is creating a stub partition and extract CPUID info from
it (with necessary guest stub code if necessary) but doing it this way like HVF x86 does is intriguing too…
Is this future-proof or are there catches with this approach?
Thank you,
> ---
> include/system/mshv.h | 3 +++
> target/i386/cpu.c | 8 ++++++++
> target/i386/mshv/mshv-cpu.c | 27 +++++++++++++++++++++++++++
> 3 files changed, 38 insertions(+)
>
> diff --git a/include/system/mshv.h b/include/system/mshv.h
> index 75286baf16..51b0420735 100644
> --- a/include/system/mshv.h
> +++ b/include/system/mshv.h
> @@ -60,4 +60,7 @@ 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 virq);
>
> +/* cpuid */
> +uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg);
> +
> #endif
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 0a7b884528..b611afc21a 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -26,6 +26,7 @@
> #include "tcg/helper-tcg.h"
> #include "exec/translation-block.h"
> #include "system/hvf.h"
> +#include "system/mshv.h"
> #include "hvf/hvf-i386.h"
> #include "kvm/kvm_i386.h"
> #include "kvm/tdx.h"
> @@ -7958,6 +7959,13 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
> r = hvf_get_supported_cpuid(wi->cpuid.eax,
> wi->cpuid.ecx,
> wi->cpuid.reg);
> + } else if (mshv_enabled()) {
> + if (wi->type != CPUID_FEATURE_WORD) {
> + return 0;
> + }
> + r = mshv_get_supported_cpuid(wi->cpuid.eax,
> + wi->cpuid.ecx,
> + wi->cpuid.reg);
> } else if (tcg_enabled()) {
> r = wi->tcg_features;
> } else {
> diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
> index 38e0a045c2..bbb58461a4 100644
> --- a/target/i386/mshv/mshv-cpu.c
> +++ b/target/i386/mshv/mshv-cpu.c
> @@ -1757,6 +1757,33 @@ void mshv_arch_destroy_vcpu(CPUState *cpu)
> g_clear_pointer(&env->emu_mmio_buf, g_free);
> }
>
> +uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg)
> +{
> + uint32_t eax, ebx, ecx, edx;
> + uint32_t ret = 0;
> +
> + host_cpuid(func, idx, &eax, &ebx, &ecx, &edx);
> + switch (reg) {
> + case R_EAX:
> + ret = eax; break;
> + case R_EBX:
> + ret = ebx; break;
> + case R_ECX:
> + ret = ecx; break;
> + case R_EDX:
> + ret = edx; break;
> + }
> +
> + /* Disable nested virtualization features not yet supported by MSHV */
> + if (func == 0x80000001 && reg == R_ECX) {
> + ret &= ~CPUID_EXT3_SVM;
> + }
> + if (func == 0x01 && reg == R_ECX) {
> + ret &= ~CPUID_EXT_VMX;
> + }
> + return ret;
> +}
> +
> /*
> * Default Microsoft Hypervisor behavior for unimplemented MSR is to send a
> * fault to the guest if it tries to access it. It is possible to override
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload
2026-02-11 15:54 ` [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload Magnus Kulke
@ 2026-02-11 23:43 ` Mohamed Mediouni
2026-02-13 9:54 ` Magnus Kulke
2026-02-12 13:32 ` Anirudh Rayabharam
1 sibling, 1 reply; 27+ messages in thread
From: Mohamed Mediouni @ 2026-02-11 23:43 UTC (permalink / raw)
To: Magnus Kulke
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
> On 11. Feb 2026, at 16:54, Magnus Kulke <magnuskulke@linux.microsoft.com> wrote:
>
> When using the extended request format we can instruct the hypervisor to
> provision enough space for requested XSAVE features. This is required
> for supporting QEMU models provided via the -cpu flag properly.
>
> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
> —
[…]
Hi,
On the 1st party Microsoft headers side (as in WHP), the two banks are defined separately.
For example:
ACountMCountSupport instead of a_count_m_count_support
Any reason in particular to diverge and would you prefer to use the definition here in WHP too?
Thank you,
> + /* 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;
> + };
> +};
> +
> enum hv_translate_gva_result_code {
> HV_TRANSLATE_GVA_SUCCESS = 0,
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload
2026-02-11 15:54 ` [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload Magnus Kulke
2026-02-11 23:43 ` Mohamed Mediouni
@ 2026-02-12 13:32 ` Anirudh Rayabharam
2026-02-13 10:27 ` Magnus Kulke
2026-02-18 6:23 ` Wei Liu
1 sibling, 2 replies; 27+ messages in thread
From: Anirudh Rayabharam @ 2026-02-12 13:32 UTC (permalink / raw)
To: Magnus Kulke
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
On Wed, Feb 11, 2026 at 04:54:03PM +0100, Magnus Kulke wrote:
> When using the extended request format we can instruct the hypervisor to
> provision enough space for requested XSAVE features. This is required
> for supporting QEMU models provided via the -cpu flag properly.
>
> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
> ---
> accel/mshv/mshv-all.c | 35 +++++--
> include/hw/hyperv/hvgdk_mini.h | 2 +
> include/hw/hyperv/hvhdk.h | 185 +++++++++++++++++++++++++++++++++
> 3 files changed, 214 insertions(+), 8 deletions(-)
>
> diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
> index bed0fa298e..8446f7128a 100644
> --- a/accel/mshv/mshv-all.c
> +++ b/accel/mshv/mshv-all.c
> @@ -112,19 +112,38 @@ static int resume_vm(int vm_fd)
>
> static int create_partition(int mshv_fd, int *vm_fd)
> {
> - int ret;
> - struct mshv_create_partition args = {0};
> + int ret, i;
> + uint64_t pt_flags;
> + union hv_partition_processor_xsave_features disabled_xsave_features;
> + union hv_partition_processor_features disabled_processor_features;
> + struct mshv_create_partition_v2 args = {0};
>
> /* Initialize pt_flags with the desired features */
> - uint64_t pt_flags = (1ULL << MSHV_PT_BIT_LAPIC) |
> - (1ULL << MSHV_PT_BIT_X2APIC) |
> - (1ULL << MSHV_PT_BIT_GPA_SUPER_PAGES);
> + pt_flags = (1ULL << MSHV_PT_BIT_LAPIC) |
> + (1ULL << MSHV_PT_BIT_X2APIC) |
> + (1ULL << MSHV_PT_BIT_GPA_SUPER_PAGES) |
> + (1ULL << MSHV_PT_BIT_CPU_AND_XSAVE_FEATURES);
>
> - /* Set default isolation type */
> - uint64_t pt_isolation = MSHV_PT_ISOLATION_NONE;
> + /* enable all */
> + disabled_xsave_features.as_uint64 = 0;
>
> + /* Enable all proc features by default */
Instead of enabling all features by default, we could query which
features are supported by the hypervisor on this host and enable only
those.
To query supported features get the HvPartitionPropertyProcessorFeatures
property via HvCallGetPartitionProperty (with HV_PARTITION_ID_SELF).
I think this would be more robust. This is what Cloud Hypervisor (well,
technically, the mshv crate) does.
Thanks,
Anirudh.
> + for (i = 0; i < MSHV_NUM_CPU_FEATURES_BANKS; i++) {
> + disabled_processor_features.as_uint64[i] = 0;
> + }
> + disabled_processor_features.reserved_bank0 = 1;
> + for (i = 0; i < MSHV_NUM_CPU_FEATURES_BANKS; i++) {
> + disabled_processor_features.as_uint64[i] = 0;
> + }
> +
> + /* populate args structure */
> args.pt_flags = pt_flags;
> - args.pt_isolation = pt_isolation;
> + args.pt_isolation = MSHV_PT_ISOLATION_NONE;
> + args.pt_disabled_xsave = disabled_xsave_features.as_uint64;
> + args.pt_num_cpu_fbanks = MSHV_NUM_CPU_FEATURES_BANKS;
> + for (i = 0; i < MSHV_NUM_CPU_FEATURES_BANKS; i++) {
> + args.pt_cpu_fbanks[i] = disabled_processor_features.as_uint64[i];
> + }
>
> ret = ioctl(mshv_fd, MSHV_CREATE_PARTITION, &args);
> if (ret < 0) {
> diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h
> index 7d7b2e9b36..a8d4b2b2b1 100644
> --- a/include/hw/hyperv/hvgdk_mini.h
> +++ b/include/hw/hyperv/hvgdk_mini.h
> @@ -456,6 +456,8 @@ typedef struct hv_input_set_vp_registers {
> struct hv_register_assoc elements[];
> } QEMU_PACKED hv_input_set_vp_registers;
>
> +#define MSHV_VP_MAX_REGISTERS 128
> +
> union hv_interrupt_control {
> uint64_t as_uint64;
> struct {
> diff --git a/include/hw/hyperv/hvhdk.h b/include/hw/hyperv/hvhdk.h
> index bf2f8cbc27..83f12a8781 100644
> --- a/include/hw/hyperv/hvhdk.h
> +++ b/include/hw/hyperv/hvhdk.h
> @@ -163,6 +163,191 @@ union hv_partition_synthetic_processor_features {
> };
> };
>
> +union hv_partition_processor_xsave_features {
> + struct {
> + uint64_t xsave_support:1;
> + uint64_t xsaveopt_support:1;
> + uint64_t avx_support:1;
> + uint64_t avx2_support:1;
> + uint64_t fma_support:1;
> + uint64_t mpx_support:1;
> + uint64_t avx512_support:1;
> + uint64_t avx512_dq_support:1;
> + uint64_t avx512_cd_support:1;
> + uint64_t avx512_bw_support:1;
> + uint64_t avx512_vl_support:1;
> + uint64_t xsave_comp_support:1;
> + uint64_t xsave_supervisor_support:1;
> + uint64_t xcr1_support:1;
> + uint64_t avx512_bitalg_support:1;
> + uint64_t avx512_i_fma_support:1;
> + uint64_t avx512_v_bmi_support:1;
> + uint64_t avx512_v_bmi2_support:1;
> + uint64_t avx512_vnni_support:1;
> + uint64_t gfni_support:1;
> + uint64_t vaes_support:1;
> + uint64_t avx512_v_popcntdq_support:1;
> + uint64_t vpclmulqdq_support:1;
> + uint64_t avx512_bf16_support:1;
> + uint64_t avx512_vp2_intersect_support:1;
> + uint64_t avx512_fp16_support:1;
> + uint64_t xfd_support:1;
> + uint64_t amx_tile_support:1;
> + uint64_t amx_bf16_support:1;
> + uint64_t amx_int8_support:1;
> + uint64_t avx_vnni_support:1;
> + uint64_t avx_ifma_support:1;
> + uint64_t avx_ne_convert_support:1;
> + uint64_t avx_vnni_int8_support:1;
> + uint64_t avx_vnni_int16_support:1;
> + uint64_t avx10_1_256_support:1;
> + uint64_t avx10_1_512_support:1;
> + uint64_t amx_fp16_support:1;
> + uint64_t reserved1:26;
> + };
> + uint64_t as_uint64;
> +};
> +
> +#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;
> + };
> +};
> +
> enum hv_translate_gva_result_code {
> HV_TRANSLATE_GVA_SUCCESS = 0,
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 08/10] target/i386: query mshv accel for supported cpuids
2026-02-11 23:35 ` Mohamed Mediouni
@ 2026-02-13 9:44 ` Magnus Kulke
2026-02-20 9:50 ` Paolo Bonzini
1 sibling, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-13 9:44 UTC (permalink / raw)
To: Mohamed Mediouni
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
On Thu, Feb 12, 2026 at 12:35:57AM +0100, Mohamed Mediouni wrote:
>
> Interesting. For WHPX on Arm, what’s done is creating a stub partition and extract CPUID info from
> it (with necessary guest stub code if necessary) but doing it this way like HVF x86 does is intriguing too…
>
> Is this future-proof or are there catches with this approach?
>
I think this is a valid approach that we also considered. I assume for
MSHV eventually we want to have a MSHV_GET_SUPPORTED_CPUID ioctl, similar
to what exists in KVM, so we can make centralize some decisions instead
of leaving it up to the VMM. This approach might end up using a dummy
partition inside the kernel, but would be an implementation detail.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload
2026-02-11 23:43 ` Mohamed Mediouni
@ 2026-02-13 9:54 ` Magnus Kulke
0 siblings, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-13 9:54 UTC (permalink / raw)
To: Mohamed Mediouni
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
On Thu, Feb 12, 2026 at 12:43:11AM +0100, Mohamed Mediouni wrote:
> On the 1st party Microsoft headers side (as in WHP), the two banks are defined separately.
>
> For example:
>
> ACountMCountSupport instead of a_count_m_count_support
>
> Any reason in particular to diverge and would you prefer to use the definition here in WHP too?
>
> Thank you,
>
I am using the rust-vmm/mshv crates as a reference for the MSHV
interface. I'm cherry picking the definition as we need them from this
source usually:
https://github.com/rust-vmm/mshv/blob/008ed04a85f98c376ea728f1db87f7de07d79a66/hv-headers/hvhdk.h#L1384
I think in the future we want to move those definitions into the
kernel's mshv UAPI header, so the WHPX code is probably more correct
in this regard and the MSHV will do something similar in the future.
best,
magnus
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload
2026-02-12 13:32 ` Anirudh Rayabharam
@ 2026-02-13 10:27 ` Magnus Kulke
2026-02-18 6:23 ` Wei Liu
1 sibling, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-02-13 10:27 UTC (permalink / raw)
To: Anirudh Rayabharam
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
> Instead of enabling all features by default, we could query which
> features are supported by the hypervisor on this host and enable only
> those.
>
> To query supported features get the HvPartitionPropertyProcessorFeatures
> property via HvCallGetPartitionProperty (with HV_PARTITION_ID_SELF).
>
> I think this would be more robust. This is what Cloud Hypervisor (well,
> technically, the mshv crate) does.
>
that makes sense, I'll adjust that part in a v2
thanks,
magnus
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload
2026-02-12 13:32 ` Anirudh Rayabharam
2026-02-13 10:27 ` Magnus Kulke
@ 2026-02-18 6:23 ` Wei Liu
2026-02-19 10:33 ` Anirudh Rayabharam
1 sibling, 1 reply; 27+ messages in thread
From: Wei Liu @ 2026-02-18 6:23 UTC (permalink / raw)
To: Anirudh Rayabharam
Cc: Magnus Kulke, qemu-devel, Wei Liu, Wei Liu, Zhao Liu,
Paolo Bonzini, Magnus Kulke
On Thu, Feb 12, 2026 at 01:32:22PM +0000, Anirudh Rayabharam wrote:
> On Wed, Feb 11, 2026 at 04:54:03PM +0100, Magnus Kulke wrote:
> > When using the extended request format we can instruct the hypervisor to
> > provision enough space for requested XSAVE features. This is required
> > for supporting QEMU models provided via the -cpu flag properly.
> >
> > Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
> > ---
> > accel/mshv/mshv-all.c | 35 +++++--
> > include/hw/hyperv/hvgdk_mini.h | 2 +
> > include/hw/hyperv/hvhdk.h | 185 +++++++++++++++++++++++++++++++++
> > 3 files changed, 214 insertions(+), 8 deletions(-)
> >
> > diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
> > index bed0fa298e..8446f7128a 100644
> > --- a/accel/mshv/mshv-all.c
> > +++ b/accel/mshv/mshv-all.c
> > @@ -112,19 +112,38 @@ static int resume_vm(int vm_fd)
> >
> > static int create_partition(int mshv_fd, int *vm_fd)
> > {
> > - int ret;
> > - struct mshv_create_partition args = {0};
> > + int ret, i;
> > + uint64_t pt_flags;
> > + union hv_partition_processor_xsave_features disabled_xsave_features;
> > + union hv_partition_processor_features disabled_processor_features;
> > + struct mshv_create_partition_v2 args = {0};
> >
> > /* Initialize pt_flags with the desired features */
> > - uint64_t pt_flags = (1ULL << MSHV_PT_BIT_LAPIC) |
> > - (1ULL << MSHV_PT_BIT_X2APIC) |
> > - (1ULL << MSHV_PT_BIT_GPA_SUPER_PAGES);
> > + pt_flags = (1ULL << MSHV_PT_BIT_LAPIC) |
> > + (1ULL << MSHV_PT_BIT_X2APIC) |
> > + (1ULL << MSHV_PT_BIT_GPA_SUPER_PAGES) |
> > + (1ULL << MSHV_PT_BIT_CPU_AND_XSAVE_FEATURES);
> >
> > - /* Set default isolation type */
> > - uint64_t pt_isolation = MSHV_PT_ISOLATION_NONE;
> > + /* enable all */
> > + disabled_xsave_features.as_uint64 = 0;
> >
> > + /* Enable all proc features by default */
>
> Instead of enabling all features by default, we could query which
> features are supported by the hypervisor on this host and enable only
> those.
>
> To query supported features get the HvPartitionPropertyProcessorFeatures
> property via HvCallGetPartitionProperty (with HV_PARTITION_ID_SELF).
>
> I think this would be more robust. This is what Cloud Hypervisor (well,
> technically, the mshv crate) does.
>
While I think querying the hypervisor is the correct action, are we
sure this gives all the supported features on the host?
Is there a case that the Linux root partition has a reduced set of
properties?
Wei
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 04/10] target/i386/mshv: fix cpuid propagation bug
2026-02-11 15:54 ` [PATCH 04/10] target/i386/mshv: fix cpuid propagation bug Magnus Kulke
@ 2026-02-18 6:24 ` Wei Liu
0 siblings, 0 replies; 27+ messages in thread
From: Wei Liu @ 2026-02-18 6:24 UTC (permalink / raw)
To: Magnus Kulke
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
On Wed, Feb 11, 2026 at 04:54:04PM +0100, Magnus Kulke wrote:
> The list argument was missing a pointer and hence e.g. -cpu qemu64 and
> -cpu EPYC would produce the same of cpuid leaves.
>
> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Acked-by: Wei Liu (Microsoft) <wei.liu@kernel.org>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload
2026-02-18 6:23 ` Wei Liu
@ 2026-02-19 10:33 ` Anirudh Rayabharam
2026-02-19 20:16 ` Wei Liu
0 siblings, 1 reply; 27+ messages in thread
From: Anirudh Rayabharam @ 2026-02-19 10:33 UTC (permalink / raw)
To: Wei Liu
Cc: Magnus Kulke, qemu-devel, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
On Wed, Feb 18, 2026 at 06:23:58AM +0000, Wei Liu wrote:
> On Thu, Feb 12, 2026 at 01:32:22PM +0000, Anirudh Rayabharam wrote:
> > On Wed, Feb 11, 2026 at 04:54:03PM +0100, Magnus Kulke wrote:
> > > When using the extended request format we can instruct the hypervisor to
> > > provision enough space for requested XSAVE features. This is required
> > > for supporting QEMU models provided via the -cpu flag properly.
> > >
> > > Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
> > > ---
> > > accel/mshv/mshv-all.c | 35 +++++--
> > > include/hw/hyperv/hvgdk_mini.h | 2 +
> > > include/hw/hyperv/hvhdk.h | 185 +++++++++++++++++++++++++++++++++
> > > 3 files changed, 214 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
> > > index bed0fa298e..8446f7128a 100644
> > > --- a/accel/mshv/mshv-all.c
> > > +++ b/accel/mshv/mshv-all.c
> > > @@ -112,19 +112,38 @@ static int resume_vm(int vm_fd)
> > >
> > > static int create_partition(int mshv_fd, int *vm_fd)
> > > {
> > > - int ret;
> > > - struct mshv_create_partition args = {0};
> > > + int ret, i;
> > > + uint64_t pt_flags;
> > > + union hv_partition_processor_xsave_features disabled_xsave_features;
> > > + union hv_partition_processor_features disabled_processor_features;
> > > + struct mshv_create_partition_v2 args = {0};
> > >
> > > /* Initialize pt_flags with the desired features */
> > > - uint64_t pt_flags = (1ULL << MSHV_PT_BIT_LAPIC) |
> > > - (1ULL << MSHV_PT_BIT_X2APIC) |
> > > - (1ULL << MSHV_PT_BIT_GPA_SUPER_PAGES);
> > > + pt_flags = (1ULL << MSHV_PT_BIT_LAPIC) |
> > > + (1ULL << MSHV_PT_BIT_X2APIC) |
> > > + (1ULL << MSHV_PT_BIT_GPA_SUPER_PAGES) |
> > > + (1ULL << MSHV_PT_BIT_CPU_AND_XSAVE_FEATURES);
> > >
> > > - /* Set default isolation type */
> > > - uint64_t pt_isolation = MSHV_PT_ISOLATION_NONE;
> > > + /* enable all */
> > > + disabled_xsave_features.as_uint64 = 0;
> > >
> > > + /* Enable all proc features by default */
> >
> > Instead of enabling all features by default, we could query which
> > features are supported by the hypervisor on this host and enable only
> > those.
> >
> > To query supported features get the HvPartitionPropertyProcessorFeatures
> > property via HvCallGetPartitionProperty (with HV_PARTITION_ID_SELF).
> >
> > I think this would be more robust. This is what Cloud Hypervisor (well,
> > technically, the mshv crate) does.
> >
>
> While I think querying the hypervisor is the correct action, are we
> sure this gives all the supported features on the host?
Yes, I confirmed this with the hypervisor team when implementing it in
the mshv crate.
>
> Is there a case that the Linux root partition has a reduced set of
> properties?
It is my understanding that the processor features we expose to a guest
must always be a subset of the processor features of the root/parent
partition. So, if some proc feature is not available for root, we cannot
make it available for any guest partitions either.
Thanks,
Anirudh.
>
> Wei
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload
2026-02-19 10:33 ` Anirudh Rayabharam
@ 2026-02-19 20:16 ` Wei Liu
0 siblings, 0 replies; 27+ messages in thread
From: Wei Liu @ 2026-02-19 20:16 UTC (permalink / raw)
To: Anirudh Rayabharam
Cc: Wei Liu, Magnus Kulke, qemu-devel, Wei Liu, Zhao Liu,
Paolo Bonzini, Magnus Kulke
On Thu, Feb 19, 2026 at 10:33:44AM +0000, Anirudh Rayabharam wrote:
[...]
> > >
> > > Instead of enabling all features by default, we could query which
> > > features are supported by the hypervisor on this host and enable only
> > > those.
> > >
> > > To query supported features get the HvPartitionPropertyProcessorFeatures
> > > property via HvCallGetPartitionProperty (with HV_PARTITION_ID_SELF).
> > >
> > > I think this would be more robust. This is what Cloud Hypervisor (well,
> > > technically, the mshv crate) does.
> > >
> >
> > While I think querying the hypervisor is the correct action, are we
> > sure this gives all the supported features on the host?
>
> Yes, I confirmed this with the hypervisor team when implementing it in
> the mshv crate.
>
> >
> > Is there a case that the Linux root partition has a reduced set of
> > properties?
>
> It is my understanding that the processor features we expose to a guest
> must always be a subset of the processor features of the root/parent
> partition. So, if some proc feature is not available for root, we cannot
> make it available for any guest partitions either.
One thing comes to mind is the confidential VM support. In our CVM
implementation, the guest can see a different set of features than the
root partition, mostly around SEV-SNP support. I cannot say 100% for
sure that if this matters.
Wei
>
> Thanks,
> Anirudh.
>
> >
> > Wei
> >
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 08/10] target/i386: query mshv accel for supported cpuids
2026-02-11 23:35 ` Mohamed Mediouni
2026-02-13 9:44 ` Magnus Kulke
@ 2026-02-20 9:50 ` Paolo Bonzini
1 sibling, 0 replies; 27+ messages in thread
From: Paolo Bonzini @ 2026-02-20 9:50 UTC (permalink / raw)
To: Mohamed Mediouni, Magnus Kulke
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Magnus Kulke
On 2/12/26 00:35, Mohamed Mediouni wrote:
>
>
>> On 11. Feb 2026, at 16:54, Magnus Kulke
>> <magnuskulke@linux.microsoft.com> wrote:
>>
>> We implement mshv_get_supported_cpuid() and invoke it in
>> x86_cpu_get_supported_feature_word() retrieve the cpu features
>> that the host is supporting. Initially we mask the virtualization
>> capabilitities potentially we might need to mask more in the
>> future.
>>
>> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
>
> Hi,
>
> Interesting. For WHPX on Arm, what’s done is creating a stub
> partition and extract CPUID info from it (with necessary guest stub
> code if necessary) but doing it this way like HVF x86 does is
> intriguing too…
>
> Is this future-proof or are there catches with this approach?
No, it's absolutely not future proof.
The difference is two-fold: first, HVF on x86 essentially implements the
hypervisor itself. It operates at the VMCS level and is a mix of KVM
and "regular" QEMU code. Second, for feature leaves HVF lists
explicitly all the supported bits and it also limits EAX to 0xD (it does
not try too hard with AMD leaves at 0x800000nn because HVF x86 is
Intel-only anyway).
So, what this patch implements is not like HVF x86. The stub partition
idea is nice and more future proof.
Paolo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/10] Support QEMU cpu models in MSHV accelerator
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
` (9 preceding siblings ...)
2026-02-11 15:54 ` [PATCH 10/10] target/i386/mshv: filter out CET bits in cpuid Magnus Kulke
@ 2026-03-02 18:34 ` Paolo Bonzini
2026-03-03 13:30 ` Magnus Kulke
10 siblings, 1 reply; 27+ messages in thread
From: Paolo Bonzini @ 2026-03-02 18:34 UTC (permalink / raw)
To: Magnus Kulke, qemu-devel; +Cc: Wei Liu, Wei Liu, Zhao Liu, Magnus Kulke
On 2/11/26 16:54, Magnus Kulke wrote:
> Hey all,
>
> In the current MSHV accelerator code passing CPU features via the -cpu
> flag doesn't work as intended yet. When using the MSHV hypervisor we
> either silently discard the specified model/features and leave it up
> to the hypervisor to provide a sensible set of features or if the user
> selects -cpu host, the hypervisor might refuse to create a partition.
>
> This changeset introduces a more comprehensive support for passing
> desired guest cpu features to the hypervisor. It's also a prerequisite
> for Live Migration support, in which we have to roundtrip CPU State
> explicitly
>
> Known issues:
>
> We will probably have to iterate a bit more on this, since recently
> support for CET_U/CET_S xstate bits has been introduced in QEMU, which
> doesn't harmonize with our current approach of configuring the
> hypervisor with static responses to cpuid queries.
Hi Magnus,
I went back to reviewing this series.
More or less, using "-cpu host" should work because MSHV already runs in
a partition. Therefore, it should be safe to assume that whatever bits
were allowed in the current partition's CPUID will also be allowed in
the nested guest.
However, you still need to mask the features corresponding to MSRs that
you do not save/restore; this includes for example TSC deadline timer,
AMX (XFD), FRED, PMU, UMWAIT are the first few that came to mind. Or
alternatively, just add them to get/put_msrs.
Later on, we probably want to share some of the code to handle MSRs
between Hyper-V and KVM. Please add some comments about the hypercalls,
since they are poorly documented, explaining how to find out which MSRs
are supported by the hypervisor.
With respect to live migration, here are a few bits of states that
should be migrated:
- the FPU registers (MshvFPU is dead code and can be removed; I missed
it during my initial review).
- the PDPTRs. That is probably okay (because you never set nor read
env->pdptrs_valid) but please check if Hyper-V supports reading them.
- KVM also has support for migrating in the middle of an exception being
delivered (for example if an EPT violation happens due to a write to the
stack); this is handled with fields such as these:
VMSTATE_UINT8(env.exception_pending, X86CPU),
VMSTATE_UINT8(env.exception_injected, X86CPU),
VMSTATE_UINT8(env.exception_has_payload, X86CPU),
VMSTATE_UINT64(env.exception_payload, X86CPU),
VMSTATE_INT32(env.exception_nr, X86CPU),
VMSTATE_INT32(env.interrupt_injected, X86CPU),
VMSTATE_UINT8(env.soft_interrupt, X86CPU),
VMSTATE_UINT8(env.nmi_injected, X86CPU),
VMSTATE_UINT8(env.nmi_pending, X86CPU),
please check how Hyper-V handles this situation so that it can be
implemented in QEMU as well.
Thanks,
Paolo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 01/10] MAINTAINERS: fix magnuskulke email-address
2026-02-11 15:54 ` [PATCH 01/10] MAINTAINERS: fix magnuskulke email-address Magnus Kulke
@ 2026-03-03 12:14 ` Peter Maydell
2026-03-03 12:53 ` Magnus Kulke
0 siblings, 1 reply; 27+ messages in thread
From: Peter Maydell @ 2026-03-03 12:14 UTC (permalink / raw)
To: Magnus Kulke
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
On Wed, 11 Feb 2026 at 16:09, Magnus Kulke
<magnuskulke@linux.microsoft.com> wrote:
>
> Consolidating email aliases.
>
> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
> ---
> MAINTAINERS | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 29f88d48f3..6272d32ed4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -569,7 +569,7 @@ F: accel/stubs/whpx-stub.c
> F: include/system/whpx.h
>
> MSHV
> -M: Magnus Kulke <magnus.kulke@linux.microsoft.com>
> +M: Magnus Kulke <magnuskulke@linux.microsoft.com>
> R: Wei Liu <wei.liu@kernel.org>
> S: Supported
> F: accel/mshv/
> @@ -578,7 +578,7 @@ F: include/hw/hyperv/hvgdk*.h
> F: include/hw/hyperv/hvhdk*.h
>
> X86 MSHV CPUs
> -M: Magnus Kulke <magnus.kulke@linux.microsoft.com>
> +M: Magnus Kulke <magnuskulke@linux.microsoft.com>
> R: Wei Liu <wei.liu@kernel.org>
> S: Supported
> F: target/i386/mshv/
Hi; I'm going to pull this MAINTAINERS patch out of this series
and apply it via target-arm.next, since the incorrect email
we currently have listed in the file bounces ("550 5.1.1 :
Recipient address rejected: User unknown in local recipient table").
thanks
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 01/10] MAINTAINERS: fix magnuskulke email-address
2026-03-03 12:14 ` Peter Maydell
@ 2026-03-03 12:53 ` Magnus Kulke
0 siblings, 0 replies; 27+ messages in thread
From: Magnus Kulke @ 2026-03-03 12:53 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Paolo Bonzini,
Magnus Kulke
On Tue, Mar 03, 2026 at 12:14:21PM +0000, Peter Maydell wrote:
> Hi; I'm going to pull this MAINTAINERS patch out of this series
> and apply it via target-arm.next, since the incorrect email
> we currently have listed in the file bounces ("550 5.1.1 :
> Recipient address rejected: User unknown in local recipient table").
>
> thanks
> -- PMM
ack, thanks!
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/10] Support QEMU cpu models in MSHV accelerator
2026-03-02 18:34 ` [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Paolo Bonzini
@ 2026-03-03 13:30 ` Magnus Kulke
2026-03-03 14:04 ` Paolo Bonzini
0 siblings, 1 reply; 27+ messages in thread
From: Magnus Kulke @ 2026-03-03 13:30 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Magnus Kulke
On Mon, Mar 02, 2026 at 07:34:21PM +0100, Paolo Bonzini wrote:
> Hi Magnus,
>
> I went back to reviewing this series.
>
> More or less, using "-cpu host" should work because MSHV already runs in a
> partition. Therefore, it should be safe to assume that whatever bits were
> allowed in the current partition's CPUID will also be allowed in the nested
> guest.
>
> However, you still need to mask the features corresponding to MSRs that you
> do not save/restore; this includes for example TSC deadline timer, AMX
> (XFD), FRED, PMU, UMWAIT are the first few that came to mind. Or
> alternatively, just add them to get/put_msrs.
>
Hey Paolo,
thanks for taking a look at this. I am currently staging follow up
patch-sets in which the MSR handling is reworked as part of the live
migration support. In those there will be more MSRs that are being
covered in a migration, using a hardcoded list in rust-vmm/mshv as
base, with some additional ones added:
https://docs.rs/crate/mshv-ioctls/0.6.7/source/src/ioctls/system.rs#363
in the future I think we want to have a MSHV_GET_SUPPORTED_MSRS ioctl
that we can query, similar to what's available for KVM.
There are "hv_partition_processor_features" that we query from the
hypervisor to filter out MSRs that are not available for a given
partition, e.g.
uint64_t tsc_adjust_support:1;
> Later on, we probably want to share some of the code to handle MSRs between
> Hyper-V and KVM. Please add some comments about the hypercalls, since they
> are poorly documented, explaining how to find out which MSRs are supported
> by the hypervisor.
>
If the hypercalls are not documented, we probably want to fix it either
in the rust-vmm/mshv create (which at the moment provides authorative
headers (until we have moved everything to the mshv uapi headers), but
i'll double check.
> With respect to live migration, here are a few bits of states that should be
> migrated:
>
> - the FPU registers (MshvFPU is dead code and can be removed; I missed it
> during my initial review).
yup, the FPU registers handling has also been reworked a bit to
accomodate XSAVE migration.
>
> - the PDPTRs. That is probably okay (because you never set nor read
> env->pdptrs_valid) but please check if Hyper-V supports reading them.
>
I'll try to find that out. Haven't stumbled over this so far, but I
understand it's relevant for 32bit PAE guest, which we probably haven't
tested thoroughly yet.
> - KVM also has support for migrating in the middle of an exception being
> delivered (for example if an EPT violation happens due to a write to the
> stack); this is handled with fields such as these:
>
> VMSTATE_UINT8(env.exception_pending, X86CPU),
> VMSTATE_UINT8(env.exception_injected, X86CPU),
> VMSTATE_UINT8(env.exception_has_payload, X86CPU),
> VMSTATE_UINT64(env.exception_payload, X86CPU),
> VMSTATE_INT32(env.exception_nr, X86CPU),
> VMSTATE_INT32(env.interrupt_injected, X86CPU),
> VMSTATE_UINT8(env.soft_interrupt, X86CPU),
> VMSTATE_UINT8(env.nmi_injected, X86CPU),
> VMSTATE_UINT8(env.nmi_pending, X86CPU),
>
> please check how Hyper-V handles this situation so that it can be
> implemented in QEMU as well.
>
Those are covered in MSHV's "vCPU Events", I think they map quite
cleanly to the QEMU representation:
https://docs.rs/mshv-bindings/0.6.7/src/mshv_bindings/x86_64/regs.rs.html#404
thanks,
magnus
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/10] Support QEMU cpu models in MSHV accelerator
2026-03-03 13:30 ` Magnus Kulke
@ 2026-03-03 14:04 ` Paolo Bonzini
0 siblings, 0 replies; 27+ messages in thread
From: Paolo Bonzini @ 2026-03-03 14:04 UTC (permalink / raw)
To: Magnus Kulke; +Cc: qemu-devel, Wei Liu, Wei Liu, Zhao Liu, Magnus Kulke
On Tue, Mar 3, 2026 at 2:31 PM Magnus Kulke
<magnuskulke@linux.microsoft.com> wrote:
>
> On Mon, Mar 02, 2026 at 07:34:21PM +0100, Paolo Bonzini wrote:
> > Hi Magnus,
> >
> > I went back to reviewing this series.
> >
> > More or less, using "-cpu host" should work because MSHV already runs in a
> > partition. Therefore, it should be safe to assume that whatever bits were
> > allowed in the current partition's CPUID will also be allowed in the nested
> > guest.
> >
> > However, you still need to mask the features corresponding to MSRs that you
> > do not save/restore; this includes for example TSC deadline timer, AMX
> > (XFD), FRED, PMU, UMWAIT are the first few that came to mind. Or
> > alternatively, just add them to get/put_msrs.
> >
>
> Hey Paolo,
>
> thanks for taking a look at this. I am currently staging follow up
> patch-sets in which the MSR handling is reworked as part of the live
> migration support.
Ok, let's start from there so that we don't have to think about
filtering out features because they're not migrated.
Thanks for the extra information, I'll study the rust-vmm docs.
> in the future I think we want to have a MSHV_GET_SUPPORTED_MSRS ioctl
> that we can query, similar to what's available for KVM.
That may not be needed if we can rely on the parent partition's CPUID
(I changed my mind and I think we can, because QEMU already filters
out CPUID features it doesn't know about).
We may want to share the knowledge of MSRs between KVM and MSHV, but
that's a different story.
Paolo
> There are "hv_partition_processor_features" that we query from the
> hypervisor to filter out MSRs that are not available for a given
> partition, e.g.
>
> uint64_t tsc_adjust_support:1;
>
> > Later on, we probably want to share some of the code to handle MSRs between
> > Hyper-V and KVM. Please add some comments about the hypercalls, since they
> > are poorly documented, explaining how to find out which MSRs are supported
> > by the hypervisor.
> >
>
> If the hypercalls are not documented, we probably want to fix it either
> in the rust-vmm/mshv create (which at the moment provides authorative
> headers (until we have moved everything to the mshv uapi headers), but
> i'll double check.
>
> > With respect to live migration, here are a few bits of states that should be
> > migrated:
> >
> > - the FPU registers (MshvFPU is dead code and can be removed; I missed it
> > during my initial review).
>
> yup, the FPU registers handling has also been reworked a bit to
> accomodate XSAVE migration.
>
> >
> > - the PDPTRs. That is probably okay (because you never set nor read
> > env->pdptrs_valid) but please check if Hyper-V supports reading them.
> >
>
> I'll try to find that out. Haven't stumbled over this so far, but I
> understand it's relevant for 32bit PAE guest, which we probably haven't
> tested thoroughly yet.
>
> > - KVM also has support for migrating in the middle of an exception being
> > delivered (for example if an EPT violation happens due to a write to the
> > stack); this is handled with fields such as these:
> >
> > VMSTATE_UINT8(env.exception_pending, X86CPU),
> > VMSTATE_UINT8(env.exception_injected, X86CPU),
> > VMSTATE_UINT8(env.exception_has_payload, X86CPU),
> > VMSTATE_UINT64(env.exception_payload, X86CPU),
> > VMSTATE_INT32(env.exception_nr, X86CPU),
> > VMSTATE_INT32(env.interrupt_injected, X86CPU),
> > VMSTATE_UINT8(env.soft_interrupt, X86CPU),
> > VMSTATE_UINT8(env.nmi_injected, X86CPU),
> > VMSTATE_UINT8(env.nmi_pending, X86CPU),
> >
> > please check how Hyper-V handles this situation so that it can be
> > implemented in QEMU as well.
> >
>
> Those are covered in MSHV's "vCPU Events", I think they map quite
> cleanly to the QEMU representation:
>
> https://docs.rs/mshv-bindings/0.6.7/src/mshv_bindings/x86_64/regs.rs.html#404
>
> thanks,
>
> magnus
>
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2026-03-03 14:05 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-11 15:54 [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Magnus Kulke
2026-02-11 15:54 ` [PATCH 01/10] MAINTAINERS: fix magnuskulke email-address Magnus Kulke
2026-03-03 12:14 ` Peter Maydell
2026-03-03 12:53 ` Magnus Kulke
2026-02-11 15:54 ` [PATCH 02/10] include/hw/hyperv: add QEMU_PACKED to uapi structs Magnus Kulke
2026-02-11 15:54 ` [PATCH 03/10] accel/mshv: use mshv_create_partition_v2 payload Magnus Kulke
2026-02-11 23:43 ` Mohamed Mediouni
2026-02-13 9:54 ` Magnus Kulke
2026-02-12 13:32 ` Anirudh Rayabharam
2026-02-13 10:27 ` Magnus Kulke
2026-02-18 6:23 ` Wei Liu
2026-02-19 10:33 ` Anirudh Rayabharam
2026-02-19 20:16 ` Wei Liu
2026-02-11 15:54 ` [PATCH 04/10] target/i386/mshv: fix cpuid propagation bug Magnus Kulke
2026-02-18 6:24 ` Wei Liu
2026-02-11 15:54 ` [PATCH 05/10] target/i386/mshv: fix various cpuid traversal bugs Magnus Kulke
2026-02-11 15:54 ` [PATCH 06/10] target/i386/mshv: change cpuid mask to UINT32_MAX Magnus Kulke
2026-02-11 15:54 ` [PATCH 07/10] target/i386/mshv: set cpu model name on -cpu host Magnus Kulke
2026-02-11 15:54 ` [PATCH 08/10] target/i386: query mshv accel for supported cpuids Magnus Kulke
2026-02-11 23:35 ` Mohamed Mediouni
2026-02-13 9:44 ` Magnus Kulke
2026-02-20 9:50 ` Paolo Bonzini
2026-02-11 15:54 ` [PATCH 09/10] target/i386/mshv: populate xsave area offsets Magnus Kulke
2026-02-11 15:54 ` [PATCH 10/10] target/i386/mshv: filter out CET bits in cpuid Magnus Kulke
2026-03-02 18:34 ` [PATCH 00/10] Support QEMU cpu models in MSHV accelerator Paolo Bonzini
2026-03-03 13:30 ` Magnus Kulke
2026-03-03 14:04 ` Paolo Bonzini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.