VirtualBox

Changeset 71082 in vbox


Ignore:
Timestamp:
Feb 21, 2018 11:18:47 AM (7 years ago)
Author:
vboxsync
Message:

VMM,SUPDrv: More NEM/win page hacking. bugref:9044

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r71081 r71082  
    19591959
    19601960    /*
     1961     * Consolidate current page state with actual page protection and access type.
     1962     * We don't really consider downgrades here, as they shouldn't happen.
     1963     */
     1964#ifndef NEM_WIN_USE_HYPERCALLS
     1965    /** @todo Someone at microsoft please explain:
    19611966     * I'm not sure WTF was going on, but I ended up in a loop if I remapped a
    1962      * readonly page as writable.  Specifically, this was an issue with the big
    1963      * VRAM mapping at 0xe0000000 when booing DSL 4.4.1.  So, in a hope to work
    1964      * around that we no longer pre-map anything, just unmap stuff and do it
    1965      * lazily here.  And here we will first unmap, restart, and then remap with
    1966      * new protection or backing.
    1967      */
     1967     * readonly page as writable (unmap, then map again).  Specifically, this was an
     1968     * issue with the big VRAM mapping at 0xe0000000 when booing DSL 4.4.1.  So, in
     1969     * a hope to work around that we no longer pre-map anything, just unmap stuff
     1970     * and do it lazily here.  And here we will first unmap, restart, and then remap
     1971     * with new protection or backing.
     1972     */
     1973#endif
     1974    int rc;
    19681975    switch (u2State)
    19691976    {
    19701977        case NEM_WIN_PAGE_STATE_UNMAPPED:
    19711978        case NEM_WIN_PAGE_STATE_NOT_SET:
    1972         {
    19731979            if (pInfo->fNemProt == NEM_PAGE_PROT_NONE)
    19741980            {
     
    19861992
    19871993            /* Map the page. */
    1988             int rc = nemR3NativeSetPhysPage(pVM,
    1989                                             pVCpu,
    1990                                             GCPhysSrc & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
    1991                                             GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
    1992                                             pInfo->fNemProt,
    1993                                             &u2State,
    1994                                             true /*fBackingState*/);
     1994            rc = nemR3NativeSetPhysPage(pVM,
     1995                                        pVCpu,
     1996                                        GCPhysSrc & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
     1997                                        GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK,
     1998                                        pInfo->fNemProt,
     1999                                        &u2State,
     2000                                        true /*fBackingState*/);
    19952001            pInfo->u2NemState = u2State;
    19962002            Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - synced => %s + %Rrc\n",
    19972003                  GCPhys, g_apszPageStates[u2State], rc));
    1998             RT_NOREF(pVCpu);
    19992004            pState->fDidSomething = true;
    20002005            pState->fCanResume    = true;
    20012006            return rc;
    2002         }
    20032007
    20042008        case NEM_WIN_PAGE_STATE_READABLE:
     
    20162020                && pState->fWriteAccess)
    20172021            {
    2018                 int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhys,
    2019                                                     HV_MAP_GPA_READABLE   | HV_MAP_GPA_WRITABLE
    2020                                                   | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN);
     2022                rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhys,
     2023                                              HV_MAP_GPA_READABLE   | HV_MAP_GPA_WRITABLE
     2024                                              | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN);
    20212025                AssertRC(rc);
    20222026                if (RT_SUCCESS(rc))
     
    20272031                    Log5(("NEM GPA write-upgrade/exit: %RGp (was %s, cMappedPages=%u)\n",
    20282032                          GCPhys, g_apszPageStates[u2State], pVM->nem.s.cMappedPages));
    2029                     return rc;
    20302033                }
    20312034            }
     2035            else
     2036            {
     2037                /* Need to emulate the acces. */
     2038                AssertBreak(pInfo->fNemProt != NEM_PAGE_PROT_NONE); /* There should be no downgrades. */
     2039                rc = VINF_SUCCESS;
     2040            }
     2041            return rc;
     2042#else
     2043            break;
    20322044#endif
    2033             break;
    20342045
    20352046        case NEM_WIN_PAGE_STATE_WRITABLE:
     
    20392050                return VINF_SUCCESS;
    20402051            }
     2052#ifdef NEM_WIN_USE_HYPERCALLS
     2053            AssertFailed(); /* There should be no downgrades. */
     2054#endif
    20412055            break;
    20422056
     
    20502064     */
    20512065#ifdef NEM_WIN_USE_HYPERCALLS
    2052     int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);
     2066    rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);
    20532067    AssertRC(rc);
    20542068    if (RT_SUCCESS(rc))
     
    27382752                                  uint8_t *pu2State, bool fBackingChanged)
    27392753{
     2754#ifdef NEM_WIN_USE_HYPERCALLS
     2755    /*
     2756     * When using the hypercalls instead of the ring-3 APIs, we don't need to
     2757     * unmap memory before modifying it.  We still want to track the state though,
     2758     * since unmap will fail when called an unmapped page and we don't want to redo
     2759     * upgrades/downgrades.
     2760     */
     2761    uint8_t const u2OldState = *pu2State;
     2762    int rc;
     2763    if (fPageProt == NEM_PAGE_PROT_NONE)
     2764    {
     2765        if (u2OldState > NEM_WIN_PAGE_STATE_UNMAPPED)
     2766        {
     2767            rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhysDst);
     2768            if (RT_SUCCESS(rc))
     2769            {
     2770                *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
     2771                uint32_t cMappedPages = ASMAtomicDecU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages);
     2772                Log5(("NEM GPA unmapped/set: %RGp (was %s, cMappedPages=%u)\n", GCPhysDst, g_apszPageStates[u2OldState], cMappedPages));
     2773            }
     2774            else
     2775                AssertLogRelMsgFailed(("nemR3NativeSetPhysPage/unmap: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc));
     2776        }
     2777        else
     2778            rc = VINF_SUCCESS;
     2779    }
     2780    else if (fPageProt & NEM_PAGE_PROT_WRITE)
     2781    {
     2782        if (u2OldState != NEM_WIN_PAGE_STATE_WRITABLE || fBackingChanged)
     2783        {
     2784            rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst,
     2785                                            HV_MAP_GPA_READABLE   | HV_MAP_GPA_WRITABLE
     2786                                          | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN);
     2787            if (RT_SUCCESS(rc))
     2788            {
     2789                *pu2State = NEM_WIN_PAGE_STATE_WRITABLE;
     2790                uint32_t cMappedPages = u2OldState <= NEM_WIN_PAGE_STATE_UNMAPPED
     2791                                      ? ASMAtomicIncU32(&pVM->nem.s.cMappedPages) : pVM->nem.s.cMappedPages;
     2792                Log5(("NEM GPA writable/set: %RGp (was %s, cMappedPages=%u)\n", GCPhysDst, g_apszPageStates[u2OldState], cMappedPages));
     2793                NOREF(cMappedPages);
     2794            }
     2795            else
     2796                AssertLogRelMsgFailed(("nemR3NativeSetPhysPage/writable: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc));
     2797        }
     2798        else
     2799            rc = VINF_SUCCESS;
     2800    }
     2801    else
     2802    {
     2803        if (u2OldState != NEM_WIN_PAGE_STATE_READABLE || fBackingChanged)
     2804        {
     2805            rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst,
     2806                                          HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN);
     2807            if (RT_SUCCESS(rc))
     2808            {
     2809                *pu2State = NEM_WIN_PAGE_STATE_READABLE;
     2810                uint32_t cMappedPages = u2OldState <= NEM_WIN_PAGE_STATE_UNMAPPED
     2811                                      ? ASMAtomicIncU32(&pVM->nem.s.cMappedPages) : pVM->nem.s.cMappedPages;
     2812                Log5(("NEM GPA read+exec/set: %RGp (was %s, cMappedPages=%u)\n", GCPhysDst, g_apszPageStates[u2OldState], cMappedPages));
     2813                NOREF(cMappedPages);
     2814            }
     2815            else
     2816                AssertLogRelMsgFailed(("nemR3NativeSetPhysPage/writable: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc));
     2817        }
     2818        else
     2819            rc = VINF_SUCCESS;
     2820    }
     2821
     2822    return VINF_SUCCESS;
     2823
     2824#else
    27402825    /*
    27412826     * Looks like we need to unmap a page before we can change the backing
     
    27512836        if (u2OldState > NEM_WIN_PAGE_STATE_UNMAPPED)
    27522837        {
    2753 #ifdef NEM_WIN_USE_HYPERCALLS
     2838# ifdef NEM_WIN_USE_HYPERCALLS
    27542839            int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhysDst);
    27552840            AssertRC(rc);
     
    27702855                return rc;
    27712856            }
    2772 #else
     2857# else
    27732858            HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhysDst, X86_PAGE_SIZE);
    27742859            if (SUCCEEDED(hrc))
     
    27892874                return VERR_NEM_INIT_FAILED;
    27902875            }
    2791 #endif
     2876# endif
    27922877        }
    27932878    }
     
    27982883    if (fPageProt & NEM_PAGE_PROT_WRITE)
    27992884    {
    2800 #ifdef NEM_WIN_USE_HYPERCALLS
     2885# ifdef NEM_WIN_USE_HYPERCALLS
    28012886        int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst,
    28022887                                            HV_MAP_GPA_READABLE   | HV_MAP_GPA_WRITABLE
     
    28132898        LogRel(("nemR3NativeSetPhysPage/writable: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc));
    28142899        return rc;
    2815 #else
     2900# else
    28162901        void *pvPage;
    28172902        int rc = nemR3NativeGCPhys2R3PtrWriteable(pVM, GCPhysSrc, &pvPage);
     
    28342919        LogRel(("nemR3NativeSetPhysPage/writable: GCPhysSrc=%RGp rc=%Rrc\n", GCPhysSrc, rc));
    28352920        return rc;
    2836 #endif
     2921# endif
    28372922    }
    28382923
    28392924    if (fPageProt & NEM_PAGE_PROT_READ)
    28402925    {
    2841 #ifdef NEM_WIN_USE_HYPERCALLS
     2926# ifdef NEM_WIN_USE_HYPERCALLS
    28422927        int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst,
    28432928                                          HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN);
     
    28532938        LogRel(("nemR3NativeSetPhysPage/readonly: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc));
    28542939        return rc;
    2855 #else
     2940# else
    28562941        const void *pvPage;
    28572942        int rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhysSrc, &pvPage);
     
    28742959        LogRel(("nemR3NativeSetPhysPage/readonly: GCPhysSrc=%RGp rc=%Rrc\n", GCPhysSrc, rc));
    28752960        return rc;
    2876 #endif
     2961# endif
    28772962    }
    28782963
     
    28802965    *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
    28812966    return VINF_SUCCESS;
     2967#endif /* !NEM_WIN_USE_HYPERCALLS */
    28822968}
    28832969
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