impemented pause-loop exiting VMX2 control

This commit is contained in:
Stanislav Shwartsman 2011-07-22 09:19:35 +00:00
parent d1780b66de
commit 9c3a4b8dab
4 changed files with 35 additions and 2 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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
//

View File

@ -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