Changeset 97178 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Oct 17, 2022 9:06:03 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 154153
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r96811 r97178 2692 2692 2693 2693 if (fWhat & CPUMCTX_EXTRN_INHIBIT_INT) 2694 { 2695 if (pVmcbCtrl->IntShadow.n.u1IntShadow) 2696 EMSetInhibitInterruptsPC(pVCpu, pVmcbGuest->u64RIP); 2697 else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 2698 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); 2699 } 2694 CPUMUpdateInterruptShadowEx(pCtx, pVmcbCtrl->IntShadow.n.u1IntShadow, pVmcbGuest->u64RIP); 2700 2695 2701 2696 if (fWhat & CPUMCTX_EXTRN_RIP) … … 3504 3499 3505 3500 /** 3506 * Checks if the guest (or nested-guest) has an interrupt shadow active right3507 * now.3508 *3509 * @returns @c true if the interrupt shadow is active, @c false otherwise.3510 * @param pVCpu The cross context virtual CPU structure.3511 *3512 * @remarks No-long-jump zone!!!3513 * @remarks Has side-effects with VMCPU_FF_INHIBIT_INTERRUPTS force-flag.3514 */3515 static bool hmR0SvmIsIntrShadowActive(PVMCPUCC pVCpu)3516 {3517 /*3518 * Instructions like STI and MOV SS inhibit interrupts till the next instruction3519 * completes. Check if we should inhibit interrupts or clear any existing3520 * interrupt inhibition.3521 */3522 if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))3523 {3524 if (pVCpu->cpum.GstCtx.rip != EMGetInhibitInterruptsPC(pVCpu))3525 {3526 /*3527 * We can clear the inhibit force flag as even if we go back to the recompiler3528 * without executing guest code in AMD-V, the flag's condition to be cleared is3529 * met and thus the cleared state is correct.3530 */3531 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);3532 return false;3533 }3534 return true;3535 }3536 return false;3537 }3538 3539 3540 /**3541 3501 * Sets the virtual interrupt intercept control in the VMCB. 3542 3502 * … … 3612 3572 3613 3573 bool const fGif = CPUMGetGuestGif(pCtx); 3614 bool const fIntShadow = hmR0SvmIsIntrShadowActive(pVCpu);3615 bool const fBlockNmi = VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS);3574 bool const fIntShadow = CPUMIsInInterruptShadowWithUpdate(pCtx); 3575 bool const fBlockNmi = CPUMAreInterruptsInhibitedByNmi(pCtx); 3616 3576 3617 3577 Log4Func(("fGif=%RTbool fBlockNmi=%RTbool fIntShadow=%RTbool fIntPending=%RTbool fNmiPending=%RTbool\n", … … 3734 3694 Assert(!VMMRZCallRing3IsEnabled(pVCpu)); 3735 3695 3736 bool const fIntShadow = hmR0SvmIsIntrShadowActive(pVCpu);3696 bool const fIntShadow = CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx); 3737 3697 #ifdef VBOX_STRICT 3738 3698 PCCPUMCTX pCtx = &pVCpu->cpum.GstCtx; … … 3782 3742 * VM-exit to determine the state. 3783 3743 */ 3784 if ( Event.n.u3Type == SVM_EVENT_NMI 3785 && Event.n.u8Vector == X86_XCPT_NMI 3786 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS)) 3787 { 3788 VMCPU_FF_SET(pVCpu, VMCPU_FF_BLOCK_NMIS); 3789 } 3744 if ( Event.n.u3Type == SVM_EVENT_NMI 3745 && Event.n.u8Vector == X86_XCPT_NMI) 3746 CPUMSetInterruptInhibitingByNmi(&pVCpu->cpum.GstCtx); 3790 3747 3791 3748 /* … … 3809 3766 * but we still need to intercept IRET in order to eventually clear NMI inhibition. 3810 3767 */ 3811 if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))3768 if (CPUMAreInterruptsInhibitedByNmi(&pVCpu->cpum.GstCtx)) 3812 3769 hmR0SvmSetCtrlIntercept(pVmcb, SVM_CTRL_INTERCEPT_IRET); 3813 3770 … … 6711 6668 /* If we are re-injecting an NMI, clear NMI blocking. */ 6712 6669 if (pVmcb->ctrl.ExitIntInfo.n.u3Type == SVM_EVENT_NMI) 6713 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_BLOCK_NMIS);6670 CPUMClearInterruptInhibitingByNmi(&pVCpu->cpum.GstCtx); 6714 6671 6715 6672 /* Determine a vectoring #PF condition, see comment in hmR0SvmExitXcptPF(). */ … … 6802 6759 DECLINLINE(void) hmR0SvmAdvanceRip(PVMCPUCC pVCpu, uint32_t cb) 6803 6760 { 6804 PCPUMCTX pCtx = &pVCpu->cpum.GstCtx; 6805 pCtx->rip += cb; 6806 6807 /* Update interrupt shadow. */ 6808 if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) 6809 && pCtx->rip != EMGetInhibitInterruptsPC(pVCpu)) 6810 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); 6761 pVCpu->cpum.GstCtx.rip += cb; 6762 CPUMClearInterruptShadow(&pVCpu->cpum.GstCtx); 6763 /** @todo clear RF. */ 6811 6764 } 6812 6765
Note:
See TracChangeset
for help on using the changeset viewer.