VirtualBox

Ignore:
Timestamp:
Mar 8, 2019 10:31:35 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129238
Message:

VMM/EM, VMM/IEM: Nested VMX: bugref:9180 Implemented NMI-exiting, NMI-window and virtual-NMI support. Moved VMCPU_FF_VMX_APIC_WRITE to high-priority post mask. Fixed calling iemMemRollback in IEMExecDecodedXXX for VMX instructions. Clear all VMX force-flags in common VM-exit handler rather than in the specific handler, esp since multiple of them may be active at the time of VM-exit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r77576 r77610  
    987987IEM_STATIC VBOXSTRICTRC     iemVmxVmexitInitIpi(PVMCPU pVCpu);
    988988IEM_STATIC VBOXSTRICTRC     iemVmxVmexitIntWindow(PVMCPU pVCpu);
     989IEM_STATIC VBOXSTRICTRC     iemVmxVmexitNmiWindow(PVMCPU pVCpu);
    989990IEM_STATIC VBOXSTRICTRC     iemVmxVmexitMtf(PVMCPU pVCpu);
    990991IEM_STATIC VBOXSTRICTRC     iemVmxVirtApicAccessMem(PVMCPU pVCpu, uint16_t offAccess, size_t cbAccess, void *pvData, uint32_t fAccess);
     
    55375538#endif
    55385539
     5540    /*
     5541     * Evaluate whether NMI blocking should be in effect.
     5542     * Normally, NMI blocking is in effect whenever we inject an NMI.
     5543     */
     5544    bool fBlockNmi;
     5545    if (   u8Vector == X86_XCPT_NMI
     5546        && (fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT))
     5547        fBlockNmi = true;
     5548
    55395549#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    55405550    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
     
    55435553        if (rcStrict0 != VINF_VMX_INTERCEPT_NOT_ACTIVE)
    55445554            return rcStrict0;
     5555
     5556        /* If virtual-NMI blocking is in effect for the nested-guest, guest NMIs are not blocked. */
     5557        if (pVCpu->cpum.GstCtx.hwvirt.vmx.fVirtNmiBlocking)
     5558        {
     5559            Assert(CPUMIsGuestVmxPinCtlsSet(pVCpu, &pVCpu->cpum.GstCtx, VMX_PIN_CTLS_VIRT_NMI));
     5560            fBlockNmi = false;
     5561        }
    55455562    }
    55465563#endif
     
    55695586    }
    55705587#endif
     5588
     5589    /*
     5590     * Set NMI blocking if necessary.
     5591     */
     5592    if (   fBlockNmi
     5593        && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS))
     5594        VMCPU_FF_SET(pVCpu, VMCPU_FF_BLOCK_NMIS);
    55715595
    55725596    /*
     
    1403814062            Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_MTF));
    1403914063        }
    14040         /** Finally, check if the VMX preemption timer has expired. */
     14064        /* VMX preemption timer takes priority over NMI-window exits. */
    1404114065        else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_PREEMPT_TIMER))
    1404214066        {
     
    1404914073                Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_PREEMPT_TIMER));
    1405014074            }
     14075        }
     14076        /* NMI-window VM-exit. */
     14077        else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW))
     14078        {
     14079            rcStrict = iemVmxVmexitNmiWindow(pVCpu);
     14080            Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW));
    1405114081        }
    1405214082    }
     
    1474114771                    fFlags |= IEM_XCPT_FLAGS_ERR;
    1474214772                    break;
    14743 
    14744                 case X86_XCPT_NMI:
    14745                     VMCPU_FF_SET(pVCpu, VMCPU_FF_BLOCK_NMIS);
    14746                     break;
    1474714773            }
    1474814774            break;
     
    1589515921
    1589615922/**
     15923 * Interface for HM and EM to emulate VM-exits for NMI-windows.
     15924 *
     15925 * @returns Strict VBox status code.
     15926 * @param   pVCpu           The cross context virtual CPU structure of the calling EMT.
     15927 * @thread  EMT(pVCpu)
     15928 */
     15929VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVmexitNmiWindow(PVMCPU pVCpu)
     15930{
     15931    VBOXSTRICTRC rcStrict = iemVmxVmexitNmiWindow(pVCpu);
     15932    if (pVCpu->iem.s.cActiveMappings)
     15933        iemMemRollback(pVCpu);
     15934    return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     15935}
     15936
     15937
     15938/**
    1589715939 * Interface for HM and EM to emulate VM-exits Monitor-Trap Flag (MTF).
    1589815940 *
     
    1594915991        rcStrict = iemVmxVmreadMem(pVCpu, cbInstr, iEffSeg, enmEffAddrMode, GCPtrDst, uFieldEnc, pExitInfo);
    1595015992    }
    15951     if (pVCpu->iem.s.cActiveMappings)
    15952         iemMemRollback(pVCpu);
    15953     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     15993    Assert(!pVCpu->iem.s.cActiveMappings);
     15994    return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict);
    1595415995}
    1595515996
     
    1598916030    uint32_t const uFieldEnc = iemGRegFetchU64(pVCpu, pExitInfo->InstrInfo.VmreadVmwrite.iReg2);
    1599016031    VBOXSTRICTRC rcStrict = iemVmxVmwrite(pVCpu, cbInstr, iEffSeg, enmEffAddrMode, u64Val, uFieldEnc, pExitInfo);
    15991     if (pVCpu->iem.s.cActiveMappings)
    15992         iemMemRollback(pVCpu);
    15993     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     16032    Assert(!pVCpu->iem.s.cActiveMappings);
     16033    return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict);
    1599416034}
    1599516035
     
    1601516055    RTGCPTR const GCPtrVmcs = pExitInfo->GCPtrEffAddr;
    1601616056    VBOXSTRICTRC rcStrict = iemVmxVmptrld(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, pExitInfo);
    16017     if (pVCpu->iem.s.cActiveMappings)
    16018         iemMemRollback(pVCpu);
    16019     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     16057    Assert(!pVCpu->iem.s.cActiveMappings);
     16058    return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict);
    1602016059}
    1602116060
     
    1604116080    RTGCPTR const GCPtrVmcs = pExitInfo->GCPtrEffAddr;
    1604216081    VBOXSTRICTRC rcStrict = iemVmxVmptrst(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, pExitInfo);
    16043     if (pVCpu->iem.s.cActiveMappings)
    16044         iemMemRollback(pVCpu);
    16045     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     16082    Assert(!pVCpu->iem.s.cActiveMappings);
     16083    return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict);
    1604616084}
    1604716085
     
    1606716105    RTGCPTR const GCPtrVmcs = pExitInfo->GCPtrEffAddr;
    1606816106    VBOXSTRICTRC rcStrict = iemVmxVmclear(pVCpu, cbInstr, iEffSeg, GCPtrVmcs, pExitInfo);
    16069     if (pVCpu->iem.s.cActiveMappings)
    16070         iemMemRollback(pVCpu);
    16071     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     16107    Assert(!pVCpu->iem.s.cActiveMappings);
     16108    return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict);
    1607216109}
    1607316110
     
    1609016127    iemInitExec(pVCpu, false /*fBypassHandlers*/);
    1609116128    VBOXSTRICTRC rcStrict = iemVmxVmlaunchVmresume(pVCpu, cbInstr, uInstrId);
    16092     if (pVCpu->iem.s.cActiveMappings)
    16093         iemMemRollback(pVCpu);
    16094     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     16129    Assert(!pVCpu->iem.s.cActiveMappings);
     16130    return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict);
    1609516131}
    1609616132
     
    1611616152    RTGCPTR const GCPtrVmxon = pExitInfo->GCPtrEffAddr;
    1611716153    VBOXSTRICTRC rcStrict = iemVmxVmxon(pVCpu, cbInstr, iEffSeg, GCPtrVmxon, pExitInfo);
    16118     if (pVCpu->iem.s.cActiveMappings)
    16119         iemMemRollback(pVCpu);
    16120     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
     16154    Assert(!pVCpu->iem.s.cActiveMappings);
     16155    return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict);
    1612116156}
    1612216157
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette