From 1f6436499d91da25490df204e170e595f6577f7d Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Tue, 22 Oct 2024 22:15:41 +0300 Subject: [PATCH] add AVX10.256 emulation VMX control --- bochs/cpu/decoder/fetchdecode32.cc | 3 +++ bochs/cpu/vmcs.cc | 5 +++++ bochs/cpu/vmx_ctrls.h | 2 ++ bochs/cpu/xsave.cc | 21 +++++++++++++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/bochs/cpu/decoder/fetchdecode32.cc b/bochs/cpu/decoder/fetchdecode32.cc index 89bd15962..74c58c674 100644 --- a/bochs/cpu/decoder/fetchdecode32.cc +++ b/bochs/cpu/decoder/fetchdecode32.cc @@ -2588,6 +2588,9 @@ int BX_CPU_C::assignHandler(bxInstruction_c *i, Bit32u fetchModeMask) #if BX_SUPPORT_EVEX if ((op_flags & BX_PREPARE_EVEX) != 0) { bool allow512 = BX_CPU_THIS_PTR cpuid->support_avx10_512(); +#if BX_SUPPORT_VMX + if (BX_CPU_THIS_PTR in_vmx_guest && BX_CPU_THIS_PTR vmcs.vmexec_ctrls3.EMULATE_AVX10_VL256()) allow512 = false; +#endif if (! allow512 && i->getVL() == BX_VL512) { BX_DEBUG(("%s: VL512 is not supported for this processor", i->getIaOpcodeNameShort())); i->execute1 = &BX_CPU_C::BxError; diff --git a/bochs/cpu/vmcs.cc b/bochs/cpu/vmcs.cc index 4969b2766..c638a0527 100644 --- a/bochs/cpu/vmcs.cc +++ b/bochs/cpu/vmcs.cc @@ -889,6 +889,8 @@ void BX_CPU_C::init_tertiary_proc_based_vmexec_ctrls(void) // [06] Enable MSRLIST instructions // [07] Virtualize IA32_SPEC_CTRL // ... + // [13] Emulate AVX10.VL256 mode + // ... cap->vmx_vmexec_ctrl3_supported_bits = 0; @@ -898,6 +900,9 @@ void BX_CPU_C::init_tertiary_proc_based_vmexec_ctrls(void) if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_SPEC_CTRL_VIRTUALIZATION)) { cap->vmx_vmexec_ctrl3_supported_bits |= VMX_VM_EXEC_CTRL3_VIRTUALIZE_IA32_SPEC_CTRL; } + if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_AVX10_1) && BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_AVX10_VL512)) { + cap->vmx_vmexec_ctrl3_supported_bits |= VMX_VM_EXEC_CTRL3_EMULATE_AVX10_VL256; + } } void BX_CPU_C::init_secondary_vmexit_ctrls(void) diff --git a/bochs/cpu/vmx_ctrls.h b/bochs/cpu/vmx_ctrls.h index 96037a089..fdb99a713 100644 --- a/bochs/cpu/vmx_ctrls.h +++ b/bochs/cpu/vmx_ctrls.h @@ -172,6 +172,7 @@ public: #define VMX_VM_EXEC_CTRL3_IPI_VIRTUALIZATION (1 << 4) /* IPI virtualization (not implemented) */ #define VMX_VM_EXEC_CTRL3_ENABLE_MSRLIST (1 << 6) /* MSRLIST */ #define VMX_VM_EXEC_CTRL3_VIRTUALIZE_IA32_SPEC_CTRL (1 << 7) +#define VMX_VM_EXEC_CTRL3_EMULATE_AVX10_VL256 (1 << 13) bool LOADIWKEY_VMEXIT() const { return vmexec_ctrls & VMX_VM_EXEC_CTRL3_LOADIWKEY_VMEXIT; } bool HLAT_ENABLE() const { return vmexec_ctrls & VMX_VM_EXEC_CTRL3_HLAT_ENABLE; } @@ -180,6 +181,7 @@ public: bool IPI_VIRTUALIZATION() const { return vmexec_ctrls & VMX_VM_EXEC_CTRL3_IPI_VIRTUALIZATION; } bool ENABLE_MSRLIST() const { return vmexec_ctrls & VMX_VM_EXEC_CTRL3_ENABLE_MSRLIST; } bool VIRTUALIZE_IA32_SPEC_CTRL() const { return vmexec_ctrls & VMX_VM_EXEC_CTRL3_VIRTUALIZE_IA32_SPEC_CTRL; } + bool EMULATE_AVX10_VL256() const { return vmexec_ctrls & VMX_VM_EXEC_CTRL3_EMULATE_AVX10_VL256; } bool query_any(Bit64u mask) const { return (vmexec_ctrls & mask) != 0; } bool query_all(Bit64u mask) const { return (vmexec_ctrls & mask) == mask; } diff --git a/bochs/cpu/xsave.cc b/bochs/cpu/xsave.cc index b1521cd30..5985b677f 100644 --- a/bochs/cpu/xsave.cc +++ b/bochs/cpu/xsave.cc @@ -814,6 +814,14 @@ void BX_CPU_C::xrstor_zmm_hi256_state(bxInstruction_c *i, bx_address offset) unsigned num_regs = long64_mode() ? 16 : 8; +#if BX_SUPPORT_VMX + if (BX_CPU_THIS_PTR in_vmx_guest && BX_CPU_THIS_PTR vmcs.vmexec_ctrls3.EMULATE_AVX10_VL256()) { + for(unsigned index=0; index < num_regs; index++) + BX_CLEAR_AVX_HIGH256(index); + return; + } +#endif + bx_address asize_mask = i->asize_mask(); // load upper part of ZMM registers from XSAVE area @@ -888,10 +896,19 @@ void BX_CPU_C::xrstor_hi_zmm_state(bxInstruction_c *i, bx_address offset) bx_address asize_mask = i->asize_mask(); - if (! BX_CPU_THIS_PTR cpuid->support_avx10_512()) { - // restore the lower 256-bit of each ZMM register and ignore the contents of upper 256-bit + bool support_avx10_512 = BX_CPU_THIS_PTR cpuid->support_avx10_512(); +#if BX_SUPPORT_VMX + if (BX_CPU_THIS_PTR in_vmx_guest && BX_CPU_THIS_PTR vmcs.vmexec_ctrls3.EMULATE_AVX10_VL256()) + support_avx10_512 = false; +#endif + + if (! support_avx10_512) { + // Restore the lower 256-bit of each ZMM register and ignore the contents of upper 256-bit. + // Zero the upper 256 bits of each ZMM register in Hi16_ZMM state irrespective of the + // corresponding XSTATE_BV value. for(unsigned index=0; index < 16; index++) { read_virtual_ymmword(i->seg(), (offset+index*64) & asize_mask, &BX_READ_YMM_REG(index+16)); + BX_CLEAR_AVX_HIGH256(index+16); } } else {