VirtualBox

Changeset 70977 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Feb 12, 2018 8:45:31 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
120824
Message:

NEM: Working on PGM notifications. bugref:9044

Location:
trunk/src/VBox/VMM/VMMR3
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3.cpp

    r70954 r70977  
    249249
    250250
    251 VMMR3_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);
     251VMMR3_INT_DECL(int)  NEMR3NotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2)
     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, pvMmio2);
     257#else
     258    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); NOREF(pvMmio2);
     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);
    257270#else
    258271    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     
    262275
    263276
    264 VMMR3_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);
     277VMMR3_INT_DECL(int)  NEMR3NotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS 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);
    270283#else
    271284    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     
    275288
    276289
    277 VMMR3_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 
    290 VMMR3_INT_DECL(int)  NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags)
     290/**
     291 * Called after the ROM range has been fully completed.
     292 *
     293 * This will be preceeded by a NEMR3NotifyPhysRomRegisterEarly() call as well a
     294 * number of NEMHCNotifyPhysPageProtChanged calls.
     295 *
     296 * @returns VBox status code
     297 * @param   pVM             The cross context VM structure.
     298 * @param   GCPhys          The ROM address (page aligned).
     299 * @param   cb              The size (page aligned).
     300 * @param   fFlags          NEM_NOTIFY_PHYS_ROM_F_XXX.
     301 */
     302VMMR3_INT_DECL(int)  NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
    291303{
    292304    int rc = VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r70954 r70977  
    2121*********************************************************************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_NEM
     23#include <iprt/nt/nt-and-windows.h>
    2324#include <WinHvPlatform.h>
    2425
     
    4243#include <iprt/path.h>
    4344#include <iprt/string.h>
     45
     46
     47/*********************************************************************************************************************************
     48*   Defined Constants And Macros                                                                                                 *
     49*********************************************************************************************************************************/
     50#ifdef LOG_ENABLED
     51# define NEM_WIN_INTERCEPT_NT_IO_CTLS
     52#endif
     53
     54
     55/*********************************************************************************************************************************
     56*   Structures and Typedefs                                                                                                      *
     57*********************************************************************************************************************************/
     58/** @name Our two-bit physical page state for PGMPAGE
     59 * @{ */
     60#define NEM_WIN_PAGE_STATE_NOT_SET      0
     61#define NEM_WIN_PAGE_STATE_UNMAPPED     1
     62#define NEM_WIN_PAGE_STATE_READABLE     2
     63#define NEM_WIN_PAGE_STATE_WRITABLE     3
     64/** @} */
    4465
    4566
     
    123144
    124145
     146#ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
     147
     148/** The real NtDeviceIoControlFile API in NTDLL.   */
     149static decltype(NtDeviceIoControlFile) *g_pfnNtDeviceIoControlFile;
     150
     151/**
     152 * Wrapper that logs the call from VID.DLL.
     153 *
     154 * This is very handy for figuring out why an API call fails.
     155 */
     156static NTSTATUS WINAPI
     157nemR3WinLogWrapper_NtDeviceIoControlFile(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx,
     158                                         PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput,
     159                                         PVOID pvOutput, ULONG cbOutput)
     160{
     161    NTSTATUS rcNt = g_pfnNtDeviceIoControlFile(hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, uFunction,
     162                                               pvInput, cbInput, pvOutput, cbOutput);
     163    if (!hEvt && !pfnApcCallback && !pvApcCtx)
     164        LogRel(("VID!NtDeviceIoControlFile: hFile=%#zx pIos=%p->{s:%#x, i:%#zx} uFunction=%#x Input=%p LB %#x Output=%p LB %#x) -> %#x; Caller=%p\n",
     165                hFile, pIos, pIos->Status, pIos->Information, uFunction, pvInput, cbInput, pvOutput, cbOutput, rcNt, ASMReturnAddress()));
     166    else
     167        LogRel(("VID!NtDeviceIoControlFile: hFile=%#zx hEvt=%#zx Apc=%p/%p pIos=%p->{s:%#x, i:%#zx} uFunction=%#x Input=%p LB %#x Output=%p LB %#x) -> %#x; Caller=%p\n",
     168                hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, pIos->Status, pIos->Information, uFunction,
     169                pvInput, cbInput, pvOutput, cbOutput, rcNt, ASMReturnAddress()));
     170    return rcNt;
     171}
     172
     173
     174/**
     175 * Patches the call table of VID.DLL so we can intercept and log
     176 * NtDeviceIoControlFile.
     177 *
     178 * This is for DEBUGGING only.
     179 *
     180 * @param   hLdrModVid      The VID module handle.
     181 */
     182static void nemR3WinInitVidIntercepts(RTLDRMOD hLdrModVid)
     183{
     184    /*
     185     * Locate the real API.
     186     */
     187    g_pfnNtDeviceIoControlFile = (decltype(NtDeviceIoControlFile) *)RTLdrGetSystemSymbol("NTDLL.DLL", "NtDeviceIoControlFile");
     188    AssertReturnVoid(g_pfnNtDeviceIoControlFile > 0);
     189
     190    /*
     191     * Locate the PE header and get what we need from it.
     192     */
     193    uint8_t const *pbImage = (uint8_t const *)RTLdrGetNativeHandle(hLdrModVid);
     194    IMAGE_DOS_HEADER const *pMzHdr  = (IMAGE_DOS_HEADER const *)pbImage;
     195    AssertReturnVoid(pMzHdr->e_magic == IMAGE_DOS_SIGNATURE);
     196    IMAGE_NT_HEADERS const *pNtHdrs = (IMAGE_NT_HEADERS const *)&pbImage[pMzHdr->e_lfanew];
     197    AssertReturnVoid(pNtHdrs->Signature == IMAGE_NT_SIGNATURE);
     198
     199    uint32_t const             cbImage   = pNtHdrs->OptionalHeader.SizeOfImage;
     200    IMAGE_DATA_DIRECTORY const ImportDir = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
     201
     202    /*
     203     * Walk the import descriptor table looking for NTDLL.DLL.
     204     */
     205    bool fSuccess = true;
     206    AssertReturnVoid(ImportDir.Size > 0);
     207    AssertReturnVoid(ImportDir.Size < cbImage);
     208    AssertReturnVoid(ImportDir.VirtualAddress > 0);
     209    AssertReturnVoid(ImportDir.VirtualAddress < cbImage);
     210    for (PIMAGE_IMPORT_DESCRIPTOR pImps = (PIMAGE_IMPORT_DESCRIPTOR)&pbImage[ImportDir.VirtualAddress];
     211         pImps->Name != 0 && pImps->FirstThunk != 0;
     212         pImps++)
     213    {
     214        AssertReturnVoid(pImps->Name < cbImage);
     215        const char *pszModName = (const char *)&pbImage[pImps->Name];
     216        if (RTStrICmpAscii(pszModName, "ntdll.dll"))
     217            continue;
     218        AssertReturnVoid(pImps->FirstThunk < cbImage);
     219        AssertReturnVoid(pImps->OriginalFirstThunk < cbImage);
     220
     221        /*
     222         * Walk the thunks table(s) looking for NtDeviceIoControlFile.
     223         */
     224        PIMAGE_THUNK_DATA pFirstThunk = (PIMAGE_THUNK_DATA)&pbImage[pImps->FirstThunk]; /* update this. */
     225        PIMAGE_THUNK_DATA pThunk      = pImps->OriginalFirstThunk == 0                  /* read from this. */
     226                                      ? (PIMAGE_THUNK_DATA)&pbImage[pImps->FirstThunk]
     227                                      : (PIMAGE_THUNK_DATA)&pbImage[pImps->OriginalFirstThunk];
     228        while (pThunk->u1.Ordinal != 0)
     229        {
     230            if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32))
     231            {
     232                AssertReturnVoid(pThunk->u1.Ordinal > 0 && pThunk->u1.Ordinal < cbImage);
     233
     234                const char *pszSymbol = (const char *)&pbImage[(uintptr_t)pThunk->u1.AddressOfData + 2];
     235                if (strcmp(pszSymbol, "NtDeviceIoControlFile") == 0)
     236                {
     237                    DWORD fOldProt = PAGE_EXECUTE;
     238                    VirtualProtect(&pFirstThunk->u1.Function, sizeof(uintptr_t), PAGE_EXECUTE_READWRITE, &fOldProt);
     239                    pFirstThunk->u1.Function = (uintptr_t)nemR3WinLogWrapper_NtDeviceIoControlFile;
     240                    VirtualProtect(&pFirstThunk->u1.Function, sizeof(uintptr_t), fOldProt, &fOldProt);
     241                    fSuccess = true;
     242                }
     243            }
     244
     245            pThunk++;
     246            pFirstThunk++;
     247        }
     248    }
     249    Assert(fSuccess);
     250}
     251#endif
     252
     253
    125254
    126255/**
     
    200329    if (RT_SUCCESS(rc))
    201330    {
     331#ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
     332        nemR3WinInitVidIntercepts(ahMods[1]);
     333#endif
    202334        for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++)
    203335        {
     
    267399    DWORD   rcWin = GetLastError();
    268400    if (FAILED(hrc))
    269         return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeHypervisorPresent failed: %Rhrc", hrc);
     401        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     402                             "WHvGetCapability/WHvCapabilityCodeHypervisorPresent failed: %Rhrc (Last=%#x/%u)",
     403                             hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    270404    if (!Caps.HypervisorPresent)
    271405    {
     
    284418    hrc = WHvGetCapability(WHvCapabilityCodeExtendedVmExits, &Caps, sizeof(Caps));
    285419    if (FAILED(hrc))
    286         return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeExtendedVmExits failed: %Rhrc", hrc);
     420        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     421                             "WHvGetCapability/WHvCapabilityCodeExtendedVmExits failed: %Rhrc (Last=%#x/%u)",
     422                             hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    287423    NEM_LOG_REL_CAP_EX("WHvCapabilityCodeExtendedVmExits", "%'#018RX64", Caps.ExtendedVmExits.AsUINT64);
    288424    pVM->nem.s.fExtendedMsrExit   = RT_BOOL(Caps.ExtendedVmExits.X64MsrExit);
     
    302438    hrc = WHvGetCapability(WHvCapabilityCodeFeatures, &Caps, sizeof(Caps));
    303439    if (FAILED(hrc))
    304         return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeFeatures failed: %Rhrc", hrc);
     440        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     441                             "WHvGetCapability/WHvCapabilityCodeFeatures failed: %Rhrc (Last=%#x/%u)",
     442                             hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    305443    if (Caps.Features.AsUINT64 & ~(uint64_t)0)
    306444        LogRel(("NEM: Warning! Unknown feature definitions: %#RX64\n", Caps.Features.AsUINT64));
     
    313451    hrc = WHvGetCapability(WHvCapabilityCodeProcessorVendor, &Caps, sizeof(Caps));
    314452    if (FAILED(hrc))
    315         return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorVendor failed: %Rhrc", hrc);
     453        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     454                             "WHvGetCapability/WHvCapabilityCodeProcessorVendor failed: %Rhrc (Last=%#x/%u)",
     455                             hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    316456    switch (Caps.ProcessorVendor)
    317457    {
     
    336476    hrc = WHvGetCapability(WHvCapabilityCodeProcessorFeatures, &Caps, sizeof(Caps));
    337477    if (FAILED(hrc))
    338         return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorFeatures failed: %Rhrc", hrc);
     478        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     479                             "WHvGetCapability/WHvCapabilityCodeProcessorFeatures failed: %Rhrc (Last=%#x/%u)",
     480                             hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    339481    NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorFeatures", "%'#018RX64", Caps.ProcessorFeatures.AsUINT64);
    340482#define NEM_LOG_REL_CPU_FEATURE(a_Field)    NEM_LOG_REL_CAP_SUB(#a_Field, Caps.ProcessorFeatures.a_Field)
     
    393535    hrc = WHvGetCapability(WHvCapabilityCodeProcessorClFlushSize, &Caps, sizeof(Caps));
    394536    if (FAILED(hrc))
    395         return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorClFlushSize failed: %Rhrc", hrc);
     537        return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     538                             "WHvGetCapability/WHvCapabilityCodeProcessorClFlushSize failed: %Rhrc (Last=%#x/%u)",
     539                             hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    396540    NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorClFlushSize", "2^%u", Caps.ProcessorClFlushSize);
    397541    if (Caps.ProcessorClFlushSize < 8 && Caps.ProcessorClFlushSize > 9)
     
    450594    HRESULT hrc = WHvCreatePartition(&hPartition);
    451595    if (FAILED(hrc))
    452         return RTErrInfoSetF(pErrInfo, VERR_NEM_VM_CREATE_FAILED, "WHvCreatePartition failed with %Rhrc", hrc);
     596        return RTErrInfoSetF(pErrInfo, VERR_NEM_VM_CREATE_FAILED, "WHvCreatePartition failed with %Rhrc (Last=%#x/%u)",
     597                             hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    453598
    454599    int rc;
     
    495640    else
    496641        rc = RTErrInfoSetF(pErrInfo, VERR_NEM_VM_CREATE_FAILED,
    497                            "Failed setting WHvPartitionPropertyCodeProcessorCount to %u: %Rhrc", pVM->cCpus, hrc);
     642                           "Failed setting WHvPartitionPropertyCodeProcessorCount to %u: %Rhrc (Last=%#x/%u)",
     643                           pVM->cCpus, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    498644    WHvDeletePartition(hPartition);
    499645
     
    590736    if (FAILED(hrc))
    591737        return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
    592                           "Failed to set WHvPartitionPropertyCodeProcessorVendor to %u: %Rhrc", Property.ProcessorVendor, hrc);
     738                          "Failed to set WHvPartitionPropertyCodeProcessorVendor to %u: %Rhrc (Last=%#x/%u)",
     739                          Property.ProcessorVendor, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    593740
    594741    /* Not sure if we really need to set the cache line flush size. */
     
    599746    if (FAILED(hrc))
    600747        return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
    601                           "Failed to set WHvPartitionPropertyCodeProcessorClFlushSize to %u: %Rhrc",
    602                           pVM->nem.s.cCacheLineFlushShift, hrc);
     748                          "Failed to set WHvPartitionPropertyCodeProcessorClFlushSize to %u: %Rhrc (Last=%#x/%u)",
     749                          pVM->nem.s.cCacheLineFlushShift, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    603750
    604751    /*
     
    614761    if (FAILED(hrc))
    615762        return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
    616                           "Failed to set WHvPartitionPropertyCodeProcessorFeatures to %'#RX64: %Rhrc",
    617                           pVM->nem.s.uCpuFeatures.u64, hrc);
     763                          "Failed to set WHvPartitionPropertyCodeProcessorFeatures to %'#RX64: %Rhrc (Last=%#x/%u)",
     764                          pVM->nem.s.uCpuFeatures.u64, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    618765
    619766    /*
     
    625772    hrc = WHvSetupPartition(hPartition);
    626773    if (FAILED(hrc))
    627         return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, "Call to WHvSetupPartition failed: %Rhrc", hrc);
     774        return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
     775                          "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)",
     776                          hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);
    628777
    629778    /* Get the handle. */
     
    655804        if (FAILED(hrc))
    656805        {
     806            NTSTATUS const rcNtLast  = RTNtCurrentTeb()->LastStatusValue;
     807            DWORD const    dwErrLast = RTNtCurrentTeb()->LastErrorValue;
    657808            while (iCpu-- > 0)
    658809            {
    659810                HRESULT hrc2 = WHvDeleteVirtualProcessor(hPartition, iCpu);
    660                 AssertLogRelMsg(SUCCEEDED(hrc2), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc\n", hPartition, iCpu, hrc2));
     811                AssertLogRelMsg(SUCCEEDED(hrc2), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n",
     812                                                  hPartition, iCpu, hrc2, RTNtCurrentTeb()->LastStatusValue,
     813                                                  RTNtCurrentTeb()->LastErrorValue));
    661814            }
    662             return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, "Call to WHvSetupPartition failed: %Rhrc", hrc);
     815            return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
     816                              "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast);
    663817        }
    664818    }
     
    692846        {
    693847            HRESULT hrc = WHvDeleteVirtualProcessor(hPartition, iCpu);
    694             AssertLogRelMsg(SUCCEEDED(hrc), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc\n", hPartition, iCpu, hrc));
     848            AssertLogRelMsg(SUCCEEDED(hrc), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n",
     849                                             hPartition, iCpu, hrc, RTNtCurrentTeb()->LastStatusValue,
     850                                             RTNtCurrentTeb()->LastErrorValue));
    695851        }
    696852        WHvDeletePartition(hPartition);
     
    713869
    714870
     871
     872DECLINLINE(int) nemR3NativeGCPhys2R3PtrReadOnly(PVM pVM, RTGCPHYS GCPhys, const void **ppv)
     873{
     874    PGMPAGEMAPLOCK Lock;
     875    int rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys, ppv, &Lock);
     876    if (RT_SUCCESS(rc))
     877        PGMPhysReleasePageMappingLock(pVM, &Lock);
     878    return rc;
     879}
     880
     881DECLINLINE(int) nemR3NativeGCPhys2R3PtrWriteable(PVM pVM, RTGCPHYS GCPhys, void **ppv)
     882{
     883    PGMPAGEMAPLOCK Lock;
     884    int rc = PGMPhysGCPhys2CCPtr(pVM, GCPhys, ppv, &Lock);
     885    if (RT_SUCCESS(rc))
     886        PGMPhysReleasePageMappingLock(pVM, &Lock);
     887    return rc;
     888}
     889
     890
    715891int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb)
    716892{
     893    LogRel(("nemR3NativeNotifyPhysRamRegister: %RGp LB %RGp\n", GCPhys, cb));
    717894    NOREF(pVM); NOREF(GCPhys); NOREF(cb);
    718895    return VINF_SUCCESS;
     
    720897
    721898
    722 int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
    723 {
     899int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2)
     900{
     901    LogRel(("nemR3NativeNotifyPhysMmioExMap: %RGp LB %RGp fFlags=%#x pvMmio2=%p\n", GCPhys, cb, fFlags, pvMmio2));
     902    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); NOREF(pvMmio2);
     903    return VINF_SUCCESS;
     904}
     905
     906
     907int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
     908{
     909    LogRel(("nemR3NativeNotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
    724910    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
    725911    return VINF_SUCCESS;
     
    727913
    728914
    729 int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
    730 {
     915/**
     916 * Called early during ROM registration, right after the pages have been
     917 * allocated and the RAM range updated.
     918 *
     919 * This will be succeeded by a number of NEMHCNotifyPhysPageProtChanged() calls
     920 * and finally a NEMR3NotifyPhysRomRegisterEarly().
     921 *
     922 * @returns VBox status code
     923 * @param   pVM             The cross context VM structure.
     924 * @param   GCPhys          The ROM address (page aligned).
     925 * @param   cb              The size (page aligned).
     926 * @param   fFlags          NEM_NOTIFY_PHYS_ROM_F_XXX.
     927 */
     928int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
     929{
     930    LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
     931#if 0 /* Let's not do this after all.  We'll protection change notifications for each page and if not we'll map them lazily. */
     932    RTGCPHYS const cPages = cb >> X86_PAGE_SHIFT;
     933    for (RTGCPHYS iPage = 0; iPage < cPages; iPage++, GCPhys += X86_PAGE_SIZE)
     934    {
     935        const void *pvPage;
     936        int rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhys, &pvPage);
     937        if (RT_SUCCESS(rc))
     938        {
     939            HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, (void *)pvPage, GCPhys, X86_PAGE_SIZE,
     940                                         WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute);
     941            if (SUCCEEDED(hrc))
     942            { /* likely */ }
     943            else
     944            {
     945                LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n",
     946                        GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
     947                return VERR_NEM_INIT_FAILED;
     948            }
     949        }
     950        else
     951        {
     952            LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc));
     953            return rc;
     954        }
     955    }
     956#else
     957    NOREF(pVM); NOREF(GCPhys); NOREF(cb);
     958#endif
     959    RT_NOREF_PV(fFlags);
     960    return VINF_SUCCESS;
     961}
     962
     963
     964/**
     965 * Called after the ROM range has been fully completed.
     966 *
     967 * This will be preceeded by a NEMR3NotifyPhysRomRegisterEarly() call as well a
     968 * number of NEMHCNotifyPhysPageProtChanged calls.
     969 *
     970 * @returns VBox status code
     971 * @param   pVM             The cross context VM structure.
     972 * @param   GCPhys          The ROM address (page aligned).
     973 * @param   cb              The size (page aligned).
     974 * @param   fFlags          NEM_NOTIFY_PHYS_ROM_F_XXX.
     975 */
     976int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
     977{
     978    LogRel(("nemR3NativeNotifyPhysRomRegisterLate: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
    731979    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
    732980    return VINF_SUCCESS;
     
    734982
    735983
    736 int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags)
    737 {
    738     NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
     984void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled)
     985{
     986    LogRel(("nemR3NativeNotifySetA20: fEnabled=%RTbool\n", fEnabled));
     987    NOREF(pVCpu); NOREF(fEnabled);
     988}
     989
     990
     991void nemR3NativeNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb)
     992{
     993    LogRel(("nemR3NativeNotifyHandlerPhysicalRegister: %RGp LB %RGp enmKind=%d\n", GCPhys, cb, enmKind));
     994    NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb);
     995}
     996
     997
     998void nemR3NativeNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb,
     999                                                int fRestoreAsRAM, bool fRestoreAsRAM2)
     1000{
     1001    LogRel(("nemR3NativeNotifyHandlerPhysicalDeregister: %RGp LB %RGp enmKind=%d fRestoreAsRAM=%d fRestoreAsRAM2=%d\n",
     1002            GCPhys, cb, enmKind, fRestoreAsRAM, fRestoreAsRAM2));
     1003    NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb); NOREF(fRestoreAsRAM); NOREF(fRestoreAsRAM2);
     1004}
     1005
     1006
     1007void nemR3NativeNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
     1008                                            RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM)
     1009{
     1010    LogRel(("nemR3NativeNotifyHandlerPhysicalModify: %RGp LB %RGp -> %RGp enmKind=%d fRestoreAsRAM=%d\n",
     1011            GCPhysOld, cb, GCPhysNew, enmKind, fRestoreAsRAM));
     1012    NOREF(pVM); NOREF(enmKind); NOREF(GCPhysOld); NOREF(GCPhysNew); NOREF(cb); NOREF(fRestoreAsRAM);
     1013}
     1014
     1015
     1016static int nemR3NativeSetPhysPage(PVM pVM, RTGCPHYS GCPhys, uint32_t fPageProt, uint8_t *pu2State, bool fBackingChanged)
     1017{
     1018    /*
     1019     * Looks like we need to unmap a page before we can change the backing
     1020     * or even modify the protection.  This is going to be *REALLY* efficient.
     1021     * PGM lends us two bits to keep track of the state here.
     1022     */
     1023    uint8_t const u2OldState = *pu2State;
     1024    uint8_t const u2NewState = fPageProt & NEM_PAGE_PROT_WRITE ? NEM_WIN_PAGE_STATE_WRITABLE
     1025                             : fPageProt & NEM_PAGE_PROT_READ  ? NEM_WIN_PAGE_STATE_READABLE : NEM_WIN_PAGE_STATE_NOT_SET;
     1026    if (   fBackingChanged
     1027        || u2NewState != u2OldState)
     1028    {
     1029        if (u2OldState > NEM_WIN_PAGE_STATE_NOT_SET)
     1030        {
     1031            HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, X86_PAGE_SIZE);
     1032            if (SUCCEEDED(hrc))
     1033            {
     1034                *pu2State = NEM_WIN_PAGE_STATE_NOT_SET;
     1035                if (u2NewState == NEM_WIN_PAGE_STATE_NOT_SET)
     1036                    return VINF_SUCCESS;
     1037            }
     1038            else
     1039            {
     1040                LogRel(("nemR3NativeSetPhysPage/unmap: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n",
     1041                        GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
     1042                return VERR_NEM_INIT_FAILED;
     1043            }
     1044        }
     1045    }
     1046
     1047    /*
     1048     * Writeable mapping?
     1049     */
     1050    if (fPageProt & NEM_PAGE_PROT_WRITE)
     1051    {
     1052        void *pvPage;
     1053        int rc = nemR3NativeGCPhys2R3PtrWriteable(pVM, GCPhys, &pvPage);
     1054        if (RT_SUCCESS(rc))
     1055        {
     1056            HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, pvPage, GCPhys, X86_PAGE_SIZE,
     1057                                         WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute | WHvMapGpaRangeFlagWrite);
     1058            if (SUCCEEDED(hrc))
     1059            {
     1060                *pu2State = NEM_WIN_PAGE_STATE_WRITABLE;
     1061                return VINF_SUCCESS;
     1062            }
     1063            LogRel(("nemR3NativeSetPhysPage/writable: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n",
     1064                    GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
     1065            return VERR_NEM_INIT_FAILED;
     1066        }
     1067        LogRel(("nemR3NativeSetPhysPage/writable: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc));
     1068        return rc;
     1069    }
     1070
     1071    if (fPageProt & NEM_PAGE_PROT_READ)
     1072    {
     1073        const void *pvPage;
     1074        int rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhys, &pvPage);
     1075        if (RT_SUCCESS(rc))
     1076        {
     1077            HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, (void *)pvPage, GCPhys, X86_PAGE_SIZE,
     1078                                         WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute);
     1079            if (SUCCEEDED(hrc))
     1080            {
     1081                *pu2State = NEM_WIN_PAGE_STATE_READABLE;
     1082                return VINF_SUCCESS;
     1083            }
     1084            LogRel(("nemR3NativeSetPhysPage/readonly: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n",
     1085                    GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
     1086            return VERR_NEM_INIT_FAILED;
     1087        }
     1088        LogRel(("nemR3NativeSetPhysPage/readonly: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc));
     1089        return rc;
     1090    }
     1091
     1092    /* We already unmapped it above. */
     1093    *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
    7391094    return VINF_SUCCESS;
    7401095}
    7411096
    7421097
    743 int 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 
    750 void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled)
    751 {
    752     NOREF(pVCpu); NOREF(fEnabled);
    753 }
    754 
     1098int nemR3NativeNotifyPhysPageAllocated(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
     1099                                       PGMPAGETYPE enmType, uint8_t *pu2State)
     1100{
     1101    LogRel(("nemR3NativeNotifyPhysPageAllocated: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
     1102            GCPhys, HCPhys, fPageProt, enmType, *pu2State));
     1103    RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType);
     1104
     1105    return nemR3NativeSetPhysPage(pVM, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/);
     1106}
     1107
     1108
     1109void nemR3NativeNotifyPhysPageProtChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
     1110                                          PGMPAGETYPE enmType, uint8_t *pu2State)
     1111{
     1112    LogRel(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
     1113            GCPhys, HCPhys, fPageProt, enmType, *pu2State));
     1114    RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType);
     1115
     1116    nemR3NativeSetPhysPage(pVM, GCPhys, fPageProt, pu2State, false /*fBackingChanged*/);
     1117}
     1118
     1119
     1120void nemR3NativeNotifyPhysPageChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew,
     1121                                      uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State)
     1122{
     1123    LogRel(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp->%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
     1124            GCPhys, HCPhysPrev, HCPhysNew, fPageProt, enmType, *pu2State));
     1125    RT_NOREF_PV(HCPhysPrev); RT_NOREF_PV(HCPhysNew); RT_NOREF_PV(enmType);
     1126
     1127    nemR3NativeSetPhysPage(pVM, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/);
     1128}
     1129
  • trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp

    r70948 r70977  
    268268        int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint);
    269269        if (RT_SUCCESS(rc))
     270        {
    270271            PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_NONE);
     272
     273            /* Tell NEM about the protection change. */
     274            if (VM_IS_NEM_ENABLED(pVM))
     275            {
     276                uint8_t     u2State = PGM_PAGE_GET_NEM_STATE(pPage);
     277                PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage);
     278                NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage),
     279                                               pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State);
     280                PGM_PAGE_SET_NEM_STATE(pPage, u2State);
     281            }
     282        }
    271283        else
    272284            AssertRC(rc);
     
    300312        int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint);
    301313        if (RT_SUCCESS(rc))
     314        {
    302315            PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, uState);
     316
     317            /* Tell NEM about the protection change. */
     318            if (VM_IS_NEM_ENABLED(pVM))
     319            {
     320                uint8_t     u2State = PGM_PAGE_GET_NEM_STATE(pPage);
     321                PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage);
     322                NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage),
     323                                               pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State);
     324                PGM_PAGE_SET_NEM_STATE(pPage, u2State);
     325            }
     326        }
    303327        else
    304328            AssertRC(rc);
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r70954 r70977  
    288288                    if (    PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_WRITE_MONITORED
    289289                        && !PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage))
    290                         pgmPhysPageMakeWriteMonitoredWritable(pVM, pPage);
     290                        pgmPhysPageMakeWriteMonitoredWritable(pVM, pPage, GCPhys);
    291291                    else
    292292                    {
     
    474474#endif
    475475                   )
    476                     pgmPhysPageMakeWriteMonitoredWritable(pVM, pPage);
     476                    pgmPhysPageMakeWriteMonitoredWritable(pVM, pPage, GCPhys);
    477477                else
    478478                {
     
    895895 * @param   GCPhys      The address of the first page.
    896896 * @param   GCPhysLast  The address of the last page.
    897  * @param   uType       The page type to replace then with.
    898  */
    899 static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, uint8_t uType)
     897 * @param   enmType     The page type to replace then with.
     898 */
     899static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, PGMPAGETYPE enmType)
    900900{
    901901    PGM_LOCK_ASSERT_OWNER(pVM);
     
    910910    while (cPagesLeft-- > 0)
    911911    {
    912         rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPageDst, GCPhys);
     912        rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPageDst, GCPhys, enmType);
    913913        AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */
    914914
    915         PGM_PAGE_SET_TYPE(pVM, pPageDst, uType);
     915        PGM_PAGE_SET_TYPE(pVM, pPageDst, enmType);
    916916
    917917        GCPhys += PAGE_SIZE;
     
    985985            pgmPoolFlushPageByGCPhys(pVM, paPhysPage[i]);
    986986
    987             rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i]);
     987            rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i], (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage));
    988988            if (RT_FAILURE(rc))
    989989            {
     
    10201020            Assert(PGM_PAGE_IS_BALLOONED(pPage));
    10211021
    1022             /* Change back to zero page. */
     1022            /* Change back to zero page.  (NEM does not need to be informed.) */
    10231023            PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ZERO);
    10241024        }
     
    18541854                if (PGM_PAGE_IS_SHARED(pPage))
    18551855                {
    1856                     uint32_t u32Checksum = pPage->s.u2Unused0 | ((uint32_t)pPage->s.u2Unused1 << 8);
     1856                    uint32_t u32Checksum = pPage->s.u2Unused0/* | ((uint32_t)pPage->s.u2Unused1 << 8)*/;
    18571857                    if (!u32Checksum)
    18581858                    {
     
    18641864                            uint32_t u32Checksum2 = RTCrc32(pvPage, PAGE_SIZE);
    18651865# if 0
    1866                             AssertMsg((u32Checksum2 & UINT32_C(0x00000303)) == u32Checksum, ("GCPhysPage=%RGp\n", GCPhysPage));
     1866                            AssertMsg((u32Checksum2 & /*UINT32_C(0x00000303)*/ 0x3) == u32Checksum, ("GCPhysPage=%RGp\n", GCPhysPage));
    18671867# else
    1868                             if ((u32Checksum2 & UINT32_C(0x00000303)) == u32Checksum)
     1868                            if ((u32Checksum2 & /*UINT32_C(0x00000303)*/ 0x3) == u32Checksum)
    18691869                                LogFlow(("shpg %#x @ %RGp %#x [OK]\n", PGM_PAGE_GET_PAGEID(pPage), GCPhysPage, u32Checksum2));
    18701870                            else
     
    19741974                        else if (!PGM_PAGE_IS_ZERO(pPage))
    19751975                        {
    1976                             rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT));
     1976                            rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT),
     1977                                                 PGMPAGETYPE_RAM);
    19771978                            AssertLogRelRCReturn(rc, rc);
    19781979                        }
     
    21232124                    if (PGM_PAGE_IS_SHARED(pPage))
    21242125                    {
    2125                         rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT));
     2126                        rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT),
     2127                                             PGMPAGETYPE_RAM);
    21262128                        AssertLogRelRCReturn(rc, rc);
    21272129                    }
     
    33893391                PGM_PAGE_SET_PTE_INDEX(pVM, pPageDst, 0);
    33903392                PGM_PAGE_SET_TRACKING(pVM, pPageDst, 0);
     3393                /* (We tell NEM at the end of the function.) */
    33913394
    33923395                pVM->pgm.s.cZeroPages--;
     
    35163519    uint32_t const fNemNotify = (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2       ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2   : 0)
    35173520                              | (pFirstMmio->fFlags & PGMREGMMIORANGE_F_OVERLAPPING ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0);
    3518     int rc = NEMR3NotifyPhysMmioExMap(pVM, GCPhys, cbRange, fNemNotify);
     3521    int rc = NEMR3NotifyPhysMmioExMap(pVM, GCPhys, cbRange, fNemNotify, pFirstMmio->pvR3);
     3522
    35193523    pgmUnlock(pVM);
     3524
    35203525#ifdef VBOX_WITH_REM
    35213526    if (!fRamExists && (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2)) /** @todo this doesn't look right. */
     
    38993904 * @param   pszDesc             Pointer to description string. This must not be freed.
    39003905 */
    3901 static int pgmR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb,
    3902                                 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
     3906static int pgmR3PhysRomRegisterLocked(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb,
     3907                                      const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
    39033908{
    39043909    /*
     
    42704275         pDevIns, GCPhys, GCPhys + cb, cb, pvBinary, cbBinary, fFlags, pszDesc));
    42714276    pgmLock(pVM);
    4272     int rc = pgmR3PhysRomRegister(pVM, pDevIns, GCPhys, cb, pvBinary, cbBinary, fFlags, pszDesc);
     4277    int rc = pgmR3PhysRomRegisterLocked(pVM, pDevIns, GCPhys, cb, pvBinary, cbBinary, fFlags, pszDesc);
    42734278    pgmUnlock(pVM);
    42744279    return rc;
     
    43154320
    43164321                for (uint32_t iPage = 0; iPage < cPages; iPage++)
    4317                     if (    !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow)
    4318                         &&  !PGM_PAGE_IS_BALLOONED(&pRom->aPages[iPage].Shadow))
     4322                    if (   !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow)
     4323                        && !PGM_PAGE_IS_BALLOONED(&pRom->aPages[iPage].Shadow))
    43194324                    {
    43204325                        Assert(PGM_PAGE_GET_STATE(&pRom->aPages[iPage].Shadow) == PGM_PAGE_STATE_ALLOCATED);
    43214326                        rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, &pRom->aPages[iPage].Shadow,
    4322                                              pRom->GCPhys + (iPage << PAGE_SHIFT));
     4327                                             pRom->GCPhys + (iPage << PAGE_SHIFT),
     4328                                             (PGMPAGETYPE)PGM_PAGE_GET_TYPE(&pRom->aPages[iPage].Shadow));
    43234329                        AssertLogRelRCReturn(rc, rc);
    43244330                    }
     
    44574463    for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3)
    44584464    {
    4459         if (    GCPhys     <= pRom->GCPhysLast
    4460             &&  GCPhysLast >= pRom->GCPhys
    4461             &&  (pRom->fFlags & PGMPHYS_ROM_FLAGS_SHADOWED))
     4465        if (   GCPhys     <= pRom->GCPhysLast
     4466            && GCPhysLast >= pRom->GCPhys
     4467            && (pRom->fFlags & PGMPHYS_ROM_FLAGS_SHADOWED))
    44624468        {
    44634469            /*
     
    44834489                    if (rc2 != VINF_SUCCESS && (rc == VINF_SUCCESS || RT_FAILURE(rc2)))
    44844490                        rc = rc2;
     4491                    uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pRamPage);
    44854492
    44864493                    PPGMPAGE pOld = PGMROMPROT_IS_ROM(pRomPage->enmProt) ? &pRomPage->Virgin : &pRomPage->Shadow;
     
    44904497                    *pRamPage = *pNew;
    44914498                    /** @todo preserve the volatile flags (handlers) when these have been moved out of HCPhys! */
     4499
     4500                    /* Tell NEM about the backing and protection change. */
     4501                    if (VM_IS_NEM_ENABLED(pVM))
     4502                    {
     4503                        PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pNew);
     4504                        NEMHCNotifyPhysPageChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pOld), PGM_PAGE_GET_HCPHYS(pNew),
     4505                                                   pgmPhysPageCalcNemProtection(pRamPage, enmType), enmType, &u2State);
     4506                        PGM_PAGE_SET_NEM_STATE(pRamPage, u2State);
     4507                    }
    44924508                }
    44934509                pRomPage->enmProt = enmProt;
     
    52475263 * @param   pPage           Pointer to the page structure.
    52485264 * @param   GCPhys          The guest physical address of the page, if applicable.
     5265 * @param   enmNewType      New page type for NEM notification, since several
     5266 *                          callers will change the type upon successful return.
    52495267 *
    52505268 * @remarks The caller must own the PGM lock.
    52515269 */
    5252 int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys)
     5270int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys,
     5271                    PGMPAGETYPE enmNewType)
    52535272{
    52545273    /*
     
    52805299        return VMSetError(pVM, VERR_PGM_PHYS_INVALID_PAGE_ID, RT_SRC_POS, "GCPhys=%RGp idPage=%#x", GCPhys, pPage);
    52815300    }
     5301    const RTHCPHYS HCPhysPrev = PGM_PAGE_GET_HCPHYS(pPage);
    52825302
    52835303    /* update page count stats. */
     
    53075327    /* Flush physical page map TLB entry. */
    53085328    pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhys);
     5329
     5330    /* Notify NEM. */
     5331    /** @todo consider doing batch NEM notifications.  */
     5332    if (VM_IS_NEM_ENABLED(pVM))
     5333    {
     5334        uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage);
     5335        NEMHCNotifyPhysPageChanged(pVM, GCPhys, HCPhysPrev, pVM->pgm.s.HCPhysZeroPg,
     5336                                   pgmPhysPageCalcNemProtection(pPage, enmNewType), enmNewType, &u2State);
     5337        PGM_PAGE_SET_NEM_STATE(pPage, u2State);
     5338    }
    53095339
    53105340    /*
  • trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp

    r69111 r70977  
    27392739                                 && PGM_PAGE_GET_PDE_TYPE(pPage) != PGM_PAGE_PDE_TYPE_PDE_DISABLED)
    27402740                        {
    2741                             rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys);
     2741                            rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys, (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage));
    27422742                            AssertRCReturn(rc, rc);
    27432743                        }
     
    27622762                                                     ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_PGM_LOAD_UNEXPECTED_PAGE_TYPE);
    27632763
    2764                             rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys);
     2764                            rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys, (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage));
    27652765                            AssertRCReturn(rc, rc);
    27662766                        }
Note: See TracChangeset for help on using the changeset viewer.

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