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
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
case VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS:
|
||||
case VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_GAP:
|
||||
case VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_WINDOW:
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
|
@ -154,6 +154,19 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMexit_PAUSE(bxInstruction_c *i)
|
||||
BX_ERROR(("VMEXIT: PAUSE"));
|
||||
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)
|
||||
|
@ -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
|
||||
//
|
||||
@ -1560,6 +1567,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
if (vmentry_ctrls & VMX_VMENTRY_CTRL1_LOAD_PAT_MSR) {
|
||||
BX_CPU_THIS_PTR msr.pat = guest.pat_msr;
|
||||
}
|
||||
vm->first_pause_time = vm->last_pause_time = 0;
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -269,6 +269,8 @@ enum VMX_vmabort_code {
|
||||
#define VMCS_32BIT_CONTROL_VMENTRY_INSTRUCTION_LENGTH 0x0000401A
|
||||
#define VMCS_32BIT_CONTROL_TPR_THRESHOLD 0x0000401C
|
||||
#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 */
|
||||
/* binary 0100_01xx_xxxx_xxx0 */
|
||||
@ -369,7 +371,7 @@ enum VMX_vmabort_code {
|
||||
#define VMCS_HOST_RSP 0x00006C14
|
||||
#define VMCS_HOST_RIP 0x00006C16
|
||||
|
||||
#define VMX_HIGHEST_VMCS_ENCODING (0x2F)
|
||||
#define VMX_HIGHEST_VMCS_ENCODING (0x30)
|
||||
|
||||
// ===============================
|
||||
// VMCS fields encoding/decoding
|
||||
@ -604,7 +606,8 @@ typedef struct bx_VMCS
|
||||
VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE | \
|
||||
VMX_VM_EXEC_CTRL3_VPID_ENABLE | \
|
||||
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
|
||||
|
||||
@ -675,6 +678,13 @@ typedef struct bx_VMCS
|
||||
bx_phy_address vmexit_msr_store_addr;
|
||||
Bit32u vmexit_msr_load_cnt;
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user