diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 6e19f5d5d..354fb4f6b 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1097,6 +1097,7 @@ public: // for now... #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) +#define BX_EVENT_SVM_VIRQ_PENDING (1<<7) // later the event list will grow rapidly Bit32u pending_event; Bit32u event_mask; diff --git a/bochs/cpu/event.cc b/bochs/cpu/event.cc index 7765adad4..0700208b0 100644 --- a/bochs/cpu/event.cc +++ b/bochs/cpu/event.cc @@ -137,7 +137,7 @@ void BX_CPU_C::VirtualInterruptAcknowledge(void) if (SVM_INTERCEPT(SVM_INTERCEPT0_VINTR)) Svm_Vmexit(SVM_VMEXIT_VINTR); - SVM_V_IRQ = 0; + clear_event(BX_EVENT_SVM_VIRQ_PENDING); BX_CPU_THIS_PTR EXT = 1; /* external event */ @@ -292,7 +292,7 @@ bx_bool BX_CPU_C::handleAsyncEvent(void) InterruptAcknowledge(); } #if BX_SUPPORT_SVM - else if (BX_CPU_THIS_PTR in_svm_guest && SVM_V_IRQ && BX_CPU_THIS_PTR get_IF() && + else if (is_unmasked_event_pending(BX_EVENT_SVM_VIRQ_PENDING) && BX_CPU_THIS_PTR get_IF() && ((SVM_V_INTR_PRIO > SVM_V_TPR) || SVM_V_IGNORE_TPR)) { // virtual interrupt acknowledge @@ -342,10 +342,10 @@ bx_bool BX_CPU_C::handleAsyncEvent(void) // BX_CPU_THIS_PTR get_TF() || // implies debug_trap is set BX_HRQ || #if BX_SUPPORT_SVM - (BX_CPU_THIS_PTR in_svm_guest && SVM_V_IRQ && BX_CPU_THIS_PTR get_IF() && + (is_unmasked_event_pending(BX_EVENT_SVM_VIRQ_PENDING) && BX_CPU_THIS_PTR get_IF() && ((SVM_V_INTR_PRIO > SVM_V_TPR) || SVM_V_IGNORE_TPR)) || #endif - is_unmasked_event_pending())) + is_unmasked_event_pending(~BX_EVENT_SVM_VIRQ_PENDING))) { BX_CPU_THIS_PTR async_event = 0; } diff --git a/bochs/cpu/svm.cc b/bochs/cpu/svm.cc index befd04dc8..1a8bc375f 100644 --- a/bochs/cpu/svm.cc +++ b/bochs/cpu/svm.cc @@ -297,7 +297,8 @@ void BX_CPU_C::SvmExitSaveGuestState(void) SVM_CONTROLS *ctrls = &BX_CPU_THIS_PTR vmcb.ctrls; vmcb_write8(SVM_CONTROL_VTPR, ctrls->v_tpr); - vmcb_write8(SVM_CONTROL_VIRQ, ctrls->v_irq); + vmcb_write8(SVM_CONTROL_VIRQ, is_pending(BX_EVENT_SVM_VIRQ_PENDING)); + clear_event(BX_EVENT_SVM_VIRQ_PENDING); } extern bx_bool isValidMSR_PAT(Bit64u pat_msr); @@ -341,7 +342,6 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckControls(SVM_CONTROLS *ctrls) } ctrls->v_tpr = vmcb_read8(SVM_CONTROL_VTPR); - ctrls->v_irq = vmcb_read8(SVM_CONTROL_VIRQ) & 0x1; ctrls->v_intr_masking = vmcb_read8(SVM_CONTROL_VINTR_MASKING) & 0x1; ctrls->v_intr_vector = vmcb_read8(SVM_CONTROL_VINTR_VECTOR); @@ -555,8 +555,9 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckGuestState(void) setEFlags((Bit32u) guest.eflags); // injecting virtual interrupt - if (SVM_V_IRQ) - BX_CPU_THIS_PTR async_event = 1; + Bit8u v_irq = vmcb_read8(SVM_CONTROL_VIRQ) & 0x1; + if (v_irq) + signal_event(BX_EVENT_SVM_VIRQ_PENDING); handleCpuContextChange(); @@ -587,6 +588,8 @@ void BX_CPU_C::Svm_Vmexit(int reason, Bit64u exitinfo1, Bit64u exitinfo2) if (BX_CPU_THIS_PTR speculative_rsp) RSP = BX_CPU_THIS_PTR prev_rsp; + mask_event(BX_EVENT_SVM_VIRQ_PENDING); + BX_CPU_THIS_PTR in_svm_guest = 0; BX_CPU_THIS_PTR svm_gif = 0; @@ -1185,7 +1188,6 @@ void BX_CPU_C::register_svm_state(bx_param_c *parent) BXRS_HEX_PARAM_FIELD(vmcb_ctrls, eventinj, BX_CPU_THIS_PTR vmcb.ctrls.eventinj); BXRS_HEX_PARAM_FIELD(vmcb_ctrls, v_tpr, BX_CPU_THIS_PTR vmcb.ctrls.v_tpr); - BXRS_PARAM_BOOL(vmcb_ctrls, v_irq, BX_CPU_THIS_PTR vmcb.ctrls.v_irq); BXRS_HEX_PARAM_FIELD(vmcb_ctrls, v_intr_prio, BX_CPU_THIS_PTR vmcb.ctrls.v_intr_prio); BXRS_PARAM_BOOL(vmcb_ctrls, v_ignore_tpr, BX_CPU_THIS_PTR vmcb.ctrls.v_ignore_tpr); BXRS_PARAM_BOOL(vmcb_ctrls, v_intr_masking, BX_CPU_THIS_PTR vmcb.ctrls.v_intr_masking); diff --git a/bochs/cpu/svm.h b/bochs/cpu/svm.h index 150735d85..1bd631301 100644 --- a/bochs/cpu/svm.h +++ b/bochs/cpu/svm.h @@ -289,7 +289,6 @@ typedef struct bx_SVM_CONTROLS bx_phy_address msrpm_base; Bit8u v_tpr; - bx_bool v_irq; Bit8u v_intr_prio; bx_bool v_ignore_tpr; bx_bool v_intr_masking; @@ -303,7 +302,6 @@ typedef struct bx_SVM_CONTROLS #if defined(NEED_CPU_REG_SHORTCUTS) #define SVM_V_TPR (BX_CPU_THIS_PTR vmcb.ctrls.v_tpr) -#define SVM_V_IRQ (BX_CPU_THIS_PTR vmcb.ctrls.v_irq) #define SVM_V_INTR_PRIO (BX_CPU_THIS_PTR vmcb.ctrls.v_intr_prio) #define SVM_V_IGNORE_TPR (BX_CPU_THIS_PTR vmcb.ctrls.v_ignore_tpr) #define SVM_V_INTR_MASKING (BX_CPU_THIS_PTR vmcb.ctrls.v_intr_masking)