diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 0f65b65d9c..52623be5d9 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -142,6 +142,8 @@ static int create_partition(int mshv_fd, int *vm_fd) int ret; uint64_t pt_flags, host_proc_features; union hv_partition_processor_xsave_features disabled_xsave_features; + union hv_partition_processor_features disabled_partition_features = {0}; + struct mshv_create_partition_v2 args = {0}; QEMU_BUILD_BUG_ON(MSHV_NUM_CPU_FEATURES_BANKS != 2); @@ -177,6 +179,11 @@ static int create_partition(int mshv_fd, int *vm_fd) } args.pt_cpu_fbanks[1] = ~host_proc_features; + /* arch-specific features we disable regardless of host support */ + mshv_arch_disable_partition_proc_features(&disabled_partition_features); + args.pt_cpu_fbanks[0] |= disabled_partition_features.as_uint64[0]; + args.pt_cpu_fbanks[1] |= disabled_partition_features.as_uint64[1]; + /* populate args structure */ args.pt_flags = pt_flags; args.pt_isolation = MSHV_PT_ISOLATION_NONE; diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index 35386c422f..ca156cdf4b 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -94,6 +94,8 @@ void mshv_arch_init_vcpu(CPUState *cpu); void mshv_arch_destroy_vcpu(CPUState *cpu); void mshv_arch_amend_proc_features( union hv_partition_synthetic_processor_features *features); +void mshv_arch_disable_partition_proc_features( + union hv_partition_processor_features *disabled_features); int mshv_arch_post_init_vm(int vm_fd); typedef struct mshv_root_hvcall mshv_root_hvcall; diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index e85311af2a..3523cfcb70 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -1129,6 +1129,12 @@ void mshv_arch_amend_proc_features( features->access_guest_idle_reg = 1; } +void mshv_arch_disable_partition_proc_features( + union hv_partition_processor_features *disabled_features) +{ + disabled_features->la57_support = 1; +} + static int set_memory_info(const struct hyperv_message *msg, struct hv_x64_memory_intercept_message *info) { @@ -1707,6 +1713,15 @@ uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg) ret &= ~CPUID_EXT_VMX; } + if (func == 0x07 && idx == 0 && reg == R_ECX) { + /* + * LA57 (5-level paging) causes incorrect GVA=>GPA translations + * in the instruction decoder/emulator. Disable until page table + * walk in x86_mmu.c works w/ 5-level paging. + */ + ret &= ~CPUID_7_0_ECX_LA57; + } + return ret; }