VirtualBox

Changeset 71043 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Feb 16, 2018 8:48:42 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
120906
Message:

NEM: More code - PoC kind of working now. bugref:9044

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

Legend:

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

    r70977 r71043  
    13281328                    uint8_t     u2State = PGM_PAGE_GET_NEM_STATE(pPage);
    13291329                    PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage);
    1330                     NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage),
     1330                    NEMHCNotifyPhysPageProtChanged(pVM, GCPhysPage, PGM_PAGE_GET_HCPHYS(pPage),
    13311331                                                   pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State);
    13321332                    PGM_PAGE_SET_NEM_STATE(pPage, u2State);
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r71040 r71043  
    47534753
    47544754#ifndef IN_RC
     4755
    47554756/**
    47564757 * Interface used by NEM to check what to do on a memory access exit.
     
    47704771 */
    47714772VMM_INT_DECL(int) PGMPhysNemPageInfoChecker(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, bool fMakeWritable, PPGMPHYSNEMPAGEINFO pInfo,
    4772                                             PFNPGMPHYSNEMQUERYCHECKER pfnChecker, void *pvUser)
     4773                                            PFNPGMPHYSNEMCHECKPAGE pfnChecker, void *pvUser)
    47734774{
    47744775    pgmLock(pVM);
     
    48484849
    48494850    return rc;
    4850 
    4851 }
     4851}
     4852
     4853
     4854/**
     4855 * NEM helper that performs @a pfnCallback on pages with NEM state @a uMinState
     4856 * or higher.
     4857 *
     4858 * @returns VBox status code from callback.
     4859 * @param   pVM             The cross context VM structure.
     4860 * @param   uMinState       The minimum NEM state value to call on.
     4861 * @param   pfnCallback     The callback function.
     4862 * @param   pvUser          User argument for the callback.
     4863 */
     4864VMM_INT_DECL(int) PGMPhysNemEnumPagesByState(PVM pVM, uint8_t uMinState, PFNPGMPHYSNEMENUMCALLBACK pfnCallback, void *pvUser)
     4865{
     4866    /*
     4867     * Just brute force this problem.
     4868     */
     4869    pgmLock(pVM);
     4870    int rc = VINF_SUCCESS;
     4871    for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX); pRam; pRam = pRam->CTX_SUFF(pNext))
     4872    {
     4873        uint32_t const cPages = pRam->cb >> X86_PAGE_SHIFT;
     4874        for (uint32_t iPage = 0; iPage < cPages; iPage++)
     4875        {
     4876            uint8_t u2State = PGM_PAGE_GET_NEM_STATE(&pRam->aPages[iPage]);
     4877            if (u2State < uMinState)
     4878            { /* likely */ }
     4879            else
     4880            {
     4881                rc = pfnCallback(pVM, pRam->GCPhys + ((RTGCPHYS)iPage << X86_PAGE_SHIFT), &u2State, pvUser);
     4882                if (RT_SUCCESS(rc))
     4883                    PGM_PAGE_SET_NEM_STATE(&pRam->aPages[iPage], u2State);
     4884                else
     4885                    break;
     4886            }
     4887        }
     4888    }
     4889    pgmUnlock(pVM);
     4890
     4891    return rc;
     4892
     4893}
     4894
    48524895#endif /* !IN_RC */
    48534896
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r71040 r71043  
    997997    aValues[iReg].Reg64 = pCtx->cr2;
    998998    iReg++;
     999Log(("=> cr2=%RX64\n", pCtx->cr2));
    9991000    aenmNames[iReg]     = WHvX64RegisterCr3;
    10001001    aValues[iReg].Reg64 = pCtx->cr3;
     
    11831184    iReg++;
    11841185
    1185     /* event injection */
    1186     /// @todo WHvRegisterPendingInterruption
     1186    /* event injection (always clear it). */
     1187    /** @todo Someone at microsoft please explain why HV_X64_PENDING_INTERRUPTION_REGISTER
     1188     * and HV_X64_INTERRUPT_STATE_REGISTER are missing from the headers.  Ditto for
     1189     * wathever structures WHvRegisterPendingEvent0/1 uses.   */
     1190    aenmNames[iReg]     = WHvRegisterPendingInterruption;
     1191    aValues[iReg].Reg64 = 0;
     1192    iReg++;
    11871193    /// @todo WHvRegisterInterruptState
    11881194    /// @todo WHvRegisterPendingEvent0
     
    13911397            fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
    13921398        }
     1399        Assert(aenmNames[29] == WHvX64RegisterCr2);
    13931400        pCtx->cr2 = aValues[29].Reg64;
     1401Log(("<= cr2=%RX64\n", pCtx->cr2));
    13941402        if (pCtx->cr3 != aValues[30].Reg64)
    13951403        {
     
    15291537        pCtx->msrSFMASK = aValues[75].Reg64;
    15301538
    1531         /* event injection */
    15321539        /// @todo WHvRegisterPendingInterruption
    15331540        /// @todo WHvRegisterInterruptState
     
    17521759}
    17531760
     1761static DECLCALLBACK(int) nemR3WinUnmapOnePageCallback(PVM pVM, RTGCPHYS GCPhys, uint8_t *pu2NemState, void *pvUser)
     1762{
     1763    RT_NOREF_PV(pvUser);
     1764    HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, X86_PAGE_SIZE);
     1765    if (SUCCEEDED(hrc))
     1766        *pu2NemState = NEM_WIN_PAGE_STATE_UNMAPPED;
     1767    else
     1768    {
     1769        LogRel(("nemR3WinUnmapOnePageCallback: GCPhys=%RGp %s hrc=%Rhrc (%#x) Last=%#x/%u (cMappedPages=%u)\n",
     1770                GCPhys, g_apszPageStates[*pu2NemState], hrc, hrc, RTNtCurrentTeb()->LastStatusValue,
     1771                RTNtCurrentTeb()->LastErrorValue, pVM->nem.s.cMappedPages));
     1772        *pu2NemState = NEM_WIN_PAGE_STATE_NOT_SET;
     1773    }
     1774    if (pVM->nem.s.cMappedPages > 0)
     1775        ASMAtomicDecU32(&pVM->nem.s.cMappedPages);
     1776    return VINF_SUCCESS;
     1777}
     1778
    17541779
    17551780/**
    1756  * @callback_method_impl{FNPGMPHYSNEMQUERYCHECKER,
    1757  *      Worker for nemR3WinHandleMemoryAccess.
    1758  *      On input the boolean at pvUser indicates the desire to make the page
    1759  *      writable, whereas upon return it indicates whether we did anything to
    1760  *      the page mapping/protection. }
     1781 * State to pass between  nemR3WinHandleMemoryAccess and
     1782 * nemR3WinHandleMemoryAccessPageCheckerCallback.
     1783 */
     1784typedef struct NEMR3WINHMACPCCSTATE
     1785{
     1786    /** Input: Write access. */
     1787    bool    fWriteAccess;
     1788    /** Output: Set if we did something. */
     1789    bool    fDidSomething;
     1790    /** Output: Set it we should resume. */
     1791    bool    fCanResume;
     1792} NEMR3WINHMACPCCSTATE;
     1793
     1794/**
     1795 * @callback_method_impl{FNPGMPHYSNEMCHECKPAGE,
     1796 *      Worker for nemR3WinHandleMemoryAccess, pvUser points to a
     1797 *      NEMR3WINHMACPCCSTATE structure. }
    17611798 */
    17621799static DECLCALLBACK(int) nemR3WinHandleMemoryAccessPageCheckerCallback(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys,
    17631800                                                                       PPGMPHYSNEMPAGEINFO pInfo, void *pvUser)
    17641801{
     1802    NEMR3WINHMACPCCSTATE *pState = (NEMR3WINHMACPCCSTATE *)pvUser;
     1803    pState->fDidSomething = false;
     1804    pState->fCanResume    = false;
     1805
    17651806    /* If A20 is disabled, we may need to make another query on the masked
    17661807       page to get the correct protection information. */
     
    17731814    {
    17741815        GCPhysSrc = GCPhys & ~(RTGCPHYS)RT_BIT_32(20);
    1775         bool const fMakeWritable = *(bool *)pvUser;
    17761816        PGMPHYSNEMPAGEINFO Info2;
    1777         int rc = PGMPhysNemPageInfoChecker(pVM, pVCpu, GCPhysSrc, fMakeWritable, &Info2, NULL, NULL);
     1817        int rc = PGMPhysNemPageInfoChecker(pVM, pVCpu, GCPhysSrc, pState->fWriteAccess, &Info2, NULL, NULL);
    17781818        AssertRCReturn(rc, rc);
    17791819
     
    17821822    }
    17831823
    1784     bool   *pfDidSomething  = (bool *)pvUser;
    1785     bool    fBackingChanged = true;
     1824    /*
     1825     * I'm not sure WTF was going on, but I ended up in a loop if I remapped a
     1826     * readonly page as writable.  Specifically, this was an issue with the big
     1827     * VRAM mapping at 0xe0000000 when booing DSL 4.4.1.  So, in a hope to work
     1828     * around that we no longer pre-map anything, just unmap stuff and do it
     1829     * lazily here.  And here we will first unmap, restart, and then remap with
     1830     * new protection or backing.
     1831     */
    17861832    switch (u2State)
    17871833    {
     
    17921838            {
    17931839                Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - #1\n", GCPhys));
    1794                 *pfDidSomething = false;
    17951840                return VINF_SUCCESS;
    17961841            }
    17971842
    1798 #if 0
    1799             /* Remap it. */
    1800             *pfDidSomething = true;
    1801             int rc = nemR3NativeSetPhysPage(pVM, GCPhysSrc & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
    1802                                             GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, pInfo->fNemProt, &u2State, fBackingChanged);
     1843            /* Don't bother remapping it if it's a write request to a non-writable page. */
     1844            if (   pState->fWriteAccess
     1845                && !(pInfo->fNemProt & NEM_PAGE_PROT_WRITE))
     1846            {
     1847                Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - #1w\n", GCPhys));
     1848                return VINF_SUCCESS;
     1849            }
     1850
     1851            /* Map the page. */
     1852            int rc = nemR3NativeSetPhysPage(pVM,
     1853                                            GCPhysSrc & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
     1854                                            GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
     1855                                            pInfo->fNemProt,
     1856                                            &u2State,
     1857                                            true /*fBackingState*/);
    18031858            pInfo->u2NemState = u2State;
    18041859            Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - synced => %s + %Rrc\n",
    18051860                  GCPhys, g_apszPageStates[u2State], rc));
    18061861            RT_NOREF(pVCpu);
     1862            pState->fDidSomething = true;
     1863            pState->fCanResume    = true;
    18071864            return rc;
    1808 #else
    1809             break;
    1810 #endif
    1811         }
     1865        }
     1866
    18121867        case NEM_WIN_PAGE_STATE_READABLE:
    1813             if (pInfo->fNemProt != NEM_PAGE_PROT_NONE)
     1868            if (   !(pInfo->fNemProt & NEM_PAGE_PROT_WRITE)
     1869                && (pInfo->fNemProt & (NEM_PAGE_PROT_READ | NEM_PAGE_PROT_EXECUTE)))
    18141870            {
    1815                 if (!(pInfo->fNemProt & NEM_PAGE_PROT_WRITE))
    1816                 {
    1817                     Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - #2\n", GCPhys));
    1818                     *pfDidSomething = false;
    1819                     return VINF_SUCCESS;
    1820                 }
    1821                 fBackingChanged = false;
     1871                Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - #2\n", GCPhys));
     1872                return VINF_SUCCESS;
    18221873            }
    18231874            break;
     1875
    18241876        case NEM_WIN_PAGE_STATE_WRITABLE:
    18251877            if (pInfo->fNemProt & NEM_PAGE_PROT_WRITE)
    18261878            {
    18271879                Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - #3\n", GCPhys));
    1828                 *pfDidSomething = false;
    18291880                return VINF_SUCCESS;
    18301881            }
    1831             if (pInfo->fNemProt != NEM_PAGE_PROT_NONE)
    1832                 fBackingChanged = false;
    18331882            break;
    1834     }
    1835 
    1836 #if 0
    1837     /* Unmap it first, then take another fault, remap it. */
     1883
     1884        default:
     1885            AssertLogRelMsgFailedReturn(("u2State=%#x\n", u2State), VERR_INTERNAL_ERROR_3);
     1886    }
     1887
     1888    /*
     1889     * Unmap and restart the instruction.
     1890     * If this fails, which it does every so often, just unmap everything for now.
     1891     */
     1892    /** @todo figure out whether we mess up the state or if it's WHv.   */
    18381893    HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, X86_PAGE_SIZE);
    18391894    if (SUCCEEDED(hrc))
    18401895    {
    1841         *pfDidSomething = true;
     1896        pState->fDidSomething = true;
     1897        pState->fCanResume    = true;
    18421898        pInfo->u2NemState = NEM_WIN_PAGE_STATE_UNMAPPED;
    1843         Log5(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp => unmapped\n", GCPhys));
     1899        Log5(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp => unmapped[%s]\n", GCPhys, g_apszPageStates[u2State]));
    18441900        return VINF_SUCCESS;
    18451901    }
    1846     LogRel(("nemR3WinHandleMemoryAccessPageCheckerCallback/unmap: GCPhysDst=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n",
    1847             GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
    1848     return VERR_NEM_INIT_FAILED;
    1849 
    1850 #else
    1851     *pfDidSomething = true;
    1852     int rc = nemR3NativeSetPhysPage(pVM, GCPhysSrc & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
    1853                                     GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, pInfo->fNemProt, &u2State, fBackingChanged);
    1854     pInfo->u2NemState = u2State;
    1855     Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - synced => %s + %Rrc\n",
    1856           GCPhys, g_apszPageStates[u2State], rc));
    1857     RT_NOREF(pVCpu);
    1858     return rc;
    1859 #endif
     1902    LogRel(("nemR3WinHandleMemoryAccessPageCheckerCallback/unmap: GCPhysDst=%RGp %s hrc=%Rhrc (%#x) Last=%#x/%u (cMappedPages=%u)\n",
     1903            GCPhys, g_apszPageStates[u2State], hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue,
     1904            pVM->nem.s.cMappedPages));
     1905
     1906    PGMPhysNemEnumPagesByState(pVM, NEM_WIN_PAGE_STATE_READABLE, nemR3WinUnmapOnePageCallback, NULL);
     1907    Log(("nemR3WinHandleMemoryAccessPageCheckerCallback: Unmapped all (cMappedPages=%u)\n", pVM->nem.s.cMappedPages));
     1908
     1909    pState->fDidSomething = true;
     1910    pState->fCanResume    = true;
     1911    pInfo->u2NemState = NEM_WIN_PAGE_STATE_UNMAPPED;
     1912    return VINF_SUCCESS;
    18601913}
    18611914
     
    18781931     * out of sync first.
    18791932     */
    1880     bool               fMakeWritableThenDidSomething = pMemCtx->AccessInfo.AccessType == WHvMemoryAccessWrite;
    1881     PGMPHYSNEMPAGEINFO Info;
    1882     int rc = PGMPhysNemPageInfoChecker(pVM, pVCpu, pMemCtx->Gpa, fMakeWritableThenDidSomething, &Info,
    1883                                        nemR3WinHandleMemoryAccessPageCheckerCallback, &fMakeWritableThenDidSomething);
     1933    NEMR3WINHMACPCCSTATE State = { pMemCtx->AccessInfo.AccessType == WHvMemoryAccessWrite, false, false };
     1934    PGMPHYSNEMPAGEINFO   Info;
     1935    int rc = PGMPhysNemPageInfoChecker(pVM, pVCpu, pMemCtx->Gpa, State.fWriteAccess, &Info,
     1936                                       nemR3WinHandleMemoryAccessPageCheckerCallback, &State);
    18841937    if (RT_SUCCESS(rc))
    18851938    {
    18861939        if (Info.fNemProt & (pMemCtx->AccessInfo.AccessType == WHvMemoryAccessWrite ? NEM_PAGE_PROT_WRITE : NEM_PAGE_PROT_READ))
    18871940        {
    1888             ////if (fMakeWritableThenDidSomething)
    1889             //{
    1890             //    Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; restarting (%s)\n",
    1891             //          pMemCtx->Gpa, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,
    1892             //          Info.fHasHandlers ? " handlers" : "", Info.fZeroPage    ? " zero-pg" : "",
    1893             //          fMakeWritableThenDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));
    1894             //    return VINF_SUCCESS;
    1895             //}
     1941            if (State.fCanResume)
     1942            {
     1943                Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; restarting (%s)\n",
     1944                      pMemCtx->Gpa, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,
     1945                      Info.fHasHandlers ? " handlers" : "", Info.fZeroPage    ? " zero-pg" : "",
     1946                      State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));
     1947                return VINF_SUCCESS;
     1948            }
    18961949        }
    18971950        Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; emulating (%s)\n",
    18981951              pMemCtx->Gpa, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,
    18991952              Info.fHasHandlers ? " handlers" : "", Info.fZeroPage    ? " zero-pg" : "",
    1900               fMakeWritableThenDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));
     1953              State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));
    19011954    }
    19021955    else
    19031956        Log4(("MemExit: %RGp rc=%Rrc%s; emulating (%s)\n", pMemCtx->Gpa, rc,
    1904               fMakeWritableThenDidSomething ? " modified-backing" : "", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));
     1957              State.fDidSomething ? " modified-backing" : "", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));
    19051958
    19061959    /*
     
    21112164        AssertRCBreakStmt(rc2, rcStrict = rc2);
    21122165
     2166#ifdef LOG_ENABLED
     2167        /*
     2168         * Do some logging.
     2169         */
     2170        if (LogIs2Enabled())
     2171            nemR3WinLogExitReason(&ExitReason);
     2172        if (LogIs3Enabled())
     2173            nemR3WinLogState(pVM, pVCpu);
     2174#endif
     2175
    21132176#ifdef VBOX_STRICT
    21142177        /* Assert that the VpContext field makes sense. */
     
    21212184            case WHvRunVpExitReasonException:
    21222185            case WHvRunVpExitReasonUnrecoverableException:
    2123                 Assert(ExitReason.IoPortAccess.VpContext.InstructionLength > 0);
     2186                Assert(   ExitReason.IoPortAccess.VpContext.InstructionLength > 0
     2187                       || (   ExitReason.ExitReason == WHvRunVpExitReasonMemoryAccess
     2188                           && ExitReason.MemoryAccess.AccessInfo.AccessType == WHvMemoryAccessExecute));
    21242189                Assert(ExitReason.IoPortAccess.VpContext.InstructionLength < 16);
    21252190                Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cpl == CPUMGetGuestCPL(pVCpu));
     
    21402205#endif
    21412206
    2142 #ifdef LOG_ENABLED
    2143         /*
    2144          * Do some logging.
    2145          */
    2146         if (LogIs2Enabled())
    2147             nemR3WinLogExitReason(&ExitReason);
    2148         if (LogIs3Enabled())
    2149             nemR3WinLogState(pVM, pVCpu);
    2150 #endif
    2151 
    21522207        /*
    21532208         * Deal with the exit.
     
    22152270        }
    22162271
     2272        /* Major hack alert! */
     2273        uint32_t const cMappedPages = pVM->nem.s.cMappedPages;
     2274        if (cMappedPages < 200)
     2275        { /* likely */ }
     2276        else
     2277        {
     2278            PGMPhysNemEnumPagesByState(pVM, NEM_WIN_PAGE_STATE_READABLE, nemR3WinUnmapOnePageCallback, NULL);
     2279            Log(("nemR3NativeRunGC: Unmapped all; cMappedPages=%u -> %u\n", cMappedPages, pVM->nem.s.cMappedPages));
     2280        }
     2281
    22172282        /* If any FF is pending, return to the EM loops.  That's okay for the
    22182283           current sledgehammer approach. */
     
    22712336    return rc;
    22722337}
     2338
    22732339
    22742340DECLINLINE(int) nemR3NativeGCPhys2R3PtrWriteable(PVM pVM, RTGCPHYS GCPhys, void **ppv)
     
    23762442
    23772443/**
    2378  * @callback_method_impl{FNPGMPHYSNEMQUERYCHECKER}
     2444 * @callback_method_impl{FNPGMPHYSNEMCHECKPAGE}
    23792445 */
    23802446static DECLCALLBACK(int) nemR3WinUnsetForA20CheckerCallback(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys,
     
    25002566            {
    25012567                *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
     2568                uint32_t cMappedPages = ASMAtomicDecU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages);
    25022569                if (u2NewState == NEM_WIN_PAGE_STATE_UNMAPPED)
    25032570                {
    2504                     Log5(("nemR3NativeSetPhysPage: %RGp => unmapped\n", GCPhysDst));
     2571                    Log5(("nemR3NativeSetPhysPage: %RGp => unmapped (total %u)\n", GCPhysDst, cMappedPages));
    25052572                    return VINF_SUCCESS;
    25062573                }
     
    25282595            if (SUCCEEDED(hrc))
    25292596            {
    2530                 Log5(("nemR3NativeSetPhysPage: %RGp => writable\n", GCPhysDst));
    25312597                *pu2State = NEM_WIN_PAGE_STATE_WRITABLE;
     2598                uint32_t cMappedPages = ASMAtomicIncU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages);
     2599                Log5(("nemR3NativeSetPhysPage: %RGp => writable (total %u)\n", GCPhysDst, cMappedPages));
    25322600                return VINF_SUCCESS;
    25332601            }
     
    25512619            {
    25522620                *pu2State = NEM_WIN_PAGE_STATE_READABLE;
    2553                 Log5(("nemR3NativeSetPhysPage: %RGp => read+exec\n", GCPhysDst));
     2621                uint32_t cMappedPages = ASMAtomicIncU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages);
     2622                Log5(("nemR3NativeSetPhysPage: %RGp => read+exec (total %u)\n", GCPhysDst, cMappedPages));
    25542623                return VINF_SUCCESS;
    25552624            }
     
    25682637
    25692638
     2639static int nemR3JustUnmapPageFromHyperV(PVM pVM, RTGCPHYS GCPhysDst, uint8_t *pu2State)
     2640{
     2641    if (*pu2State <= NEM_WIN_PAGE_STATE_UNMAPPED)
     2642    {
     2643        Log5(("nemR3JustUnmapPageFromHyperV: %RGp == unmapped\n", GCPhysDst));
     2644        *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
     2645        return VINF_SUCCESS;
     2646    }
     2647
     2648    HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhysDst, X86_PAGE_SIZE);
     2649    if (SUCCEEDED(hrc))
     2650    {
     2651        uint32_t cMappedPages = ASMAtomicDecU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages);
     2652        *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
     2653        Log5(("nemR3JustUnmapPageFromHyperV: %RGp => unmapped (total %u)\n", GCPhysDst, cMappedPages));
     2654        return VINF_SUCCESS;
     2655    }
     2656    LogRel(("nemR3JustUnmapPageFromHyperV(%RGp): failed! hrc=%Rhrc (%#x) Last=%#x/%u\n",
     2657            GCPhysDst, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
     2658    return VERR_INTERNAL_ERROR_3;
     2659}
     2660
     2661
    25702662int nemR3NativeNotifyPhysPageAllocated(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
    25712663                                       PGMPAGETYPE enmType, uint8_t *pu2State)
     
    25762668
    25772669    int rc;
     2670#if 0
    25782671    if (   pVM->nem.s.fA20Enabled
    25792672        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     
    25872680
    25882681    }
     2682#else
     2683    RT_NOREF_PV(fPageProt);
     2684    if (   pVM->nem.s.fA20Enabled
     2685        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     2686        rc = nemR3JustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     2687    else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys))
     2688        rc = nemR3JustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     2689    else
     2690        rc = VINF_SUCCESS; /* ignore since we've got the alias page at this address. */
     2691#endif
    25892692    return rc;
    25902693}
     
    25982701    RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType);
    25992702
     2703#if 0
    26002704    if (   pVM->nem.s.fA20Enabled
    26012705        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     
    26082712            nemR3NativeSetPhysPage(pVM, GCPhys, GCPhys, fPageProt, pu2State, false /*fBackingChanged*/);
    26092713    }
     2714#else
     2715    RT_NOREF_PV(fPageProt);
     2716    if (   pVM->nem.s.fA20Enabled
     2717        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     2718        nemR3JustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     2719    else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys))
     2720        nemR3JustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     2721    /* else: ignore since we've got the alias page at this address. */
     2722#endif
    26102723}
    26112724
     
    26182731    RT_NOREF_PV(HCPhysPrev); RT_NOREF_PV(HCPhysNew); RT_NOREF_PV(enmType);
    26192732
     2733#if 0
    26202734    if (   pVM->nem.s.fA20Enabled
    26212735        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     
    26282742            nemR3NativeSetPhysPage(pVM, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/);
    26292743    }
    2630 }
    2631 
     2744#else
     2745    RT_NOREF_PV(fPageProt);
     2746    if (   pVM->nem.s.fA20Enabled
     2747        || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys))
     2748        nemR3JustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     2749    else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys))
     2750        nemR3JustUnmapPageFromHyperV(pVM, GCPhys, pu2State);
     2751    /* else: ignore since we've got the alias page at this address. */
     2752#endif
     2753}
     2754
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r71040 r71043  
    8383     * controls. */
    8484    RTR3PTR                     hPartitionDevice;
     85
     86    /** Number of currently mapped pages. */
     87    uint32_t volatile           cMappedPages;
    8588#endif
    8689
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