VirtualBox

Changeset 71224 in vbox


Ignore:
Timestamp:
Mar 6, 2018 1:08:53 AM (7 years ago)
Author:
vboxsync
Message:

NEM/w: Optimizations and build fixes for the other configurations. bugref:9044

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r71223 r71224  
    2929                (a_Dst).fFlags   = CPUMSELREG_FLAGS_VALID; \
    3030            } while (0)
    31 
    32 /** The CPUMCTX_EXTRN_XXX mask for IEM. */
    33 #define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM      CPUMCTX_EXTRN_ALL
    3431
    3532
     
    11781175}
    11791176
    1180 #ifdef IN_RING0
     1177
     1178#ifdef NEM_WIN_USE_OUR_OWN_RUN_API
     1179
     1180# ifdef IN_RING0
    11811181/**
    11821182 * Wrapper around nemR0WinImportState that converts VERR_NEM_CHANGE_PGM_MODE and
     
    12071207    AssertMsgFailedReturn(("%s/%u: nemR0WinImportState failed: %Rrc\n", pszCaller, pGVCpu->idCpu, rc), rc);
    12081208}
    1209 #endif /* IN_RING0 */
     1209# endif /* IN_RING0 */
    12101210
    12111211/**
     
    12901290    nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header);
    12911291    VBOXSTRICTRC rcStrict;
    1292 #ifdef IN_RING0
     1292# ifdef IN_RING0
    12931293    rcStrict = nemR0WinImportStateStrict(pGVCpu->pGVM, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "MemExit");
    12941294    if (rcStrict != VINF_SUCCESS)
    12951295        return rcStrict;
    1296 #else
     1296# else
    12971297    rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
    12981298    AssertRCReturn(rc, rc);
    12991299    NOREF(pGVCpu);
    1300 #endif
     1300# endif
    13011301
    13021302    if (pMsg->InstructionByteCount > 0)
     
    14001400        pCtx->rdi = pMsg->Rdi;
    14011401        pCtx->rsi = pMsg->Rsi;
    1402 #ifdef IN_RING0
     1402# ifdef IN_RING0
    14031403        rcStrict = nemR0WinImportStateStrict(pGVCpu->pGVM, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "IOExit");
    14041404        if (rcStrict != VINF_SUCCESS)
    14051405            return rcStrict;
    1406 #else
     1406# else
    14071407        int rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
    14081408        AssertRCReturn(rc, rc);
    14091409        RT_NOREF(pGVCpu);
    1410 #endif
     1410# endif
    14111411
    14121412        Log4(("IOExit/%u: %04x:%08RX64: %s%s %#x LB %u (emulating)\n",
     
    15281528     * does another VM exit.
    15291529     */
    1530 #ifdef IN_RING0
     1530# ifdef IN_RING0
    15311531    pVCpu->nem.s.uIoCtlBuf.idCpu = pGVCpu->idCpu;
    15321532    NTSTATUS rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlStopVirtualProcessor.uFunction,
     
    15381538        return rcStrict;
    15391539    }
    1540 #else
     1540# else
    15411541    BOOL fRet = VidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu);
    15421542    if (fRet)
     
    15461546    }
    15471547    RT_NOREF(pGVM, pGVCpu);
    1548 #endif
     1548# endif
    15491549
    15501550    /*
    15511551     * Dang. The CPU stopped by itself and we got a couple of message to deal with.
    15521552     */
    1553 #ifdef IN_RING0
     1553# ifdef IN_RING0
    15541554    AssertLogRelMsgReturn(rcNt == ERROR_VID_STOP_PENDING, ("rcNt=%#x\n", rcNt),
    15551555                          RT_SUCCESS(rcStrict) ?  VERR_INTERNAL_ERROR_3 : rcStrict);
    1556 #else
     1556# else
    15571557    DWORD dwErr = RTNtLastErrorValue();
    15581558    AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u (%#x)\n", dwErr, dwErr),
    15591559                          RT_SUCCESS(rcStrict) ?  VERR_INTERNAL_ERROR_3 : rcStrict);
    1560 #endif
     1560# endif
    15611561    Log8(("nemHCWinStopCpu: Stopping CPU pending...\n"));
    15621562
     
    15651565     * Note! We can safely ASSUME that rcStrict isn't an important information one.
    15661566     */
    1567 #ifdef IN_RING0
     1567# ifdef IN_RING0
    15681568    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
    15691569    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_GET_NEXT_MESSAGE;
     
    15751575    AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
    15761576                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
    1577 #else
     1577# else
    15781578    BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    15791579                                                     VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
    15801580    AssertLogRelMsgReturn(fWait, ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    15811581                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
    1582 #endif
     1582# endif
    15831583
    15841584    /* It should be a hypervisor message and definitely not a stop request completed message. */
     
    15971597     * that as handled too.  CPU is back into fully stopped stated then.
    15981598     */
    1599 #ifdef IN_RING0
     1599# ifdef IN_RING0
    16001600    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
    16011601    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE;
     
    16071607    AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("2st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
    16081608                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
    1609 #else
     1609# else
    16101610    fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    16111611                                                VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
    16121612    AssertLogRelMsgReturn(fWait, ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    16131613                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
    1614 #endif
     1614# endif
    16151615
    16161616    /* It should be a stop request completed message. */
     
    16221622
    16231623    /* Mark this as handled. */
    1624 #ifdef IN_RING0
     1624# ifdef IN_RING0
    16251625    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
    16261626    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_HANDLE_MESSAGE;
     
    16321632    AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
    16331633                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
    1634 #else
     1634# else
    16351635    fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, VID_MSHAGN_F_HANDLE_MESSAGE, 30000 /*ms*/);
    16361636    AssertLogRelMsgReturn(fWait, ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    16371637                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
    1638 #endif
     1638# endif
    16391639    Log8(("nemHCWinStopCpu: Stopped the CPU (rcStrict=%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict) ));
    16401640    return rcStrict;
     
    16461646    PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
    16471647    LogFlow(("NEM/%u: %04x:%08RX64 efl=%#08RX64 <=\n", pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags));
    1648 #ifdef LOG_ENABLED
     1648# ifdef LOG_ENABLED
    16491649    if (LogIs3Enabled())
    16501650        nemHCWinLogState(pVM, pVCpu);
    1651 #endif
     1651# endif
    16521652
    16531653    /*
     
    16681668        if ((pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK)) != (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK))
    16691669        {
    1670 #ifdef IN_RING0
     1670# ifdef IN_RING0
    16711671            int rc2 = nemR0WinExportState(pGVM, pGVCpu, pCtx);
    1672 #else
     1672# else
    16731673            int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu, pCtx);
    16741674            RT_NOREF(pGVM, pGVCpu);
    1675 #endif
     1675# endif
    16761676            AssertRCReturn(rc2, rc2);
    16771677        }
     
    16871687            else
    16881688            {
    1689 #ifdef IN_RING0
     1689# ifdef IN_RING0
    16901690                pVCpu->nem.s.uIoCtlBuf.idCpu = pGVCpu->idCpu;
    16911691                NTSTATUS rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlStartVirtualProcessor.uFunction,
     
    16951695                AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("VidStartVirtualProcessor failed for CPU #%u: %#x\n", pGVCpu->idCpu, rcNt),
    16961696                                      VERR_INTERNAL_ERROR_3);
    1697 #else
     1697# else
    16981698                AssertLogRelMsgReturn(g_pfnVidStartVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu),
    16991699                                      ("VidStartVirtualProcessor failed for CPU #%u: %u (%#x, rcNt=%#x)\n",
    17001700                                       pVCpu->idCpu, RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()),
    17011701                                      VERR_INTERNAL_ERROR_3);
    1702 #endif
     1702# endif
    17031703                pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;
    17041704            }
     
    17061706            if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED))
    17071707            {
    1708 #ifdef IN_RING0
     1708# ifdef IN_RING0
    17091709                pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
    17101710                pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = pVCpu->nem.s.fHandleAndGetFlags;
     
    17161716                VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
    17171717                if (rcNt == STATUS_SUCCESS)
    1718 #else
     1718# else
    17191719                BOOL fRet = VidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    17201720                                                           pVCpu->nem.s.fHandleAndGetFlags, cMillies);
    17211721                VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
    17221722                if (fRet)
    1723 #endif
     1723# endif
    17241724                {
    17251725                    /*
     
    17411741                       so after NtAlertThread we end up here with a STATUS_TIMEOUT.  And yeah,
    17421742                       the error code conversion is into WAIT_XXX, i.e. NT status codes. */
    1743 #ifndef IN_RING0
     1743# ifndef IN_RING0
    17441744                    DWORD rcNt = GetLastError();
    1745 #endif
     1745# endif
    17461746                    LogFlow(("NEM/%u: VidMessageSlotHandleAndGetNext -> %#x\n", pVCpu->idCpu, rcNt));
    17471747                    AssertLogRelMsgReturn(   rcNt == STATUS_TIMEOUT
     
    17881788    if (pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | (CPUMCTX_EXTRN_NEM_WIN_MASK & ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT)))
    17891789    {
    1790 #ifdef IN_RING0
     1790# ifdef IN_RING0
    17911791        int rc2 = nemR0WinImportState(pGVM, pGVCpu, pCtx, CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK);
    17921792        if (RT_SUCCESS(rc2))
     
    18031803            }
    18041804        }
    1805 #else
     1805# else
    18061806        int rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK);
    18071807        if (RT_SUCCESS(rc2))
    18081808            pCtx->fExtrn = 0;
    1809 #endif
     1809# endif
    18101810        else if (RT_SUCCESS(rcStrict))
    18111811            rcStrict = rc2;
     
    18191819}
    18201820
     1821#endif /* NEM_WIN_USE_OUR_OWN_RUN_API */
    18211822
    18221823
  • trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp

    r71223 r71224  
    17681768VMMR0_INT_DECL(VBOXSTRICTRC) NEMR0RunGuestCode(PGVM pGVM, VMCPUID idCpu)
    17691769{
     1770#ifdef NEM_WIN_USE_OUR_OWN_RUN_API
    17701771    PVM pVM = pGVM->pVM;
    17711772    return nemHCWinRunGC(pVM, &pVM->aCpus[idCpu], pGVM, &pGVM->aCpus[idCpu]);
     1773#else
     1774    RT_NOREF(pGVM, idCpu);
     1775    return VERR_NOT_IMPLEMENTED;
     1776#endif
    17721777}
    17731778
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r71222 r71224  
    15701570     * Emulate the memory access, either access handler or special memory.
    15711571     */
     1572    rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
     1573    AssertRCReturn(rc, rc);
     1574
    15721575    VBOXSTRICTRC rcStrict;
    15731576    if (pMemCtx->InstructionByteCount > 0)
     
    16401643         * Both AMD-V and VT-x includes the address size in the exit info, at least on
    16411644         * CPUs that are reasonably new. */
     1645# if 0 // requires sledgehammer
    16421646        Assert(   pIoPortCtx->Ds.Base     == pCtx->ds.u64Base
    16431647               && pIoPortCtx->Ds.Limit    == pCtx->ds.u32Limit
     
    16501654        Assert(pIoPortCtx->Rcx == pCtx->rcx);
    16511655        Assert(pIoPortCtx->Rcx == pCtx->rcx);
     1656# endif
     1657
     1658        int rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
     1659        AssertRCReturn(rc, rc);
    16521660
    16531661        rcStrict = IEMExecOne(pVCpu);
     
    17301738    /*
    17311739     * The run loop.
    1732      *
    1733      * Current approach to state updating to use the sledgehammer and sync
    1734      * everything every time.  This will be optimized later.
    1735      */
     1740     */
     1741    PCPUMCTX     pCtx            = CPUMQueryGuestCtxPtr(pVCpu);
    17361742    const bool   fSingleStepping = false; /** @todo get this from somewhere. */
    1737     VBOXSTRICTRC rcStrict = VINF_SUCCESS;
     1743    VBOXSTRICTRC rcStrict        = VINF_SUCCESS;
    17381744    for (unsigned iLoop = 0;;iLoop++)
    17391745    {
     
    17411747         * Copy the state.
    17421748         */
    1743         PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
    17441749        int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu, pCtx);
    17451750        AssertRCBreakStmt(rc2, rcStrict = rc2);
     
    17621767                                     rcStrict = VERR_INTERNAL_ERROR);
    17631768            Log2(("WHvRunVirtualProcessor -> %#x; exit code %#x (%d) (cpu status %u)\n",
    1764                   hrc, ExitReason.ExitReason, ExitReason.ExitReason, nemR3WinCpuGetRunningStatus(pVCpu) ));
     1769                  hrc, ExitReason.ExitReason, ExitReason.ExitReason, nemHCWinCpuGetRunningStatus(pVCpu) ));
    17651770        }
    17661771        else
     
    17701775        }
    17711776
     1777# if 0 /* sledgehammer approach */
    17721778        /*
    17731779         * Copy back the state.
    17741780         */
    1775         rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx);
     1781        rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, UINT64_MAX);
    17761782        AssertRCBreakStmt(rc2, rcStrict = rc2);
     1783# endif
    17771784
    17781785# ifdef LOG_ENABLED
     
    17861793# endif
    17871794
    1788 # ifdef VBOX_STRICT
     1795# if 0 //def VBOX_STRICT - requires sledgehammer
    17891796        /* Assert that the VpContext field makes sense. */
    17901797        switch (ExitReason.ExitReason)
     
    19041911    }
    19051912
     1913
     1914    /*
     1915     * Copy back the state before returning.
     1916     */
     1917    if (pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | (CPUMCTX_EXTRN_NEM_WIN_MASK & ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT)))
     1918    {
     1919        int rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK);
     1920        if (RT_SUCCESS(rc2))
     1921            pCtx->fExtrn = 0;
     1922        else if (RT_SUCCESS(rcStrict))
     1923            rcStrict = rc2;
     1924    }
     1925    else
     1926        pCtx->fExtrn = 0;
     1927
    19061928    return rcStrict;
    19071929}
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r71222 r71224  
    7070
    7171/** Windows: Checks if a_GCPhys is subject to the limited A20 gate emulation. */
    72 # define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys)     ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K)
     72# define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys)    ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K)
    7373/** Windows: Checks if a_GCPhys is relevant to the limited A20 gate emulation. */
    7474# define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys)    \
    7575    ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) )
     76
     77/** The CPUMCTX_EXTRN_XXX mask for IEM. */
     78# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM     CPUMCTX_EXTRN_ALL
    7679
    7780#endif /* RT_OS_WINDOWS */
Note: See TracChangeset for help on using the changeset viewer.

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