VirtualBox

Changeset 70954 in vbox


Ignore:
Timestamp:
Feb 10, 2018 8:10:44 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
120797
Message:

NEM: Working on PGM notifications. bugref:9044

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r70942 r70954  
    243243        VMMAll/MMAllHyper.cpp \
    244244        VMMAll/MMAllPagePool.cpp \
     245        VMMAll/NEMAll.cpp \
    245246        VMMAll/PDMAll.cpp \
    246247        VMMAll/PDMAllCritSect.cpp \
     
    786787        VMMAll/MMAllHyper.cpp \
    787788        VMMAll/MMAllPagePool.cpp \
     789        VMMAll/NEMAll.cpp \
    788790        VMMAll/PDMAll.cpp \
    789791        VMMAll/PDMAllCritSect.cpp \
  • trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp

    r69111 r70954  
    2626#include <VBox/vmm/mm.h>
    2727#include <VBox/vmm/em.h>
     28#include <VBox/vmm/nem.h>
    2829#include <VBox/vmm/stam.h>
    2930#ifdef VBOX_WITH_REM
     
    3132#endif
    3233#include <VBox/vmm/dbgf.h>
    33 #ifdef VBOX_WITH_REM
    34 # include <VBox/vmm/rem.h>
    35 #endif
    3634#include "PGMInternal.h"
    3735#include <VBox/vmm/vm.h>
     
    5149*********************************************************************************************************************************/
    5250static int  pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(PVM pVM, PPGMPHYSHANDLER pCur, PPGMRAMRANGE pRam);
    53 static void pgmHandlerPhysicalDeregisterNotifyREM(PVM pVM, PPGMPHYSHANDLER pCur);
     51static void pgmHandlerPhysicalDeregisterNotifyREMAndNEM(PVM pVM, PPGMPHYSHANDLER pCur, int fRestoreRAM);
    5452static void pgmHandlerPhysicalResetRamFlags(PVM pVM, PPGMPHYSHANDLER pCur);
    5553
     
    285283        if (rc == VINF_PGM_SYNC_CR3)
    286284            rc = VINF_PGM_GCPHYS_ALIASED;
     285
     286#if defined(IN_RING3) || defined(IN_RING0)
     287        NEMHCNotifyHandlerPhysicalRegister(pVM, pType->enmKind, GCPhys, GCPhysLast - GCPhys + 1);
     288#endif
    287289        pgmUnlock(pVM);
    288290
     
    421423 * @param   pVM             The cross context VM structure.
    422424 * @param   pPhysHandler    The handler to deregister (but not free).
    423  */
    424 int pgmHandlerPhysicalExDeregister(PVM pVM, PPGMPHYSHANDLER pPhysHandler)
    425 {
    426     LogFlow(("pgmHandlerPhysicalExDeregister: Removing Range %RGp-%RGp %s\n",
    427              pPhysHandler->Core.Key, pPhysHandler->Core.KeyLast, R3STRING(pPhysHandler->pszDesc)));
     425 * @param   fRestoreAsRAM   How this will likely be restored, if we know (true,
     426 *                          false, or if we don't know -1).
     427 */
     428int pgmHandlerPhysicalExDeregister(PVM pVM, PPGMPHYSHANDLER pPhysHandler, int fRestoreAsRAM)
     429{
     430    LogFlow(("pgmHandlerPhysicalExDeregister: Removing Range %RGp-%RGp %s fRestoreAsRAM=%d\n",
     431             pPhysHandler->Core.Key, pPhysHandler->Core.KeyLast, R3STRING(pPhysHandler->pszDesc), fRestoreAsRAM));
    428432    AssertReturn(pPhysHandler->Core.Key != NIL_RTGCPHYS, VERR_PGM_HANDLER_NOT_FOUND);
    429433
     
    441445         */
    442446        pgmHandlerPhysicalResetRamFlags(pVM, pPhysHandler);
    443         pgmHandlerPhysicalDeregisterNotifyREM(pVM, pPhysHandler);
     447        pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pPhysHandler, fRestoreAsRAM);
    444448        pVM->pgm.s.pLastPhysHandlerR0 = 0;
    445449        pVM->pgm.s.pLastPhysHandlerR3 = 0;
     
    520524         */
    521525        pgmHandlerPhysicalResetRamFlags(pVM, pRemoved);
    522         pgmHandlerPhysicalDeregisterNotifyREM(pVM, pRemoved);
     526        pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pRemoved, -1);
    523527        pVM->pgm.s.pLastPhysHandlerR0 = 0;
    524528        pVM->pgm.s.pLastPhysHandlerR3 = 0;
     
    542546 * Shared code with modify.
    543547 */
    544 static void pgmHandlerPhysicalDeregisterNotifyREM(PVM pVM, PPGMPHYSHANDLER pCur)
     548static void pgmHandlerPhysicalDeregisterNotifyREMAndNEM(PVM pVM, PPGMPHYSHANDLER pCur, int fRestoreAsRAM)
    545549{
    546550    PPGMPHYSHANDLERTYPEINT  pCurType    = PGMPHYSHANDLER_GET_TYPE(pVM, pCur);
     
    555559     * included in the REM notification or not.
    556560     */
    557     if (    (pCur->Core.Key & PAGE_OFFSET_MASK)
    558         ||  ((pCur->Core.KeyLast + 1) & PAGE_OFFSET_MASK))
     561    if (   (pCur->Core.Key          & PAGE_OFFSET_MASK)
     562        || ((pCur->Core.KeyLast + 1) & PAGE_OFFSET_MASK))
    559563    {
    560564        Assert(pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO);
     
    595599    }
    596600
     601    /*
     602     * Tell REM and NEM.
     603     */
    597604#ifdef VBOX_WITH_REM
    598     /*
    599      * Tell REM.
    600      */
    601     const bool fRestoreAsRAM = pCurType->pfnHandlerR3
    602                             && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO; /** @todo this isn't entirely correct. */
     605    const bool fRestoreAsRAM2 = pCurType->pfnHandlerR3
     606                             && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO; /** @todo this isn't entirely correct. */
    603607# ifndef IN_RING3
    604608    REMNotifyHandlerPhysicalDeregister(pVM, pCurType->enmKind, GCPhysStart, GCPhysLast - GCPhysStart + 1,
    605                                        !!pCurType->pfnHandlerR3, fRestoreAsRAM);
     609                                       !!pCurType->pfnHandlerR3, fRestoreAsRAM2);
    606610# else
    607611    REMR3NotifyHandlerPhysicalDeregister(pVM, pCurType->enmKind, GCPhysStart, GCPhysLast - GCPhysStart + 1,
    608                                          !!pCurType->pfnHandlerR3, fRestoreAsRAM);
     612                                         !!pCurType->pfnHandlerR3, fRestoreAsRAM2);
    609613# endif
     614#endif
     615#if defined(IN_RING3) || defined(IN_RING0)
     616    NEMHCNotifyHandlerPhysicalDeregister(pVM, pCurType->enmKind, GCPhysStart, GCPhysLast - GCPhysStart + 1,
     617                                         fRestoreAsRAM, fRestoreAsRAM2);
    610618#else
    611     RT_NOREF_PV(pCurType);
     619    RT_NOREF_PV(fRestoreAsRAM); /** @todo this needs more work for REM! */
    612620#endif
    613621}
     
    816824         */
    817825        pgmHandlerPhysicalResetRamFlags(pVM, pCur);
    818 #ifdef VBOX_WITH_REM
    819         PPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE(pVM, pCur);
    820         const bool fRestoreAsRAM = pCurType->pfnHandlerR3
    821                                 && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO; /** @todo this isn't entirely correct. */
     826#if defined(VBOX_WITH_REM) || defined(IN_RING3) || defined(IN_RING0)
     827        PPGMPHYSHANDLERTYPEINT const pCurType      = PGMPHYSHANDLER_GET_TYPE(pVM, pCur);
     828        bool const                   fRestoreAsRAM = pCurType->pfnHandlerR3 /** @todo this isn't entirely correct. */
     829                                                  && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO;
    822830#endif
    823831
     
    842850                if (RTAvlroGCPhysInsert(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, &pCur->Core))
    843851                {
     852#if defined(VBOX_WITH_REM) || defined(IN_RING3) || defined(IN_RING0)
     853                    RTGCPHYS            const cb            = GCPhysLast - GCPhys + 1;
     854                    PGMPHYSHANDLERKIND  const enmKind       = pCurType->enmKind;
     855#endif
    844856#ifdef VBOX_WITH_REM
    845                     RTGCPHYS            cb            = GCPhysLast - GCPhys + 1;
    846                     PGMPHYSHANDLERKIND  enmKind       = pCurType->enmKind;
    847                     bool                fHasHCHandler = !!pCurType->pfnHandlerR3;
     857                    bool                const fHasHCHandler = !!pCurType->pfnHandlerR3;
    848858#endif
    849859
     
    852862                     */
    853863                    rc = pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(pVM, pCur, pRam);
     864
     865#if defined(IN_RING3) || defined(IN_RING0)
     866                    NEMHCNotifyHandlerPhysicalModify(pVM, enmKind, GCPhysCurrent, GCPhys, cb, fRestoreAsRAM);
     867#endif
     868
    854869                    pgmUnlock(pVM);
    855870
     
    888903         * We've only gotta notify REM and free the memory.
    889904         */
    890         pgmHandlerPhysicalDeregisterNotifyREM(pVM, pCur);
     905        pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pCur, -1);
    891906        pVM->pgm.s.pLastPhysHandlerR0 = 0;
    892907        pVM->pgm.s.pLastPhysHandlerR3 = 0;
  • trunk/src/VBox/VMM/VMMR3/NEMR3.cpp

    r70948 r70954  
    235235}
    236236
     237
     238VMMR3_INT_DECL(int)  NEMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb)
     239{
     240    int rc = VINF_SUCCESS;
     241#ifdef VBOX_WITH_NATIVE_NEM
     242    if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)
     243        rc = nemR3NativeNotifyPhysRamRegister(pVM, GCPhys, cb);
     244#else
     245    NOREF(pVM); NOREF(GCPhys); NOREF(cb);
     246#endif
     247    return rc;
     248}
     249
     250
     251VMMR3_INT_DECL(int)  NEMR3NotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
     252{
     253    int rc = VINF_SUCCESS;
     254#ifdef VBOX_WITH_NATIVE_NEM
     255    if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)
     256        rc = nemR3NativeNotifyPhysMmioExMap(pVM, GCPhys, cb, fFlags);
     257#else
     258    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     259#endif
     260    return rc;
     261}
     262
     263
     264VMMR3_INT_DECL(int)  NEMR3NotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
     265{
     266    int rc = VINF_SUCCESS;
     267#ifdef VBOX_WITH_NATIVE_NEM
     268    if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)
     269        rc = nemR3NativeNotifyPhysMmioExUnmap(pVM, GCPhys, cb, fFlags);
     270#else
     271    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     272#endif
     273    return rc;
     274}
     275
     276
     277VMMR3_INT_DECL(int)  NEMR3NotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags)
     278{
     279    int rc = VINF_SUCCESS;
     280#ifdef VBOX_WITH_NATIVE_NEM
     281    if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)
     282        rc = nemR3NativeNotifyPhysRomRegisterEarly(pVM, GCPhys, cb, fFlags);
     283#else
     284    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     285#endif
     286    return rc;
     287}
     288
     289
     290VMMR3_INT_DECL(int)  NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags)
     291{
     292    int rc = VINF_SUCCESS;
     293#ifdef VBOX_WITH_NATIVE_NEM
     294    if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)
     295        rc = nemR3NativeNotifyPhysRomRegisterLate(pVM, GCPhys, cb, fFlags);
     296#else
     297    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     298#endif
     299    return rc;
     300}
     301
     302
     303VMMR3_INT_DECL(void) NEMR3NotifySetA20(PVMCPU pVCpu, bool fEnabled)
     304{
     305#ifdef VBOX_WITH_NATIVE_NEM
     306    if (pVCpu->pVMR3->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)
     307        nemR3NativeNotifySetA20(pVCpu, fEnabled);
     308#else
     309    NOREF(pVCpu); NOREF(fEnabled);
     310#endif
     311}
     312
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r70948 r70954  
    122122#endif
    123123
     124
     125
     126/**
     127 * Worker for nemR3NativeInit that probes and load the native API.
     128 *
     129 * @returns VBox status code.
     130 * @param   fForced             Whether the HMForced flag is set and we should
     131 *                              fail if we cannot initialize.
     132 * @param   pErrInfo            Where to always return error info.
     133 */
     134static int nemR3WinInitProbeAndLoad(bool fForced, PRTERRINFO pErrInfo)
     135{
     136    /*
     137     * Check that the DLL files we need are present, but without loading them.
     138     * We'd like to avoid loading them unnecessarily.
     139     */
     140    WCHAR wszPath[MAX_PATH + 64];
     141    UINT  cwcPath = GetSystemDirectoryW(wszPath, MAX_PATH);
     142    if (cwcPath >= MAX_PATH || cwcPath < 2)
     143        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "GetSystemDirectoryW failed (%#x / %u)", cwcPath, GetLastError());
     144
     145    if (wszPath[cwcPath - 1] != '\\' || wszPath[cwcPath - 1] != '/')
     146        wszPath[cwcPath++] = '\\';
     147    RTUtf16CopyAscii(&wszPath[cwcPath], RT_ELEMENTS(wszPath) - cwcPath, "WinHvPlatform.dll");
     148    if (GetFileAttributesW(wszPath) == INVALID_FILE_ATTRIBUTES)
     149        return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "The native API dll was not found (%ls)", wszPath);
     150
     151    /*
     152     * Check that we're in a VM and that the hypervisor identifies itself as Hyper-V.
     153     */
     154    if (!ASMHasCpuId())
     155        return RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "No CPUID support");
     156    if (!ASMIsValidStdRange(ASMCpuId_EAX(0)))
     157        return RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "No CPUID leaf #1");
     158    if (!(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_HVP))
     159        return RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Not in a hypervisor partition (HVP=0)");
     160
     161    uint32_t cMaxHyperLeaf = 0;
     162    uint32_t uEbx = 0;
     163    uint32_t uEcx = 0;
     164    uint32_t uEdx = 0;
     165    ASMCpuIdExSlow(0x40000000, 0, 0, 0, &cMaxHyperLeaf, &uEbx, &uEcx, &uEdx);
     166    if (!ASMIsValidHypervisorRange(cMaxHyperLeaf))
     167        return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Invalid hypervisor CPUID range (%#x %#x %#x %#x)",
     168                             cMaxHyperLeaf, uEbx, uEcx, uEdx);
     169    if (   uEbx != UINT32_C(0x7263694d) /* Micr */
     170        || uEcx != UINT32_C(0x666f736f) /* osof */
     171        || uEdx != UINT32_C(0x76482074) /* t Hv */)
     172        return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE,
     173                             "Not Hyper-V CPUID signature: %#x %#x %#x (expected %#x %#x %#x)",
     174                             uEbx, uEcx, uEdx, UINT32_C(0x7263694d), UINT32_C(0x666f736f), UINT32_C(0x76482074));
     175    if (cMaxHyperLeaf < UINT32_C(0x40000005))
     176        return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Too narrow hypervisor CPUID range (%#x)", cMaxHyperLeaf);
     177
     178    /** @todo would be great if we could recognize a root partition from the
     179     *        CPUID info, but I currently don't dare do that. */
     180
     181    /*
     182     * Now try load the DLLs and resolve the APIs.
     183     */
     184    static const char * const s_apszDllNames[2] = { "WinHvPlatform.dll",  "vid.dll" };
     185    RTLDRMOD                  ahMods[2]         = { NIL_RTLDRMOD,          NIL_RTLDRMOD };
     186    int                       rc = VINF_SUCCESS;
     187    for (unsigned i = 0; i < RT_ELEMENTS(s_apszDllNames); i++)
     188    {
     189        int rc2 = RTLdrLoadSystem(s_apszDllNames[i], true /*fNoUnload*/, &ahMods[i]);
     190        if (RT_FAILURE(rc2))
     191        {
     192            if (!RTErrInfoIsSet(pErrInfo))
     193                RTErrInfoSetF(pErrInfo, rc2, "Failed to load API DLL: %s: %Rrc", s_apszDllNames[i], rc2);
     194            else
     195                RTErrInfoAddF(pErrInfo, rc2, "; %s: %Rrc", s_apszDllNames[i], rc2);
     196            ahMods[i] = NIL_RTLDRMOD;
     197            rc = VERR_NEM_INIT_FAILED;
     198        }
     199    }
     200    if (RT_SUCCESS(rc))
     201    {
     202        for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++)
     203        {
     204            int rc2 = RTLdrGetSymbol(ahMods[g_aImports[i].idxDll], g_aImports[i].pszName, (void **)g_aImports[i].ppfn);
     205            if (RT_FAILURE(rc2))
     206            {
     207                *g_aImports[i].ppfn = NULL;
     208
     209                LogRel(("NEM:  %s: Failed to import %s!%s: %Rrc",
     210                        g_aImports[i].fOptional ? "info" : fForced ? "fatal" : "error",
     211                        s_apszDllNames[g_aImports[i].idxDll], g_aImports[i].pszName, rc2));
     212                if (!g_aImports[i].fOptional)
     213                {
     214                    if (RTErrInfoIsSet(pErrInfo))
     215                        RTErrInfoAddF(pErrInfo, rc2, ", %s!%s",
     216                                      s_apszDllNames[g_aImports[i].idxDll], g_aImports[i].pszName);
     217                    else
     218                        rc = RTErrInfoSetF(pErrInfo, rc2, "Failed to import: %s!%s",
     219                                           s_apszDllNames[g_aImports[i].idxDll], g_aImports[i].pszName);
     220                    Assert(RT_FAILURE(rc));
     221                }
     222            }
     223        }
     224        if (RT_SUCCESS(rc))
     225            Assert(!RTErrInfoIsSet(pErrInfo));
     226    }
     227
     228    for (unsigned i = 0; i < RT_ELEMENTS(ahMods); i++)
     229        RTLdrClose(ahMods[i]);
     230    return rc;
     231}
    124232
    125233
     
    413521    /*
    414522     * Error state.
    415      *
    416      * The error message will be non-empty on failure, 'rc' may or  may not
    417      * be set.  Early API detection failures will not set 'rc', so we'll sort
    418      * that out at the other end of the function.
     523     * The error message will be non-empty on failure and 'rc' will be set too.
    419524     */
    420525    RTERRINFOSTATIC ErrInfo;
    421     int             rc = VINF_SUCCESS;
    422526    PRTERRINFO pErrInfo = RTErrInfoInitStatic(&ErrInfo);
    423 
    424     /*
    425      * Check that the DLL files we need are present, but without loading them.
    426      * We'd like to avoid loading them unnecessarily.
    427      */
    428     WCHAR wszPath[MAX_PATH + 64];
    429     UINT  cwcPath = GetSystemDirectoryW(wszPath, MAX_PATH);
    430     if (cwcPath >= MAX_PATH || cwcPath < 2)
    431         rc = RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "GetSystemDirectoryW failed (%#x / %u)", cwcPath, GetLastError());
    432     else
    433     {
    434         if (wszPath[cwcPath - 1] != '\\' || wszPath[cwcPath - 1] != '/')
    435             wszPath[cwcPath++] = '\\';
    436         RTUtf16CopyAscii(&wszPath[cwcPath], RT_ELEMENTS(wszPath) - cwcPath, "WinHvPlatform.dll");
    437         if (GetFileAttributesW(wszPath) == INVALID_FILE_ATTRIBUTES)
    438             rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "The native API dll was not found (%ls)", wszPath);
    439         else
     527    int rc = nemR3WinInitProbeAndLoad(fForced, pErrInfo);
     528    if (RT_SUCCESS(rc))
     529    {
     530        /*
     531         * Check the capabilties of the hypervisor, starting with whether it's present.
     532         */
     533        rc = nemR3WinInitCheckCapabilities(pVM, pErrInfo);
     534        if (RT_SUCCESS(rc))
    440535        {
    441536            /*
    442              * Check that we're in a VM and that the hypervisor identifies itself as Hyper-V.
     537             * Create and initialize a partition.
    443538             */
    444             if (!ASMHasCpuId())
    445                 rc = RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "No CPUID support");
    446             else if (!ASMIsValidStdRange(ASMCpuId_EAX(0)))
    447                 rc = RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "No CPUID leaf #1");
    448             else if (!(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_HVP))
    449                 rc = RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Not in a hypervisor partition (HVP=0)");
    450             else
     539            rc = nemR3WinInitCreatePartition(pVM, pErrInfo);
     540            if (RT_SUCCESS(rc))
    451541            {
    452                 uint32_t cMaxHyperLeaf = 0;
    453                 uint32_t uEbx = 0;
    454                 uint32_t uEcx = 0;
    455                 uint32_t uEdx = 0;
    456                 ASMCpuIdExSlow(0x40000000, 0, 0, 0, &cMaxHyperLeaf, &uEbx, &uEcx, &uEdx);
    457                 if (!ASMIsValidHypervisorRange(cMaxHyperLeaf))
    458                     rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Invalid hypervisor CPUID range (%#x %#x %#x %#x)",
    459                                        cMaxHyperLeaf, uEbx, uEcx, uEdx);
    460                 else if (   uEbx != UINT32_C(0x7263694d) /* Micr */
    461                          || uEcx != UINT32_C(0x666f736f) /* osof */
    462                          || uEdx != UINT32_C(0x76482074) /* t Hv */)
    463                     rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE,
    464                                        "Not Hyper-V CPUID signature: %#x %#x %#x (expected %#x %#x %#x)",
    465                                        uEbx, uEcx, uEdx, UINT32_C(0x7263694d), UINT32_C(0x666f736f), UINT32_C(0x76482074));
    466                 else if (cMaxHyperLeaf < UINT32_C(0x40000005))
    467                     rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Too narrow hypervisor CPUID range (%#x)", cMaxHyperLeaf);
    468                 else
    469                 {
    470                     /** @todo would be great if we could recognize a root partition from the
    471                      *        CPUID info, but I currently don't dare do that. */
    472 
    473                     /*
    474                      * Now try load the DLLs and resolve the APIs.
    475                      */
    476                     static const char * const s_pszDllPrefixes[] = { "WinHvPlatform.dll!",  "vid.dll!" };
    477                     RTLDRMOD                  ahMods[2]          = { NIL_RTLDRMOD,          NIL_RTLDRMOD };
    478                     rc = RTLdrLoadSystem("vid.dll", true /*fNoUnload*/, &ahMods[1]);
    479                     if (RT_SUCCESS(rc))
    480                     {
    481                         rc = RTLdrLoadSystem("WinHvPlatform.dll", true /*fNoUnload*/, &ahMods[0]);
    482                         if (RT_SUCCESS(rc))
    483                         {
    484                             for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++)
    485                             {
    486                                 int rc2 = RTLdrGetSymbol(ahMods[g_aImports[i].idxDll], g_aImports[i].pszName,
    487                                                          (void **)g_aImports[i].ppfn);
    488                                 if (RT_FAILURE(rc2))
    489                                 {
    490                                     *g_aImports[i].ppfn = NULL;
    491 
    492                                     LogRel(("NEM:  %s: Failed to import %s%s: %Rrc",
    493                                             g_aImports[i].fOptional ? "info" : fForced ? "fatal" : "error",
    494                                             s_pszDllPrefixes[g_aImports[i].idxDll], g_aImports[i].pszName, rc2));
    495                                     if (!g_aImports[i].fOptional)
    496                                     {
    497                                         if (RTErrInfoIsSet(pErrInfo))
    498                                             RTErrInfoAddF(pErrInfo, rc2, ", %s%s",
    499                                                           s_pszDllPrefixes[g_aImports[i].idxDll], g_aImports[i].pszName);
    500                                         else
    501                                             rc = RTErrInfoSetF(pErrInfo, rc2, "Failed to import: %s%s",
    502                                                                s_pszDllPrefixes[g_aImports[i].idxDll], g_aImports[i].pszName);
    503                                         Assert(RT_FAILURE(rc));
    504                                     }
    505                                 }
    506                             }
    507                             if (RT_SUCCESS(rc))
    508                             {
    509                                 Assert(!RTErrInfoIsSet(pErrInfo));
    510 
    511                                 /*
    512                                  * Check the capabilties of the hypervisor, starting with whether it's present.
    513                                  */
    514                                 rc = nemR3WinInitCheckCapabilities(pVM, pErrInfo);
    515                                 if (RT_SUCCESS(rc))
    516                                 {
    517                                     /*
    518                                      * Create and initialize a partition.
    519                                      */
    520                                     rc = nemR3WinInitCreatePartition(pVM, pErrInfo);
    521                                     if (RT_SUCCESS(rc))
    522                                     {
    523                                         VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API);
    524                                         Log(("NEM: Marked active!\n"));
    525                                     }
    526                                 }
    527                             }
    528                             RTLdrClose(ahMods[0]);
    529                         }
    530                         else
    531                             rc = RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
    532                                                "Failed to load API DLL 'WinHvPlatform.dll': %Rrc", rc);
    533                         RTLdrClose(ahMods[1]);
    534                     }
    535                     else
    536                         rc = RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Failed to load API DLL 'vid.dll': %Rrc", rc);
    537                 }
     542                VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API);
     543                Log(("NEM: Marked active!\n"));
    538544            }
    539545        }
     
    706712}
    707713
     714
     715int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb)
     716{
     717    NOREF(pVM); NOREF(GCPhys); NOREF(cb);
     718    return VINF_SUCCESS;
     719}
     720
     721
     722int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
     723{
     724    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     725    return VINF_SUCCESS;
     726}
     727
     728
     729int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
     730{
     731    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     732    return VINF_SUCCESS;
     733}
     734
     735
     736int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags)
     737{
     738    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     739    return VINF_SUCCESS;
     740}
     741
     742
     743int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags)
     744{
     745    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     746    return VINF_SUCCESS;
     747}
     748
     749
     750void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled)
     751{
     752    NOREF(pVCpu); NOREF(fEnabled);
     753}
     754
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r70951 r70954  
    2525#include <VBox/vmm/iom.h>
    2626#include <VBox/vmm/mm.h>
     27#include <VBox/vmm/nem.h>
    2728#include <VBox/vmm/stam.h>
    2829#ifdef VBOX_WITH_REM
     
    17461747    }
    17471748    pgmPhysInvalidatePageMapTLB(pVM);
     1749
     1750    /*
     1751     * Notify NEM while holding the lock (experimental) and REM without (like always).
     1752     */
     1753    rc = NEMR3NotifyPhysRamRegister(pVM, GCPhys, cb);
    17481754    pgmUnlock(pVM);
    1749 
    17501755#ifdef VBOX_WITH_REM
    1751     /*
    1752      * Notify REM.
    1753      */
    17541756    REMR3NotifyPhysRamRegister(pVM, GCPhys, cb, REM_NOTIFY_PHYS_RAM_FLAGS_RAM);
    17551757#endif
    1756 
    1757     return VINF_SUCCESS;
     1758    return rc;
    17581759}
    17591760
     
    34663467                {
    34673468                    pCurMmio->fFlags &= ~PGMREGMMIORANGE_F_MAPPED;
    3468                     pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3);
     3469                    pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3, fRamExists);
    34693470                }
    34703471
     
    35103511    pgmPhysInvalidatePageMapTLB(pVM);
    35113512
     3513    /*
     3514     * Notify NEM while holding the lock (experimental) and REM without (like always).
     3515     */
     3516    uint32_t const fNemNotify = (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2       ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2   : 0)
     3517                              | (pFirstMmio->fFlags & PGMREGMMIORANGE_F_OVERLAPPING ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0);
     3518    int rc = NEMR3NotifyPhysMmioExMap(pVM, GCPhys, cbRange, fNemNotify);
    35123519    pgmUnlock(pVM);
    3513 
    35143520#ifdef VBOX_WITH_REM
    3515     /*
    3516      * Inform REM without holding the PGM lock.
    3517      */
    3518     if (!fRamExists && (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2))
     3521    if (!fRamExists && (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2)) /** @todo this doesn't look right. */
    35193522        REMR3NotifyPhysRamRegister(pVM, GCPhys, cbRange, REM_NOTIFY_PHYS_RAM_FLAGS_MMIO2);
    35203523#endif
    3521     return VINF_SUCCESS;
     3524    return rc;
    35223525}
    35233526
     
    35673570    int rc = pgmLock(pVM);
    35683571    AssertRCReturn(rc, rc);
    3569     AssertReturnStmt(pFirstMmio->fFlags & PGMREGMMIORANGE_F_MAPPED, pgmUnlock(pVM), VERR_WRONG_ORDER);
     3572    uint16_t const fOldFlags = pFirstMmio->fFlags;
     3573    AssertReturnStmt(fOldFlags & PGMREGMMIORANGE_F_MAPPED, pgmUnlock(pVM), VERR_WRONG_ORDER);
    35703574
    35713575    /*
    35723576     * If plain MMIO, we must deregister the handlers first.
    35733577     */
    3574     if (!(pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2))
     3578    if (!(fOldFlags & PGMREGMMIORANGE_F_MMIO2))
    35753579    {
    35763580        PPGMREGMMIORANGE pCurMmio = pFirstMmio;
    3577         rc = pgmHandlerPhysicalExDeregister(pVM, pFirstMmio->pPhysHandlerR3);
     3581        rc = pgmHandlerPhysicalExDeregister(pVM, pFirstMmio->pPhysHandlerR3, RT_BOOL(fOldFlags & PGMREGMMIORANGE_F_OVERLAPPING));
    35783582        AssertRCReturnStmt(rc, pgmUnlock(pVM), rc);
    35793583        while (!(pCurMmio->fFlags & PGMREGMMIORANGE_F_LAST_CHUNK))
    35803584        {
    35813585            pCurMmio = pCurMmio->pNextR3;
    3582             rc = pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3);
     3586            rc = pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3, RT_BOOL(fOldFlags & PGMREGMMIORANGE_F_OVERLAPPING));
    35833587            AssertRCReturnStmt(rc, pgmUnlock(pVM), VERR_PGM_PHYS_MMIO_EX_IPE);
    35843588        }
     
    35903594     * Unmap it.
    35913595     */
    3592 #ifdef VBOX_WITH_REM
    3593     RTGCPHYS        GCPhysRangeREM;
    3594     bool            fInformREM;
    3595 #endif
    3596     if (pFirstMmio->fFlags & PGMREGMMIORANGE_F_OVERLAPPING)
     3596    RTGCPHYS const GCPhysRangeNotify = pFirstMmio->RamRange.GCPhys;
     3597    if (fOldFlags & PGMREGMMIORANGE_F_OVERLAPPING)
    35973598    {
    35983599        /*
     
    36043605         */
    36053606        /* Only one chunk allowed when overlapping! */
    3606         Assert(pFirstMmio->fFlags & PGMREGMMIORANGE_F_LAST_CHUNK);
     3607        Assert(fOldFlags & PGMREGMMIORANGE_F_LAST_CHUNK);
    36073608
    36083609        /* Restore the RAM pages we've replaced. */
     
    36123613
    36133614        uint32_t cPagesLeft = pFirstMmio->RamRange.cb >> PAGE_SHIFT;
    3614         if (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2)
     3615        if (fOldFlags & PGMREGMMIORANGE_F_MMIO2)
    36153616            pVM->pgm.s.cZeroPages += cPagesLeft;
    36163617
     
    36243625        /* Flush physical page map TLB. */
    36253626        pgmPhysInvalidatePageMapTLB(pVM);
    3626 #ifdef VBOX_WITH_REM
    3627         GCPhysRangeREM = NIL_RTGCPHYS;  /* shuts up gcc */
    3628         fInformREM     = false;
    3629 #endif
    36303627
    36313628        /* Update range state. */
     
    36393636         * Unlink the chunks related to the MMIO/MMIO2 region.
    36403637         */
    3641 #ifdef VBOX_WITH_REM
    3642         GCPhysRangeREM = pFirstMmio->RamRange.GCPhys;
    3643         fInformREM     = RT_BOOL(pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2);
    3644 #endif
    36453638        for (PPGMREGMMIORANGE pCurMmio = pFirstMmio; ; pCurMmio = pCurMmio->pNextR3)
    36463639        {
     
    36653658    pgmPhysInvalidRamRangeTlbs(pVM);
    36663659
     3660    /*
     3661     * Notify NEM while holding the lock (experimental) and REM without (like always).
     3662     */
     3663    uint32_t const fNemFlags = (fOldFlags & PGMREGMMIORANGE_F_MMIO2       ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2   : 0)
     3664                             | (fOldFlags & PGMREGMMIORANGE_F_OVERLAPPING ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0);
     3665    rc = NEMR3NotifyPhysMmioExUnmap(pVM, GCPhysRangeNotify, cbRange, fNemFlags);
    36673666    pgmUnlock(pVM);
    3668 
    36693667#ifdef VBOX_WITH_REM
    3670     /*
    3671      * Inform REM without holding the PGM lock.
    3672      */
    3673     if (fInformREM)
    3674         REMR3NotifyPhysRamDeregister(pVM, GCPhysRangeREM, cbRange);
     3668    if ((fOldFlags & (PGMREGMMIORANGE_F_OVERLAPPING | PGMREGMMIORANGE_F_MMIO2)) == PGMREGMMIORANGE_F_MMIO2)
     3669        REMR3NotifyPhysRamDeregister(pVM, GCPhysRangeNotify, cbRange);
    36753670#endif
    3676 
    3677     return VINF_SUCCESS;
     3671    return rc;
    36783672}
    36793673
     
    40914085
    40924086
     4087            /* Notify NEM before we register handlers. */
     4088            uint32_t const fNemNotify = (fRamExists ? NEM_NOTIFY_PHYS_ROM_F_REPLACE : 0)
     4089                                      | (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED ? NEM_NOTIFY_PHYS_ROM_F_SHADOW : 0);
     4090            rc = NEMR3NotifyPhysRomRegisterEarly(pVM, GCPhys, cb, fNemNotify);
     4091
    40934092            /*
    40944093             * !HACK ALERT!  REM + (Shadowed) ROM ==> mess.
     
    41054104                REMR3NotifyPhysRomRegister(pVM, GCPhys, cb, NULL, true /* fShadowed */);
    41064105#endif
    4107                 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType,
    4108                                                 pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew),
    4109                                                 pszDesc);
     4106                if (RT_SUCCESS(rc))
     4107                    rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType,
     4108                                                    pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew),
     4109                                                    pszDesc);
    41104110            }
    41114111            else
    41124112            {
    4113                 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType,
    4114                                                 pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew),
    4115                                                 pszDesc);
     4113                if (RT_SUCCESS(rc))
     4114                    rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType,
     4115                                                    pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew),
     4116                                                    pszDesc);
    41164117#ifdef VBOX_WITH_REM
    41174118                REMR3NotifyPhysRomRegister(pVM, GCPhys, cb, NULL, false /* fShadowed */);
     
    42034204                        pgmPhysInvalidatePageMapTLB(pVM);
    42044205                        GMMR3AllocatePagesCleanup(pReq);
    4205                         return VINF_SUCCESS;
     4206
     4207                        /* Notify NEM again. */
     4208                        return NEMR3NotifyPhysRomRegisterLate(pVM, GCPhys, cb, fNemNotify);
    42064209                    }
    42074210
     
    45354538        REMR3A20Set(pVCpu->pVMR3, pVCpu, fEnable);
    45364539#endif
     4540        NEMR3NotifySetA20(pVCpu, fEnable);
    45374541#ifdef PGM_WITH_A20
    45384542        pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL;
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r70945 r70954  
    115115void    nemR3NativeReset(PVM pVM);
    116116void    nemR3NativeResetCpu(PVMCPU pVCpu);
     117int     nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);
     118int     nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
     119int     nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
     120int     nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags);
     121int     nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags);
     122void    nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled);
    117123#endif
    118124
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r69474 r70954  
    41954195int             pgmHandlerPhysicalExDup(PVM pVM, PPGMPHYSHANDLER pPhysHandlerSrc, PPGMPHYSHANDLER *ppPhysHandler);
    41964196int             pgmHandlerPhysicalExRegister(PVM pVM, PPGMPHYSHANDLER pPhysHandler, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast);
    4197 int             pgmHandlerPhysicalExDeregister(PVM pVM, PPGMPHYSHANDLER pPhysHandler);
     4197int             pgmHandlerPhysicalExDeregister(PVM pVM, PPGMPHYSHANDLER pPhysHandler, int fRestoreAsRAM);
    41984198int             pgmHandlerPhysicalExDestroy(PVM pVM, PPGMPHYSHANDLER pHandler);
    41994199void            pgmR3HandlerPhysicalUpdateAll(PVM pVM);
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