VirtualBox

Changeset 71222 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 5, 2018 10:07:48 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
121132
Message:

NEM/win,VMM,PGM: Ported NEM runloop to ring-0. bugref:9044

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VBoxVMM.d

    r69111 r71222  
    5858    probe r0__vmm__return__to__ring3__rc(struct VMCPU *a_pVCpu, struct CPUMCTX *p_Ctx, int a_rc);
    5959    probe r0__vmm__return__to__ring3__hm(struct VMCPU *a_pVCpu, struct CPUMCTX *p_Ctx, int a_rc);
     60    probe r0__vmm__return__to__ring3__nem(struct VMCPU *a_pVCpu, struct CPUMCTX *p_Ctx, int a_rc);
    6061
    6162
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r71184 r71222  
    4040NEM_TMPL_STATIC const char * const g_apszPageStates[4] = { "not-set", "unmapped", "readable", "writable" };
    4141
     42/** HV_INTERCEPT_ACCESS_TYPE names. */
     43static const char * const g_apszHvInterceptAccessTypes[4] = { "read", "write", "exec", "!undefined!" };
     44
    4245
    4346/*********************************************************************************************************************************
     
    6770    PGVM pGVM = GVMMR0FastGetGVMByVM(pVM);
    6871    AssertReturn(pGVM, VERR_INVALID_VM_HANDLE);
    69     return nemR0WinMapPages(pGVM, pVM, &pGVM->aCpus[pVCpu->idCpu], GCPhysSrc, GCPhysDst, 1, fFlags);
     72    return nemR0WinMapPages(pGVM, pVM, &pGVM->aCpus[pVCpu->idCpu],
     73                            GCPhysSrc & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
     74                            GCPhysDst & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
     75                            1, fFlags);
    7076#else
    7177    pVCpu->nem.s.Hypercall.MapPages.GCPhysSrc   = GCPhysSrc & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK;
     
    9197    PGVM pGVM = GVMMR0FastGetGVMByVM(pVM);
    9298    AssertReturn(pGVM, VERR_INVALID_VM_HANDLE);
    93     return nemR0WinUnmapPages(pGVM, &pGVM->aCpus[pVCpu->idCpu], GCPhys, 1);
     99    return nemR0WinUnmapPages(pGVM, &pGVM->aCpus[pVCpu->idCpu], GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, 1);
    94100# else
    95101    pVCpu->nem.s.Hypercall.UnmapPages.GCPhys    = GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK;
     
    100106
    101107#endif /* NEM_WIN_USE_HYPERCALLS_FOR_PAGES */
    102 
    103 
    104108#ifndef IN_RING0
    105109
    106110NEM_TMPL_STATIC int nemHCWinCopyStateToHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
    107111{
    108 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
     112# ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
    109113    NOREF(pCtx);
    110114    int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, 0, NULL);
     
    112116    return rc;
    113117
    114 #else
     118# else
    115119    WHV_REGISTER_NAME  aenmNames[128];
    116120    WHV_REGISTER_VALUE aValues[128];
     
    157161
    158162    /* Segments */
    159 #define COPY_OUT_SEG(a_idx, a_enmName, a_SReg) \
     163#  define COPY_OUT_SEG(a_idx, a_enmName, a_SReg) \
    160164        do { \
    161165            aenmNames[a_idx]                  = a_enmName; \
     
    391395    Assert(iReg < RT_ELEMENTS(aValues));
    392396    Assert(iReg < RT_ELEMENTS(aenmNames));
    393 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
     397#  ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
    394398    Log12(("Calling WHvSetVirtualProcessorRegisters(%p, %u, %p, %u, %p)\n",
    395399           pVM->nem.s.hPartition, pVCpu->idCpu, aenmNames, iReg, aValues));
    396 #endif
     400#  endif
    397401    HRESULT hrc = WHvSetVirtualProcessorRegisters(pVM->nem.s.hPartition, pVCpu->idCpu, aenmNames, iReg, aValues);
    398402    if (SUCCEEDED(hrc))
     
    402406                           hrc, RTNtLastStatusValue(), RTNtLastErrorValue()));
    403407    return VERR_INTERNAL_ERROR;
    404 #endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */
     408# endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */
    405409}
    406410
     
    408412NEM_TMPL_STATIC int nemHCWinCopyStateFromHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fWhat)
    409413{
    410 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
     414# ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
    411415    /* See NEMR0ImportState */
    412416    NOREF(pCtx);
     
    421425    return rc;
    422426
    423 #else
     427# else
    424428    WHV_REGISTER_NAME  aenmNames[128];
    425429
     
    534538    Assert(RT_ELEMENTS(aValues) >= cRegs);
    535539    Assert(RT_ELEMENTS(aenmNames) >= cRegs);
    536 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
     540#  ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
    537541    Log12(("Calling WHvGetVirtualProcessorRegisters(%p, %u, %p, %u, %p)\n",
    538542          pVM->nem.s.hPartition, pVCpu->idCpu, aenmNames, cRegs, aValues));
    539 #endif
     543#  endif
    540544    HRESULT hrc = WHvGetVirtualProcessorRegisters(pVM->nem.s.hPartition, pVCpu->idCpu, aenmNames, cRegs, aValues);
    541545    if (SUCCEEDED(hrc))
     
    567571
    568572        /* Segments */
    569 #define COPY_BACK_SEG(a_idx, a_enmName, a_SReg) \
     573#  define COPY_BACK_SEG(a_idx, a_enmName, a_SReg) \
    570574            do { \
    571575                Assert(aenmNames[a_idx] == a_enmName); \
     
    774778                           hrc, RTNtLastStatusValue(), RTNtLastErrorValue()));
    775779    return VERR_INTERNAL_ERROR;
    776 #endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */
    777 }
     780# endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */
     781}
     782
     783#endif /* !IN_RING0 */
    778784
    779785
     
    11721178}
    11731179
    1174 #ifdef IN_RING3
     1180#ifdef IN_RING0
     1181/**
     1182 * Wrapper around nemR0WinImportState that converts VERR_NEM_CHANGE_PGM_MODE and
     1183 * VERR_NEM_FLUSH_TBL into informational status codes and logs+asserts statuses.
     1184 *
     1185 * @returns VBox strict status code.
     1186 * @param   pGVM            The global (ring-0) VM structure.
     1187 * @param   pGVCpu          The global (ring-0) per CPU structure.
     1188 * @param   pCtx            The CPU context to import into.
     1189 * @param   fWhat           What to import.
     1190 * @param   pszCaller       Whoe is doing the importing.
     1191 */
     1192DECLINLINE(VBOXSTRICTRC) nemR0WinImportStateStrict(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat, const char *pszCaller)
     1193{
     1194    int rc = nemR0WinImportState(pGVM, pGVCpu, pCtx, fWhat);
     1195    if (RT_SUCCESS(rc))
     1196    {
     1197        Assert(rc == VINF_SUCCESS);
     1198        return VINF_SUCCESS;
     1199    }
     1200
     1201    if (rc == VERR_NEM_CHANGE_PGM_MODE || rc == VERR_NEM_FLUSH_TLB)
     1202    {
     1203        Log4(("%s/%u: nemR0WinImportState -> %Rrc\n", pszCaller, pGVCpu->idCpu, -rc));
     1204        return -rc;
     1205    }
     1206    AssertMsgFailedReturn(("%s/%u: nemR0WinImportState failed: %Rrc\n", pszCaller, pGVCpu->idCpu, rc), rc);
     1207}
     1208#endif /* IN_RING0 */
    11751209
    11761210/**
     
    12011235 * @param   pMsg            The message.
    12021236 * @param   pCtx            The register context.
     1237 * @param   pGVCpu          The global (ring-0) per CPU structure (NULL in r3).
    12031238 */
    12041239NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageMemory(PVM pVM, PVMCPU pVCpu, HV_X64_MEMORY_INTERCEPT_MESSAGE const *pMsg,
    1205                                                          PCPUMCTX pCtx)
    1206 {
     1240                                                         PCPUMCTX pCtx, PGVMCPU pGVCpu)
     1241{
     1242    Assert(   pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_READ
     1243           || pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE
     1244           || pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_EXECUTE);
     1245
    12071246    /*
    12081247     * Whatever we do, we must clear pending event ejection upon resume.
     
    12261265            if (State.fCanResume)
    12271266            {
    1228                 Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; restarting (%s)\n",
     1267                Log4(("MemExit/%u: %04x:%08RX64: %RGp (=>%RHp) %s fProt=%u%s%s%s; restarting (%s)\n",
     1268                      pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
    12291269                      pMsg->GuestPhysicalAddress, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,
    12301270                      Info.fHasHandlers ? " handlers" : "", Info.fZeroPage    ? " zero-pg" : "",
    1231                       State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType]));
     1271                      State.fDidSomething ? "" : " no-change", g_apszHvInterceptAccessTypes[pMsg->Header.InterceptAccessType]));
    12321272                return VINF_SUCCESS;
    12331273            }
    12341274        }
    1235         Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; emulating (%s)\n",
     1275        Log4(("MemExit/%u: %04x:%08RX64: %RGp (=>%RHp) %s fProt=%u%s%s%s; emulating (%s)\n",
     1276              pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
    12361277              pMsg->GuestPhysicalAddress, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,
    12371278              Info.fHasHandlers ? " handlers" : "", Info.fZeroPage    ? " zero-pg" : "",
    1238               State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType]));
     1279              State.fDidSomething ? "" : " no-change", g_apszHvInterceptAccessTypes[pMsg->Header.InterceptAccessType]));
    12391280    }
    12401281    else
    1241         Log4(("MemExit: %RGp rc=%Rrc%s; emulating (%s)\n", pMsg->GuestPhysicalAddress, rc,
    1242               State.fDidSomething ? " modified-backing" : "", g_apszWHvMemAccesstypes[pMsg->Header.InterceptAccessType]));
     1282        Log4(("MemExit/%u: %04x:%08RX64: %RGp rc=%Rrc%s; emulating (%s)\n",
     1283              pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, pMsg->GuestPhysicalAddress, rc,
     1284              State.fDidSomething ? " modified-backing" : "", g_apszHvInterceptAccessTypes[pMsg->Header.InterceptAccessType]));
    12431285
    12441286    /*
     
    12461288     */
    12471289    nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header);
     1290    VBOXSTRICTRC rcStrict;
     1291#ifdef IN_RING0
     1292    rcStrict = nemR0WinImportStateStrict(pGVCpu->pGVM, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "MemExit");
     1293    if (rcStrict != VINF_SUCCESS)
     1294        return rcStrict;
     1295#else
    12481296    rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
    12491297    AssertRCReturn(rc, rc);
    1250 
    1251     VBOXSTRICTRC rcStrict;
     1298    NOREF(pGVCpu);
     1299#endif
     1300
    12521301    if (pMsg->InstructionByteCount > 0)
    12531302        rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, CPUMCTX2CORE(pCtx), pMsg->Header.Rip,
     
    12681317 * @param   pVCpu           The cross context per CPU structure.
    12691318 * @param   pMsg            The message.
     1319 * @param   pGVCpu          The global (ring-0) per CPU structure (NULL in r3).
    12701320 */
    12711321NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageIoPort(PVM pVM, PVMCPU pVCpu, HV_X64_IO_PORT_INTERCEPT_MESSAGE const *pMsg,
    1272                                                          PCPUMCTX pCtx)
     1322                                                         PCPUMCTX pCtx, PGVMCPU pGVCpu)
    12731323{
    12741324    Assert(   pMsg->AccessInfo.AccessSize == 1
    12751325           || pMsg->AccessInfo.AccessSize == 2
    12761326           || pMsg->AccessInfo.AccessSize == 4);
     1327    Assert(   pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_READ
     1328           || pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE);
    12771329
    12781330    /*
     
    12941346        {
    12951347            rcStrict = IOMIOPortWrite(pVM, pVCpu, pMsg->PortNumber, (uint32_t)pMsg->Rax & fAndMask, pMsg->AccessInfo.AccessSize);
    1296             Log4(("IOExit: %04x:%08RX64: OUT %#x, %#x LB %u rcStrict=%Rrc\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
    1297                   pMsg->PortNumber, (uint32_t)pMsg->Rax & fAndMask, pMsg->AccessInfo.AccessSize, VBOXSTRICTRC_VAL(rcStrict) ));
     1348            Log4(("IOExit/%u: %04x:%08RX64: OUT %#x, %#x LB %u rcStrict=%Rrc\n",
     1349                  pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, pMsg->PortNumber,
     1350                  (uint32_t)pMsg->Rax & fAndMask, pMsg->AccessInfo.AccessSize, VBOXSTRICTRC_VAL(rcStrict) ));
    12981351            if (IOM_SUCCESS(rcStrict))
    12991352            {
     
    13061359            uint32_t uValue = 0;
    13071360            rcStrict = IOMIOPortRead(pVM, pVCpu, pMsg->PortNumber, &uValue, pMsg->AccessInfo.AccessSize);
    1308             Log4(("IOExit: %04x:%08RX64: IN %#x LB %u -> %#x, rcStrict=%Rrc\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
    1309                   pMsg->PortNumber, pMsg->AccessInfo.AccessSize, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     1361            Log4(("IOExit/%u: %04x:%08RX64: IN %#x LB %u -> %#x, rcStrict=%Rrc\n", pVCpu->idCpu, pMsg->Header.CsSegment.Selector,
     1362                  pMsg->Header.Rip, pMsg->PortNumber, pMsg->AccessInfo.AccessSize, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
    13101363            if (IOM_SUCCESS(rcStrict))
    13111364            {
     
    13151368                    pCtx->rax = uValue;
    13161369                pCtx->fExtrn &= ~CPUMCTX_EXTRN_RAX;
    1317                 Log4(("IOExit: RAX %#RX64 -> %#RX64\n", pMsg->Rax, pCtx->rax));
     1370                Log4(("IOExit/%u: RAX %#RX64 -> %#RX64\n", pVCpu->idCpu, pMsg->Rax, pCtx->rax));
    13181371                nemHCWinCopyStateFromX64Header(pCtx, &pMsg->Header);
    13191372                nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
     
    13461399        pCtx->rdi = pMsg->Rdi;
    13471400        pCtx->rsi = pMsg->Rsi;
     1401#ifdef IN_RING0
     1402        rcStrict = nemR0WinImportStateStrict(pGVCpu->pGVM, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "IOExit");
     1403        if (rcStrict != VINF_SUCCESS)
     1404            return rcStrict;
     1405#else
    13481406        int rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);
    13491407        AssertRCReturn(rc, rc);
    1350 
    1351         Log4(("IOExit: %04x:%08RX64: %s%s %#x LB %u (emulating)\n", pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
     1408        RT_NOREF(pGVCpu);
     1409#endif
     1410
     1411        Log4(("IOExit/%u: %04x:%08RX64: %s%s %#x LB %u (emulating)\n",
     1412              pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip,
    13521413              pMsg->AccessInfo.RepPrefix ? "REP " : "",
    13531414              pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE ? "OUTS" : "INS",
     
    13791440 * @param   pMappingHeader  The message slot mapping.
    13801441 * @param   pCtx            The register context.
     1442 * @param   pGVCpu          The global (ring-0) per CPU structure (NULL in r3).
    13811443 */
    13821444NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessage(PVM pVM, PVMCPU pVCpu, VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader,
    1383                                                    PCPUMCTX pCtx)
     1445                                                   PCPUMCTX pCtx, PGVMCPU pGVCpu)
    13841446{
    13851447    if (pMappingHeader->enmVidMsgType == VidMessageHypervisorMessage)
     
    13911453            case HvMessageTypeUnmappedGpa:
    13921454                Assert(pMsg->Header.PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment));
    1393                 return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx);
     1455                return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx, pGVCpu);
    13941456
    13951457            case HvMessageTypeGpaIntercept:
    13961458                Assert(pMsg->Header.PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment));
    1397                 return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx);
     1459                return nemHCWinHandleMessageMemory(pVM, pVCpu, &pMsg->X64MemoryIntercept, pCtx, pGVCpu);
    13981460
    13991461            case HvMessageTypeX64IoPortIntercept:
    14001462                Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64IoPortIntercept));
    1401                 return nemHCWinHandleMessageIoPort(pVM, pVCpu, &pMsg->X64IoPortIntercept, pCtx);
     1463                return nemHCWinHandleMessageIoPort(pVM, pVCpu, &pMsg->X64IoPortIntercept, pCtx, pGVCpu);
    14021464
    14031465            case HvMessageTypeX64Halt:
     
    14541516 *                          exit.
    14551517 * @param   pMappingHeader  The message slot mapping.
     1518 * @param   pGVM            The global (ring-0) VM structure (NULL in r3).
     1519 * @param   pGVCpu          The global (ring-0) per CPU structure (NULL in r3).
    14561520 */
    14571521NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinStopCpu(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rcStrict,
    1458                                              VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader)
     1522                                             VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader,
     1523                                             PGVM pGVM, PGVMCPU pGVCpu)
    14591524{
    14601525    /*
     
    14621527     * does another VM exit.
    14631528     */
     1529#ifdef IN_RING0
     1530    pVCpu->nem.s.uIoCtlBuf.idCpu = pGVCpu->idCpu;
     1531    NTSTATUS rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlStopVirtualProcessor.uFunction,
     1532                                            &pVCpu->nem.s.uIoCtlBuf.idCpu, sizeof(pVCpu->nem.s.uIoCtlBuf.idCpu),
     1533                                            NULL, 0);
     1534    if (NT_SUCCESS(rcNt))
     1535    {
     1536        Log8(("nemHCWinStopCpu: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
     1537        return rcStrict;
     1538    }
     1539#else
    14641540    BOOL fRet = VidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu);
    14651541    if (fRet)
     
    14681544        return rcStrict;
    14691545    }
     1546    RT_NOREF(pGVM, pGVCpu);
     1547#endif
    14701548
    14711549    /*
    14721550     * Dang. The CPU stopped by itself and we got a couple of message to deal with.
    14731551     */
     1552#ifdef IN_RING0
     1553    AssertLogRelMsgReturn(rcNt == ERROR_VID_STOP_PENDING, ("rcNt=%#x\n", rcNt),
     1554                          RT_SUCCESS(rcStrict) ?  VERR_INTERNAL_ERROR_3 : rcStrict);
     1555#else
    14741556    DWORD dwErr = RTNtLastErrorValue();
    1475     AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u\n", dwErr),
     1557    AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u (%#x)\n", dwErr, dwErr),
    14761558                          RT_SUCCESS(rcStrict) ?  VERR_INTERNAL_ERROR_3 : rcStrict);
     1559#endif
    14771560    Log8(("nemHCWinStopCpu: Stopping CPU pending...\n"));
    14781561
     
    14811564     * Note! We can safely ASSUME that rcStrict isn't an important information one.
    14821565     */
     1566#ifdef IN_RING0
     1567    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
     1568    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_GET_NEXT_MESSAGE;
     1569    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = 30000; /*ms*/
     1570    rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
     1571                                   &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
     1572                                   sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
     1573                                   NULL, 0);
     1574    AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
     1575                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1576#else
    14831577    BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    14841578                                                     VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
    1485     AssertLogRelMsgReturn(fWait,
    1486                           ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
     1579    AssertLogRelMsgReturn(fWait, ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    14871580                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1581#endif
    14881582
    14891583    /* It should be a hypervisor message and definitely not a stop request completed message. */
     
    14941588                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
    14951589
    1496     VBOXSTRICTRC rcStrict2 = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, CPUMQueryGuestCtxPtr(pVCpu));
     1590    VBOXSTRICTRC rcStrict2 = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, CPUMQueryGuestCtxPtr(pVCpu), pGVCpu);
    14971591    if (rcStrict2 != VINF_SUCCESS && RT_SUCCESS(rcStrict))
    14981592        rcStrict = rcStrict2;
     
    15021596     * that as handled too.  CPU is back into fully stopped stated then.
    15031597     */
     1598#ifdef IN_RING0
     1599    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
     1600    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE;
     1601    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = 30000; /*ms*/
     1602    rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
     1603                                   &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
     1604                                   sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
     1605                                   NULL, 0);
     1606    AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("2st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
     1607                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1608#else
    15041609    fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    15051610                                                VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
    1506     AssertLogRelMsgReturn(fWait,
    1507                           ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
     1611    AssertLogRelMsgReturn(fWait, ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    15081612                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1613#endif
    15091614
    15101615    /* It should be a stop request completed message. */
     
    15161621
    15171622    /* Mark this as handled. */
    1518     fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    1519                                                 VID_MSHAGN_F_HANDLE_MESSAGE, 30000 /*ms*/);
    1520     AssertLogRelMsgReturn(fWait,
    1521                           ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
     1623#ifdef IN_RING0
     1624    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
     1625    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_HANDLE_MESSAGE;
     1626    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = 30000; /*ms*/
     1627    rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
     1628                                   &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
     1629                                   sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
     1630                                   NULL, 0);
     1631    AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
    15221632                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1633#else
     1634    fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, VID_MSHAGN_F_HANDLE_MESSAGE, 30000 /*ms*/);
     1635    AssertLogRelMsgReturn(fWait, ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
     1636                          RT_SUCCESS(rcStrict) ? VERR_INTERNAL_ERROR_3 : rcStrict);
     1637#endif
    15231638    Log8(("nemHCWinStopCpu: Stopped the CPU (rcStrict=%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict) ));
    15241639    return rcStrict;
     
    15261641
    15271642
    1528 NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinRunGC(PVM pVM, PVMCPU pVCpu)
     1643NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinRunGC(PVM pVM, PVMCPU pVCpu, PGVM pGVM, PGVMCPU pGVCpu)
    15291644{
    15301645    PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
    1531     LogFlow(("nemHCWinRunGC: Entering #%u cs:rip=%04x:%08RX64 efl=%#08RX64\n", pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags));
     1646    LogFlow(("NEM/%u: %04x:%08RX64 efl=%#08RX64 <=\n", pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags));
    15321647#ifdef LOG_ENABLED
    15331648    if (LogIs3Enabled())
     
    15521667        if ((pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK)) != (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK))
    15531668        {
     1669#ifdef IN_RING0
     1670            int rc2 = nemR0WinExportState(pGVM, pGVCpu, pCtx);
     1671#else
    15541672            int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu, pCtx);
     1673            RT_NOREF(pGVM, pGVCpu);
     1674#endif
    15551675            AssertRCReturn(rc2, rc2);
    15561676        }
     
    15661686            else
    15671687            {
    1568                 if (g_pfnVidStartVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu))
    1569                     pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;
    1570                 else
    1571                     AssertLogRelMsgFailedReturn(("VidStartVirtualProcessor failed for CPU #%u: %u (%#x, rcNt=%#x)\n",
    1572                                                  pVCpu->idCpu, RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()),
    1573                                                 VERR_INTERNAL_ERROR_3);
     1688#ifdef IN_RING0
     1689                pVCpu->nem.s.uIoCtlBuf.idCpu = pGVCpu->idCpu;
     1690                NTSTATUS rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlStartVirtualProcessor.uFunction,
     1691                                                        &pVCpu->nem.s.uIoCtlBuf.idCpu, sizeof(pVCpu->nem.s.uIoCtlBuf.idCpu),
     1692                                                        NULL, 0);
     1693                LogFlow(("NEM/%u: IoCtlStartVirtualProcessor -> %#x\n", pVCpu->idCpu, rcNt));
     1694                AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("VidStartVirtualProcessor failed for CPU #%u: %#x\n", pGVCpu->idCpu, rcNt),
     1695                                      VERR_INTERNAL_ERROR_3);
     1696#else
     1697                AssertLogRelMsgReturn(g_pfnVidStartVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu),
     1698                                      ("VidStartVirtualProcessor failed for CPU #%u: %u (%#x, rcNt=%#x)\n",
     1699                                       pVCpu->idCpu, RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue()),
     1700                                      VERR_INTERNAL_ERROR_3);
     1701#endif
     1702                pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE;
    15741703            }
    15751704
    1576             if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED))
     1705            if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED))
    15771706            {
     1707#ifdef IN_RING0
     1708                pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
     1709                pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = pVCpu->nem.s.fHandleAndGetFlags;
     1710                pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = cMillies;
     1711                NTSTATUS rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
     1712                                                        &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
     1713                                                        sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
     1714                                                        NULL, 0);
     1715                VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
     1716                if (rcNt == STATUS_SUCCESS)
     1717#else
    15781718                BOOL fRet = VidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    15791719                                                           pVCpu->nem.s.fHandleAndGetFlags, cMillies);
    1580                 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM);
     1720                VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT);
    15811721                if (fRet)
     1722#endif
    15821723                {
    15831724                    /*
    15841725                     * Deal with the message.
    15851726                     */
    1586                     rcStrict = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, pCtx);
     1727                    rcStrict = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, pCtx, pGVCpu);
    15871728                    pVCpu->nem.s.fHandleAndGetFlags |= VID_MSHAGN_F_HANDLE_MESSAGE;
     1729                    if (rcStrict == VINF_SUCCESS)
     1730                    { /* hopefully likely */ }
     1731                    else
     1732                    {
     1733                        LogFlow(("NEM/%u: breaking: nemHCWinHandleMessage -> %Rrc\n", pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) ));
     1734                        break;
     1735                    }
    15881736                }
    15891737                else
     
    15921740                       so after NtAlertThread we end up here with a STATUS_TIMEOUT.  And yeah,
    15931741                       the error code conversion is into WAIT_XXX, i.e. NT status codes. */
    1594                     DWORD dwErr = GetLastError();
    1595                     if (   dwErr == STATUS_TIMEOUT
    1596                         || dwErr == STATUS_ALERTED  /* just in case */
    1597                         || dwErr == STATUS_USER_APC /* ditto */ )
    1598                         pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; /* exits are likely */
    1599                     else
    1600                         AssertLogRelMsgFailedReturn(("VidMessageSlotHandleAndGetNext failed for CPU #%u: %u (%#x, rcNt=%#x)\n",
    1601                                                      pVCpu->idCpu, dwErr, dwErr, RTNtLastStatusValue()),
    1602                                                     VERR_INTERNAL_ERROR_3);
     1742#ifndef IN_RING0
     1743                    DWORD rcNt = GetLastError();
     1744#endif
     1745                    LogFlow(("NEM/%u: VidMessageSlotHandleAndGetNext -> %#x\n", pVCpu->idCpu, rcNt));
     1746                    AssertLogRelMsgReturn(   rcNt == STATUS_TIMEOUT
     1747                                          || rcNt == STATUS_ALERTED  /* just in case */
     1748                                          || rcNt == STATUS_USER_APC /* ditto */
     1749                                          , ("VidMessageSlotHandleAndGetNext failed for CPU #%u: %#x (%u)\n", pVCpu->idCpu, rcNt, rcNt),
     1750                                          VERR_INTERNAL_ERROR_3);
     1751                    pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; /* exits are likely */
    16031752                }
    16041753
     
    16121761                /** @todo Try handle pending flags, not just return to EM loops.  Take care
    16131762                 *        not to set important RCs here unless we've handled a message. */
    1614                 LogFlow(("nemHCWinRunGC: returning: pending FF (%#x / %#x)\n", pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions));
     1763                LogFlow(("NEM/%u: breaking: pending FF (%#x / %#x)\n",
     1764                         pVCpu->idCpu, pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions));
    16151765            }
    16161766            else
    1617                 LogFlow(("nemHCWinRunGC: returning: canceled %d (pre exec)\n", VMCPU_GET_STATE(pVCpu) ));
     1767                LogFlow(("NEM/%u: breaking: canceled %d (pre exec)\n", pVCpu->idCpu, VMCPU_GET_STATE(pVCpu) ));
    16181768        }
    16191769        else
    1620             LogFlow(("nemHCWinRunGC: returning: pending FF (pre exec)\n"));
     1770            LogFlow(("NEM/%u: breaking: pending FF (pre exec)\n", pVCpu->idCpu));
    16211771        break;
    16221772    } /* the run loop */
     
    16301780    {
    16311781        pVCpu->nem.s.fHandleAndGetFlags = 0;
    1632         rcStrict = nemHCWinStopCpu(pVM, pVCpu, rcStrict, pMappingHeader);
     1782        rcStrict = nemHCWinStopCpu(pVM, pVCpu, rcStrict, pMappingHeader, pGVM, pGVCpu);
    16331783    }
    16341784
     
    16371787    if (pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | (CPUMCTX_EXTRN_NEM_WIN_MASK & ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT)))
    16381788    {
     1789#ifdef IN_RING0
     1790        int rc2 = nemR0WinImportState(pGVM, pGVCpu, pCtx, CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK);
     1791        if (RT_SUCCESS(rc2))
     1792            pCtx->fExtrn = 0;
     1793        else if (rc2 == VERR_NEM_CHANGE_PGM_MODE || rc2 == VERR_NEM_FLUSH_TLB)
     1794        {
     1795            pCtx->fExtrn = 0;
     1796            if (rcStrict == VINF_SUCCESS || rcStrict == -rc2)
     1797                rcStrict = -rc2;
     1798            else
     1799            {
     1800                pVCpu->nem.s.rcPgmPending = -rc2;
     1801                LogFlow(("NEM/%u: rcPgmPending=%Rrc (rcStrict=%Rrc)\n", pVCpu->idCpu, rc2, VBOXSTRICTRC_VAL(rcStrict) ));
     1802            }
     1803        }
     1804#else
    16391805        int rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK);
    16401806        if (RT_SUCCESS(rc2))
    16411807            pCtx->fExtrn = 0;
     1808#endif
    16421809        else if (RT_SUCCESS(rcStrict))
    16431810            rcStrict = rc2;
     
    16461813        pCtx->fExtrn = 0;
    16471814
    1648     LogFlow(("nemHCWinRunGC: Leaving #%u cs:rip=%04x:%08RX64 efl=%#08RX64\n", pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags));
     1815    LogFlow(("NEM/%u: %04x:%08RX64 efl=%#08RX64 => %Rrc\n",
     1816             pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip, pCtx->rflags, VBOXSTRICTRC_VAL(rcStrict) ));
    16491817    return rcStrict;
    16501818}
    1651 #endif
    1652 
    1653 #endif /* IN_RING0 */
     1819
    16541820
    16551821
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r71152 r71222  
    943943                                if (RT_SUCCESS(rc))
    944944                                {
    945                                     pVM->pVMR3 = RTR0MemObjAddressR3(pGVM->gvmm.s.VMMapObj);
    946                                     AssertPtr((void *)pVM->pVMR3);
     945                                    PVMR3 pVMR3 = RTR0MemObjAddressR3(pGVM->gvmm.s.VMMapObj);
     946                                    pVM->pVMR3 = pVMR3;
     947                                    AssertPtr((void *)pVMR3);
    947948
    948949                                    /* Initialize all the VM pointers. */
     
    950951                                    {
    951952                                        pVM->aCpus[i].pVMR0           = pVM;
    952                                         pVM->aCpus[i].pVMR3           = pVM->pVMR3;
     953                                        pVM->aCpus[i].pVMR3           = pVMR3;
    953954                                        pVM->aCpus[i].idHostCpu       = NIL_RTCPUID;
    954955                                        pVM->aCpus[i].hNativeThreadR0 = NIL_RTNATIVETHREAD;
     
    972973                                        pHandle->ProcId               = ProcId;
    973974                                        pGVM->pVM                     = pVM;
     975                                        pGVM->pVMR3                   = pVMR3;
    974976                                        pGVM->aCpus[0].hEMT           = hEMT0;
    975977                                        pVM->aCpus[0].hNativeThreadR0 = hEMT0;
    976978                                        pGVMM->cEMTs += cCpus;
     979
     980                                        for (uint32_t i = 0; i < cCpus; i++)
     981                                        {
     982                                            pGVM->aCpus[i].pVCpu          = &pVM->aCpus[i];
     983                                            pGVM->aCpus[i].pVM            = pVM;
     984                                        }
    977985
    978986                                        /* Associate it with the session and create the context hook for EMT0. */
     
    9941002
    9951003                                                *ppVM = pVM;
    996                                                 Log(("GVMMR0CreateVM: pVM=%p pVMR3=%p pGVM=%p hGVM=%d\n", pVM, pVM->pVMR3, pGVM, iHandle));
     1004                                                Log(("GVMMR0CreateVM: pVM=%p pVMR3=%p pGVM=%p hGVM=%d\n", pVM, pVMR3, pGVM, iHandle));
    9971005                                                return VINF_SUCCESS;
    9981006                                            }
     
    10631071        pGVM->aCpus[i].gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
    10641072        pGVM->aCpus[i].hEMT                  = NIL_RTNATIVETHREAD;
     1073        pGVM->aCpus[i].pGVM                  = pGVM;
     1074        pGVM->aCpus[i].pVCpu                 = NULL;
     1075        pGVM->aCpus[i].pVM                   = NULL;
    10651076    }
    10661077}
     
    11861197
    11871198    /* Be careful here because we might theoretically be racing someone else cleaning up. */
    1188     if (    pHandle->pVM == pVM
    1189         &&  (   (   pHandle->hEMT0  == hSelf
    1190                  && pHandle->ProcId == ProcId)
    1191              || pHandle->hEMT0 == NIL_RTNATIVETHREAD)
    1192         &&  VALID_PTR(pHandle->pvObj)
    1193         &&  VALID_PTR(pHandle->pSession)
    1194         &&  VALID_PTR(pHandle->pGVM)
    1195         &&  pHandle->pGVM->u32Magic == GVM_MAGIC)
     1199    if (   pHandle->pVM == pVM
     1200        && (   (   pHandle->hEMT0  == hSelf
     1201                && pHandle->ProcId == ProcId)
     1202            || pHandle->hEMT0 == NIL_RTNATIVETHREAD)
     1203        && VALID_PTR(pHandle->pvObj)
     1204        && VALID_PTR(pHandle->pSession)
     1205        && VALID_PTR(pHandle->pGVM)
     1206        && pHandle->pGVM->u32Magic == GVM_MAGIC)
    11961207    {
    11971208        /* Check that other EMTs have deregistered. */
     
    13501361     */
    13511362    PGVM pGVM = pHandle->pGVM;
    1352     if (    VALID_PTR(pGVM)
    1353         &&  pGVM->u32Magic == GVM_MAGIC)
     1363    if (   VALID_PTR(pGVM)
     1364        && pGVM->u32Magic == GVM_MAGIC)
    13541365    {
    13551366        pGVMM->cEMTs -= pGVM->cCpus;
  • trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp

    r71184 r71222  
    2424#include <iprt/nt/hyperv.h>
    2525#include <iprt/nt/vid.h>
     26#include <winerror.h>
    2627
    2728#include <VBox/vmm/nem.h>
     
    5051
    5152/*********************************************************************************************************************************
     53*   Internal Functions                                                                                                           *
     54*********************************************************************************************************************************/
     55typedef uint32_t DWORD; /* for winerror.h constants */
     56
     57
     58/*********************************************************************************************************************************
    5259*   Global Variables                                                                                                             *
    5360*********************************************************************************************************************************/
     
    5865*   Internal Functions                                                                                                           *
    5966*********************************************************************************************************************************/
    60 NEM_TMPL_STATIC int nemR0WinMapPages(PGVM pGVM, PVM pVM, PGVMCPU pGVCpu, RTGCPHYS GCPhysSrc, RTGCPHYS GCPhysDst,
    61                                      uint32_t cPages, uint32_t fFlags);
    62 NEM_TMPL_STATIC int nemR0WinUnmapPages(PGVM pGVM, PGVMCPU pGVCpu, RTGCPHYS GCPhys, uint32_t cPages);
     67NEM_TMPL_STATIC int  nemR0WinMapPages(PGVM pGVM, PVM pVM, PGVMCPU pGVCpu, RTGCPHYS GCPhysSrc, RTGCPHYS GCPhysDst,
     68                                      uint32_t cPages, uint32_t fFlags);
     69NEM_TMPL_STATIC int  nemR0WinUnmapPages(PGVM pGVM, PGVMCPU pGVCpu, RTGCPHYS GCPhys, uint32_t cPages);
     70NEM_TMPL_STATIC int  nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx);
     71NEM_TMPL_STATIC int  nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat);
     72DECLINLINE(NTSTATUS) nemR0NtPerformIoControl(PGVM pGVM, uint32_t uFunction, void *pvInput, uint32_t cbInput,
     73                                                     void *pvOutput, uint32_t cbOutput);
    6374
    6475
     
    497508 * @param   fWhat       What to export. To be defined, UINT64_MAX for now.
    498509 */
    499 static int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx)
     510NEM_TMPL_STATIC int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx)
    500511{
    501512    PVMCPU                     pVCpu  = &pGVM->pVM->aCpus[pGVCpu->idCpu];
     
    10751086 * @param   fWhat       What to import, CPUMCTX_EXTRN_XXX.
    10761087 */
    1077 static int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat)
     1088NEM_TMPL_STATIC int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat)
    10781089{
    10791090    HV_INPUT_GET_VP_REGISTERS *pInput = (HV_INPUT_GET_VP_REGISTERS *)pGVCpu->nem.s.pbHypercallData;
     
    16941705    pCtx->fExtrn &= ~fWhat;
    16951706
     1707    /* Typical. */
     1708    if (!fMaybeChangedMode && !fFlushTlb)
     1709        return VINF_SUCCESS;
     1710
     1711    /*
     1712     * Slow.
     1713     */
    16961714    int rc = VINF_SUCCESS;
    16971715    if (fMaybeChangedMode)
     
    16991717        rc = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
    17001718        if (rc == VINF_PGM_CHANGE_MODE)
    1701             rc = VERR_NEM_CHANGE_PGM_MODE;
    1702         else
    1703             AssertRC(rc);
    1704     }
    1705     if (fFlushTlb && rc == VINF_SUCCESS)
     1719        {
     1720            LogFlow(("nemR0WinImportState: -> VERR_NEM_CHANGE_PGM_MODE!\n"));
     1721            return VERR_NEM_CHANGE_PGM_MODE;
     1722        }
     1723        AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc));
     1724    }
     1725
     1726    if (fFlushTlb)
     1727    {
     1728        LogFlow(("nemR0WinImportState: -> VERR_NEM_FLUSH_TLB!\n"));
    17061729        rc = VERR_NEM_FLUSH_TLB; /* Calling PGMFlushTLB w/o long jump setup doesn't work, ring-3 does it. */
     1730    }
    17071731
    17081732    return rc;
     
    17411765}
    17421766
     1767
     1768VMMR0_INT_DECL(VBOXSTRICTRC) NEMR0RunGuestCode(PGVM pGVM, VMCPUID idCpu)
     1769{
     1770    PVM pVM = pGVM->pVM;
     1771    return nemHCWinRunGC(pVM, &pVM->aCpus[idCpu], pGVM, &pGVM->aCpus[idCpu]);
     1772}
     1773
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r71198 r71222  
    506506
    507507/**
     508 * Does EMT specific VM initialization.
     509 *
     510 * @returns VBox status code.
     511 * @param   pGVM        The ring-0 VM structure.
     512 * @param   pVM         The cross context VM structure.
     513 * @param   idCpu       The EMT that's calling.
     514 */
     515static int vmmR0InitVMEmt(PGVM pGVM, PVM pVM, VMCPUID idCpu)
     516{
     517    /* Paranoia (caller checked these already). */
     518    AssertReturn(idCpu < pGVM->cCpus, VERR_INVALID_CPU_ID);
     519    AssertReturn(pGVM->aCpus[idCpu].hEMT == RTThreadNativeSelf(), VERR_INVALID_CPU_ID);
     520
     521#ifdef LOG_ENABLED
     522    /*
     523     * Registration of ring 0 loggers.
     524     */
     525    PVMCPU       pVCpu     = &pVM->aCpus[idCpu];
     526    PVMMR0LOGGER pR0Logger = pVCpu->vmm.s.pR0LoggerR0;
     527    if (   pR0Logger
     528        && !pR0Logger->fRegistered)
     529    {
     530        RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
     531        pR0Logger->fRegistered = true;
     532    }
     533#endif
     534    RT_NOREF(pVM);
     535
     536    return VINF_SUCCESS;
     537}
     538
     539
     540
     541/**
    508542 * Terminates the R0 bits for a particular VM instance.
    509543 *
     
    11671201                VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    11681202
    1169 #ifdef LOG_ENABLED
    1170                 /*
    1171                  * Ugly: Lazy registration of ring 0 loggers.
    1172                  */
    1173                 if (pVCpu->idCpu > 0)
    1174                 {
    1175                     PVMMR0LOGGER pR0Logger = pVCpu->vmm.s.pR0LoggerR0;
    1176                     if (   pR0Logger
    1177                         && RT_UNLIKELY(!pR0Logger->fRegistered))
    1178                     {
    1179                         RTLogSetDefaultInstanceThread(&pR0Logger->Logger, (uintptr_t)pVM->pSession);
    1180                         pR0Logger->fRegistered = true;
    1181                     }
    1182                 }
    1183 #endif
    1184 
    11851203#ifdef VMM_R0_TOUCH_FPU
    11861204                /*
     
    13211339        }
    13221340
     1341        case VMMR0_DO_NEM_RUN:
     1342        {
     1343            /*
     1344             * Setup the longjmp machinery and execute guest code (calls NEMR0RunGuestCode).
     1345             */
     1346            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     1347            int rc = vmmR0CallRing3SetJmp2(&pVCpu->vmm.s.CallRing3JmpBufR0, NEMR0RunGuestCode, pGVM, idCpu);
     1348            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     1349            STAM_COUNTER_INC(&pVM->vmm.s.StatRunRC);
     1350
     1351            pVCpu->vmm.s.iLastGZRc = rc;
     1352
     1353            /*
     1354             * Fire dtrace probe and collect statistics.
     1355             */
     1356            VBOXVMM_R0_VMM_RETURN_TO_RING3_NEM(pVCpu, CPUMQueryGuestCtxPtr(pVCpu), rc);
     1357#ifdef VBOX_WITH_STATISTICS
     1358            vmmR0RecordRC(pVM, pVCpu, rc);
     1359#endif
     1360            break;
     1361        }
     1362
     1363
    13231364        /*
    13241365         * For profiling.
     
    15391580        case VMMR0_DO_VMMR0_INIT:
    15401581            rc = vmmR0InitVM(pGVM, pVM, RT_LODWORD(u64Arg), RT_HIDWORD(u64Arg));
     1582            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     1583            break;
     1584
     1585        /*
     1586         * Does EMT specific ring-0 init.
     1587         */
     1588        case VMMR0_DO_VMMR0_INIT_EMT:
     1589            rc = vmmR0InitVMEmt(pGVM, pVM, idCpu);
    15411590            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    15421591            break;
  • trunk/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm

    r69221 r71222  
    5656;
    5757BEGINPROC vmmR0CallRing3SetJmp
     58GLOBALNAME vmmR0CallRing3SetJmp2
    5859GLOBALNAME vmmR0CallRing3SetJmpEx
    5960    ;
  • trunk/src/VBox/VMM/VMMR0/VMMR0JmpA-x86.asm

    r69221 r71222  
    5353;
    5454BEGINPROC vmmR0CallRing3SetJmp
     55GLOBALNAME vmmR0CallRing3SetJmp2
    5556GLOBALNAME vmmR0CallRing3SetJmpEx
    5657    ;
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r71184 r71222  
    19141914#ifndef NEM_WIN_USE_OUR_OWN_RUN_API
    19151915    return nemR3WinWHvRunGC(pVM, pVCpu);
    1916 #elif 1
    1917     return nemHCWinRunGC(pVM, pVCpu);
     1916#elif 0
     1917    return nemHCWinRunGC(pVM, pVCpu, NULL /*pGVM*/, NULL /*pGVCpu*/);
    19181918#else
    1919     int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_RUN_GC, 0, NULL);
    1920     if (RT_SUCCESS(rc))
    1921         return pVCpu->nem.s.rcRing0;
    1922     return rc;
     1919    VBOXSTRICTRC rcStrict = VMMR3CallR0EmtFast(pVM, pVCpu, VMMR0_DO_NEM_RUN);
     1920    if (RT_SUCCESS(rcStrict))
     1921    {
     1922        /* We deal wtih VINF_NEM_CHANGE_PGM_MODE and VINF_NEM_FLUSH_TLB here, since we're running
     1923           the risk of getting these while we already got another RC (I/O ports). */
     1924        VBOXSTRICTRC rcPgmPending = pVCpu->nem.s.rcPgmPending;
     1925        pVCpu->nem.s.rcPgmPending = VINF_SUCCESS;
     1926        if (   rcStrict == VINF_NEM_CHANGE_PGM_MODE
     1927            || rcStrict == VINF_PGM_CHANGE_MODE
     1928            || rcPgmPending == VINF_NEM_CHANGE_PGM_MODE )
     1929        {
     1930            LogFlow(("nemR3NativeRunGC: calling PGMChangeMode...\n"));
     1931            int rc = PGMChangeMode(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR4(pVCpu), CPUMGetGuestEFER(pVCpu));
     1932            AssertRCReturn(rc, rc);
     1933            if (rcStrict == VINF_NEM_CHANGE_PGM_MODE || rcStrict == VINF_NEM_FLUSH_TLB)
     1934                rcStrict = VINF_SUCCESS;
     1935        }
     1936        else if (rcStrict == VINF_NEM_FLUSH_TLB || rcPgmPending == VINF_NEM_FLUSH_TLB)
     1937        {
     1938            LogFlow(("nemR3NativeRunGC: calling PGMFlushTLB...\n"));
     1939            int rc = PGMFlushTLB(pVCpu, CPUMGetGuestCR3(pVCpu), true);
     1940            AssertRCReturn(rc, rc);
     1941            if (rcStrict == VINF_NEM_FLUSH_TLB || rcStrict == VINF_NEM_CHANGE_PGM_MODE)
     1942                rcStrict = VINF_SUCCESS;
     1943        }
     1944        else
     1945            AssertMsg(rcPgmPending == VINF_SUCCESS, ("rcPgmPending=%Rrc\n", VBOXSTRICTRC_VAL(rcPgmPending) ));
     1946    }
     1947    return rcStrict;
    19231948#endif
    19241949}
  • trunk/src/VBox/VMM/VMMR3/PGM.cpp

    r70948 r71222  
    35043504    }
    35053505    /* Override the shadow mode is nested paging is active. */
    3506     pVM->pgm.s.fNestedPaging = HMIsNestedPagingActive(pVM);
    3507     if (pVM->pgm.s.fNestedPaging)
    3508         enmShadowMode = HMGetShwPagingMode(pVM);
     3506    if (VM_IS_NEM_ENABLED(pVM))
     3507    {
     3508        pVM->pgm.s.fNestedPaging = true;
     3509        enmShadowMode = PGMMODE_NESTED;
     3510    }
     3511    else
     3512    {
     3513        pVM->pgm.s.fNestedPaging = HMIsNestedPagingActive(pVM);
     3514        if (pVM->pgm.s.fNestedPaging)
     3515            enmShadowMode = HMGetShwPagingMode(pVM);
     3516    }
    35093517
    35103518    *penmSwitcher = enmSwitcher;
  • trunk/src/VBox/VMM/VMMR3/PGMBth.h

    r70948 r71222  
    135135    PVM pVM = pVCpu->pVMR3;
    136136
    137     Assert(HMIsNestedPagingActive(pVM) == pVM->pgm.s.fNestedPaging);
     137    Assert((HMIsNestedPagingActive(pVM) || VM_IS_NEM_ENABLED(pVM)) == pVM->pgm.s.fNestedPaging);
    138138    Assert(!pVM->pgm.s.fNestedPaging);
    139139
  • trunk/src/VBox/VMM/VMMR3/PGMShw.h

    r70948 r71222  
    191191    PVM          pVM       = pVCpu->pVMR3;
    192192
    193     Assert(HMIsNestedPagingActive(pVM) == pVM->pgm.s.fNestedPaging);
     193    Assert((HMIsNestedPagingActive(pVM) || VM_IS_NEM_ENABLED(pVM)) == pVM->pgm.s.fNestedPaging);
    194194    Assert(pVM->pgm.s.fNestedPaging);
    195195    Assert(!pVCpu->pgm.s.pShwPageCR3R3);
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r71083 r71222  
    528528
    529529/**
     530 * Worker for VMMR3InitR0 that calls ring-0 to do EMT specific initialization.
     531 *
     532 * @returns VBox status code.
     533 * @param   pVM         The cross context VM structure.
     534 * @param   pVCpu       The cross context per CPU structure.
     535 * @thread  EMT(pVCpu)
     536 */
     537static DECLCALLBACK(int) vmmR3InitR0Emt(PVM pVM, PVMCPU pVCpu)
     538{
     539    return VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_VMMR0_INIT_EMT, 0, NULL);
     540}
     541
     542
     543/**
    530544 * Initializes the R0 VMM.
    531545 *
     
    561575        rc = VINF_SUCCESS;
    562576#else
    563         rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_VMMR0_INIT,
    564                               RT_MAKE_U64(VMMGetSvnRev(), vmmGetBuildType()), NULL);
     577        rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_VMMR0_INIT, RT_MAKE_U64(VMMGetSvnRev(), vmmGetBuildType()), NULL);
    565578#endif
    566579        /*
     
    592605    else
    593606        LogRel(("VMM: Thread-context hooks unavailable\n"));
     607
     608    /*
     609     * Send all EMTs to ring-0 to get their logger initialized.
     610     */
     611    for (VMCPUID idCpu = 0; RT_SUCCESS(rc) && idCpu < pVM->cCpus; idCpu++)
     612        rc = VMR3ReqCallWait(pVM, idCpu, (PFNRT)vmmR3InitR0Emt, 2, pVM, &pVM->aCpus[idCpu]);
    594613
    595614    return rc;
     
    14311450        }
    14321451        rc = vmmR3ServiceCallRing3Request(pVM, pVCpu);
     1452        if (RT_FAILURE(rc))
     1453            return rc;
     1454        /* Resume R0 */
     1455    }
     1456}
     1457
     1458
     1459/**
     1460 * Perform one of the fast I/O control VMMR0 operation.
     1461 *
     1462 * @returns VBox strict status code.
     1463 * @param   pVM             The cross context VM structure.
     1464 * @param   pVCpu           The cross context virtual CPU structure.
     1465 * @param   enmOperation    The operation to perform.
     1466 */
     1467VMMR3_INT_DECL(VBOXSTRICTRC) VMMR3CallR0EmtFast(PVM pVM, PVMCPU pVCpu, VMMR0OPERATION enmOperation)
     1468{
     1469    for (;;)
     1470    {
     1471        VBOXSTRICTRC rcStrict;
     1472        do
     1473        {
     1474#ifdef NO_SUPCALLR0VMM
     1475            rcStrict = VERR_GENERAL_FAILURE;
     1476#else
     1477            rcStrict = SUPR3CallVMMR0Fast(pVM->pVMR0, enmOperation, pVCpu->idCpu);
     1478            if (RT_LIKELY(rcStrict == VINF_SUCCESS))
     1479                rcStrict = pVCpu->vmm.s.iLastGZRc;
     1480#endif
     1481        } while (rcStrict == VINF_EM_RAW_INTERRUPT_HYPER);
     1482
     1483#ifdef LOG_ENABLED
     1484        /*
     1485         * Flush the log
     1486         */
     1487        PVMMR0LOGGER pR0LoggerR3 = pVCpu->vmm.s.pR0LoggerR3;
     1488        if (    pR0LoggerR3
     1489            &&  pR0LoggerR3->Logger.offScratch > 0)
     1490            RTLogFlushR0(NULL, &pR0LoggerR3->Logger);
     1491#endif /* !LOG_ENABLED */
     1492        if (rcStrict != VINF_VMM_CALL_HOST)
     1493            return rcStrict;
     1494        int rc = vmmR3ServiceCallRing3Request(pVM, pVCpu);
    14331495        if (RT_FAILURE(rc))
    14341496            return rc;
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r71184 r71222  
    169169#ifdef RT_OS_WINDOWS
    170170# ifdef NEM_WIN_USE_OUR_OWN_RUN_API
     171    /** Pending VERR_NEM_CHANGE_PGM_MODE or VERR_NEM_FLUSH_TLB. */
     172    int32_t                     rcPgmPending;
    171173    /** The VID_MSHAGN_F_XXX flags.
    172174     * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
     
    201203        uint8_t                 ab[64];
    202204        HV_PARTITION_ID         idPartition;
     205        HV_VP_INDEX             idCpu;
     206# ifdef VID_MSHAGN_F_GET_NEXT_MESSAGE
     207        VID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT MsgSlotHandleAndGetNext;
     208# endif
    203209    } uIoCtlBuf;
    204210#endif
  • trunk/src/VBox/VMM/include/VMMInternal.h

    r69474 r71222  
    610610DECLASM(int)    vmmR0CallRing3SetJmp(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMP pfn, PVM pVM, PVMCPU pVCpu);
    611611
    612 /**
    613  * Callback function for vmmR0CallRing3SetJmpEx.
     612
     613/**
     614 * Callback function for vmmR0CallRing3SetJmp2.
    614615 *
    615616 * @returns VBox status code.
    616617 * @param   pvUser      The user argument.
    617618 */
     619typedef DECLCALLBACK(int) FNVMMR0SETJMP2(PGVM pGVM, VMCPUID idCpu);
     620/** Pointer to FNVMMR0SETJMP2(). */
     621typedef FNVMMR0SETJMP2 *PFNVMMR0SETJMP2;
     622
     623/**
     624 * Same as vmmR0CallRing3SetJmp except for the function signature.
     625 *
     626 * @returns VINF_SUCCESS on success or whatever is passed to vmmR0CallRing3LongJmp.
     627 * @param   pJmpBuf     The jmp_buf to set.
     628 * @param   pfn         The function to be called when not resuming.
     629 * @param   pGVM        The ring-0 VM structure.
     630 * @param   idCpu       The ID of the calling EMT.
     631 */
     632DECLASM(int)    vmmR0CallRing3SetJmp2(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMP2 pfn, PGVM pGVM, VMCPUID idCpu);
     633
     634
     635/**
     636 * Callback function for vmmR0CallRing3SetJmpEx.
     637 *
     638 * @returns VBox status code.
     639 * @param   pvUser      The user argument.
     640 */
    618641typedef DECLCALLBACK(int) FNVMMR0SETJMPEX(void *pvUser);
    619 /** Pointer to FNVMMR0SETJMP(). */
     642/** Pointer to FNVMMR0SETJMPEX(). */
    620643typedef FNVMMR0SETJMPEX *PFNVMMR0SETJMPEX;
    621644
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