From 40ba9c8d7b4f73cd3d24771729f5f23838e395df Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Tue, 25 Sep 2012 09:35:38 +0000 Subject: [PATCH] introducing new interface for handling CPU events based on vector of events and not on many not related variables. this is very initial implementation which takes into new interface only few events, more will code soon --- bochs/cpu/apic.cc | 3 +- bochs/cpu/cpu.cc | 5 ++-- bochs/cpu/cpu.h | 60 +++++++++++++++++++++++++++----------- bochs/cpu/ctrl_xfer16.cc | 2 +- bochs/cpu/ctrl_xfer32.cc | 2 +- bochs/cpu/ctrl_xfer64.cc | 2 +- bochs/cpu/event.cc | 46 +++++++++++++---------------- bochs/cpu/flag_ctrl_pro.cc | 2 +- bochs/cpu/init.cc | 24 ++++----------- bochs/cpu/proc_ctrl.cc | 9 +++--- bochs/cpu/smm.cc | 5 ++-- bochs/cpu/vmx.cc | 35 +++++++++++----------- 12 files changed, 100 insertions(+), 95 deletions(-) diff --git a/bochs/cpu/apic.cc b/bochs/cpu/apic.cc index ff0a9734a..f50f996a7 100644 --- a/bochs/cpu/apic.cc +++ b/bochs/cpu/apic.cc @@ -1173,8 +1173,7 @@ void bx_local_apic_c::deactivate_vmx_preemption_timer(void) void bx_local_apic_c::vmx_preemption_timer_expired(void *this_ptr) { bx_local_apic_c *class_ptr = (bx_local_apic_c *) this_ptr; - class_ptr->cpu->pending_vmx_timer_expired = 1; - class_ptr->cpu->async_event = 1; + class_ptr->cpu->signal_event(BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED); class_ptr->deactivate_vmx_preemption_timer(); } #endif diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index cee3015da..cbe5466ca 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -589,8 +589,7 @@ void BX_CPU_C::prefetch(void) #if BX_X86_DEBUGGER if (hwbreakpoint_check(laddr, BX_HWDebugInstruction, BX_HWDebugInstruction)) { - BX_CPU_THIS_PTR async_event = 1; - BX_CPU_THIS_PTR codebp = 1; + signal_event(BX_EVENT_CODE_BREAKPOINT_ASSIST); if (! interrupts_inhibited(BX_INHIBIT_DEBUG)) { // The next instruction could already hit a code breakpoint but // async_event won't take effect immediatelly. @@ -609,7 +608,7 @@ void BX_CPU_C::prefetch(void) } } else { - BX_CPU_THIS_PTR codebp = 0; + clear_event(BX_EVENT_CODE_BREAKPOINT_ASSIST); } #endif diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 09b51c889..32e450964 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -611,15 +611,15 @@ BOCHSAPI extern BX_CPU_C bx_cpu; } // invalidate prefetch queue and call prefetch() when RF is set -#define IMPLEMENT_EFLAG_SET_ACCESSOR_RF(name,bitnum) \ - BX_CPP_INLINE void BX_CPU_C::assert_##name() { \ +#define IMPLEMENT_EFLAG_SET_ACCESSOR_RF(bitnum) \ + BX_CPP_INLINE void BX_CPU_C::assert_RF() { \ invalidate_prefetch_q(); \ BX_CPU_THIS_PTR eflags |= (1<= 2 - bx_bool pending_vmx_timer_expired; -#endif Bit64u vmcsptr; bx_hostpageaddr_t vmcshostptr; Bit64u vmxonptr; @@ -1094,24 +1090,54 @@ public: // for now... #define BX_ACTIVITY_STATE_MWAIT_IF (5) unsigned activity_state; +#define BX_EVENT_NMI (1<<0) +#define BX_EVENT_SMI (1<<1) +#define BX_EVENT_INIT (1<<2) +#define BX_EVENT_CODE_BREAKPOINT_ASSIST (1<<3) +#define BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED (1<<4) +#define BX_EVENT_VMX_INTERRUPT_WINDOW_EXITING (1<<5) +#define BX_EVENT_VMX_NMI_WINDOW_EXITING (1<<6) +// later the event list will grow rapidly + Bit32u pending_event; + Bit32u event_mask; Bit32u async_event; -#define BX_ASYNC_EVENT_STOP_TRACE (0x80000000) + BX_SMF BX_CPP_INLINE void signal_event(Bit32u event) { + BX_CPU_THIS_PTR pending_event |= event; + BX_CPU_THIS_PTR async_event = 1; + } + + BX_SMF BX_CPP_INLINE void clear_event(Bit32u event) { + BX_CPU_THIS_PTR pending_event &= ~event; + } + + BX_SMF BX_CPP_INLINE void mask_event(Bit32u event) { + BX_CPU_THIS_PTR event_mask |= event; + } + BX_SMF BX_CPP_INLINE void unmask_event(Bit32u event) { + BX_CPU_THIS_PTR event_mask &= ~event; + } + + BX_SMF BX_CPP_INLINE bx_bool is_masked_event(Bit32u event) { + return (BX_CPU_THIS_PTR event_mask & event) != 0; + } + + BX_SMF BX_CPP_INLINE bx_bool is_pending(Bit32u event) { + return (BX_CPU_THIS_PTR pending_event & event) != 0; + } + BX_SMF BX_CPP_INLINE bx_bool is_unmasked_event_pending(Bit32u event) { + return (BX_CPU_THIS_PTR pending_event & ~BX_CPU_THIS_PTR event_mask & event) != 0; + } + +#define BX_ASYNC_EVENT_STOP_TRACE (1<<31) #if BX_X86_DEBUGGER bx_bool in_repeat; - bx_bool codebp; #endif bx_bool in_smm; unsigned cpu_mode; bx_bool user_pl; bx_bool INTR; - bx_bool pending_SMI; - bx_bool pending_NMI; - bx_bool pending_INIT; - bx_bool disable_SMI; - bx_bool disable_NMI; - bx_bool disable_INIT; #if BX_CPU_LEVEL >= 5 bx_bool ignore_bad_msrs; #endif @@ -4756,7 +4782,7 @@ IMPLEMENT_EFLAG_SET_ACCESSOR_AC ( 18) IMPLEMENT_EFLAG_SET_ACCESSOR (AC, 18) #endif IMPLEMENT_EFLAG_SET_ACCESSOR_VM ( 17) -IMPLEMENT_EFLAG_SET_ACCESSOR_RF (RF, 16) +IMPLEMENT_EFLAG_SET_ACCESSOR_RF ( 16) IMPLEMENT_EFLAG_SET_ACCESSOR (NT, 14) IMPLEMENT_EFLAG_SET_ACCESSOR (DF, 10) IMPLEMENT_EFLAG_SET_ACCESSOR_IF_TF(IF, 9) diff --git a/bochs/cpu/ctrl_xfer16.cc b/bochs/cpu/ctrl_xfer16.cc index 688b744df..6f7dabaef 100644 --- a/bochs/cpu/ctrl_xfer16.cc +++ b/bochs/cpu/ctrl_xfer16.cc @@ -547,7 +547,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET16(bxInstruction_c *i) #if BX_SUPPORT_VMX if (!BX_CPU_THIS_PTR in_vmx_guest || !VMEXIT(VMX_VM_EXEC_CTRL1_NMI_VMEXIT)) #endif - BX_CPU_THIS_PTR disable_NMI = 0; + unmask_event(BX_EVENT_NMI); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_iret; diff --git a/bochs/cpu/ctrl_xfer32.cc b/bochs/cpu/ctrl_xfer32.cc index df31e4593..a37cf47ce 100644 --- a/bochs/cpu/ctrl_xfer32.cc +++ b/bochs/cpu/ctrl_xfer32.cc @@ -590,7 +590,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET32(bxInstruction_c *i) #if BX_SUPPORT_VMX if (!BX_CPU_THIS_PTR in_vmx_guest || !VMEXIT(VMX_VM_EXEC_CTRL1_NMI_VMEXIT)) #endif - BX_CPU_THIS_PTR disable_NMI = 0; + unmask_event(BX_EVENT_NMI); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_iret; diff --git a/bochs/cpu/ctrl_xfer64.cc b/bochs/cpu/ctrl_xfer64.cc index 40f05653e..d65ab1cef 100644 --- a/bochs/cpu/ctrl_xfer64.cc +++ b/bochs/cpu/ctrl_xfer64.cc @@ -429,7 +429,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET64(bxInstruction_c *i) #if BX_SUPPORT_VMX if (!BX_CPU_THIS_PTR in_vmx_guest || !VMEXIT(VMX_VM_EXEC_CTRL1_NMI_VMEXIT)) #endif - BX_CPU_THIS_PTR disable_NMI = 0; + unmask_event(BX_EVENT_NMI); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_iret; diff --git a/bochs/cpu/event.cc b/bochs/cpu/event.cc index c039a6579..0120ec81b 100644 --- a/bochs/cpu/event.cc +++ b/bochs/cpu/event.cc @@ -34,10 +34,7 @@ bx_bool BX_CPU_C::handleWaitForEvent(void) while (1) { if ((BX_CPU_INTR && (BX_CPU_THIS_PTR get_IF() || BX_CPU_THIS_PTR activity_state == BX_ACTIVITY_STATE_MWAIT_IF)) || -#if BX_SUPPORT_VMX >= 2 - BX_CPU_THIS_PTR pending_vmx_timer_expired || -#endif - BX_CPU_THIS_PTR pending_NMI || BX_CPU_THIS_PTR pending_SMI || BX_CPU_THIS_PTR pending_INIT) + is_pending(BX_EVENT_NMI | BX_EVENT_SMI | BX_EVENT_INIT | BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED)) { // interrupt ends the HALT condition #if BX_SUPPORT_MONITOR_MWAIT @@ -194,14 +191,14 @@ bx_bool BX_CPU_C::handleAsyncEvent(void) // STOPCLK // SMI // INIT - if (BX_CPU_THIS_PTR pending_SMI && ! BX_CPU_THIS_PTR smm_mode() && SVM_GIF) + if (is_pending(BX_EVENT_SMI) && ! BX_CPU_THIS_PTR smm_mode() && SVM_GIF) { // clear SMI pending flag and disable NMI when SMM was accepted - BX_CPU_THIS_PTR pending_SMI = 0; + clear_event(BX_EVENT_SMI); enter_system_management_mode(); } - if (BX_CPU_THIS_PTR pending_INIT && ! BX_CPU_THIS_PTR disable_INIT && SVM_GIF) { + if (is_unmasked_event_pending(BX_EVENT_INIT) && SVM_GIF) { #if BX_SUPPORT_SVM if (BX_CPU_THIS_PTR in_svm_guest) { if (SVM_INTERCEPT(SVM_INTERCEPT0_INIT)) Svm_Vmexit(SVM_VMEXIT_INIT); @@ -255,13 +252,13 @@ bx_bool BX_CPU_C::handleAsyncEvent(void) // boundary because of certain instructions like STI. } #if BX_SUPPORT_VMX >= 2 - else if (BX_CPU_THIS_PTR in_vmx_guest && BX_CPU_THIS_PTR pending_vmx_timer_expired) { - BX_CPU_THIS_PTR pending_vmx_timer_expired = 0; + else if (BX_CPU_THIS_PTR in_vmx_guest && is_pending(BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED)) { + clear_event(BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED); VMexit_PreemptionTimerExpired(); } #endif #if BX_SUPPORT_VMX - else if (! BX_CPU_THIS_PTR disable_NMI && BX_CPU_THIS_PTR in_vmx_guest && + else if (! is_masked_event(BX_EVENT_NMI) && BX_CPU_THIS_PTR in_vmx_guest && VMEXIT(VMX_VM_EXEC_CTRL2_NMI_WINDOW_VMEXIT)) { // NMI-window exiting @@ -269,14 +266,14 @@ bx_bool BX_CPU_C::handleAsyncEvent(void) VMexit(VMX_VMEXIT_NMI_WINDOW, 0); } #endif - else if (BX_CPU_THIS_PTR pending_NMI && ! BX_CPU_THIS_PTR disable_NMI) { + else if (is_unmasked_event_pending(BX_EVENT_NMI)) { #if BX_SUPPORT_SVM if (BX_CPU_THIS_PTR in_svm_guest) { if (SVM_INTERCEPT(SVM_INTERCEPT0_NMI)) Svm_Vmexit(SVM_VMEXIT_NMI); } #endif - BX_CPU_THIS_PTR pending_NMI = 0; - BX_CPU_THIS_PTR disable_NMI = 1; + clear_event(BX_EVENT_NMI); + mask_event(BX_EVENT_NMI); BX_CPU_THIS_PTR EXT = 1; /* external event */ #if BX_SUPPORT_VMX VMexit_Event(BX_NMI, 2, 0, 0); @@ -285,7 +282,7 @@ bx_bool BX_CPU_C::handleAsyncEvent(void) interrupt(2, BX_NMI, 0, 0); } #if BX_SUPPORT_VMX - else if (BX_CPU_THIS_PTR vmx_interrupt_window && BX_CPU_THIS_PTR get_IF()) { + else if (is_pending(BX_EVENT_VMX_INTERRUPT_WINDOW_EXITING) && BX_CPU_THIS_PTR get_IF()) { // interrupt-window exiting BX_DEBUG(("VMEXIT: interrupt window exiting")); VMexit(VMX_VMEXIT_INTERRUPT_WINDOW, 0); @@ -351,12 +348,12 @@ bx_bool BX_CPU_C::handleAsyncEvent(void) // BX_CPU_THIS_PTR get_TF() // implies debug_trap is set BX_HRQ #if BX_SUPPORT_VMX - || BX_CPU_THIS_PTR vmx_interrupt_window - || (BX_CPU_THIS_PTR in_vmx_guest && ! BX_CPU_THIS_PTR disable_NMI && + || is_pending(BX_EVENT_VMX_INTERRUPT_WINDOW_EXITING) + || (BX_CPU_THIS_PTR in_vmx_guest && ! is_masked_event(BX_EVENT_NMI) && VMEXIT(VMX_VM_EXEC_CTRL2_NMI_WINDOW_VMEXIT)) #endif #if BX_SUPPORT_VMX >= 2 - || BX_CPU_THIS_PTR pending_vmx_timer_expired + || is_pending(BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED) #endif #if BX_SUPPORT_SVM || (BX_CPU_THIS_PTR in_svm_guest && SVM_V_IRQ && BX_CPU_THIS_PTR get_IF() && @@ -364,7 +361,7 @@ bx_bool BX_CPU_C::handleAsyncEvent(void) #endif #if BX_X86_DEBUGGER // a debug code breakpoint is set in current page - || BX_CPU_THIS_PTR codebp + || is_pending(BX_EVENT_CODE_BREAKPOINT_ASSIST) #endif )) BX_CPU_THIS_PTR async_event = 0; @@ -391,7 +388,7 @@ void BX_CPU_C::deliver_SIPI(unsigned vector) BX_CPU_THIS_PTR activity_state = BX_ACTIVITY_STATE_ACTIVE; RIP = 0; load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], vector*0x100); - BX_CPU_THIS_PTR disable_INIT = 0; // enable INIT pin back + unmask_event(BX_EVENT_INIT); // enable INIT pin back BX_INFO(("CPU %d started up at %04X:%08X by APIC", BX_CPU_THIS_PTR bx_cpuid, vector*0x100, EIP)); } else { @@ -401,22 +398,19 @@ void BX_CPU_C::deliver_SIPI(unsigned vector) void BX_CPU_C::deliver_INIT(void) { - if (! BX_CPU_THIS_PTR disable_INIT) { - BX_CPU_THIS_PTR pending_INIT = 1; - BX_CPU_THIS_PTR async_event = 1; + if (! is_masked_event(BX_EVENT_INIT)) { + signal_event(BX_EVENT_INIT); } } void BX_CPU_C::deliver_NMI(void) { - BX_CPU_THIS_PTR pending_NMI = 1; - BX_CPU_THIS_PTR async_event = 1; + signal_event(BX_EVENT_NMI); } void BX_CPU_C::deliver_SMI(void) { - BX_CPU_THIS_PTR pending_SMI = 1; - BX_CPU_THIS_PTR async_event = 1; + signal_event(BX_EVENT_SMI); } void BX_CPU_C::set_INTR(bx_bool value) diff --git a/bochs/cpu/flag_ctrl_pro.cc b/bochs/cpu/flag_ctrl_pro.cc index 6927efbc7..f74af1fc7 100644 --- a/bochs/cpu/flag_ctrl_pro.cc +++ b/bochs/cpu/flag_ctrl_pro.cc @@ -38,7 +38,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::setEFlags(Bit32u val) if (val & EFlagsRFMask) invalidate_prefetch_q(); if (val & EFlagsTFMask) { - BX_CPU_THIS_PTR async_event = 1; // TF == 1 || RF == 1 + BX_CPU_THIS_PTR async_event = 1; // TF == 1 } if (val & EFlagsIFMask) { diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index 605d21d47..49d8dac40 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -624,22 +624,16 @@ void BX_CPU_C::register_state(void) register_svm_state(cpu); #endif + BXRS_HEX_PARAM_SIMPLE32(cpu, pending_event); + BXRS_HEX_PARAM_SIMPLE32(cpu, event_mask); BXRS_HEX_PARAM_SIMPLE32(cpu, async_event); BXRS_PARAM_BOOL(cpu, INTR, INTR); #if BX_X86_DEBUGGER BXRS_PARAM_BOOL(cpu, in_repeat, in_repeat); - // for debug only (no need for save/restore), calculated in prefetch() - BXRS_PARAM_BOOL(cpu, codebp, codebp); #endif BXRS_PARAM_BOOL(cpu, in_smm, in_smm); - BXRS_PARAM_BOOL(cpu, disable_SMI, disable_SMI); - BXRS_PARAM_BOOL(cpu, pending_SMI, pending_SMI); - BXRS_PARAM_BOOL(cpu, disable_NMI, disable_NMI); - BXRS_PARAM_BOOL(cpu, pending_NMI, pending_NMI); - BXRS_PARAM_BOOL(cpu, disable_INIT, disable_INIT); - BXRS_PARAM_BOOL(cpu, pending_INIT, pending_INIT); #if BX_DEBUGGER bx_list_c *tlb = new bx_list_c(cpu, "TLB"); @@ -942,15 +936,11 @@ void BX_CPU_C::reset(unsigned source) #if BX_X86_DEBUGGER BX_CPU_THIS_PTR in_repeat = 0; - BX_CPU_THIS_PTR codebp = 0; #endif BX_CPU_THIS_PTR in_smm = 0; - BX_CPU_THIS_PTR disable_SMI = 0; - BX_CPU_THIS_PTR pending_SMI = 0; - BX_CPU_THIS_PTR disable_NMI = 0; - BX_CPU_THIS_PTR pending_NMI = 0; - BX_CPU_THIS_PTR disable_INIT = 0; - BX_CPU_THIS_PTR pending_INIT = 0; + + BX_CPU_THIS_PTR pending_event = 0; + BX_CPU_THIS_PTR event_mask = 0; if (source == BX_RESET_HARDWARE) { BX_CPU_THIS_PTR smbase = 0x30000; // do not change SMBASE on INIT @@ -1121,10 +1111,6 @@ void BX_CPU_C::reset(unsigned source) #if BX_SUPPORT_VMX BX_CPU_THIS_PTR in_vmx = BX_CPU_THIS_PTR in_vmx_guest = 0; BX_CPU_THIS_PTR in_smm_vmx = BX_CPU_THIS_PTR in_smm_vmx_guest = 0; - BX_CPU_THIS_PTR vmx_interrupt_window = 0; -#if BX_SUPPORT_VMX >= 2 - BX_CPU_THIS_PTR pending_vmx_timer_expired = 0; -#endif BX_CPU_THIS_PTR vmcsptr = BX_CPU_THIS_PTR vmxonptr = BX_INVALID_VMCSPTR; BX_CPU_THIS_PTR vmcshostptr = 0; /* enable VMX, should be done in BIOS instead */ diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index 8008df23a..d1708ee88 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -777,10 +777,11 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MWAIT(bxInstruction_c *i) if (ECX & 1) { #if BX_SUPPORT_VMX // When "interrupt window exiting" VMX control is set MWAIT instruction - // won't cause the processor to enter BX_ACTIVITY_STATE_MWAIT_IF sleep - // state with EFLAGS.IF = 0 - if (BX_CPU_THIS_PTR vmx_interrupt_window && ! BX_CPU_THIS_PTR get_IF()) { - BX_NEXT_TRACE(i); + // 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()) { + BX_NEXT_TRACE(i); + } } #endif BX_CPU_THIS_PTR activity_state = BX_ACTIVITY_STATE_MWAIT_IF; diff --git a/bochs/cpu/smm.cc b/bochs/cpu/smm.cc index 5681df58a..35dd2a9e3 100644 --- a/bochs/cpu/smm.cc +++ b/bochs/cpu/smm.cc @@ -51,7 +51,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RSM(bxInstruction_c *i) BX_INFO(("RSM: Resuming from System Management Mode")); - BX_CPU_THIS_PTR disable_NMI = 0; + unmask_event(BX_EVENT_NMI | BX_EVENT_SMI); Bit32u saved_state[SMM_SAVE_STATE_MAP_SIZE], n; // reset reserved bits @@ -114,7 +114,8 @@ void BX_CPU_C::enter_system_management_mode(void) #endif BX_CPU_THIS_PTR in_smm = 1; - BX_CPU_THIS_PTR disable_NMI = 1; + + mask_event(BX_EVENT_NMI | BX_EVENT_SMI); Bit32u saved_state[SMM_SAVE_STATE_MAP_SIZE], n; // reset reserved bits diff --git a/bochs/cpu/vmx.cc b/bochs/cpu/vmx.cc index 7d8cd517b..0be3c9e66 100644 --- a/bochs/cpu/vmx.cc +++ b/bochs/cpu/vmx.cc @@ -1635,7 +1635,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification) } if (guest.interruptibility_state & BX_VMX_INTERRUPTS_BLOCKED_NMI_BLOCKED) { - BX_CPU_THIS_PTR disable_NMI = 1; + mask_event(BX_EVENT_NMI); } else { if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_NMI_WINDOW_VMEXIT) @@ -1643,8 +1643,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification) } if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT) { - BX_CPU_THIS_PTR async_event = 1; - BX_CPU_THIS_PTR vmx_interrupt_window = 1; // set up interrupt window exiting + signal_event(BX_EVENT_VMX_INTERRUPT_WINDOW_EXITING); } handleCpuContextChange(); @@ -1876,9 +1875,9 @@ void BX_CPU_C::VMexitSaveGuestState(void) else interruptibility_state |= BX_VMX_INTERRUPTS_BLOCKED_BY_STI; } - if (BX_CPU_THIS_PTR disable_SMI) + if (is_masked_event(BX_EVENT_SMI)) interruptibility_state |= BX_VMX_INTERRUPTS_BLOCKED_SMI_BLOCKED; - if (BX_CPU_THIS_PTR disable_NMI) + if (is_masked_event(BX_EVENT_NMI)) interruptibility_state |= BX_VMX_INTERRUPTS_BLOCKED_NMI_BLOCKED; VMwrite32(VMCS_32BIT_GUEST_INTERRUPTIBILITY_STATE, interruptibility_state); @@ -1896,7 +1895,7 @@ void BX_CPU_C::VMexitSaveGuestState(void) // Deactivate VMX preemtion timer BX_CPU_THIS_PTR lapic.deactivate_vmx_preemption_timer(); - BX_CPU_THIS_PTR pending_vmx_timer_expired = 0; + clear_event(BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED); // Store back to VMCS 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()); @@ -2142,6 +2141,11 @@ void BX_CPU_C::VMexit(Bit32u reason, Bit64u qualification) BX_CPU_THIS_PTR in_vmx_guest = 0; + // entering VMX root mode: clear possibly pending guest VMX events + clear_event(BX_EVENT_VMX_INTERRUPT_WINDOW_EXITING | + BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED | + BX_EVENT_VMX_NMI_WINDOW_EXITING); + // // STEP 2: Load Host State // @@ -2161,8 +2165,8 @@ void BX_CPU_C::VMexit(Bit32u reason, Bit64u qualification) // STEP 4: Go back to VMX host // - BX_CPU_THIS_PTR disable_INIT = 1; // INIT is disabled in VMX root mode - BX_CPU_THIS_PTR vmx_interrupt_window = 0; + mask_event(BX_EVENT_INIT); // INIT is disabled in VMX root mode + BX_CPU_THIS_PTR errorno = 0; BX_CPU_THIS_PTR EXT = 0; @@ -2217,7 +2221,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMXON(bxInstruction_c *i) BX_CPU_THIS_PTR vmcshostptr = 0; BX_CPU_THIS_PTR vmxonptr = pAddr; BX_CPU_THIS_PTR in_vmx = 1; - BX_CPU_THIS_PTR disable_INIT = 1; // INIT is disabled in VMX root mode + mask_event(BX_EVENT_INIT); // INIT is disabled in VMX root mode // block and disable A20M; #if BX_SUPPORT_MONITOR_MWAIT @@ -2268,7 +2272,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMXOFF(bxInstruction_c *i) { BX_CPU_THIS_PTR vmxonptr = BX_INVALID_VMCSPTR; BX_CPU_THIS_PTR in_vmx = 0; // leave VMX operation mode - BX_CPU_THIS_PTR disable_INIT = 0; + unmask_event(BX_EVENT_INIT); // unblock and enable A20M; #if BX_SUPPORT_MONITOR_MWAIT BX_CPU_THIS_PTR monitor.reset_monitor(); @@ -2504,7 +2508,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMLAUNCH(bxInstruction_c *i) */ BX_CPU_THIS_PTR in_vmx_guest = 1; - BX_CPU_THIS_PTR disable_INIT = 0; + + unmask_event(BX_EVENT_INIT); if (VMEXIT(VMX_VM_EXEC_CTRL2_TSC_OFFSET)) BX_CPU_THIS_PTR tsc_offset = VMread64(VMCS_64BIT_CONTROL_TSC_OFFSET); @@ -2515,13 +2520,11 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMLAUNCH(bxInstruction_c *i) if (PIN_VMEXIT(VMX_VM_EXEC_CTRL1_VMX_PREEMPTION_TIMER_VMEXIT)) { Bit32u timer_value = VMread32(VMCS_32BIT_GUEST_PREEMPTION_TIMER_VALUE); if (timer_value == 0) { - BX_CPU_THIS_PTR pending_vmx_timer_expired = 1; - BX_CPU_THIS_PTR async_event = 1; + signal_event(BX_EVENT_VMX_PREEMPTION_TIMER_EXPIRED); } else { // activate VMX preemption timer BX_DEBUG(("VMX preemption timer active")); - BX_CPU_THIS_PTR pending_vmx_timer_expired = 0; BX_CPU_THIS_PTR lapic.set_vmx_preemption_timer(timer_value); } } @@ -3127,10 +3130,6 @@ void BX_CPU_C::register_vmx_state(bx_param_c *parent) BXRS_PARAM_BOOL(vmx, in_vmx_guest, BX_CPU_THIS_PTR in_vmx_guest); BXRS_PARAM_BOOL(vmx, in_smm_vmx, BX_CPU_THIS_PTR in_smm_vmx); BXRS_PARAM_BOOL(vmx, in_smm_vmx_guest, BX_CPU_THIS_PTR in_smm_vmx_guest); - BXRS_PARAM_BOOL(vmx, vmx_interrupt_window, BX_CPU_THIS_PTR vmx_interrupt_window); -#if BX_SUPPORT_VMX >= 2 - BXRS_PARAM_BOOL(vmx, pending_vmx_timer_expired, BX_CPU_THIS_PTR pending_vmx_timer_expired); -#endif bx_list_c *vmcache = new bx_list_c(vmx, "VMCS_CACHE");