rename VMEXIT controls in Bochs code to match their actual names and meaning
This commit is contained in:
parent
6b5928f522
commit
62c2c877d0
@ -1014,7 +1014,7 @@ bool BX_CPP_AttrRegparmN(1) BX_CPU_C::check_CR0(bx_address cr0_val)
|
||||
BX_ERROR(("check_CR0(0x%08x): attempt to clear CR0.NE in vmx mode !", temp_cr0.get32()));
|
||||
return 0;
|
||||
}
|
||||
if (!BX_CPU_THIS_PTR in_vmx_guest && !SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST)) {
|
||||
if (!BX_CPU_THIS_PTR in_vmx_guest && !SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST)) {
|
||||
if (!temp_cr0.get_PE() || !temp_cr0.get_PG()) {
|
||||
BX_ERROR(("check_CR0(0x%08x): attempt to clear CR0.PE/CR0.PG in vmx mode !", temp_cr0.get32()));
|
||||
return 0;
|
||||
@ -1474,7 +1474,7 @@ void BX_CPU_C::WriteCR8(bxInstruction_c *i, bx_address val)
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX && BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && VMEXIT(VMX_VM_EXEC_CTRL2_TPR_SHADOW)) {
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && VMEXIT(VMX_VM_EXEC_CTRL1_TPR_SHADOW)) {
|
||||
VMX_Write_Virtual_APIC(BX_LAPIC_TPR, tpr);
|
||||
VMX_TPR_Virtualization();
|
||||
return;
|
||||
@ -1498,7 +1498,7 @@ Bit32u BX_CPU_C::ReadCR8(bxInstruction_c *i)
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
VMexit_CR8_Read(i);
|
||||
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && VMEXIT(VMX_VM_EXEC_CTRL2_TPR_SHADOW)) {
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && VMEXIT(VMX_VM_EXEC_CTRL1_TPR_SHADOW)) {
|
||||
Bit32u tpr = (VMX_Read_Virtual_APIC(BX_LAPIC_TPR) >> 4) & 0xf;
|
||||
return tpr;
|
||||
}
|
||||
|
@ -502,9 +502,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDMSR(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_X2APIC_MODE)) {
|
||||
if (index >= 0x800 && index <= 0x8FF) {
|
||||
if (index == 0x808 || SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS)) {
|
||||
if (index == 0x808 || SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_REGISTERS)) {
|
||||
unsigned vapic_offset = (index & 0xff) << 4;
|
||||
RAX = VMX_Read_Virtual_APIC(vapic_offset);
|
||||
RDX = VMX_Read_Virtual_APIC(vapic_offset + 4);
|
||||
@ -1198,7 +1198,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::WRMSR(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_X2APIC_MODE)) {
|
||||
if (Virtualize_X2APIC_Write(index, val_64))
|
||||
BX_NEXT_INSTR(i);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MONITOR(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_MONITOR_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_MONITOR_VMEXIT)) {
|
||||
VMexit(VMX_VMEXIT_MONITOR, 0);
|
||||
}
|
||||
}
|
||||
@ -132,7 +132,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MWAIT(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_MWAIT_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_MWAIT_VMEXIT)) {
|
||||
VMexit(VMX_VMEXIT_MWAIT, BX_CPU_THIS_PTR monitor.armed);
|
||||
}
|
||||
}
|
||||
@ -189,7 +189,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MWAIT(bxInstruction_c *i)
|
||||
// When "interrupt window exiting" VMX control is set MWAIT instruction
|
||||
// won't cause the processor to enter sleep state with EFLAGS.IF = 0
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT) && ! BX_CPU_THIS_PTR get_IF()) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_INTERRUPT_WINDOW_VMEXIT) && ! BX_CPU_THIS_PTR get_IF()) {
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +455,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::INVLPG(bxInstruction_c* i)
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_INVLPG_VMEXIT)) VMexit(VMX_VMEXIT_INVLPG, laddr);
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_INVLPG_VMEXIT)) VMexit(VMX_VMEXIT_INVLPG, laddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -708,7 +708,7 @@ bx_phy_address BX_CPU_C::translate_linear_long_mode(bx_address laddr, Bit32u &lp
|
||||
entry_addr[leaf] = ppf + ((laddr >> (9 + 9*leaf)) & 0xff8);
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE))
|
||||
entry_addr[leaf] = translate_guest_physical(entry_addr[leaf], laddr, true /* laddr_valid */, true /* page walk */, IS_USER_PAGE(combined_access), BX_READ);
|
||||
}
|
||||
#endif
|
||||
@ -905,7 +905,7 @@ bool BX_CPP_AttrRegparmN(1) BX_CPU_C::CheckPDPTR(bx_phy_address cr3_val)
|
||||
cr3_val &= 0xffffffe0;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE))
|
||||
cr3_val = translate_guest_physical(cr3_val, 0, false /* laddr_valid */, true /* page walk */, 0, BX_READ);
|
||||
}
|
||||
#endif
|
||||
@ -1004,7 +1004,7 @@ bx_phy_address BX_CPU_C::translate_linear_PAE(bx_address laddr, Bit32u &lpf_mask
|
||||
entry_addr[leaf] = ppf + ((laddr >> (9 + 9*leaf)) & 0xff8);
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE))
|
||||
entry_addr[leaf] = translate_guest_physical(entry_addr[leaf], laddr, true /* laddr_valid */, true /* page walk */, IS_USER_PAGE(combined_access), BX_READ);
|
||||
}
|
||||
#endif
|
||||
@ -1145,7 +1145,7 @@ bx_phy_address BX_CPU_C::translate_linear_legacy(bx_address laddr, Bit32u &lpf_m
|
||||
entry_addr[leaf] = ppf + ((laddr >> (10 + 10*leaf)) & 0xffc);
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE))
|
||||
entry_addr[leaf] = translate_guest_physical(entry_addr[leaf], laddr, true /* laddr_valid */, true /* page walk */, IS_USER_PAGE(combined_access), BX_READ);
|
||||
}
|
||||
#endif
|
||||
@ -1377,7 +1377,7 @@ bx_phy_address BX_CPU_C::translate_linear(bx_TLB_entry *tlbEntry, bx_address lad
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
bool spp_page = false;
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE)) {
|
||||
paddress = translate_guest_physical(paddress, laddr, true /* laddr_valid */, false /* page walk */, IS_USER_PAGE(combined_access), rw, isShadowStack & !user, &spp_page);
|
||||
}
|
||||
}
|
||||
@ -1423,7 +1423,7 @@ bx_phy_address BX_CPU_C::translate_linear(bx_TLB_entry *tlbEntry, bx_address lad
|
||||
|
||||
if (! BX_CPU_THIS_PTR cr0.get_PG()
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
&& ! (BX_CPU_THIS_PTR in_vmx_guest && SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE))
|
||||
&& ! (BX_CPU_THIS_PTR in_vmx_guest && SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE))
|
||||
#endif
|
||||
#if BX_SUPPORT_SVM
|
||||
&& ! (BX_CPU_THIS_PTR in_svm_guest && SVM_NESTED_PAGING_ENABLED)
|
||||
@ -1937,7 +1937,7 @@ bx_phy_address BX_CPU_C::translate_guest_physical(bx_phy_address guest_paddr, bx
|
||||
|
||||
Bit64u offset_mask = BX_CONST64(0x0000ffffffffffff);
|
||||
Bit32u combined_access = 0x7, access_mask = 0;
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_MBE_CTRL))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_MBE_CTRL))
|
||||
combined_access |= BX_EPT_MBE_USER_EXECUTE;
|
||||
|
||||
BX_DEBUG(("EPT walk for guest paddr 0x" FMT_PHY_ADDRX, guest_paddr));
|
||||
@ -1947,7 +1947,7 @@ bx_phy_address BX_CPU_C::translate_guest_physical(bx_phy_address guest_paddr, bx
|
||||
rw = BX_WRITE;
|
||||
|
||||
if (rw == BX_EXECUTE) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_MBE_CTRL)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_MBE_CTRL)) {
|
||||
access_mask |= user_page ? BX_EPT_MBE_USER_EXECUTE : BX_EPT_MBE_SUPERVISOR_EXECUTE;
|
||||
}
|
||||
else {
|
||||
@ -1967,7 +1967,7 @@ bx_phy_address BX_CPU_C::translate_guest_physical(bx_phy_address guest_paddr, bx
|
||||
offset_mask >>= 9;
|
||||
Bit64u curr_entry = entry[leaf];
|
||||
Bit32u curr_access_mask = curr_entry & 0x7;
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_MBE_CTRL)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_MBE_CTRL)) {
|
||||
curr_access_mask |= (curr_entry & BX_EPT_MBE_USER_EXECUTE);
|
||||
}
|
||||
|
||||
@ -2054,7 +2054,7 @@ bx_phy_address BX_CPU_C::translate_guest_physical(bx_phy_address guest_paddr, bx
|
||||
|
||||
if ((access_mask & combined_access) != access_mask) {
|
||||
vmexit_reason = VMX_VMEXIT_EPT_VIOLATION;
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_SUBPAGE_WR_PROTECT_CTRL) && (entry[leaf] & BX_SUB_PAGE_PROTECTED) != 0 && leaf == BX_LEVEL_PTE) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_SUBPAGE_WR_PROTECT_CTRL) && (entry[leaf] & BX_SUB_PAGE_PROTECTED) != 0 && leaf == BX_LEVEL_PTE) {
|
||||
// if cumulative read-access bit is 0, the write access is not eligible for SPP
|
||||
if ((access_mask & BX_EPT_WRITE) != 0 && (combined_access & BX_EPT_ENTRY_READ_WRITE) == BX_EPT_ENTRY_READ_ONLY && guest_laddr_valid && ! is_page_walk) {
|
||||
if (spp_walk(guest_paddr, guest_laddr, BX_MEMTYPE_WB)) { // memory type indicated in IA32_VMX_BASIC MSR
|
||||
@ -2077,7 +2077,7 @@ bx_phy_address BX_CPU_C::translate_guest_physical(bx_phy_address guest_paddr, bx
|
||||
if (vmexit_reason == VMX_VMEXIT_EPT_VIOLATION) {
|
||||
combined_access &= entry[leaf];
|
||||
vmexit_qualification = access_mask | (combined_access << 3);
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_MBE_CTRL) && (rw == BX_EXECUTE)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_MBE_CTRL) && (rw == BX_EXECUTE)) {
|
||||
vmexit_qualification &= (0x3f); // reset all bit bits beyond [5:0]
|
||||
vmexit_qualification |= (1<<2); // bit2 indicate the operation was instruction fetch
|
||||
if (combined_access & BX_EPT_MBE_USER_EXECUTE)
|
||||
@ -2096,7 +2096,7 @@ bx_phy_address BX_CPU_C::translate_guest_physical(bx_phy_address guest_paddr, bx
|
||||
if (BX_VMX_EPT_SUPERVISOR_SHADOW_STACK_CTRL_ENABLED && (entry[leaf] & BX_SUPERVISOR_SHADOW_STACK_PAGE) != 0)
|
||||
vmexit_qualification |= (1 << 14);
|
||||
#endif
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_VIOLATION_EXCEPTION)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_VIOLATION_EXCEPTION)) {
|
||||
if ((entry[leaf] & BX_SUPPRESS_EPT_VIOLATION_EXCEPTION) == 0)
|
||||
Virtualization_Exception(vmexit_qualification, guest_paddr, guest_laddr);
|
||||
}
|
||||
@ -2110,7 +2110,7 @@ bx_phy_address BX_CPU_C::translate_guest_physical(bx_phy_address guest_paddr, bx
|
||||
if (BX_VMX_EPT_ACCESS_DIRTY_ENABLED) {
|
||||
// write access and Dirty-bit is not set in the leaf entry
|
||||
unsigned dirty_update = (rw & 1) && !(entry[leaf] & 0x200);
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_PML_ENABLE))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_PML_ENABLE))
|
||||
vmx_page_modification_logging(guest_paddr, dirty_update);
|
||||
|
||||
update_ept_access_dirty(entry_addr, entry, MEMTYPE(eptptr_memtype), leaf, rw & 1);
|
||||
@ -2290,7 +2290,7 @@ bool BX_CPU_C::dbg_translate_guest_physical_ept(bx_phy_address guest_paddr, bx_p
|
||||
BX_MEM(0)->readPhysicalPage(BX_CPU_THIS, pt_address, 8, &pte);
|
||||
#if BX_DEBUGGER
|
||||
if (verbose)
|
||||
dbg_print_ept_paging_pte(level, pte, SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_MBE_CTRL));
|
||||
dbg_print_ept_paging_pte(level, pte, SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_MBE_CTRL));
|
||||
#endif
|
||||
switch(pte & 7) {
|
||||
case BX_EPT_ENTRY_NOT_PRESENT:
|
||||
@ -2370,7 +2370,7 @@ bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy, bx_ad
|
||||
offset_mask >>= 9;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE)) {
|
||||
if (! dbg_translate_guest_physical_ept(pt_address, &pt_address, verbose))
|
||||
goto page_fault;
|
||||
}
|
||||
@ -2414,7 +2414,7 @@ bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy, bx_ad
|
||||
pt_address += ((laddr >> (10 + 10*level)) & 0xffc);
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE)) {
|
||||
if (! dbg_translate_guest_physical_ept(pt_address, &pt_address, verbose))
|
||||
goto page_fault;
|
||||
}
|
||||
@ -2450,7 +2450,7 @@ bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy, bx_ad
|
||||
}
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_EPT_ENABLE)) {
|
||||
if (! dbg_translate_guest_physical_ept(paddress, &paddress, verbose))
|
||||
goto page_fault;
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::HLT(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_HLT_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_HLT_VMEXIT)) {
|
||||
VMexit(VMX_VMEXIT_HLT, 0);
|
||||
}
|
||||
}
|
||||
@ -264,7 +264,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::WBINVD(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_WBINVD_VMEXIT)) {
|
||||
VMexit(VMX_VMEXIT_WBINVD, 0);
|
||||
}
|
||||
}
|
||||
@ -594,7 +594,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDPMC(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_RDPMC_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_RDPMC_VMEXIT)) {
|
||||
VMexit(VMX_VMEXIT_RDPMC, 0);
|
||||
}
|
||||
}
|
||||
@ -650,7 +650,7 @@ Bit64u BX_CPU_C::get_TSC_VMXAdjust(Bit64u tsc)
|
||||
{
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_TSC_OFFSET) && SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_TSC_SCALING)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_TSC_OFFSET) && SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_TSC_SCALING)) {
|
||||
Bit128u product_128;
|
||||
long_mul(&product_128,tsc,BX_CPU_THIS_PTR vmcs.tsc_multiplier);
|
||||
tsc = (product_128.lo >> 48) | (product_128.hi << 16); // tsc = (uint64) (long128(tsc_value * tsc_multiplier) >> 48);
|
||||
@ -683,7 +683,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSC(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_RDTSC_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_RDTSC_VMEXIT)) {
|
||||
VMexit(VMX_VMEXIT_RDTSC, 0);
|
||||
}
|
||||
}
|
||||
@ -716,7 +716,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSCP(bxInstruction_c *i)
|
||||
#if BX_SUPPORT_VMX
|
||||
// RDTSCP will always #UD in legacy VMX mode, the #UD takes priority over any other exception the instruction may incur.
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_RDTSCP)) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_RDTSCP)) {
|
||||
BX_ERROR(("%s in VMX guest: not allowed to use instruction !", i->getIaOpcodeNameShort()));
|
||||
exception(BX_UD_EXCEPTION, 0);
|
||||
}
|
||||
@ -730,7 +730,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSCP(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_RDTSC_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_RDTSC_VMEXIT)) {
|
||||
VMexit(VMX_VMEXIT_RDTSCP, 0);
|
||||
}
|
||||
}
|
||||
@ -763,7 +763,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDPID_Ed(bxInstruction_c *i)
|
||||
#if BX_SUPPORT_VMX
|
||||
// RDTSCP will always #UD in legacy VMX mode
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_RDTSCP)) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_RDTSCP)) {
|
||||
BX_ERROR(("%s in VMX guest: not allowed to use instruction !", i->getIaOpcodeNameShort()));
|
||||
exception(BX_UD_EXCEPTION, 0);
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SLDT_Ew(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_LDTR_TR_ACCESS, BX_READ);
|
||||
#endif
|
||||
|
||||
@ -339,7 +339,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::STR_Ew(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_LDTR_TR_ACCESS, BX_READ);
|
||||
#endif
|
||||
|
||||
@ -390,7 +390,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LLDT_Ew(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_LDTR_TR_ACCESS, BX_WRITE);
|
||||
#endif
|
||||
|
||||
@ -493,7 +493,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LTR_Ew(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_LDTR_TR_ACCESS, BX_WRITE);
|
||||
#endif
|
||||
|
||||
@ -769,7 +769,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SGDT_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_GDTR_IDTR_ACCESS, BX_READ);
|
||||
#endif
|
||||
|
||||
@ -803,7 +803,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SIDT_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_GDTR_IDTR_ACCESS, BX_READ);
|
||||
#endif
|
||||
|
||||
@ -836,7 +836,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LGDT_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_GDTR_IDTR_ACCESS, BX_WRITE);
|
||||
#endif
|
||||
|
||||
@ -871,7 +871,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LIDT_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_GDTR_IDTR_ACCESS, BX_WRITE);
|
||||
#endif
|
||||
|
||||
@ -907,7 +907,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SGDT64_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_GDTR_IDTR_ACCESS, BX_READ);
|
||||
#endif
|
||||
|
||||
@ -939,7 +939,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SIDT64_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_GDTR_IDTR_ACCESS, BX_READ);
|
||||
#endif
|
||||
|
||||
@ -971,7 +971,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LGDT64_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_GDTR_IDTR_ACCESS, BX_WRITE);
|
||||
#endif
|
||||
|
||||
@ -1007,7 +1007,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LIDT64_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT))
|
||||
VMexit_Instruction(i, VMX_VMEXIT_GDTR_IDTR_ACCESS, BX_WRITE);
|
||||
#endif
|
||||
|
||||
|
@ -80,7 +80,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDRAND_Ew(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_RDRAND_VMEXIT)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_RDRAND_VMEXIT)) {
|
||||
VMexit_Instruction(i, VMX_VMEXIT_RDRAND, BX_READ);
|
||||
}
|
||||
}
|
||||
@ -104,7 +104,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDRAND_Ed(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_RDRAND_VMEXIT)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_RDRAND_VMEXIT)) {
|
||||
VMexit_Instruction(i, VMX_VMEXIT_RDRAND, BX_READ);
|
||||
}
|
||||
}
|
||||
@ -129,7 +129,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDRAND_Eq(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_RDRAND_VMEXIT)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_RDRAND_VMEXIT)) {
|
||||
VMexit_Instruction(i, VMX_VMEXIT_RDRAND, BX_READ);
|
||||
}
|
||||
}
|
||||
@ -154,7 +154,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDSEED_Ew(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_RDSEED_VMEXIT)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_RDSEED_VMEXIT)) {
|
||||
VMexit_Instruction(i, VMX_VMEXIT_RDSEED, BX_READ);
|
||||
}
|
||||
}
|
||||
@ -178,7 +178,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDSEED_Ed(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_RDSEED_VMEXIT)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_RDSEED_VMEXIT)) {
|
||||
VMexit_Instruction(i, VMX_VMEXIT_RDSEED, BX_READ);
|
||||
}
|
||||
}
|
||||
@ -203,7 +203,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDSEED_Eq(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_RDSEED_VMEXIT)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_RDSEED_VMEXIT)) {
|
||||
VMexit_Instruction(i, VMX_VMEXIT_RDSEED, BX_READ);
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ bool BX_CPP_AttrRegparmN(1) BX_CPU_C::is_virtual_apic_page(bx_phy_address paddr)
|
||||
{
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_ACCESSES))
|
||||
if (PPFOf(paddr) == vm->apic_access_page) return true;
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ bool BX_CPP_AttrRegparmN(2) BX_CPU_C::virtual_apic_access_vmexit(unsigned offset
|
||||
}
|
||||
|
||||
// access is not instruction fetch because cpu::prefetch will crash them
|
||||
if (! VMEXIT(VMX_VM_EXEC_CTRL2_TPR_SHADOW) || len > 4 || offset >= 0x400)
|
||||
if (! VMEXIT(VMX_VM_EXEC_CTRL1_TPR_SHADOW) || len > 4 || offset >= 0x400)
|
||||
return true;
|
||||
|
||||
BX_CPU_THIS_PTR vmcs.apic_access = offset;
|
||||
@ -91,7 +91,7 @@ void BX_CPU_C::VMX_Write_Virtual_X2APIC(unsigned offset, Bit64u val64)
|
||||
|
||||
bx_phy_address BX_CPU_C::VMX_Virtual_Apic_Read(bx_phy_address paddr, unsigned len, void *data)
|
||||
{
|
||||
BX_ASSERT(SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES));
|
||||
BX_ASSERT(SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_ACCESSES));
|
||||
|
||||
BX_INFO(("Virtual Apic RD 0x" FMT_ADDRX " len = %d", paddr, len));
|
||||
|
||||
@ -102,7 +102,7 @@ bx_phy_address BX_CPU_C::VMX_Virtual_Apic_Read(bx_phy_address paddr, unsigned le
|
||||
// access is not instruction fetch because cpu::prefetch will crash them
|
||||
if (! vmexit) {
|
||||
|
||||
if (!SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS)) {
|
||||
if (!SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_REGISTERS)) {
|
||||
// if 'Virtualize Apic Registers' control is disabled allow only aligned access to VTPR
|
||||
if (offset != BX_LAPIC_TPR) vmexit = true;
|
||||
}
|
||||
@ -174,7 +174,7 @@ bx_phy_address BX_CPU_C::VMX_Virtual_Apic_Read(bx_phy_address paddr, unsigned le
|
||||
|
||||
void BX_CPU_C::VMX_Virtual_Apic_Write(bx_phy_address paddr, unsigned len, void *data)
|
||||
{
|
||||
BX_ASSERT(SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES));
|
||||
BX_ASSERT(SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_ACCESSES));
|
||||
|
||||
BX_INFO(("Virtual Apic WR 0x" FMT_ADDRX " len = %d", paddr, len));
|
||||
|
||||
@ -192,7 +192,7 @@ void BX_CPU_C::VMX_Virtual_Apic_Write(bx_phy_address paddr, unsigned len, void *
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY)) {
|
||||
if (offset == BX_LAPIC_EOI) {
|
||||
signal_event(BX_EVENT_VMX_VEOI_UPDATE);
|
||||
}
|
||||
@ -215,14 +215,14 @@ void BX_CPU_C::VMX_Virtual_Apic_Write(bx_phy_address paddr, unsigned len, void *
|
||||
case BX_LAPIC_TIMER_INITIAL_COUNT:
|
||||
case BX_LAPIC_TIMER_DIVIDE_CFG:
|
||||
// VMX_VMEXIT_APIC_ACCESS if the control is disabled
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS)) break;
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_REGISTERS)) break;
|
||||
// else fall through
|
||||
|
||||
case BX_LAPIC_EOI:
|
||||
case BX_LAPIC_ICR_LO:
|
||||
// VMX_VMEXIT_APIC_ACCESS if both controls are disabled
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY) &&
|
||||
! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS)) break;
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY) &&
|
||||
! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_REGISTERS)) break;
|
||||
// else fall through
|
||||
|
||||
// remap access to virtual apic page
|
||||
@ -280,7 +280,7 @@ void BX_CPU_C::VMX_Evaluate_Pending_Virtual_Interrupts(void)
|
||||
{
|
||||
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||
|
||||
if (! VMEXIT(VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT) && (vm->rvi >> 4) > (vm->vppr >> 4))
|
||||
if (! VMEXIT(VMX_VM_EXEC_CTRL1_INTERRUPT_WINDOW_VMEXIT) && (vm->rvi >> 4) > (vm->vppr >> 4))
|
||||
{
|
||||
BX_INFO(("Pending Virtual Interrupt Vector 0x%x", vm->rvi));
|
||||
signal_event(BX_EVENT_PENDING_VMX_VIRTUAL_INTR);
|
||||
@ -301,7 +301,7 @@ void BX_CPU_C::VMX_TPR_Virtualization(void)
|
||||
clear_event(BX_EVENT_VMX_VTPR_UPDATE);
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY)) {
|
||||
VMX_PPR_Virtualization();
|
||||
VMX_Evaluate_Pending_Virtual_Interrupts();
|
||||
}
|
||||
@ -341,7 +341,7 @@ void BX_CPU_C::VMX_EOI_Virtualization(void)
|
||||
|
||||
clear_event(BX_EVENT_VMX_VEOI_UPDATE);
|
||||
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY))
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY))
|
||||
{
|
||||
VMX_Write_Virtual_APIC(BX_LAPIC_EOI, 0);
|
||||
|
||||
@ -410,7 +410,7 @@ void BX_CPU_C::VMX_Write_VICR(void)
|
||||
|
||||
// reserved bits (31:20, 17:16, 13), 15 (trigger mode), 12 (delivery status), 10:8 (delivery mode) must be 0
|
||||
// destination shorthand: must be self
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY) &&
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY) &&
|
||||
(vicr & 0xfff3b700) == 0 && (dest_shorthand == 0x1) && vector >= 16)
|
||||
{
|
||||
VMX_Self_IPI_Virtualization(vector);
|
||||
@ -470,7 +470,7 @@ bool BX_CPU_C::Virtualize_X2APIC_Write(unsigned msr, Bit64u val_64)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY)) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY)) {
|
||||
if (msr == 0x80b) {
|
||||
// EOI virtualization
|
||||
if (val_64 != 0)
|
||||
|
@ -659,50 +659,50 @@ void BX_CPU_C::init_primary_proc_based_vmexec_ctrls(void)
|
||||
// [31] Secondary proc-based vmexec controls
|
||||
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits =
|
||||
VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL2_TSC_OFFSET |
|
||||
VMX_VM_EXEC_CTRL2_HLT_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL2_INVLPG_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL2_RDPMC_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL2_RDTSC_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL2_DRx_ACCESS_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL2_IO_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL2_IO_BITMAPS |
|
||||
VMX_VM_EXEC_CTRL2_MSR_BITMAPS |
|
||||
VMX_VM_EXEC_CTRL2_PAUSE_VMEXIT;
|
||||
VMX_VM_EXEC_CTRL1_INTERRUPT_WINDOW_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL1_TSC_OFFSET |
|
||||
VMX_VM_EXEC_CTRL1_HLT_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL1_INVLPG_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL1_RDPMC_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL1_RDTSC_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL1_DRx_ACCESS_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL1_IO_VMEXIT |
|
||||
VMX_VM_EXEC_CTRL1_IO_BITMAPS |
|
||||
VMX_VM_EXEC_CTRL1_MSR_BITMAPS |
|
||||
VMX_VM_EXEC_CTRL1_PAUSE_VMEXIT;
|
||||
|
||||
#if BX_SUPPORT_MONITOR_MWAIT
|
||||
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_MONITOR_MWAIT)) {
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |=
|
||||
VMX_VM_EXEC_CTRL2_MWAIT_VMEXIT | VMX_VM_EXEC_CTRL2_MONITOR_VMEXIT;
|
||||
VMX_VM_EXEC_CTRL1_MWAIT_VMEXIT | VMX_VM_EXEC_CTRL1_MONITOR_VMEXIT;
|
||||
}
|
||||
#endif
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_TPR_SHADOW)) {
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_TPR_SHADOW;
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL1_TPR_SHADOW;
|
||||
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_LONG_MODE))
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |=
|
||||
VMX_VM_EXEC_CTRL2_CR8_WRITE_VMEXIT | VMX_VM_EXEC_CTRL2_CR8_READ_VMEXIT;
|
||||
VMX_VM_EXEC_CTRL1_CR8_WRITE_VMEXIT | VMX_VM_EXEC_CTRL1_CR8_READ_VMEXIT;
|
||||
}
|
||||
#endif
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VIRTUAL_NMI))
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_NMI_WINDOW_EXITING;
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL1_NMI_WINDOW_EXITING;
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_MONITOR_TRAP_FLAG))
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_MONITOR_TRAP_FLAG;
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL1_MONITOR_TRAP_FLAG;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT)) {
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |=
|
||||
VMX_VM_EXEC_CTRL2_CR3_WRITE_VMEXIT | VMX_VM_EXEC_CTRL2_CR3_READ_VMEXIT;
|
||||
VMX_VM_EXEC_CTRL1_CR3_WRITE_VMEXIT | VMX_VM_EXEC_CTRL1_CR3_READ_VMEXIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// enable secondary vm exec controls if there are secondary proc-based vmexec controls present
|
||||
if (cap->vmx_vmexec_ctrl2_supported_bits != 0)
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_SECONDARY_CONTROLS;
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL1_SECONDARY_CONTROLS;
|
||||
|
||||
// enable tertiary vm exec controls if there are tertiary proc-based vmexec controls present
|
||||
if (cap->vmx_vmexec_ctrl3_supported_bits != 0)
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_TERTIARY_CONTROLS;
|
||||
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL1_TERTIARY_CONTROLS;
|
||||
}
|
||||
|
||||
void BX_CPU_C::init_secondary_proc_based_vmexec_ctrls(void)
|
||||
@ -742,79 +742,79 @@ void BX_CPU_C::init_secondary_proc_based_vmexec_ctrls(void)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_APIC_VIRTUALIZATION))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_ACCESSES;
|
||||
#endif
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_EPT_ENABLE;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_EPT_ENABLE;
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_DESCRIPTOR_TABLE_EXIT))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT;
|
||||
#endif
|
||||
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_RDTSCP))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_RDTSCP;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_RDTSCP;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_X2APIC_VIRTUALIZATION))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_VIRTUALIZE_X2APIC_MODE;
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VPID))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VPID_ENABLE;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_VPID_ENABLE;
|
||||
#endif
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_WBINVD_VMEXIT))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_WBINVD_VMEXIT;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_UNRESTRICTED_GUEST))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST;
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VINTR_DELIVERY))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS | VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_REGISTERS | VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY;
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PAUSE_LOOP_EXITING))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_PAUSE_LOOP_VMEXIT;
|
||||
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_INVPCID))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_INVPCID;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_INVPCID;
|
||||
#endif
|
||||
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_RDRAND))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_RDRAND_VMEXIT;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_RDRAND_VMEXIT;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VMCS_SHADOWING))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VMCS_SHADOWING;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_VMCS_SHADOWING;
|
||||
#endif
|
||||
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_RDSEED))
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_RDSEED_VMEXIT;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_RDSEED_VMEXIT;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PML)) {
|
||||
if (! BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT))
|
||||
BX_PANIC(("VMX PML feature requires EPT support !"));
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_PML_ENABLE;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_PML_ENABLE;
|
||||
}
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT_EXCEPTION)) {
|
||||
if (! BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPTP_SWITCHING))
|
||||
BX_PANIC(("#VE exception feature requires EPTP switching support !"));
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_EPT_VIOLATION_EXCEPTION;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_EPT_VIOLATION_EXCEPTION;
|
||||
}
|
||||
#endif
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_XSAVES)) {
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_XSAVES_XRSTORS;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_XSAVES_XRSTORS;
|
||||
}
|
||||
#endif
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_MBE_CONTROL)) {
|
||||
if (! BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT))
|
||||
BX_PANIC(("VMX MBE feature requires EPT support !"));
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_MBE_CTRL;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_MBE_CTRL;
|
||||
}
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_SPP)) {
|
||||
if (! BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT))
|
||||
BX_PANIC(("VMX SPP feature requires EPT support !"));
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_SUBPAGE_WR_PROTECT_CTRL;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_SUBPAGE_WR_PROTECT_CTRL;
|
||||
}
|
||||
#endif
|
||||
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_TSC_SCALING)) {
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_TSC_SCALING;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_TSC_SCALING;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
// enable vm functions secondary vmexec control if there are supported vmfunctions
|
||||
if (cap->vmx_vmfunc_supported_bits != 0)
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VMFUNC_ENABLE;
|
||||
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL2_VMFUNC_ENABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -167,12 +167,12 @@ void BX_CPU_C::VMexit_PAUSE(void)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR in_vmx_guest);
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_PAUSE_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_PAUSE_VMEXIT)) {
|
||||
VMexit(VMX_VMEXIT_PAUSE, 0);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT) && CPL == 0) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_PAUSE_LOOP_VMEXIT) && CPL == 0) {
|
||||
VMX_PLE *ple = &BX_CPU_THIS_PTR vmcs.ple;
|
||||
Bit64u currtime = bx_pc_system.time_ticks();
|
||||
if ((currtime - ple->last_pause_time) > ple->pause_loop_exiting_gap) {
|
||||
@ -323,7 +323,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::VMexit_MSR(unsigned op, Bit32u msr)
|
||||
BX_ASSERT(BX_CPU_THIS_PTR in_vmx_guest);
|
||||
|
||||
bool vmexit = false;
|
||||
if (! VMEXIT(VMX_VM_EXEC_CTRL2_MSR_BITMAPS)) vmexit = true;
|
||||
if (! VMEXIT(VMX_VM_EXEC_CTRL1_MSR_BITMAPS)) vmexit = true;
|
||||
else {
|
||||
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||
Bit8u field;
|
||||
@ -372,7 +372,7 @@ void BX_CPP_AttrRegparmN(3) BX_CPU_C::VMexit_IO(bxInstruction_c *i, unsigned por
|
||||
|
||||
bool vmexit = false;
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_IO_BITMAPS)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_IO_BITMAPS)) {
|
||||
// always VMEXIT on port "wrap around" case
|
||||
if ((port + len) > 0x10000) vmexit = true;
|
||||
else {
|
||||
@ -407,7 +407,7 @@ void BX_CPP_AttrRegparmN(3) BX_CPU_C::VMexit_IO(bxInstruction_c *i, unsigned por
|
||||
if (combined_bitmap & mask) vmexit = true;
|
||||
}
|
||||
}
|
||||
else if (VMEXIT(VMX_VM_EXEC_CTRL2_IO_VMEXIT)) vmexit = true;
|
||||
else if (VMEXIT(VMX_VM_EXEC_CTRL1_IO_VMEXIT)) vmexit = true;
|
||||
|
||||
if (vmexit) {
|
||||
BX_DEBUG(("VMEXIT: I/O port 0x%04x", port));
|
||||
@ -568,7 +568,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMexit_CR3_Read(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR in_vmx_guest);
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_CR3_READ_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_CR3_READ_VMEXIT)) {
|
||||
BX_DEBUG(("VMEXIT: CR3 read"));
|
||||
Bit64u qualification = 3 | (VMX_VMEXIT_CR_ACCESS_CR_READ << 4) | (i->dst() << 8);
|
||||
VMexit(VMX_VMEXIT_CR_ACCESS, qualification);
|
||||
@ -581,7 +581,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::VMexit_CR3_Write(bxInstruction_c *i, bx_ad
|
||||
|
||||
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_CR3_WRITE_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_CR3_WRITE_VMEXIT)) {
|
||||
for (unsigned n=0; n < vm->vm_cr3_target_cnt; n++) {
|
||||
if (vm->vm_cr3_target_value[n] == val) return;
|
||||
}
|
||||
@ -613,7 +613,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMexit_CR8_Read(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR in_vmx_guest);
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_CR8_READ_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_CR8_READ_VMEXIT)) {
|
||||
BX_DEBUG(("VMEXIT: CR8 read"));
|
||||
Bit64u qualification = 8 | (VMX_VMEXIT_CR_ACCESS_CR_READ << 4) | (i->dst() << 8);
|
||||
VMexit(VMX_VMEXIT_CR_ACCESS, qualification);
|
||||
@ -624,7 +624,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMexit_CR8_Write(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR in_vmx_guest);
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_CR8_WRITE_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_CR8_WRITE_VMEXIT)) {
|
||||
BX_DEBUG(("VMEXIT: CR8 write"));
|
||||
Bit64u qualification = 8 | (i->src() << 8);
|
||||
VMexit(VMX_VMEXIT_CR_ACCESS, qualification);
|
||||
@ -646,7 +646,7 @@ void BX_CPU_C::VMexit_DR_Access(unsigned read, unsigned dr, unsigned reg)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR in_vmx_guest);
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_DRx_ACCESS_VMEXIT))
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_DRx_ACCESS_VMEXIT))
|
||||
{
|
||||
BX_DEBUG(("VMEXIT: DR%d %s access", dr, read ? "READ" : "WRITE"));
|
||||
|
||||
@ -661,7 +661,7 @@ void BX_CPU_C::VMexit_DR_Access(unsigned read, unsigned dr, unsigned reg)
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
Bit16u BX_CPU_C::VMX_Get_Current_VPID(void)
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR in_vmx_guest || !SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VPID_ENABLE))
|
||||
if (! BX_CPU_THIS_PTR in_vmx_guest || !SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VPID_ENABLE))
|
||||
return 0;
|
||||
|
||||
return BX_CPU_THIS_PTR vmcs.vpid;
|
||||
@ -673,7 +673,7 @@ bool BX_CPP_AttrRegparmN(1) BX_CPU_C::Vmexit_Vmread(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR in_vmx_guest);
|
||||
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VMCS_SHADOWING)) return true;
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VMCS_SHADOWING)) return true;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
|
||||
@ -700,7 +700,7 @@ bool BX_CPP_AttrRegparmN(1) BX_CPU_C::Vmexit_Vmwrite(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR in_vmx_guest);
|
||||
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VMCS_SHADOWING)) return true;
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VMCS_SHADOWING)) return true;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
|
||||
|
@ -29,7 +29,7 @@
|
||||
void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMFUNC(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (! BX_CPU_THIS_PTR in_vmx_guest || ! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VMFUNC_ENABLE))
|
||||
if (! BX_CPU_THIS_PTR in_vmx_guest || ! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_VMFUNC_ENABLE))
|
||||
exception(BX_UD_EXCEPTION, 0);
|
||||
|
||||
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||
|
120
bochs/cpu/vmx.cc
120
bochs/cpu/vmx.cc
@ -575,17 +575,17 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
//
|
||||
|
||||
vm->pin_vmexec_ctrls = VMread32(VMCS_32BIT_CONTROL_PIN_BASED_EXEC_CONTROLS);
|
||||
vm->vmexec_ctrls2 = VMread32(VMCS_32BIT_CONTROL_PROCESSOR_BASED_VMEXEC_CONTROLS);
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_SECONDARY_CONTROLS))
|
||||
vm->vmexec_ctrls3 = VMread32(VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS);
|
||||
vm->vmexec_ctrls1 = VMread32(VMCS_32BIT_CONTROL_PROCESSOR_BASED_VMEXEC_CONTROLS);
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_SECONDARY_CONTROLS))
|
||||
vm->vmexec_ctrls2 = VMread32(VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS);
|
||||
else
|
||||
vm->vmexec_ctrls2 = 0;
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_TERTIARY_CONTROLS))
|
||||
vm->vmexec_ctrls3 = VMread64(VMCS_64BIT_CONTROL_TERTIARY_VMEXEC_CONTROLS);
|
||||
else
|
||||
vm->vmexec_ctrls3 = 0;
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_TERTIARY_CONTROLS))
|
||||
vm->vmexec_ctrls4 = VMread64(VMCS_64BIT_CONTROL_TERTIARY_VMEXEC_CONTROLS);
|
||||
else
|
||||
vm->vmexec_ctrls4 = 0;
|
||||
|
||||
vm->vm_exceptions_bitmap = VMread32(VMCS_32BIT_CONTROL_EXECUTION_BITMAP);
|
||||
vm->vm_pf_mask = VMread32(VMCS_32BIT_CONTROL_PAGE_FAULT_ERR_CODE_MASK);
|
||||
vm->vm_pf_match = VMread32(VMCS_32BIT_CONTROL_PAGE_FAULT_ERR_CODE_MATCH);
|
||||
@ -611,21 +611,21 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
|
||||
if (~vm->vmexec_ctrls2 & VMX_CHECKS_USE_MSR_VMX_PROCBASED_CTRLS_LO) {
|
||||
if (~vm->vmexec_ctrls1 & VMX_CHECKS_USE_MSR_VMX_PROCBASED_CTRLS_LO) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: VMX proc-based controls allowed 0-settings"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
if (vm->vmexec_ctrls2 & ~VMX_CHECKS_USE_MSR_VMX_PROCBASED_CTRLS_HI) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: VMX proc-based controls allowed 1-settings [0x%08x]", vm->vmexec_ctrls2 & ~VMX_CHECKS_USE_MSR_VMX_PROCBASED_CTRLS_HI));
|
||||
if (vm->vmexec_ctrls1 & ~VMX_CHECKS_USE_MSR_VMX_PROCBASED_CTRLS_HI) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: VMX proc-based controls allowed 1-settings [0x%08x]", vm->vmexec_ctrls1 & ~VMX_CHECKS_USE_MSR_VMX_PROCBASED_CTRLS_HI));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
|
||||
if (~vm->vmexec_ctrls3 & VMX_MSR_VMX_PROCBASED_CTRLS2_LO) {
|
||||
if (~vm->vmexec_ctrls2 & VMX_MSR_VMX_PROCBASED_CTRLS2_LO) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: VMX secondary proc-based controls allowed 0-settings"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
if (vm->vmexec_ctrls3 & ~VMX_MSR_VMX_PROCBASED_CTRLS2_HI) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: VMX secondary controls allowed 1-settings [0x%08x]", vm->vmexec_ctrls3 & ~VMX_MSR_VMX_PROCBASED_CTRLS2_HI));
|
||||
if (vm->vmexec_ctrls2 & ~VMX_MSR_VMX_PROCBASED_CTRLS2_HI) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: VMX secondary controls allowed 1-settings [0x%08x]", vm->vmexec_ctrls2 & ~VMX_MSR_VMX_PROCBASED_CTRLS2_HI));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
|
||||
@ -634,7 +634,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_IO_BITMAPS) {
|
||||
if (vm->vmexec_ctrls1 & VMX_VM_EXEC_CTRL1_IO_BITMAPS) {
|
||||
vm->io_bitmap_addr[0] = VMread64(VMCS_64BIT_CONTROL_IO_BITMAP_A);
|
||||
vm->io_bitmap_addr[1] = VMread64(VMCS_64BIT_CONTROL_IO_BITMAP_B);
|
||||
// I/O bitmaps control enabled
|
||||
@ -646,7 +646,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_MSR_BITMAPS) {
|
||||
if (vm->vmexec_ctrls1 & VMX_VM_EXEC_CTRL1_MSR_BITMAPS) {
|
||||
// MSR bitmaps control enabled
|
||||
vm->msr_bitmap_addr = (bx_phy_address) VMread64(VMCS_64BIT_CONTROL_MSR_BITMAPS);
|
||||
if (! IsValidPageAlignedPhyAddr(vm->msr_bitmap_addr)) {
|
||||
@ -663,14 +663,14 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
|
||||
if (! (vm->pin_vmexec_ctrls & VMX_PIN_BASED_VMEXEC_CTRL_VIRTUAL_NMI)) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_NMI_WINDOW_EXITING) {
|
||||
if (vm->vmexec_ctrls1 & VMX_VM_EXEC_CTRL1_NMI_WINDOW_EXITING) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: misconfigured virtual NMI control"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VMCS_SHADOWING) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VMCS_SHADOWING) {
|
||||
vm->vmread_bitmap_addr = (bx_phy_address) VMread64(VMCS_64BIT_CONTROL_VMREAD_BITMAP_ADDR);
|
||||
if (! IsValidPageAlignedPhyAddr(vm->vmread_bitmap_addr)) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: VMREAD bitmap phy addr malformed"));
|
||||
@ -683,7 +683,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_VIOLATION_EXCEPTION) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_VIOLATION_EXCEPTION) {
|
||||
vm->ve_info_addr = (bx_phy_address) VMread64(VMCS_64BIT_CONTROL_VE_EXCEPTION_INFO_ADDR);
|
||||
if (! IsValidPageAlignedPhyAddr(vm->ve_info_addr)) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: broken #VE information address"));
|
||||
@ -693,7 +693,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_TPR_SHADOW) {
|
||||
if (vm->vmexec_ctrls1 & VMX_VM_EXEC_CTRL1_TPR_SHADOW) {
|
||||
vm->virtual_apic_page_addr = (bx_phy_address) VMread64(VMCS_64BIT_CONTROL_VIRTUAL_APIC_PAGE_ADDR);
|
||||
if (! IsValidPageAlignedPhyAddr(vm->virtual_apic_page_addr)) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: virtual apic phy addr malformed"));
|
||||
@ -701,7 +701,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY) {
|
||||
if (! PIN_VMEXIT(VMX_PIN_BASED_VMEXEC_CTRL_EXTERNAL_INTERRUPT_VMEXIT)) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: virtual interrupt delivery must be set together with external interrupt exiting"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
@ -725,7 +725,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
|
||||
if (! (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES)) {
|
||||
if (! (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_ACCESSES)) {
|
||||
Bit8u tpr_shadow = (VMX_Read_Virtual_APIC(BX_LAPIC_TPR) >> 4) & 0xf;
|
||||
if (vm->vm_tpr_threshold > tpr_shadow) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: TPR threshold > TPR shadow"));
|
||||
@ -736,9 +736,9 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
else { // TPR shadow is disabled
|
||||
if (vm->vmexec_ctrls3 & (VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE |
|
||||
VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS |
|
||||
VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY))
|
||||
if (vm->vmexec_ctrls2 & (VMX_VM_EXEC_CTRL2_VIRTUALIZE_X2APIC_MODE |
|
||||
VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_REGISTERS |
|
||||
VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY))
|
||||
{
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: apic virtualization is enabled without TPR shadow"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
@ -746,7 +746,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
#endif // BX_SUPPORT_VMX >= 2
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_ACCESSES) {
|
||||
vm->apic_access_page = (bx_phy_address) VMread64(VMCS_64BIT_CONTROL_APIC_ACCESS_ADDR);
|
||||
if (! IsValidPageAlignedPhyAddr(vm->apic_access_page)) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: apic access page phy addr malformed"));
|
||||
@ -754,7 +754,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VIRTUALIZE_X2APIC_MODE) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: virtualize X2APIC mode enabled together with APIC access virtualization"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
@ -762,7 +762,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_ENABLE) {
|
||||
vm->eptptr = (bx_phy_address) VMread64(VMCS_64BIT_CONTROL_EPTPTR);
|
||||
if (! is_eptptr_valid(vm->eptptr)) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: invalid EPTPTR value"));
|
||||
@ -770,13 +770,13 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: unrestricted guest without EPT"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VPID_ENABLE) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VPID_ENABLE) {
|
||||
vm->vpid = VMread16(VMCS_16BIT_CONTROL_VPID);
|
||||
if (vm->vpid == 0) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: guest VPID == 0"));
|
||||
@ -784,12 +784,12 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_PAUSE_LOOP_VMEXIT) {
|
||||
vm->ple.pause_loop_exiting_gap = VMread32(VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_GAP);
|
||||
vm->ple.pause_loop_exiting_window = VMread32(VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_WINDOW);
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VMFUNC_ENABLE)
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VMFUNC_ENABLE)
|
||||
vm->vmfunc_ctrls = VMread64(VMCS_64BIT_CONTROL_VMFUNC_CTRLS);
|
||||
else
|
||||
vm->vmfunc_ctrls = 0;
|
||||
@ -800,7 +800,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
|
||||
if (vm->vmfunc_ctrls & VMX_VMFUNC_EPTP_SWITCHING_MASK) {
|
||||
if ((vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) == 0) {
|
||||
if ((vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_ENABLE) == 0) {
|
||||
BX_ERROR(("VMFAIL: VMFUNC EPTP-SWITCHING: EPT disabled"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
@ -812,8 +812,8 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_PML_ENABLE) {
|
||||
if ((vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) == 0) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_PML_ENABLE) {
|
||||
if ((vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_ENABLE) == 0) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: PML is enabled without EPT"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
@ -826,8 +826,8 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
vm->pml_index = VMread16(VMCS_16BIT_GUEST_PML_INDEX);
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_SUBPAGE_WR_PROTECT_CTRL) {
|
||||
if ((vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) == 0) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_SUBPAGE_WR_PROTECT_CTRL) {
|
||||
if ((vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_ENABLE) == 0) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: SPP is enabled without EPT"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
@ -839,14 +839,14 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_MBE_CTRL) {
|
||||
if ((vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) == 0) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_MBE_CTRL) {
|
||||
if ((vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_ENABLE) == 0) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: MBE is enabled without EPT"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_XSAVES_XRSTORS)
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_XSAVES_XRSTORS)
|
||||
vm->xss_exiting_bitmap = VMread64(VMCS_64BIT_CONTROL_XSS_EXITING_BITMAP);
|
||||
else
|
||||
vm->xss_exiting_bitmap = 0;
|
||||
@ -854,7 +854,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
|
||||
#endif // BX_SUPPORT_X86_64
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_TSC_SCALING) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_TSC_SCALING) {
|
||||
if ((vm->tsc_multiplier = VMread64(VMCS_64BIT_CONTROL_TSC_MULTIPLIER)) == 0) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: TSC multiplier should be non zero"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
@ -1040,7 +1040,7 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST) {
|
||||
unsigned protected_mode_guest = (Bit32u) VMread_natural(VMCS_GUEST_CR0) & BX_CR0_PE_MASK;
|
||||
if (! protected_mode_guest) push_error_reference = 0;
|
||||
}
|
||||
@ -1378,7 +1378,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
guest.cr0 = VMread_natural(VMCS_GUEST_CR0);
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST) {
|
||||
if (~guest.cr0 & (VMX_MSR_CR0_FIXED0 & ~(BX_CR0_PE_MASK | BX_CR0_PG_MASK))) {
|
||||
BX_ERROR(("VMENTER FAIL: VMCS guest invalid CR0"));
|
||||
return VMX_VMEXIT_VMENTRY_FAILURE_GUEST_STATE;
|
||||
@ -1585,7 +1585,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
break;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
case BX_DATA_READ_WRITE_ACCESSED:
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST) {
|
||||
if (guest.sregs[BX_SEG_REG_CS].cache.dpl != 0) {
|
||||
BX_ERROR(("VMENTER FAIL: VMCS unrestricted guest CS.DPL != 0"));
|
||||
return VMX_VMEXIT_VMENTRY_FAILURE_GUEST_STATE;
|
||||
@ -1633,7 +1633,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
}
|
||||
}
|
||||
|
||||
if (! (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST)) {
|
||||
if (! (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST)) {
|
||||
if (guest.sregs[n].cache.type <= 11) {
|
||||
// data segment or non-conforming code segment
|
||||
if (guest.sregs[n].selector.rpl > guest.sregs[n].cache.dpl) {
|
||||
@ -1663,7 +1663,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
}
|
||||
|
||||
if (! v8086_guest) {
|
||||
if (! (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST)) {
|
||||
if (! (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST)) {
|
||||
if (guest.sregs[BX_SEG_REG_SS].selector.rpl != guest.sregs[BX_SEG_REG_CS].selector.rpl) {
|
||||
BX_ERROR(("VMENTER FAIL: VMCS guest CS.RPL != SS.RPL"));
|
||||
return VMX_VMEXIT_VMENTRY_FAILURE_GUEST_STATE;
|
||||
@ -1875,7 +1875,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
}
|
||||
|
||||
Bit32u revision = VMXReadRevisionID((bx_phy_address) vm->vmcs_linkptr);
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VMCS_SHADOWING) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VMCS_SHADOWING) {
|
||||
if ((revision & BX_VMCS_SHADOW_BIT_MASK) == 0) {
|
||||
*qualification = (Bit64u) VMENTER_ERR_GUEST_STATE_LINK_POINTER;
|
||||
BX_ERROR(("VMFAIL: VMCS link pointer must indicate shadow VMCS revision ID = %d", revision));
|
||||
@ -1997,7 +1997,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
|
||||
if (! x86_64_guest && (guest.cr4 & BX_CR4_PAE_MASK) != 0 && (guest.cr0 & BX_CR0_PG_MASK) != 0) {
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_ENABLE) {
|
||||
for (n=0;n<4;n++)
|
||||
guest.pdptr[n] = VMread64(VMCS_64BIT_GUEST_IA32_PDPTE0 + 2*n);
|
||||
|
||||
@ -2068,7 +2068,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
BX_CPU_THIS_PTR cr3 = guest.cr3;
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_ENABLE) {
|
||||
// load PDPTR only in PAE legacy mode
|
||||
if (BX_CPU_THIS_PTR cr0.get_PG() && BX_CPU_THIS_PTR cr4.get_PAE() && !x86_64_guest) {
|
||||
for (n = 0; n < 4; n++)
|
||||
@ -2171,16 +2171,16 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
mask_event(BX_EVENT_NMI);
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_MONITOR_TRAP_FLAG) {
|
||||
if (vm->vmexec_ctrls1 & VMX_VM_EXEC_CTRL1_MONITOR_TRAP_FLAG) {
|
||||
signal_event(BX_EVENT_VMX_MONITOR_TRAP_FLAG);
|
||||
mask_event(BX_EVENT_VMX_MONITOR_TRAP_FLAG);
|
||||
BX_CPU_THIS_PTR async_event = 1;
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_NMI_WINDOW_EXITING)
|
||||
if (vm->vmexec_ctrls1 & VMX_VM_EXEC_CTRL1_NMI_WINDOW_EXITING)
|
||||
signal_event(BX_EVENT_VMX_VIRTUAL_NMI);
|
||||
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT)
|
||||
if (vm->vmexec_ctrls1 & VMX_VM_EXEC_CTRL1_INTERRUPT_WINDOW_VMEXIT)
|
||||
signal_event(BX_EVENT_VMX_INTERRUPT_WINDOW_EXITING);
|
||||
|
||||
handleCpuContextChange();
|
||||
@ -2362,7 +2362,7 @@ void BX_CPU_C::VMexitSaveGuestState(Bit32u reason)
|
||||
VMwrite_natural(VMCS_GUEST_CR4, BX_CPU_THIS_PTR cr4.get32());
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_EPT_ENABLE) {
|
||||
// save only if guest running in legacy PAE mode
|
||||
if (BX_CPU_THIS_PTR cr0.get_PG() && BX_CPU_THIS_PTR cr4.get_PAE() && !long_mode()) {
|
||||
for(n=0; n<4; n++) {
|
||||
@ -2528,11 +2528,11 @@ void BX_CPU_C::VMexitSaveGuestState(Bit32u reason)
|
||||
if (vm->vmexit_ctrls & VMX_VMEXIT_CTRL1_STORE_VMX_PREEMPTION_TIMER)
|
||||
VMwrite32(VMCS_32BIT_GUEST_PREEMPTION_TIMER_VALUE, BX_CPU_THIS_PTR lapic.read_vmx_preemption_timer());
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY) {
|
||||
VMwrite16(VMCS_16BIT_GUEST_INTERRUPT_STATUS, (((Bit16u) vm->svi) << 8) | vm->rvi);
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_PML_ENABLE) {
|
||||
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_PML_ENABLE) {
|
||||
VMwrite16(VMCS_16BIT_GUEST_PML_INDEX, vm->pml_index);
|
||||
}
|
||||
#endif
|
||||
@ -3169,7 +3169,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMLAUNCH(bxInstruction_c *i)
|
||||
|
||||
unmask_event(BX_EVENT_INIT);
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_TSC_OFFSET))
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_TSC_OFFSET))
|
||||
BX_CPU_THIS_PTR tsc_offset = VMread64(VMCS_64BIT_CONTROL_TSC_OFFSET);
|
||||
else
|
||||
BX_CPU_THIS_PTR tsc_offset = 0;
|
||||
@ -3202,7 +3202,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMLAUNCH(bxInstruction_c *i)
|
||||
// - When Virtualize APIC Access is disabled the code would pass through TPR
|
||||
// threshold check but no VMExit would occur (otherwise VMEntry should fail
|
||||
// consistency checks before).
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_TPR_SHADOW)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_TPR_SHADOW)) {
|
||||
VMX_TPR_Virtualization();
|
||||
}
|
||||
#endif
|
||||
@ -3882,7 +3882,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::INVPCID(bxInstruction_c *i)
|
||||
#if BX_SUPPORT_VMX
|
||||
// INVPCID will always #UD in legacy VMX mode, the #UD takes priority over any other exception the instruction may incur.
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_INVPCID)) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_INVPCID)) {
|
||||
BX_ERROR(("INVPCID in VMX guest: not allowed to use instruction !"));
|
||||
exception(BX_UD_EXCEPTION, 0);
|
||||
}
|
||||
@ -3897,7 +3897,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::INVPCID(bxInstruction_c *i)
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
// INVPCID will always #UD in legacy VMX mode
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_INVLPG_VMEXIT)) {
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL1_INVLPG_VMEXIT)) {
|
||||
VMexit_Instruction(i, VMX_VMEXIT_INVPCID, BX_WRITE);
|
||||
}
|
||||
}
|
||||
@ -4015,9 +4015,9 @@ void BX_CPU_C::register_vmx_state(bx_param_c *parent)
|
||||
bx_list_c *vmexec_ctrls = new bx_list_c(vmcache, "VMEXEC_CTRLS");
|
||||
|
||||
BXRS_HEX_PARAM_FIELD(vmexec_ctrls, pin_vmexec_ctrls, BX_CPU_THIS_PTR vmcs.pin_vmexec_ctrls);
|
||||
BXRS_HEX_PARAM_FIELD(vmexec_ctrls, vmexec_ctrls1, BX_CPU_THIS_PTR vmcs.vmexec_ctrls1);
|
||||
BXRS_HEX_PARAM_FIELD(vmexec_ctrls, vmexec_ctrls2, BX_CPU_THIS_PTR vmcs.vmexec_ctrls2);
|
||||
BXRS_HEX_PARAM_FIELD(vmexec_ctrls, vmexec_ctrls3, BX_CPU_THIS_PTR vmcs.vmexec_ctrls3);
|
||||
BXRS_HEX_PARAM_FIELD(vmexec_ctrls, vmexec_ctrls4, BX_CPU_THIS_PTR vmcs.vmexec_ctrls4);
|
||||
BXRS_HEX_PARAM_FIELD(vmexec_ctrls, vm_exceptions_bitmap, BX_CPU_THIS_PTR vmcs.vm_exceptions_bitmap);
|
||||
BXRS_HEX_PARAM_FIELD(vmexec_ctrls, tsc_multiplier, BX_CPU_THIS_PTR vmcs.tsc_multiplier);
|
||||
BXRS_HEX_PARAM_FIELD(vmexec_ctrls, vm_pf_mask, BX_CPU_THIS_PTR vmcs.vm_pf_mask);
|
||||
|
140
bochs/cpu/vmx.h
140
bochs/cpu/vmx.h
@ -735,79 +735,79 @@ typedef struct bx_VMCS
|
||||
|
||||
Bit32u pin_vmexec_ctrls;
|
||||
|
||||
#define VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT (1 << 2)
|
||||
#define VMX_VM_EXEC_CTRL2_TSC_OFFSET (1 << 3)
|
||||
#define VMX_VM_EXEC_CTRL2_HLT_VMEXIT (1 << 7)
|
||||
#define VMX_VM_EXEC_CTRL2_INVLPG_VMEXIT (1 << 9)
|
||||
#define VMX_VM_EXEC_CTRL2_MWAIT_VMEXIT (1 << 10)
|
||||
#define VMX_VM_EXEC_CTRL2_RDPMC_VMEXIT (1 << 11)
|
||||
#define VMX_VM_EXEC_CTRL2_RDTSC_VMEXIT (1 << 12)
|
||||
#define VMX_VM_EXEC_CTRL2_CR3_WRITE_VMEXIT (1 << 15) /* legacy must be '1 */
|
||||
#define VMX_VM_EXEC_CTRL2_CR3_READ_VMEXIT (1 << 16) /* legacy must be '1 */
|
||||
#define VMX_VM_EXEC_CTRL2_TERTIARY_CONTROLS (1 << 17)
|
||||
#define VMX_VM_EXEC_CTRL2_CR8_WRITE_VMEXIT (1 << 19) /* TPR shadow */
|
||||
#define VMX_VM_EXEC_CTRL2_CR8_READ_VMEXIT (1 << 20) /* TPR shadow */
|
||||
#define VMX_VM_EXEC_CTRL2_TPR_SHADOW (1 << 21) /* TPR shadow */
|
||||
#define VMX_VM_EXEC_CTRL2_NMI_WINDOW_EXITING (1 << 22) /* Virtual NMI */
|
||||
#define VMX_VM_EXEC_CTRL2_DRx_ACCESS_VMEXIT (1 << 23)
|
||||
#define VMX_VM_EXEC_CTRL2_IO_VMEXIT (1 << 24)
|
||||
#define VMX_VM_EXEC_CTRL2_IO_BITMAPS (1 << 25)
|
||||
#define VMX_VM_EXEC_CTRL2_MONITOR_TRAP_FLAG (1 << 27) /* Monitor Trap Flag */
|
||||
#define VMX_VM_EXEC_CTRL2_MSR_BITMAPS (1 << 28)
|
||||
#define VMX_VM_EXEC_CTRL2_MONITOR_VMEXIT (1 << 29)
|
||||
#define VMX_VM_EXEC_CTRL2_PAUSE_VMEXIT (1 << 30)
|
||||
#define VMX_VM_EXEC_CTRL2_SECONDARY_CONTROLS (1 << 31)
|
||||
#define VMX_VM_EXEC_CTRL1_INTERRUPT_WINDOW_VMEXIT (1 << 2)
|
||||
#define VMX_VM_EXEC_CTRL1_TSC_OFFSET (1 << 3)
|
||||
#define VMX_VM_EXEC_CTRL1_HLT_VMEXIT (1 << 7)
|
||||
#define VMX_VM_EXEC_CTRL1_INVLPG_VMEXIT (1 << 9)
|
||||
#define VMX_VM_EXEC_CTRL1_MWAIT_VMEXIT (1 << 10)
|
||||
#define VMX_VM_EXEC_CTRL1_RDPMC_VMEXIT (1 << 11)
|
||||
#define VMX_VM_EXEC_CTRL1_RDTSC_VMEXIT (1 << 12)
|
||||
#define VMX_VM_EXEC_CTRL1_CR3_WRITE_VMEXIT (1 << 15) /* legacy must be '1 */
|
||||
#define VMX_VM_EXEC_CTRL1_CR3_READ_VMEXIT (1 << 16) /* legacy must be '1 */
|
||||
#define VMX_VM_EXEC_CTRL1_TERTIARY_CONTROLS (1 << 17)
|
||||
#define VMX_VM_EXEC_CTRL1_CR8_WRITE_VMEXIT (1 << 19) /* TPR shadow */
|
||||
#define VMX_VM_EXEC_CTRL1_CR8_READ_VMEXIT (1 << 20) /* TPR shadow */
|
||||
#define VMX_VM_EXEC_CTRL1_TPR_SHADOW (1 << 21) /* TPR shadow */
|
||||
#define VMX_VM_EXEC_CTRL1_NMI_WINDOW_EXITING (1 << 22) /* Virtual NMI */
|
||||
#define VMX_VM_EXEC_CTRL1_DRx_ACCESS_VMEXIT (1 << 23)
|
||||
#define VMX_VM_EXEC_CTRL1_IO_VMEXIT (1 << 24)
|
||||
#define VMX_VM_EXEC_CTRL1_IO_BITMAPS (1 << 25)
|
||||
#define VMX_VM_EXEC_CTRL1_MONITOR_TRAP_FLAG (1 << 27) /* Monitor Trap Flag */
|
||||
#define VMX_VM_EXEC_CTRL1_MSR_BITMAPS (1 << 28)
|
||||
#define VMX_VM_EXEC_CTRL1_MONITOR_VMEXIT (1 << 29)
|
||||
#define VMX_VM_EXEC_CTRL1_PAUSE_VMEXIT (1 << 30)
|
||||
#define VMX_VM_EXEC_CTRL1_SECONDARY_CONTROLS (1 << 31)
|
||||
|
||||
#define VMX_VM_EXEC_CTRL1_SUPPORTED_BITS \
|
||||
(BX_CPU_THIS_PTR vmx_cap.vmx_proc_vmexec_ctrl_supported_bits)
|
||||
|
||||
Bit32u vmexec_ctrls1;
|
||||
|
||||
#define VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_ACCESSES (1 << 0) /* APIC virtualization */
|
||||
#define VMX_VM_EXEC_CTRL2_EPT_ENABLE (1 << 1) /* EPT */
|
||||
#define VMX_VM_EXEC_CTRL2_DESCRIPTOR_TABLE_VMEXIT (1 << 2) /* Descriptor Table VMEXIT */
|
||||
#define VMX_VM_EXEC_CTRL2_RDTSCP (1 << 3)
|
||||
#define VMX_VM_EXEC_CTRL2_VIRTUALIZE_X2APIC_MODE (1 << 4) /* Virtualize X2APIC */
|
||||
#define VMX_VM_EXEC_CTRL2_VPID_ENABLE (1 << 5) /* VPID */
|
||||
#define VMX_VM_EXEC_CTRL2_WBINVD_VMEXIT (1 << 6) /* WBINVD VMEXIT */
|
||||
#define VMX_VM_EXEC_CTRL2_UNRESTRICTED_GUEST (1 << 7) /* Unrestricted Guest */
|
||||
#define VMX_VM_EXEC_CTRL2_VIRTUALIZE_APIC_REGISTERS (1 << 8)
|
||||
#define VMX_VM_EXEC_CTRL2_VIRTUAL_INT_DELIVERY (1 << 9)
|
||||
#define VMX_VM_EXEC_CTRL2_PAUSE_LOOP_VMEXIT (1 << 10) /* PAUSE loop exiting */
|
||||
#define VMX_VM_EXEC_CTRL2_RDRAND_VMEXIT (1 << 11)
|
||||
#define VMX_VM_EXEC_CTRL2_INVPCID (1 << 12)
|
||||
#define VMX_VM_EXEC_CTRL2_VMFUNC_ENABLE (1 << 13) /* VM Functions */
|
||||
#define VMX_VM_EXEC_CTRL2_VMCS_SHADOWING (1 << 14) /* VMCS Shadowing */
|
||||
#define VMX_VM_EXEC_CTRL2_SGX_ENCLS_VMEXIT (1 << 15) /* ENCLS/SGX (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL2_RDSEED_VMEXIT (1 << 16)
|
||||
#define VMX_VM_EXEC_CTRL2_PML_ENABLE (1 << 17) /* Page Modification Logging */
|
||||
#define VMX_VM_EXEC_CTRL2_EPT_VIOLATION_EXCEPTION (1 << 18) /* #VE Exception */
|
||||
#define VMX_VM_EXEC_CTRL2_SUPPRESS_GUEST_VMX_TRACE (1 << 19) /* Processor Trace (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL2_XSAVES_XRSTORS (1 << 20) /* XSAVES */
|
||||
#define VMX_VM_EXEC_CTRL2_MBE_CTRL (1 << 22) /* Mode Based Execution Control */
|
||||
#define VMX_VM_EXEC_CTRL2_SUBPAGE_WR_PROTECT_CTRL (1 << 23) /* Sub-Page Write Protection Control */
|
||||
#define VMX_VM_EXEC_CTRL2_PROCESSOR_TRACE_USE_GPA (1 << 24) /* Processor Trace (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL2_TSC_SCALING (1 << 25) /* TSC Scaling */
|
||||
#define VMX_VM_EXEC_CTRL2_USER_MWAIT_TPAUSE_VMEXIT (1 << 26) // not implemented yet
|
||||
#define VMX_VM_EXEC_CTRL2_PCONFIG_ENABLE (1 << 27) // not implemented yet
|
||||
#define VMX_VM_EXEC_CTRL2_SGX_ENCLV_VMEXIT (1 << 28) /* ENCLV/SGX (not implemented) */
|
||||
|
||||
#define VMX_VM_EXEC_CTRL2_SUPPORTED_BITS \
|
||||
(BX_CPU_THIS_PTR vmx_cap.vmx_proc_vmexec_ctrl_supported_bits)
|
||||
(BX_CPU_THIS_PTR vmx_cap.vmx_vmexec_ctrl2_supported_bits)
|
||||
|
||||
Bit32u vmexec_ctrls2;
|
||||
|
||||
#define VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES (1 << 0) /* APIC virtualization */
|
||||
#define VMX_VM_EXEC_CTRL3_EPT_ENABLE (1 << 1) /* EPT */
|
||||
#define VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT (1 << 2) /* Descriptor Table VMEXIT */
|
||||
#define VMX_VM_EXEC_CTRL3_RDTSCP (1 << 3)
|
||||
#define VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE (1 << 4) /* Virtualize X2APIC */
|
||||
#define VMX_VM_EXEC_CTRL3_VPID_ENABLE (1 << 5) /* VPID */
|
||||
#define VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT (1 << 6) /* WBINVD VMEXIT */
|
||||
#define VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST (1 << 7) /* Unrestricted Guest */
|
||||
#define VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS (1 << 8)
|
||||
#define VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY (1 << 9)
|
||||
#define VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT (1 << 10) /* PAUSE loop exiting */
|
||||
#define VMX_VM_EXEC_CTRL3_RDRAND_VMEXIT (1 << 11)
|
||||
#define VMX_VM_EXEC_CTRL3_INVPCID (1 << 12)
|
||||
#define VMX_VM_EXEC_CTRL3_VMFUNC_ENABLE (1 << 13) /* VM Functions */
|
||||
#define VMX_VM_EXEC_CTRL3_VMCS_SHADOWING (1 << 14) /* VMCS Shadowing */
|
||||
#define VMX_VM_EXEC_CTRL3_SGX_ENCLS_VMEXIT (1 << 15) /* ENCLS/SGX (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_RDSEED_VMEXIT (1 << 16)
|
||||
#define VMX_VM_EXEC_CTRL3_PML_ENABLE (1 << 17) /* Page Modification Logging */
|
||||
#define VMX_VM_EXEC_CTRL3_EPT_VIOLATION_EXCEPTION (1 << 18) /* #VE Exception */
|
||||
#define VMX_VM_EXEC_CTRL3_SUPPRESS_GUEST_VMX_TRACE (1 << 19) /* Processor Trace (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_XSAVES_XRSTORS (1 << 20) /* XSAVES */
|
||||
#define VMX_VM_EXEC_CTRL3_MBE_CTRL (1 << 22) /* Mode Based Execution Control */
|
||||
#define VMX_VM_EXEC_CTRL3_SUBPAGE_WR_PROTECT_CTRL (1 << 23) /* Sub-Page Write Protection Control */
|
||||
#define VMX_VM_EXEC_CTRL3_PROCESSOR_TRACE_USE_GPA (1 << 24) /* Processor Trace (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_TSC_SCALING (1 << 25) /* TSC Scaling */
|
||||
#define VMX_VM_EXEC_CTRL3_USER_MWAIT_TPAUSE_VMEXIT (1 << 26) // not implemented yet
|
||||
#define VMX_VM_EXEC_CTRL3_PCONFIG_ENABLE (1 << 27) // not implemented yet
|
||||
#define VMX_VM_EXEC_CTRL3_SGX_ENCLV_VMEXIT (1 << 28) /* ENCLV/SGX (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_LOADIWKEY_VMEXIT (1 << 0) /* KeyLocker (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_HLAT_ENABLE (1 << 1) /* HLAT (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_EPT_PAGING_WRITE (1 << 2) /* HLAT (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_GUEST_PAGING_VERIFICATION (1 << 3) /* HLAT (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_IPI_VIRTUALIZATION (1 << 4) /* IPI virtualization (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL3_VIRTUALIZE_IA32_SPEC_CTRL (1 << 7)
|
||||
|
||||
#define VMX_VM_EXEC_CTRL3_SUPPORTED_BITS \
|
||||
(BX_CPU_THIS_PTR vmx_cap.vmx_vmexec_ctrl2_supported_bits)
|
||||
|
||||
Bit32u vmexec_ctrls3;
|
||||
|
||||
#define VMX_VM_EXEC_CTRL4_LOADIWKEY_VMEXIT (1 << 0) /* KeyLocker (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL4_HLAT_ENABLE (1 << 1) /* HLAT (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL4_EPT_PAGING_WRITE (1 << 2) /* HLAT (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL4_GUEST_PAGING_VERIFICATION (1 << 3) /* HLAT (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL4_IPI_VIRTUALIZATION (1 << 4) /* IPI virtualization (not implemented) */
|
||||
#define VMX_VM_EXEC_CTRL4_VIRTUALIZE_IA32_SPEC_CTRL (1 << 7)
|
||||
|
||||
#define VMX_VM_EXEC_CTRL4_SUPPORTED_BITS \
|
||||
(BX_CPU_THIS_PTR vmx_cap.vmx_vmexec_ctrl3_supported_bits)
|
||||
|
||||
Bit64u vmexec_ctrls4;
|
||||
Bit64u vmexec_ctrls3;
|
||||
|
||||
Bit64u vmcs_linkptr;
|
||||
|
||||
@ -961,9 +961,9 @@ typedef struct bx_VMCS
|
||||
|
||||
#define PIN_VMEXIT(ctrl) (BX_CPU_THIS_PTR vmcs.pin_vmexec_ctrls & (ctrl))
|
||||
|
||||
#define PRIMARY_VMEXEC_CONTROL(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls2 & (ctrl))
|
||||
#define SECONDARY_VMEXEC_CONTROL(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls3 & (ctrl))
|
||||
#define TERTIARY_VMEXEC_CONTROL(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls4 & (ctrl))
|
||||
#define PRIMARY_VMEXEC_CONTROL(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls1 & (ctrl))
|
||||
#define SECONDARY_VMEXEC_CONTROL(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls2 & (ctrl))
|
||||
#define TERTIARY_VMEXEC_CONTROL(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls3 & (ctrl))
|
||||
|
||||
#define VMEXIT(ctrl) PRIMARY_VMEXEC_CONTROL(ctrl)
|
||||
|
||||
@ -1063,7 +1063,7 @@ const Bit32u VMX_MSR_VMX_PINBASED_CTRLS_LO = 0x00000016;
|
||||
const Bit32u VMX_MSR_VMX_PROCBASED_CTRLS_LO = 0x0401E172;
|
||||
// Allowed 1-settings
|
||||
#define VMX_MSR_VMX_PROCBASED_CTRLS_HI \
|
||||
(VMX_VM_EXEC_CTRL2_SUPPORTED_BITS | VMX_MSR_VMX_PROCBASED_CTRLS_LO)
|
||||
(VMX_VM_EXEC_CTRL1_SUPPORTED_BITS | VMX_MSR_VMX_PROCBASED_CTRLS_LO)
|
||||
|
||||
#define VMX_MSR_VMX_PROCBASED_CTRLS \
|
||||
GET64_FROM_HI32_LO32(VMX_MSR_VMX_PROCBASED_CTRLS_HI, VMX_MSR_VMX_PROCBASED_CTRLS_LO)
|
||||
@ -1234,7 +1234,7 @@ const Bit64u VMX_MSR_VMCS_ENUM =
|
||||
const Bit32u VMX_MSR_VMX_PROCBASED_CTRLS2_LO = 0x00000000;
|
||||
// Allowed 1-settings
|
||||
#define VMX_MSR_VMX_PROCBASED_CTRLS2_HI \
|
||||
(VMX_VM_EXEC_CTRL3_SUPPORTED_BITS | VMX_MSR_VMX_PROCBASED_CTRLS2_LO)
|
||||
(VMX_VM_EXEC_CTRL2_SUPPORTED_BITS | VMX_MSR_VMX_PROCBASED_CTRLS2_LO)
|
||||
|
||||
#define VMX_MSR_VMX_PROCBASED_CTRLS2 \
|
||||
GET64_FROM_HI32_LO32(VMX_MSR_VMX_PROCBASED_CTRLS2_HI, VMX_MSR_VMX_PROCBASED_CTRLS2_LO)
|
||||
@ -1244,7 +1244,7 @@ const Bit32u VMX_MSR_VMX_PROCBASED_CTRLS2_LO = 0x00000000;
|
||||
// -----------------------------
|
||||
|
||||
// Allowed 1-settings
|
||||
#define VMX_MSR_VMX_PROCBASED_CTRLS3 (VMX_VM_EXEC_CTRL4_SUPPORTED_BITS)
|
||||
#define VMX_MSR_VMX_PROCBASED_CTRLS3 (VMX_VM_EXEC_CTRL3_SUPPORTED_BITS)
|
||||
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
|
@ -141,7 +141,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVEC(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_XSAVES_XRSTORS)) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_XSAVES_XRSTORS)) {
|
||||
BX_ERROR(("%s in VMX guest: not allowed to use instruction !", i->getIaOpcodeNameShort()));
|
||||
exception(BX_UD_EXCEPTION, 0);
|
||||
}
|
||||
@ -244,7 +244,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_XSAVES_XRSTORS)) {
|
||||
if (! SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL2_XSAVES_XRSTORS)) {
|
||||
BX_ERROR(("%s in VMX guest: not allowed to use instruction !", i->getIaOpcodeNameShort()));
|
||||
exception(BX_UD_EXCEPTION, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user