impemented pause-loop exiting VMX2 control
This commit is contained in:
parent
d1780b66de
commit
9c3a4b8dab
@ -136,6 +136,8 @@ bx_bool BX_CPU_C::vmcs_field_supported(Bit32u encoding)
|
|||||||
#endif
|
#endif
|
||||||
#if BX_SUPPORT_VMX >= 2
|
#if BX_SUPPORT_VMX >= 2
|
||||||
case VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS:
|
case VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS:
|
||||||
|
case VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_GAP:
|
||||||
|
case VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_WINDOW:
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -154,6 +154,19 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMexit_PAUSE(bxInstruction_c *i)
|
|||||||
BX_ERROR(("VMEXIT: PAUSE"));
|
BX_ERROR(("VMEXIT: PAUSE"));
|
||||||
VMexit(i, VMX_VMEXIT_PAUSE, 0);
|
VMexit(i, VMX_VMEXIT_PAUSE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT) && CPL == 0) {
|
||||||
|
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||||
|
Bit64u currtime = bx_pc_system.time_ticks();
|
||||||
|
if ((currtime - vm->last_pause_time) > vm->pause_loop_exiting_gap) {
|
||||||
|
vm->first_pause_time = currtime;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((currtime - vm->first_pause_time) > vm->pause_loop_exiting_window)
|
||||||
|
VMexit(i, VMX_VMEXIT_PAUSE, 0);
|
||||||
|
}
|
||||||
|
vm->last_pause_time = currtime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BX_CPP_AttrRegparmN(2) BX_CPU_C::VMexit_INVLPG(bxInstruction_c *i, bx_address laddr)
|
void BX_CPP_AttrRegparmN(2) BX_CPU_C::VMexit_INVLPG(bxInstruction_c *i, bx_address laddr)
|
||||||
|
@ -528,6 +528,13 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BX_SUPPORT_VMX >= 2
|
||||||
|
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT) {
|
||||||
|
vm->pause_loop_exiting_gap = VMread32(VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_GAP);
|
||||||
|
vm->pause_loop_exiting_window = VMread32(VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_WINDOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load VM-entry control fields to VMCS Cache
|
// Load VM-entry control fields to VMCS Cache
|
||||||
//
|
//
|
||||||
@ -1560,6 +1567,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
|||||||
if (vmentry_ctrls & VMX_VMENTRY_CTRL1_LOAD_PAT_MSR) {
|
if (vmentry_ctrls & VMX_VMENTRY_CTRL1_LOAD_PAT_MSR) {
|
||||||
BX_CPU_THIS_PTR msr.pat = guest.pat_msr;
|
BX_CPU_THIS_PTR msr.pat = guest.pat_msr;
|
||||||
}
|
}
|
||||||
|
vm->first_pause_time = vm->last_pause_time = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -269,6 +269,8 @@ enum VMX_vmabort_code {
|
|||||||
#define VMCS_32BIT_CONTROL_VMENTRY_INSTRUCTION_LENGTH 0x0000401A
|
#define VMCS_32BIT_CONTROL_VMENTRY_INSTRUCTION_LENGTH 0x0000401A
|
||||||
#define VMCS_32BIT_CONTROL_TPR_THRESHOLD 0x0000401C
|
#define VMCS_32BIT_CONTROL_TPR_THRESHOLD 0x0000401C
|
||||||
#define VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS 0x0000401E
|
#define VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS 0x0000401E
|
||||||
|
#define VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_GAP 0x00004020
|
||||||
|
#define VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_WINDOW 0x00004022
|
||||||
|
|
||||||
/* VMCS 32-bit read only data fields */
|
/* VMCS 32-bit read only data fields */
|
||||||
/* binary 0100_01xx_xxxx_xxx0 */
|
/* binary 0100_01xx_xxxx_xxx0 */
|
||||||
@ -369,7 +371,7 @@ enum VMX_vmabort_code {
|
|||||||
#define VMCS_HOST_RSP 0x00006C14
|
#define VMCS_HOST_RSP 0x00006C14
|
||||||
#define VMCS_HOST_RIP 0x00006C16
|
#define VMCS_HOST_RIP 0x00006C16
|
||||||
|
|
||||||
#define VMX_HIGHEST_VMCS_ENCODING (0x2F)
|
#define VMX_HIGHEST_VMCS_ENCODING (0x30)
|
||||||
|
|
||||||
// ===============================
|
// ===============================
|
||||||
// VMCS fields encoding/decoding
|
// VMCS fields encoding/decoding
|
||||||
@ -604,7 +606,8 @@ typedef struct bx_VMCS
|
|||||||
VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE | \
|
VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE | \
|
||||||
VMX_VM_EXEC_CTRL3_VPID_ENABLE | \
|
VMX_VM_EXEC_CTRL3_VPID_ENABLE | \
|
||||||
VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT | \
|
VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT | \
|
||||||
VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST)
|
VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST | \
|
||||||
|
VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -675,6 +678,13 @@ typedef struct bx_VMCS
|
|||||||
bx_phy_address vmexit_msr_store_addr;
|
bx_phy_address vmexit_msr_store_addr;
|
||||||
Bit32u vmexit_msr_load_cnt;
|
Bit32u vmexit_msr_load_cnt;
|
||||||
bx_phy_address vmexit_msr_load_addr;
|
bx_phy_address vmexit_msr_load_addr;
|
||||||
|
|
||||||
|
#if BX_SUPPORT_VMX >= 2
|
||||||
|
Bit32u pause_loop_exiting_gap;
|
||||||
|
Bit32u pause_loop_exiting_window;
|
||||||
|
Bit64u last_pause_time; // used for pause loop exiting
|
||||||
|
Bit32u first_pause_time;
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// VM-Entry Control Fields
|
// VM-Entry Control Fields
|
||||||
|
Loading…
Reference in New Issue
Block a user