VirtualBox

Changeset 92426 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Nov 15, 2021 1:25:47 PM (3 years ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:10092 Refactor PGMGstGetPage and related API and functions to pass more info back to callers on page walk failures.

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

Legend:

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

    r91580 r92426  
    14261426    }
    14271427
    1428     RTGCPHYS    GCPhys;
    1429     uint64_t    fFlags;
    1430     int rc = PGMGstGetPage(pVCpu, GCPtrPC, &fFlags, &GCPhys);
    1431     if (RT_SUCCESS(rc)) { /* probable */ }
     1428    PGMPTWALK Walk;
     1429    int rc = PGMGstGetPage(pVCpu, GCPtrPC, &Walk);
     1430    if (RT_SUCCESS(rc))
     1431        Assert(Walk.fSucceeded); /* probable. */
    14321432    else
    14331433    {
     
    14351435        return iemRaisePageFault(pVCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, rc);
    14361436    }
    1437     if ((fFlags & X86_PTE_US) || pVCpu->iem.s.uCpl != 3) { /* likely */ }
     1437    if ((Walk.fEffective & X86_PTE_US) || pVCpu->iem.s.uCpl != 3) { /* likely */ }
    14381438    else
    14391439    {
     
    14411441        return iemRaisePageFault(pVCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    14421442    }
    1443     if (!(fFlags & X86_PTE_PAE_NX) || !(pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE)) { /* likely */ }
     1443    if (!(Walk.fEffective & X86_PTE_PAE_NX) || !(pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE)) { /* likely */ }
    14441444    else
    14451445    {
     
    14471447        return iemRaisePageFault(pVCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    14481448    }
    1449     GCPhys |= GCPtrPC & PAGE_OFFSET_MASK;
     1449    RTGCPHYS const GCPhys = Walk.GCPhys | (GCPtrPC & PAGE_OFFSET_MASK);
    14501450    /** @todo Check reserved bits and such stuff. PGM is better at doing
    14511451     *        that, so do it when implementing the guest virtual address
     
    17441744        {
    17451745            pVCpu->iem.s.CodeTlb.cTlbMisses++;
    1746             RTGCPHYS    GCPhys;
    1747             uint64_t    fFlags;
    1748             int rc = PGMGstGetPage(pVCpu, GCPtrFirst, &fFlags, &GCPhys);
     1746            PGMPTWALK Walk;
     1747            int rc = PGMGstGetPage(pVCpu, GCPtrFirst, &Walk);
    17491748            if (RT_FAILURE(rc))
    17501749            {
     
    17541753
    17551754            AssertCompile(IEMTLBE_F_PT_NO_EXEC == 1);
     1755            Assert(Walk.fSucceeded);
    17561756            pTlbe->uTag             = uTag;
    1757             pTlbe->fFlagsAndPhysRev = (~fFlags & (X86_PTE_US | X86_PTE_RW | X86_PTE_D)) | (fFlags >> X86_PTE_PAE_BIT_NX);
    1758             pTlbe->GCPhys           = GCPhys;
     1757            pTlbe->fFlagsAndPhysRev = (~Walk.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D))
     1758                                    | (Walk.fEffective >> X86_PTE_PAE_BIT_NX);
     1759            pTlbe->GCPhys           = Walk.GCPhys;
    17591760            pTlbe->pbMappingR3      = NULL;
    17601761        }
     
    19611962    Assert(cbToTryRead >= cbMin - cbLeft); /* ASSUMPTION based on iemInitDecoderAndPrefetchOpcodes. */
    19621963
    1963     RTGCPHYS    GCPhys;
    1964     uint64_t    fFlags;
    1965     int rc = PGMGstGetPage(pVCpu, GCPtrNext, &fFlags, &GCPhys);
     1964    PGMPTWALK Walk;
     1965    int rc = PGMGstGetPage(pVCpu, GCPtrNext, &Walk);
    19661966    if (RT_FAILURE(rc))
    19671967    {
     
    19691969        return iemRaisePageFault(pVCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, rc);
    19701970    }
    1971     if (!(fFlags & X86_PTE_US) && pVCpu->iem.s.uCpl == 3)
     1971    if (!(Walk.fEffective & X86_PTE_US) && pVCpu->iem.s.uCpl == 3)
    19721972    {
    19731973        Log(("iemOpcodeFetchMoreBytes: %RGv - supervisor page\n", GCPtrNext));
    19741974        return iemRaisePageFault(pVCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    19751975    }
    1976     if ((fFlags & X86_PTE_PAE_NX) && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE))
     1976    if ((Walk.fEffective & X86_PTE_PAE_NX) && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE))
    19771977    {
    19781978        Log(("iemOpcodeFetchMoreBytes: %RGv - NX\n", GCPtrNext));
    19791979        return iemRaisePageFault(pVCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    19801980    }
    1981     GCPhys |= GCPtrNext & PAGE_OFFSET_MASK;
     1981    RTGCPHYS const GCPhys = Walk.GCPhys | (GCPtrNext & PAGE_OFFSET_MASK);
    19821982    Log5(("GCPtrNext=%RGv GCPhys=%RGp cbOpcodes=%#x\n",  GCPtrNext,  GCPhys,  pVCpu->iem.s.cbOpcode));
    19831983    /** @todo Check reserved bits and such stuff. PGM is better at doing
     
    81378137     *        iemSvmWorldSwitch/iemVmxWorldSwitch to work around raising a page-fault
    81388138     *        here. */
    8139     RTGCPHYS    GCPhys;
    8140     uint64_t    fFlags;
    8141     int rc = PGMGstGetPage(pVCpu, GCPtrMem, &fFlags, &GCPhys);
     8139    PGMPTWALK Walk;
     8140    int rc = PGMGstGetPage(pVCpu, GCPtrMem, &Walk);
    81428141    if (RT_FAILURE(rc))
    81438142    {
     
    81518150    /* If the page is writable and does not have the no-exec bit set, all
    81528151       access is allowed.  Otherwise we'll have to check more carefully... */
    8153     if ((fFlags & (X86_PTE_RW | X86_PTE_US | X86_PTE_PAE_NX)) != (X86_PTE_RW | X86_PTE_US))
     8152    if ((Walk.fEffective & (X86_PTE_RW | X86_PTE_US | X86_PTE_PAE_NX)) != (X86_PTE_RW | X86_PTE_US))
    81548153    {
    81558154        /* Write to read only memory? */
    81568155        if (   (fAccess & IEM_ACCESS_TYPE_WRITE)
    8157             && !(fFlags & X86_PTE_RW)
     8156            && !(Walk.fEffective & X86_PTE_RW)
    81588157            && (   (    pVCpu->iem.s.uCpl == 3
    81598158                    && !(fAccess & IEM_ACCESS_WHAT_SYS))
     
    81668165
    81678166        /* Kernel memory accessed by userland? */
    8168         if (   !(fFlags & X86_PTE_US)
     8167        if (   !(Walk.fEffective & X86_PTE_US)
    81698168            && pVCpu->iem.s.uCpl == 3
    81708169            && !(fAccess & IEM_ACCESS_WHAT_SYS))
     
    81778176        /* Executing non-executable memory? */
    81788177        if (   (fAccess & IEM_ACCESS_TYPE_EXEC)
    8179             && (fFlags & X86_PTE_PAE_NX)
     8178            && (Walk.fEffective & X86_PTE_PAE_NX)
    81808179            && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE) )
    81818180        {
     
    81938192    /** @todo testcase: check when A and D bits are actually set by the CPU.  */
    81948193    uint32_t fAccessedDirty = fAccess & IEM_ACCESS_TYPE_WRITE ? X86_PTE_D | X86_PTE_A : X86_PTE_A;
    8195     if ((fFlags & fAccessedDirty) != fAccessedDirty)
     8194    if ((Walk.fEffective & fAccessedDirty) != fAccessedDirty)
    81968195    {
    81978196        int rc2 = PGMGstModifyPage(pVCpu, GCPtrMem, 1, fAccessedDirty, ~(uint64_t)fAccessedDirty);
     
    81998198    }
    82008199
    8201     GCPhys |= GCPtrMem & PAGE_OFFSET_MASK;
     8200    RTGCPHYS const GCPhys = Walk.GCPhys | (GCPtrMem & PAGE_OFFSET_MASK);
    82028201    *pGCPhysMem = GCPhys;
    82038202    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMAll/PGMAll.cpp

    r92344 r92426  
    5151DECLINLINE(int) pgmShwGetPaePoolPagePD(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPOOLPAGE *ppShwPde);
    5252#ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
    53 static int pgmGstSlatWalk(PVMCPUCC pVCpu, RTGCPHYS GCPhysNested, bool fIsLinearAddrValid, RTGCPTR GCPtrNested, PPGMPTWALKGST pWalk);
     53static int pgmGstSlatWalk(PVMCPUCC pVCpu, RTGCPHYS GCPhysNested, bool fIsLinearAddrValid, RTGCPTR GCPtrNested, PPGMPTWALK pWalk,
     54                          PPGMPTWALKGST pGstWalk);
    5455#endif
    5556static int pgmShwSyncLongModePDPtr(PVMCPUCC pVCpu, RTGCPTR64 GCPtr, X86PGPAEUINT uGstPml4e, X86PGPAEUINT uGstPdpe, PX86PDPAE *ppPD);
     
    17231724 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
    17241725 * @param   GCPtr       Guest Context virtual address of the page.
    1725  * @param   pfFlags     Where to store the flags. These are X86_PTE_*, even for big pages.
    1726  * @param   pGCPhys     Where to store the GC physical address of the page.
    1727  *                      This is page aligned. The fact that the
    1728  */
    1729 VMMDECL(int) PGMGstGetPage(PVMCPUCC pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)
     1726 * @param   pWalk       Where to store the page walk information.
     1727 */
     1728VMMDECL(int) PGMGstGetPage(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk)
    17301729{
    17311730    VMCPU_ASSERT_EMT(pVCpu);
     1731    Assert(pWalk);
     1732    RT_BZERO(pWalk, sizeof(*pWalk));
    17321733    uintptr_t idx = pVCpu->pgm.s.idxGuestModeData;
    17331734    AssertReturn(idx < RT_ELEMENTS(g_aPgmGuestModeData), VERR_PGM_MODE_IPE);
    17341735    AssertReturn(g_aPgmGuestModeData[idx].pfnGetPage, VERR_PGM_MODE_IPE);
    1735     return g_aPgmGuestModeData[idx].pfnGetPage(pVCpu, GCPtr, pfFlags, pGCPhys);
     1736    return g_aPgmGuestModeData[idx].pfnGetPage(pVCpu, GCPtr, pWalk);
    17361737}
    17371738
     
    17531754 * @param   pWalk       Where to return the walk result. This is valid for some
    17541755 *                      error codes as well.
    1755  */
    1756 int pgmGstPtWalk(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALKGST pWalk)
     1756 * @param   pGstWalk    The guest mode specific page walk information.
     1757 */
     1758int pgmGstPtWalk(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PPGMPTWALKGST pGstWalk)
    17571759{
    17581760    VMCPU_ASSERT_EMT(pVCpu);
     
    17601762    {
    17611763        case PGMMODE_32_BIT:
    1762             pWalk->enmType = PGMPTWALKGSTTYPE_32BIT;
    1763             return PGM_GST_NAME_32BIT(Walk)(pVCpu, GCPtr, &pWalk->u.Legacy);
     1764            pGstWalk->enmType = PGMPTWALKGSTTYPE_32BIT;
     1765            return PGM_GST_NAME_32BIT(Walk)(pVCpu, GCPtr, pWalk, &pGstWalk->u.Legacy);
    17641766
    17651767        case PGMMODE_PAE:
    17661768        case PGMMODE_PAE_NX:
    1767             pWalk->enmType = PGMPTWALKGSTTYPE_PAE;
    1768             return PGM_GST_NAME_PAE(Walk)(pVCpu, GCPtr, &pWalk->u.Pae);
     1769            pGstWalk->enmType = PGMPTWALKGSTTYPE_PAE;
     1770            return PGM_GST_NAME_PAE(Walk)(pVCpu, GCPtr, pWalk, &pGstWalk->u.Pae);
    17691771
    17701772        case PGMMODE_AMD64:
    17711773        case PGMMODE_AMD64_NX:
    1772             pWalk->enmType = PGMPTWALKGSTTYPE_AMD64;
    1773             return PGM_GST_NAME_AMD64(Walk)(pVCpu, GCPtr, &pWalk->u.Amd64);
     1774            pGstWalk->enmType = PGMPTWALKGSTTYPE_AMD64;
     1775            return PGM_GST_NAME_AMD64(Walk)(pVCpu, GCPtr, pWalk, &pGstWalk->u.Amd64);
    17741776
    17751777        case PGMMODE_REAL:
    17761778        case PGMMODE_PROTECTED:
    1777             pWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
     1779            pGstWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
    17781780            return VERR_PGM_NOT_USED_IN_MODE;
    17791781
     
    17841786        default:
    17851787            AssertFailed();
    1786             pWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
     1788            pGstWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
    17871789            return VERR_PGM_NOT_USED_IN_MODE;
    17881790    }
     
    18131815 * @param   pWalk               Where to return the walk result. This is valid for
    18141816 *                              some error codes as well.
     1817 * @param   pGstWalk            The second-level paging-mode specific walk
     1818 *                              information.
    18151819 */
    18161820static int pgmGstSlatWalk(PVMCPUCC pVCpu, RTGCPHYS GCPhysNested, bool fIsLinearAddrValid, RTGCPTR GCPtrNested,
    1817                           PPGMPTWALKGST pWalk)
    1818 {
    1819     Assert(pVCpu->pgm.s.enmGuestSlatMode != PGMSLAT_DIRECT);
     1821                          PPGMPTWALK pWalk, PPGMPTWALKGST pGstWalk)
     1822{
     1823    Assert(   pVCpu->pgm.s.enmGuestSlatMode != PGMSLAT_DIRECT
     1824           && pVCpu->pgm.s.enmGuestSlatMode != PGMSLAT_INVALID);
    18201825    switch (pVCpu->pgm.s.enmGuestSlatMode)
    18211826    {
    18221827        case PGMSLAT_EPT:
    1823             pWalk->enmType = PGMPTWALKGSTTYPE_EPT;
    1824             return PGM_GST_SLAT_NAME_EPT(Walk)(pVCpu, GCPhysNested, fIsLinearAddrValid, GCPtrNested, &pWalk->u.Ept);
     1828            pGstWalk->enmType = PGMPTWALKGSTTYPE_EPT;
     1829            return PGM_GST_SLAT_NAME_EPT(Walk)(pVCpu, GCPhysNested, fIsLinearAddrValid, GCPtrNested, pWalk, &pGstWalk->u.Ept);
    18251830
    18261831        default:
    18271832            AssertFailed();
    1828             pWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
     1833            pGstWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
    18291834            return VERR_PGM_NOT_USED_IN_MODE;
    18301835    }
     
    18511856 *                      the result of this walk.  This is valid for some error
    18521857 *                      codes as well.
    1853  */
    1854 int pgmGstPtWalkNext(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALKGST pWalk)
     1858 * @param   pGstWalk    The guest-mode specific walk information.
     1859 */
     1860int pgmGstPtWalkNext(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PPGMPTWALKGST pGstWalk)
    18551861{
    18561862    /*
     
    18581864     * We also limit ourselves to the next page.
    18591865     */
    1860     if (   pWalk->u.Core.fSucceeded
    1861         && GCPtr - pWalk->u.Core.GCPtr == PAGE_SIZE)
    1862     {
    1863         Assert(pWalk->u.Core.uLevel == 0);
    1864         if (pWalk->enmType == PGMPTWALKGSTTYPE_AMD64)
     1866    if (   pWalk->fSucceeded
     1867        && GCPtr - pWalk->GCPtr == PAGE_SIZE)
     1868    {
     1869        Assert(pWalk->uLevel == 0);
     1870        if (pGstWalk->enmType == PGMPTWALKGSTTYPE_AMD64)
    18651871        {
    18661872            /*
    18671873             * AMD64
    18681874             */
    1869             if (!pWalk->u.Core.fGigantPage && !pWalk->u.Core.fBigPage)
     1875            if (!pWalk->fGigantPage && !pWalk->fBigPage)
    18701876            {
    18711877                /*
     
    18781884                                        | X86_PDE_PCD | X86_PDE_A  | X86_PDE_PAE_NX | X86_PDE_PS;
    18791885
    1880                 if ((GCPtr >> X86_PD_PAE_SHIFT) == (pWalk->u.Core.GCPtr >> X86_PD_PAE_SHIFT))
     1886                if ((GCPtr >> X86_PD_PAE_SHIFT) == (pWalk->GCPtr >> X86_PD_PAE_SHIFT))
    18811887                {
    1882                     if (pWalk->u.Amd64.pPte)
     1888                    if (pGstWalk->u.Amd64.pPte)
    18831889                    {
    18841890                        X86PTEPAE Pte;
    1885                         Pte.u = pWalk->u.Amd64.pPte[1].u;
    1886                         if (   (Pte.u & fPteSame) == (pWalk->u.Amd64.Pte.u & fPteSame)
     1891                        Pte.u = pGstWalk->u.Amd64.pPte[1].u;
     1892                        if (   (Pte.u & fPteSame) == (pGstWalk->u.Amd64.Pte.u & fPteSame)
    18871893                            && !(Pte.u & (pVCpu)->pgm.s.fGstAmd64MbzPteMask))
    18881894                        {
    1889 
    1890                             pWalk->u.Core.GCPtr  = GCPtr;
    1891                             pWalk->u.Core.GCPhys = Pte.u & X86_PTE_PAE_PG_MASK;
    1892                             pWalk->u.Amd64.Pte.u = Pte.u;
    1893                             pWalk->u.Amd64.pPte++;
     1895                            pWalk->GCPtr  = GCPtr;
     1896                            pWalk->GCPhys = Pte.u & X86_PTE_PAE_PG_MASK;
     1897                            pGstWalk->u.Amd64.Pte.u = Pte.u;
     1898                            pGstWalk->u.Amd64.pPte++;
    18941899                            return VINF_SUCCESS;
    18951900                        }
    18961901                    }
    18971902                }
    1898                 else if ((GCPtr >> X86_PDPT_SHIFT) == (pWalk->u.Core.GCPtr >> X86_PDPT_SHIFT))
     1903                else if ((GCPtr >> X86_PDPT_SHIFT) == (pWalk->GCPtr >> X86_PDPT_SHIFT))
    18991904                {
    19001905                    Assert(!((GCPtr >> X86_PT_PAE_SHIFT) & X86_PT_PAE_MASK)); /* Must be first PT entry. */
    1901                     if (pWalk->u.Amd64.pPde)
     1906                    if (pGstWalk->u.Amd64.pPde)
    19021907                    {
    19031908                        X86PDEPAE Pde;
    1904                         Pde.u = pWalk->u.Amd64.pPde[1].u;
    1905                         if (   (Pde.u & fPdeSame) == (pWalk->u.Amd64.Pde.u & fPdeSame)
     1909                        Pde.u = pGstWalk->u.Amd64.pPde[1].u;
     1910                        if (   (Pde.u & fPdeSame) == (pGstWalk->u.Amd64.Pde.u & fPdeSame)
    19061911                            && !(Pde.u & (pVCpu)->pgm.s.fGstAmd64MbzPdeMask))
    19071912                        {
    19081913                            /* Get the new PTE and check out the first entry. */
    19091914                            int rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, PGM_A20_APPLY(pVCpu, (Pde.u & X86_PDE_PAE_PG_MASK)),
    1910                                                                &pWalk->u.Amd64.pPt);
     1915                                                               &pGstWalk->u.Amd64.pPt);
    19111916                            if (RT_SUCCESS(rc))
    19121917                            {
    1913                                 pWalk->u.Amd64.pPte = &pWalk->u.Amd64.pPt->a[0];
     1918                                pGstWalk->u.Amd64.pPte = &pGstWalk->u.Amd64.pPt->a[0];
    19141919                                X86PTEPAE Pte;
    1915                                 Pte.u = pWalk->u.Amd64.pPte->u;
    1916                                 if (   (Pte.u & fPteSame) == (pWalk->u.Amd64.Pte.u & fPteSame)
     1920                                Pte.u = pGstWalk->u.Amd64.pPte->u;
     1921                                if (   (Pte.u & fPteSame) == (pGstWalk->u.Amd64.Pte.u & fPteSame)
    19171922                                    && !(Pte.u & (pVCpu)->pgm.s.fGstAmd64MbzPteMask))
    19181923                                {
    1919                                     pWalk->u.Core.GCPtr  = GCPtr;
    1920                                     pWalk->u.Core.GCPhys = Pte.u & X86_PTE_PAE_PG_MASK;
    1921                                     pWalk->u.Amd64.Pte.u = Pte.u;
    1922                                     pWalk->u.Amd64.Pde.u = Pde.u;
    1923                                     pWalk->u.Amd64.pPde++;
     1924                                    pWalk->GCPtr  = GCPtr;
     1925                                    pWalk->GCPhys = Pte.u & X86_PTE_PAE_PG_MASK;
     1926                                    pGstWalk->u.Amd64.Pte.u = Pte.u;
     1927                                    pGstWalk->u.Amd64.Pde.u = Pde.u;
     1928                                    pGstWalk->u.Amd64.pPde++;
    19241929                                    return VINF_SUCCESS;
    19251930                                }
     
    19291934                }
    19301935            }
    1931             else if (!pWalk->u.Core.fGigantPage)
     1936            else if (!pWalk->fGigantPage)
    19321937            {
    1933                 if ((GCPtr & X86_PAGE_2M_BASE_MASK) == (pWalk->u.Core.GCPtr & X86_PAGE_2M_BASE_MASK))
     1938                if ((GCPtr & X86_PAGE_2M_BASE_MASK) == (pWalk->GCPtr & X86_PAGE_2M_BASE_MASK))
    19341939                {
    1935                     pWalk->u.Core.GCPtr   = GCPtr;
    1936                     pWalk->u.Core.GCPhys += PAGE_SIZE;
     1940                    pWalk->GCPtr   = GCPtr;
     1941                    pWalk->GCPhys += PAGE_SIZE;
    19371942                    return VINF_SUCCESS;
    19381943                }
     
    19401945            else
    19411946            {
    1942                 if ((GCPtr & X86_PAGE_1G_BASE_MASK) == (pWalk->u.Core.GCPtr & X86_PAGE_1G_BASE_MASK))
     1947                if ((GCPtr & X86_PAGE_1G_BASE_MASK) == (pWalk->GCPtr & X86_PAGE_1G_BASE_MASK))
    19431948                {
    1944                     pWalk->u.Core.GCPtr   = GCPtr;
    1945                     pWalk->u.Core.GCPhys += PAGE_SIZE;
     1949                    pWalk->GCPtr   = GCPtr;
     1950                    pWalk->GCPhys += PAGE_SIZE;
    19461951                    return VINF_SUCCESS;
    19471952                }
     
    19501955    }
    19511956    /* Case we don't handle.  Do full walk. */
    1952     return pgmGstPtWalk(pVCpu, GCPtr, pWalk);
    1953 }
    1954 
    1955 
    1956 /**
    1957  * Checks if the page is present.
    1958  *
    1959  * @returns true if the page is present.
    1960  * @returns false if the page is not present.
    1961  * @param   pVCpu       The cross context virtual CPU structure.
    1962  * @param   GCPtr       Address within the page.
    1963  */
    1964 VMMDECL(bool) PGMGstIsPagePresent(PVMCPUCC pVCpu, RTGCPTR GCPtr)
    1965 {
    1966     VMCPU_ASSERT_EMT(pVCpu);
    1967     int rc = PGMGstGetPage(pVCpu, GCPtr, NULL, NULL);
    1968     return RT_SUCCESS(rc);
     1957    return pgmGstPtWalk(pVCpu, GCPtr, pWalk, pGstWalk);
    19691958}
    19701959
     
    31793168#ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
    31803169    /* Update the guest SLAT mode if it's a nested-guest. */
    3181     if (CPUMIsGuestVmxEptPagingEnabled(pVCpu))
    3182     {
    3183         if (PGMMODE_WITH_PAGING(enmGuestMode))
    3184             pVCpu->pgm.s.enmGuestSlatMode = PGMSLAT_EPT;
    3185         else
    3186             pVCpu->pgm.s.enmGuestSlatMode = PGMSLAT_DIRECT;
    3187     }
     3170    if (   CPUMIsGuestVmxEptPagingEnabled(pVCpu)
     3171        && PGMMODE_WITH_PAGING(enmGuestMode))
     3172        pVCpu->pgm.s.enmGuestSlatMode = PGMSLAT_EPT;
    31883173    else
    3189         Assert(pVCpu->pgm.s.enmGuestSlatMode == PGMSLAT_DIRECT);
     3174        pVCpu->pgm.s.enmGuestSlatMode = PGMSLAT_DIRECT;
    31903175#endif
    31913176
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r92381 r92426  
    170170 *
    171171 * @param   pVCpu           The cross context virtual CPU structure of the calling EMT.
    172  * @param   pGstWalk        The guest page table walk result.
     172 * @param   pWalk           The guest page table walk result.
    173173 * @param   uErr            The error code.
    174174 */
    175 PGM_BTH_DECL(VBOXSTRICTRC, Trap0eHandlerGuestFault)(PVMCPUCC pVCpu, PGSTPTWALK pGstWalk, RTGCUINT uErr)
     175PGM_BTH_DECL(VBOXSTRICTRC, Trap0eHandlerGuestFault)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, RTGCUINT uErr)
    176176{
    177177    /*
     
    181181                     ? uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US | X86_TRAP_PF_ID)
    182182                     : uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US);
    183     if (   pGstWalk->Core.fRsvdError
    184         || pGstWalk->Core.fBadPhysAddr)
     183    if (   pWalk->fRsvdError
     184        || pWalk->fBadPhysAddr)
    185185    {
    186186        uNewErr |= X86_TRAP_PF_RSVD | X86_TRAP_PF_P;
    187         Assert(!pGstWalk->Core.fNotPresent);
    188     }
    189     else if (!pGstWalk->Core.fNotPresent)
     187        Assert(!pWalk->fNotPresent);
     188    }
     189    else if (!pWalk->fNotPresent)
    190190        uNewErr |= X86_TRAP_PF_P;
    191191    TRPMSetErrorCode(pVCpu, uNewErr);
    192192
    193     LogFlow(("Guest trap; cr2=%RGv uErr=%RGv lvl=%d\n", pGstWalk->Core.GCPtr, uErr, pGstWalk->Core.uLevel));
     193    LogFlow(("Guest trap; cr2=%RGv uErr=%RGv lvl=%d\n", pWalk->GCPtr, uErr, pWalk->uLevel));
    194194    STAM_STATS({ pVCpu->pgmr0.s.pStatTrap0eAttributionR0 = &pVCpu->pgm.s.Stats.StatRZTrap0eTime2GuestTrap; });
    195195    return VINF_EM_RAW_GUEST_TRAP;
     
    211211 * @param   pvFault         The fault address.
    212212 * @param   pPage           The guest page at @a pvFault.
    213  * @param   pGstWalk        The guest page table walk result.
     213 * @param   pWalk           The guest page table walk result.
     214 * @param   pGstWalk        The guest paging-mode specific walk information.
    214215 * @param   pfLockTaken     PGM lock taken here or not (out).  This is true
    215216 *                          when we're called.
     
    218219                                                                RTGCPTR pvFault, PPGMPAGE pPage, bool *pfLockTaken
    219220# if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) || defined(DOXYGEN_RUNNING)
     221                                                                , PPGMPTWALK pWalk
    220222                                                                , PGSTPTWALK pGstWalk
    221223# endif
     
    234236         */
    235237# if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    236         const RTGCPHYS  GCPhysFault = pGstWalk->Core.GCPhys;
     238        const RTGCPHYS  GCPhysFault = pWalk->GCPhys;
    237239# else
    238240        const RTGCPHYS  GCPhysFault = PGM_A20_APPLY(pVCpu, (RTGCPHYS)pvFault);
     
    277279                && pCurType->enmKind != PGMPHYSHANDLERKIND_WRITE
    278280#   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    279                 && (pGstWalk->Core.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK))
    280                                               == PGM_PTATTRS_W_MASK  /** @todo Remove pGstWalk->Core.fEffectiveUS and X86_PTE_US further down in the sync code. */
     281                && (pWalk->fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK))
     282                                      == PGM_PTATTRS_W_MASK  /** @todo Remove pGstWalk->Core.fEffectiveUS and X86_PTE_US further down in the sync code. */
    281283#   endif
    282284               )
     
    418420     * Walk the guest page translation tables and check if it's a guest fault.
    419421     */
     422    PGMPTWALK Walk;
    420423    GSTPTWALK GstWalk;
    421     rc = PGM_GST_NAME(Walk)(pVCpu, pvFault, &GstWalk);
     424    rc = PGM_GST_NAME(Walk)(pVCpu, pvFault, &Walk, &GstWalk);
    422425    if (RT_FAILURE_NP(rc))
    423         return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &GstWalk, uErr));
     426        return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &Walk, uErr));
    424427
    425428    /* assert some GstWalk sanity. */
     
    432435    /*AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u)); - ditto */
    433436    /*AssertMsg(GstWalk.Core.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u)); - ditto */
    434     Assert(GstWalk.Core.fSucceeded);
     437    Assert(Walk.fSucceeded);
    435438
    436439    if (uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US | X86_TRAP_PF_ID))
    437440    {
    438441        if (    (   (uErr & X86_TRAP_PF_RW)
    439                  && !(GstWalk.Core.fEffective & PGM_PTATTRS_W_MASK)
     442                 && !(Walk.fEffective & PGM_PTATTRS_W_MASK)
    440443                 && (   (uErr & X86_TRAP_PF_US)
    441444                     || CPUMIsGuestR0WriteProtEnabled(pVCpu)) )
    442             ||  ((uErr & X86_TRAP_PF_US) && !(GstWalk.Core.fEffective & PGM_PTATTRS_US_MASK))
    443             ||  ((uErr & X86_TRAP_PF_ID) && (GstWalk.Core.fEffective & PGM_PTATTRS_NX_MASK))
     445            ||  ((uErr & X86_TRAP_PF_US) && !(Walk.fEffective & PGM_PTATTRS_US_MASK))
     446            ||  ((uErr & X86_TRAP_PF_ID) &&  (Walk.fEffective & PGM_PTATTRS_NX_MASK))
    444447           )
    445             return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &GstWalk, uErr));
     448            return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &Walk, uErr));
    446449    }
    447450
     
    468471    }
    469472#   endif
    470     if (GstWalk.Core.fBigPage)
     473    if (Walk.fBigPage)
    471474    {
    472475        Assert(GstWalk.Pde.u & X86_PDE_PS);
     
    521524        Assert(GstWalk.Pte.u == GstWalk.pPte->u);
    522525    }
     526#if 0
     527    /* Disabling this since it's not reliable for SMP, see @bugref{10092#c22}. */
    523528    AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u || GstWalk.pPte->u == GstWalk.pPde->u,
    524529              ("%RX64 %RX64 pPte=%p pPde=%p Pte=%RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u, GstWalk.pPte, GstWalk.pPde, (uint64_t)GstWalk.pPte->u));
     530#endif
     531
    525532#  else  /* !PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
    526533    GSTPDE const PdeSrcDummy = { X86_PDE_P | X86_PDE_US | X86_PDE_RW | X86_PDE_A}; /** @todo eliminate this */
     
    541548        PPGMPAGE pPage;
    542549#   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    543         rc = pgmPhysGetPageEx(pVM, GstWalk.Core.GCPhys, &pPage);
     550        rc = pgmPhysGetPageEx(pVM, Walk.GCPhys, &pPage);
    544551        if (RT_SUCCESS(rc) && PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage))
    545552            return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerDoAccessHandlers)(pVCpu, uErr, pRegFrame, pvFault, pPage,
    546                                                                                  pfLockTaken, &GstWalk));
     553                                                                                 pfLockTaken, &Walk, &GstWalk));
    547554        rc = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, 1, uErr);
    548555#   else
     
    618625#ifdef DEBUG_bird
    619626        AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u || GstWalk.pPte->u == GstWalk.pPde->u || pVM->cCpus > 1, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u)); // - triggers with smp w7 guests.
    620         AssertMsg(GstWalk.Core.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u || pVM->cCpus > 1, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u)); // - ditto.
     627        AssertMsg(Walk.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u || pVM->cCpus > 1, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u)); // - ditto.
    621628#endif
    622629    }
     
    669676     */
    670677#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    671     RTGCPHYS GCPhys = GstWalk.Core.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
     678    RTGCPHYS GCPhys = Walk.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
    672679#  else
    673680    RTGCPHYS GCPhys = PGM_A20_APPLY(pVCpu, (RTGCPHYS)pvFault & ~(RTGCPHYS)PAGE_OFFSET_MASK);
     
    694701# if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    695702        return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerDoAccessHandlers)(pVCpu, uErr, pRegFrame, pvFault, pPage, pfLockTaken,
    696                                                                              &GstWalk));
     703                                                                             &Walk, &GstWalk));
    697704# else
    698705        return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerDoAccessHandlers)(pVCpu, uErr, pRegFrame, pvFault, pPage, pfLockTaken));
     
    778785             * Check to see if we need to emulate the instruction if CR0.WP=0.
    779786             */
    780             if (    !(GstWalk.Core.fEffective & PGM_PTATTRS_W_MASK)
     787            if (    !(Walk.fEffective & PGM_PTATTRS_W_MASK)
    781788                &&  (CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG
    782789                &&  CPUMGetGuestCPL(pVCpu) < 3)
     
    797804                 */
    798805#    if (PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_PAE) && 1
    799                 if (   (GstWalk.Core.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK)) == PGM_PTATTRS_US_MASK
    800                     && (GstWalk.Core.fBigPage || (GstWalk.Pde.u & X86_PDE_RW))
     806                if (   (Walk.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK)) == PGM_PTATTRS_US_MASK
     807                    && (Walk.fBigPage || (GstWalk.Pde.u & X86_PDE_RW))
    801808                    && pVM->cCpus == 1 /* Sorry, no go on SMP. Add CFGM option? */)
    802809                {
    803                     Log(("PGM #PF: Netware WP0+RO+US hack: pvFault=%RGp uErr=%#x (big=%d)\n", pvFault, uErr, GstWalk.Core.fBigPage));
    804                     rc = pgmShwMakePageSupervisorAndWritable(pVCpu, pvFault, GstWalk.Core.fBigPage, PGM_MK_PG_IS_WRITE_FAULT);
     810                    Log(("PGM #PF: Netware WP0+RO+US hack: pvFault=%RGp uErr=%#x (big=%d)\n", pvFault, uErr, Walk.fBigPage));
     811                    rc = pgmShwMakePageSupervisorAndWritable(pVCpu, pvFault, Walk.fBigPage, PGM_MK_PG_IS_WRITE_FAULT);
    805812                    if (rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3)
    806813                    {
     
    817824                /* Interpret the access. */
    818825                rc = VBOXSTRICTRC_TODO(PGMInterpretInstruction(pVM, pVCpu, pRegFrame, pvFault));
    819                 Log(("PGM #PF: WP0 emulation (pvFault=%RGp uErr=%#x cpl=%d fBig=%d fEffUs=%d)\n", pvFault, uErr, CPUMGetGuestCPL(pVCpu), GstWalk.Core.fBigPage, !!(GstWalk.Core.fEffective & PGM_PTATTRS_US_MASK)));
     826                Log(("PGM #PF: WP0 emulation (pvFault=%RGp uErr=%#x cpl=%d fBig=%d fEffUs=%d)\n", pvFault, uErr, CPUMGetGuestCPL(pVCpu), Walk.fBigPage, !!(Walk.fEffective & PGM_PTATTRS_US_MASK)));
    820827                if (RT_SUCCESS(rc))
    821828                    STAM_COUNTER_INC(&pVCpu->pgm.s.Stats.StatRZTrap0eWPEmulInRZ);
     
    855862#   endif
    856863#   ifdef VBOX_STRICT
    857                 RTGCPHYS GCPhys2 = RTGCPHYS_MAX;
    858                 uint64_t fPageGst = UINT64_MAX;
     864                PGMPTWALK GstPageWalk;
     865                GstPageWalk.GCPhys = RTGCPHYS_MAX;
    859866                if (!pVM->pgm.s.fNestedPaging)
    860867                {
    861                     rc = PGMGstGetPage(pVCpu, pvFault, &fPageGst, &GCPhys2);
    862                     AssertMsg(RT_SUCCESS(rc) && ((fPageGst & X86_PTE_RW) || ((CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG && CPUMGetGuestCPL(pVCpu) < 3)), ("rc=%Rrc fPageGst=%RX64\n", rc, fPageGst));
    863                     LogFlow(("Obsolete physical monitor page out of sync %RGv - phys %RGp flags=%08llx\n", pvFault, GCPhys2, (uint64_t)fPageGst));
     868                    rc = PGMGstGetPage(pVCpu, pvFault, &GstPageWalk);
     869                    AssertMsg(RT_SUCCESS(rc) && ((GstPageWalk.fEffective & X86_PTE_RW) || ((CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG && CPUMGetGuestCPL(pVCpu) < 3)), ("rc=%Rrc fPageGst=%RX64\n", rc, GstPageWalk.fEffective));
     870                    LogFlow(("Obsolete physical monitor page out of sync %RGv - phys %RGp flags=%08llx\n", pvFault, GstPageWalk.GCPhys, GstPageWalk.fEffective));
    864871                }
    865872#    if 0 /* Bogus! Triggers incorrectly with w7-64 and later for the SyncPage case: "Pde at %RGv changed behind our back?" */
     
    867874                rc = PGMShwGetPage(pVCpu, pvFault, &fPageShw, NULL);
    868875                AssertMsg((RT_SUCCESS(rc) && (fPageShw & X86_PTE_RW)) || pVM->cCpus > 1 /* new monitor can be installed/page table flushed between the trap exit and PGMTrap0eHandler */,
    869                           ("rc=%Rrc fPageShw=%RX64 GCPhys2=%RGp fPageGst=%RX64 pvFault=%RGv\n", rc, fPageShw, GCPhys2, fPageGst, pvFault));
     876                          ("rc=%Rrc fPageShw=%RX64 GCPhys2=%RGp fPageGst=%RX64 pvFault=%RGv\n", rc, fPageShw, GstPageWalk.GCPhys, fPageGst, pvFault));
    870877#    endif
    871878#   endif /* VBOX_STRICT */
     
    879886         * mode accesses the page again.
    880887         */
    881         else if (   (GstWalk.Core.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK)) == PGM_PTATTRS_US_MASK
    882                  && (GstWalk.Core.fBigPage || (GstWalk.Pde.u & X86_PDE_RW))
     888        else if (   (Walk.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK)) == PGM_PTATTRS_US_MASK
     889                 && (Walk.fBigPage || (GstWalk.Pde.u & X86_PDE_RW))
    883890                 &&  pVCpu->pgm.s.cNetwareWp0Hacks > 0
    884891                 &&  (CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG
     
    909916        {
    910917            /* Get guest page flags. */
    911             uint64_t fPageGst;
    912             int rc2 = PGMGstGetPage(pVCpu, pvFault, &fPageGst, NULL);
     918            PGMPTWALK GstPageWalk;
     919            int rc2 = PGMGstGetPage(pVCpu, pvFault, &GstPageWalk);
    913920            if (RT_SUCCESS(rc2))
    914921            {
  • trunk/src/VBox/VMM/VMMAll/PGMAllGst.h

    r92336 r92426  
    2424 || PGM_GST_TYPE == PGM_TYPE_PAE \
    2525 || PGM_GST_TYPE == PGM_TYPE_AMD64
    26 DECLINLINE(int) PGM_GST_NAME(Walk)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PGSTPTWALK pWalk);
    27 #endif
    28 PGM_GST_DECL(int,  GetPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys);
     26DECLINLINE(int) PGM_GST_NAME(Walk)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PGSTPTWALK pGstWalk);
     27#endif
     28PGM_GST_DECL(int,  GetPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk);
    2929PGM_GST_DECL(int,  ModifyPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
    3030
     
    7676
    7777
    78 DECLINLINE(int) PGM_GST_NAME(WalkReturnNotPresent)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel)
     78DECLINLINE(int) PGM_GST_NAME(WalkReturnNotPresent)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel)
    7979{
    8080    NOREF(iLevel); NOREF(pVCpu);
    81     pWalk->Core.fNotPresent     = true;
    82     pWalk->Core.uLevel          = (uint8_t)iLevel;
     81    pWalk->fNotPresent     = true;
     82    pWalk->uLevel          = (uint8_t)iLevel;
    8383    return VERR_PAGE_TABLE_NOT_PRESENT;
    8484}
    8585
    86 DECLINLINE(int) PGM_GST_NAME(WalkReturnBadPhysAddr)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel, int rc)
     86DECLINLINE(int) PGM_GST_NAME(WalkReturnBadPhysAddr)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel, int rc)
    8787{
    8888    AssertMsg(rc == VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS, ("%Rrc\n", rc)); NOREF(rc); NOREF(pVCpu);
    89     pWalk->Core.fBadPhysAddr    = true;
    90     pWalk->Core.uLevel          = (uint8_t)iLevel;
     89    pWalk->fBadPhysAddr    = true;
     90    pWalk->uLevel          = (uint8_t)iLevel;
    9191    return VERR_PAGE_TABLE_NOT_PRESENT;
    9292}
    9393
    94 DECLINLINE(int) PGM_GST_NAME(WalkReturnRsvdError)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel)
     94DECLINLINE(int) PGM_GST_NAME(WalkReturnRsvdError)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel)
    9595{
    9696    NOREF(pVCpu);
    97     pWalk->Core.fRsvdError      = true;
    98     pWalk->Core.uLevel          = (uint8_t)iLevel;
     97    pWalk->fRsvdError      = true;
     98    pWalk->uLevel          = (uint8_t)iLevel;
    9999    return VERR_PAGE_TABLE_NOT_PRESENT;
    100100}
     
    110110 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
    111111 * @param   GCPtr       The guest virtual address to walk by.
    112  * @param   pWalk       Where to return the walk result. This is always set.
    113  */
    114 DECLINLINE(int) PGM_GST_NAME(Walk)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PGSTPTWALK pWalk)
     112 * @param   pWalk       The common page walk information.
     113 * @param   pGstWalk    The guest mode specific page walk information.
     114 *
     115 * @warning Callers must initialize @a pWalk and @a pGstWalk before calling this
     116 *          function.
     117 */
     118DECLINLINE(int) PGM_GST_NAME(Walk)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PGSTPTWALK pGstWalk)
    115119{
    116120    int rc;
    117121
    118122#ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     123/** @def PGM_GST_SLAT_WALK
     124 * Macro to perform guest second-level address translation (EPT or Nested).
     125 *
     126 * @param   pVCpu           The cross context virtual CPU structure of the calling EMT.
     127 * @param   a_GCPtrNested   The nested-guest linear address that caused the
     128 *                          second-level translation.
     129 * @param   a_GCPhysNested  The nested-guest physical address to translate.
     130 * @param   a_GCPhysOut     Where to store the guest-physical address (result).
     131 */
    119132# define PGM_GST_SLAT_WALK(a_pVCpu, a_GCPtrNested, a_GCPhysNested, a_GCPhysOut, a_pWalk) \
    120133    do { \
    121134        if ((a_pVCpu)->pgm.s.enmGuestSlatMode != PGMSLAT_DIRECT) \
    122135        { \
    123             PGMPTWALKGST SlatWalk; \
    124             int const rcX = pgmGstSlatWalk(a_pVCpu, a_GCPhysNested, true /* fIsLinearAddrValid */, a_GCPtrNested, &SlatWalk); \
     136            PGMPTWALK    SlatWalk; \
     137            PGMPTWALKGST SlatGstWalk; \
     138            int const rcX = pgmGstSlatWalk(a_pVCpu, a_GCPhysNested, true /* fIsLinearAddrValid */, a_GCPtrNested, &SlatWalk, \
     139                                           &SlatGstWalk); \
    125140            if (RT_SUCCESS(rcX)) \
    126                 (a_GCPhysOut) = SlatWalk.u.Core.GCPhys; \
     141                (a_GCPhysOut) = SlatWalk.GCPhys; \
    127142            else \
    128143            { \
    129                 (a_pWalk)->Core = SlatWalk.u.Core; \
     144                *(a_pWalk) = SlatWalk; \
    130145                return rcX; \
    131146            } \
     
    135150
    136151    /*
    137      * Init the walking structure.
     152     * Init the walking structures.
    138153     */
    139154    RT_ZERO(*pWalk);
    140     pWalk->Core.GCPtr = GCPtr;
     155    RT_ZERO(*pGstWalk);
     156    pWalk->GCPtr = GCPtr;
    141157
    142158# if PGM_GST_TYPE == PGM_TYPE_32BIT \
     
    155171         * The PML4 table.
    156172         */
    157         rc = pgmGstGetLongModePML4PtrEx(pVCpu, &pWalk->pPml4);
     173        rc = pgmGstGetLongModePML4PtrEx(pVCpu, &pGstWalk->pPml4);
    158174        if (RT_SUCCESS(rc)) { /* probable */ }
    159175        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 4, rc);
    160176
    161177        PX86PML4E pPml4e;
    162         pWalk->pPml4e  = pPml4e  = &pWalk->pPml4->a[(GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK];
     178        pGstWalk->pPml4e  = pPml4e  = &pGstWalk->pPml4->a[(GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK];
    163179        X86PML4E  Pml4e;
    164         pWalk->Pml4e.u = Pml4e.u = pPml4e->u;
     180        pGstWalk->Pml4e.u = Pml4e.u = pPml4e->u;
    165181
    166182        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pml4e)) { /* probable */ }
     
    170186        else return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 4);
    171187
    172         pWalk->Core.fEffective = fEffective = Pml4e.u & (  X86_PML4E_P   | X86_PML4E_RW | X86_PML4E_US | X86_PML4E_PWT
    173                                                          | X86_PML4E_PCD | X86_PML4E_A  | X86_PML4E_NX);
     188        pWalk->fEffective = fEffective = Pml4e.u & (  X86_PML4E_P   | X86_PML4E_RW | X86_PML4E_US | X86_PML4E_PWT
     189                                                    | X86_PML4E_PCD | X86_PML4E_A  | X86_PML4E_NX);
    174190
    175191        /*
     
    180196        PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPdpt, GCPhysPdpt, pWalk);
    181197#endif
    182         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPdpt, &pWalk->pPdpt);
     198        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPdpt, &pGstWalk->pPdpt);
    183199        if (RT_SUCCESS(rc)) { /* probable */ }
    184200        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 3, rc);
    185201
    186202# elif PGM_GST_TYPE == PGM_TYPE_PAE
    187         rc = pgmGstGetPaePDPTPtrEx(pVCpu, &pWalk->pPdpt);
     203        rc = pgmGstGetPaePDPTPtrEx(pVCpu, &pGstWalk->pPdpt);
    188204        if (RT_SUCCESS(rc)) { /* probable */ }
    189205        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 8, rc);
     
    193209# if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
    194210        PX86PDPE pPdpe;
    195         pWalk->pPdpe  = pPdpe  = &pWalk->pPdpt->a[(GCPtr >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
     211        pGstWalk->pPdpe  = pPdpe  = &pGstWalk->pPdpt->a[(GCPtr >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
    196212        X86PDPE  Pdpe;
    197         pWalk->Pdpe.u = Pdpe.u = pPdpe->u;
     213        pGstWalk->Pdpe.u = Pdpe.u = pPdpe->u;
    198214
    199215        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pdpe)) { /* probable */ }
     
    204220
    205221# if PGM_GST_TYPE == PGM_TYPE_AMD64
    206         pWalk->Core.fEffective = fEffective &= (Pdpe.u & (  X86_PDPE_P   | X86_PDPE_RW  | X86_PDPE_US
    207                                                           | X86_PDPE_PWT | X86_PDPE_PCD | X86_PDPE_A))
    208                                              | (Pdpe.u & X86_PDPE_LM_NX);
     222        pWalk->fEffective = fEffective &= (Pdpe.u & (  X86_PDPE_P   | X86_PDPE_RW  | X86_PDPE_US
     223                                                     | X86_PDPE_PWT | X86_PDPE_PCD | X86_PDPE_A))
     224                                        | (Pdpe.u & X86_PDPE_LM_NX);
    209225# else
    210226        /* NX in the legacy-mode PAE PDPE is reserved. The valid check above ensures the NX bit is not set. */
    211         pWalk->Core.fEffective = fEffective  = X86_PDPE_P | X86_PDPE_RW  | X86_PDPE_US | X86_PDPE_A
    212                                              | (Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD));
     227        pWalk->fEffective = fEffective  = X86_PDPE_P | X86_PDPE_RW  | X86_PDPE_US | X86_PDPE_A
     228                                        | (Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD));
    213229# endif
    214230
     
    220236        PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPd, GCPhysPd, pWalk);
    221237# endif
    222         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPd, &pWalk->pPd);
     238        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPd, &pGstWalk->pPd);
    223239        if (RT_SUCCESS(rc)) { /* probable */ }
    224240        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 2, rc);
    225241
    226242# elif PGM_GST_TYPE == PGM_TYPE_32BIT
    227         rc = pgmGstGet32bitPDPtrEx(pVCpu, &pWalk->pPd);
     243        rc = pgmGstGet32bitPDPtrEx(pVCpu, &pGstWalk->pPd);
    228244        if (RT_SUCCESS(rc)) { /* probable */ }
    229245        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 8, rc);
     
    232248    {
    233249        PGSTPDE pPde;
    234         pWalk->pPde  = pPde  = &pWalk->pPd->a[(GCPtr >> GST_PD_SHIFT) & GST_PD_MASK];
     250        pGstWalk->pPde  = pPde  = &pGstWalk->pPd->a[(GCPtr >> GST_PD_SHIFT) & GST_PD_MASK];
    235251        GSTPDE  Pde;
    236         pWalk->Pde.u = Pde.u = pPde->u;
     252        pGstWalk->Pde.u = Pde.u = pPde->u;
    237253        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pde)) { /* probable */ }
    238254        else return PGM_GST_NAME(WalkReturnNotPresent)(pVCpu, pWalk, 2);
     
    253269            fEffective |= Pde.u & (X86_PDE4M_D | X86_PDE4M_G);
    254270            fEffective |= (Pde.u & X86_PDE4M_PAT) >> X86_PDE4M_PAT_SHIFT;
    255             pWalk->Core.fEffective = fEffective;
     271            pWalk->fEffective = fEffective;
    256272            Assert(GST_IS_NX_ACTIVE(pVCpu) || !(fEffective & PGM_PTATTRS_NX_MASK));
    257273            Assert(fEffective & PGM_PTATTRS_R_MASK);
    258274
    259             pWalk->Core.fBigPage   = true;
    260             pWalk->Core.fSucceeded = true;
     275            pWalk->fBigPage   = true;
     276            pWalk->fSucceeded = true;
    261277            RTGCPHYS GCPhysPde = GST_GET_BIG_PDE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pde)
    262278                               | (GCPtr & GST_BIG_PAGE_OFFSET_MASK);
     
    264280            PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPde, GCPhysPde, pWalk);
    265281# endif
    266             pWalk->Core.GCPhys     = GCPhysPde;
    267             PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->Core.GCPhys);
     282            pWalk->GCPhys     = GCPhysPde;
     283            PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->GCPhys);
    268284            return VINF_SUCCESS;
    269285        }
     
    272288            return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 2);
    273289# if PGM_GST_TYPE == PGM_TYPE_32BIT
    274         pWalk->Core.fEffective = fEffective  = Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
    275                                                         | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A);
     290        pWalk->fEffective = fEffective  = Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
     291                                                   | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A);
    276292# else
    277         pWalk->Core.fEffective = fEffective &= (Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
    278                                                          | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A))
    279                                              | (Pde.u & X86_PDE_PAE_NX);
     293        pWalk->fEffective = fEffective &= (Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
     294                                                    | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A))
     295                                        | (Pde.u & X86_PDE_PAE_NX);
    280296# endif
    281297
     
    287303        PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPt, GCPhysPt, pWalk);
    288304# endif
    289         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPt, &pWalk->pPt);
     305        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPt, &pGstWalk->pPt);
    290306        if (RT_SUCCESS(rc)) { /* probable */ }
    291307        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 1, rc);
     
    293309    {
    294310        PGSTPTE pPte;
    295         pWalk->pPte  = pPte  = &pWalk->pPt->a[(GCPtr >> GST_PT_SHIFT) & GST_PT_MASK];
     311        pGstWalk->pPte  = pPte  = &pGstWalk->pPt->a[(GCPtr >> GST_PT_SHIFT) & GST_PT_MASK];
    296312        GSTPTE  Pte;
    297         pWalk->Pte.u = Pte.u = pPte->u;
     313        pGstWalk->Pte.u = Pte.u = pPte->u;
    298314
    299315        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pte)) { /* probable */ }
     
    313329# endif
    314330        fEffective |= Pte.u & (X86_PTE_D | X86_PTE_PAT | X86_PTE_G);
    315         pWalk->Core.fEffective = fEffective;
     331        pWalk->fEffective = fEffective;
    316332        Assert(GST_IS_NX_ACTIVE(pVCpu) || !(fEffective & PGM_PTATTRS_NX_MASK));
    317333        Assert(fEffective & PGM_PTATTRS_R_MASK);
    318334
    319         pWalk->Core.fSucceeded = true;
     335        pWalk->fSucceeded = true;
    320336        RTGCPHYS GCPhysPte = GST_GET_PTE_GCPHYS(Pte)
    321337                           | (GCPtr & PAGE_OFFSET_MASK);
     
    323339        PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPte, GCPhysPte, pWalk);
    324340# endif
    325         pWalk->Core.GCPhys     = GCPhysPte;
     341        pWalk->GCPhys     = GCPhysPte;
    326342        return VINF_SUCCESS;
    327343    }
     
    341357 * @param   pVCpu       The cross context virtual CPU structure.
    342358 * @param   GCPtr       Guest Context virtual address of the page.
    343  * @param   pfFlags     Where to store the flags. These are X86_PTE_*, even for big pages.
    344  * @param   pGCPhys     Where to store the GC physical address of the page.
    345  *                      This is page aligned!
    346  */
    347 PGM_GST_DECL(int, GetPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)
     359 * @param   pWalk       Where to store the page walk info.
     360 */
     361PGM_GST_DECL(int, GetPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk)
    348362{
    349363#if PGM_GST_TYPE == PGM_TYPE_REAL \
     
    352366     * Fake it.
    353367     */
    354     if (pfFlags)
    355         *pfFlags = X86_PTE_P | X86_PTE_RW | X86_PTE_US;
    356     if (pGCPhys)
    357         *pGCPhys = GCPtr & PAGE_BASE_GC_MASK;
     368    RT_ZERO(*pWalk);
     369    pWalk->fSucceeded = true;
     370    pWalk->GCPtr      = GCPtr;
     371    pWalk->GCPhys     = GCPtr & PAGE_BASE_GC_MASK;
     372    pWalk->fEffective = X86_PTE_P | X86_PTE_RW | X86_PTE_US;
     373    pWalk->GCPhys     = GCPtr & PAGE_BASE_GC_MASK;
    358374    NOREF(pVCpu);
    359375    return VINF_SUCCESS;
     
    363379   || PGM_GST_TYPE == PGM_TYPE_AMD64
    364380
    365     GSTPTWALK Walk;
    366     int rc = PGM_GST_NAME(Walk)(pVCpu, GCPtr, &Walk);
     381    PGMPTWALK Walk;
     382    GSTPTWALK GstWalk;
     383    RT_ZERO(Walk);
     384    RT_ZERO(GstWalk);
     385    int rc = PGM_GST_NAME(Walk)(pVCpu, GCPtr, &Walk, &GstWalk);
    367386    if (RT_FAILURE(rc))
    368387        return rc;
    369388
    370     if (pGCPhys)
    371         *pGCPhys = Walk.Core.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
    372 
    373     if (pfFlags)
     389    uint64_t fFlags;
     390    if (!Walk.fBigPage)
     391        fFlags = (GstWalk.Pte.u & ~(GST_PTE_PG_MASK | X86_PTE_RW | X86_PTE_US))                      /* NX not needed */
     392               | (Walk.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK))
     393# if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
     394               | (Walk.fEffective & PGM_PTATTRS_NX_MASK)
     395# endif
     396                 ;
     397    else
    374398    {
    375         if (!Walk.Core.fBigPage)
    376             *pfFlags = (Walk.Pte.u & ~(GST_PTE_PG_MASK | X86_PTE_RW | X86_PTE_US))                      /* NX not needed */
    377                      | (Walk.Core.fEffective & (  PGM_PTATTRS_W_MASK
    378                                                 | PGM_PTATTRS_US_MASK))
     399        fFlags = (GstWalk.Pde.u & ~(GST_PTE_PG_MASK | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PS))   /* NX not needed */
     400               | (Walk.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK | PGM_PTATTRS_PAT_MASK))
    379401# if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
    380                      | (Walk.Core.fEffective & PGM_PTATTRS_NX_MASK)
    381 # endif
    382                      ;
    383         else
    384         {
    385             *pfFlags = (Walk.Pde.u & ~(GST_PTE_PG_MASK | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PS))   /* NX not needed */
    386                      | (Walk.Core.fEffective & (  PGM_PTATTRS_W_MASK
    387                                                 | PGM_PTATTRS_US_MASK
    388                                                 | PGM_PTATTRS_PAT_MASK))
    389 # if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
    390                      | (Walk.Core.fEffective & PGM_PTATTRS_NX_MASK)
    391 # endif
    392                      ;
    393         }
     402               | (Walk.fEffective & PGM_PTATTRS_NX_MASK)
     403# endif
     404               ;
    394405    }
    395406
     407    pWalk->fSucceeded = true;
     408    pWalk->GCPtr      = GCPtr;
     409    pWalk->GCPhys     = Walk.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
     410    pWalk->fEffective = fFlags;
    396411    return VINF_SUCCESS;
    397412
     
    425440    for (;;)
    426441    {
    427         GSTPTWALK Walk;
    428         int rc = PGM_GST_NAME(Walk)(pVCpu, GCPtr, &Walk);
     442        PGMPTWALK Walk;
     443        GSTPTWALK GstWalk;
     444        int rc = PGM_GST_NAME(Walk)(pVCpu, GCPtr, &Walk, &GstWalk);
    429445        if (RT_FAILURE(rc))
    430446            return rc;
    431447
    432         if (!Walk.Core.fBigPage)
     448        if (!Walk.fBigPage)
    433449        {
    434450            /*
     
    438454             */
    439455            unsigned iPTE = (GCPtr >> GST_PT_SHIFT) & GST_PT_MASK;
    440             while (iPTE < RT_ELEMENTS(Walk.pPt->a))
     456            while (iPTE < RT_ELEMENTS(GstWalk.pPt->a))
    441457            {
    442                 GSTPTE Pte = Walk.pPt->a[iPTE];
     458                GSTPTE Pte = GstWalk.pPt->a[iPTE];
    443459                Pte.u = (Pte.u & (fMask | X86_PTE_PAE_PG_MASK))
    444460                      | (fFlags & ~GST_PTE_PG_MASK);
    445                 Walk.pPt->a[iPTE] = Pte;
     461                GstWalk.pPt->a[iPTE] = Pte;
    446462
    447463                /* next page */
     
    460476            GSTPDE PdeNew;
    461477# if PGM_GST_TYPE == PGM_TYPE_32BIT
    462             PdeNew.u = (Walk.Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PG_HIGH_MASK | X86_PDE4M_PS))
     478            PdeNew.u = (GstWalk.Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PG_HIGH_MASK | X86_PDE4M_PS))
    463479# else
    464             PdeNew.u = (Walk.Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PS))
     480            PdeNew.u = (GstWalk.Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PS))
    465481# endif
    466482                     | (fFlags & ~GST_PTE_PG_MASK)
    467483                     | ((fFlags & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT);
    468             *Walk.pPde = PdeNew;
     484            *GstWalk.pPde = PdeNew;
    469485
    470486            /* advance */
  • trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h

    r92336 r92426  
    1717
    1818#if PGM_GST_TYPE == PGM_TYPE_EPT
    19 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel)
     19DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel)
    2020{
    2121    NOREF(pVCpu);
    22     pWalk->Core.fNotPresent     = true;
    23     pWalk->Core.uLevel          = (uint8_t)iLevel;
     22    pWalk->fNotPresent     = true;
     23    pWalk->uLevel          = (uint8_t)iLevel;
    2424    return VERR_PAGE_TABLE_NOT_PRESENT;
    2525}
    2626
    2727
    28 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel, int rc)
     28DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel, int rc)
    2929{
    3030    AssertMsg(rc == VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS, ("%Rrc\n", rc)); NOREF(rc); NOREF(pVCpu);
    31     pWalk->Core.fBadPhysAddr    = true;
    32     pWalk->Core.uLevel          = (uint8_t)iLevel;
     31    pWalk->fBadPhysAddr    = true;
     32    pWalk->uLevel          = (uint8_t)iLevel;
    3333    return VERR_PAGE_TABLE_NOT_PRESENT;
    3434}
    3535
    3636
    37 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel)
     37DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel)
    3838{
    3939    NOREF(pVCpu);
    40     pWalk->Core.fRsvdError      = true;
    41     pWalk->Core.uLevel          = (uint8_t)iLevel;
     40    pWalk->fRsvdError      = true;
     41    pWalk->uLevel          = (uint8_t)iLevel;
    4242    return VERR_PAGE_TABLE_NOT_PRESENT;
    4343}
     
    4545
    4646DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(Walk)(PVMCPUCC pVCpu, RTGCPHYS GCPhysNested, bool fIsLinearAddrValid, RTGCPTR GCPtrNested,
    47                                             PGSTPTWALK pWalk)
    48 {
     47                                            PPGMPTWALK pWalk, PGSTPTWALK pGstWalk)
     48{
     49    /** @todo implement figuring out fEptMisconfig. */
    4950    /*
    50      * Init walk structure.
     51     * Init walk structures.
    5152     */
    52     int rc;
    5353    RT_ZERO(*pWalk);
    54     pWalk->Core.GCPtr              = GCPtrNested;
    55     pWalk->Core.GCPhysNested       = GCPhysNested;
    56     pWalk->Core.fIsSlat            = true;
    57     pWalk->Core.fIsLinearAddrValid = fIsLinearAddrValid;
     54    RT_ZERO(*pGstWalk);
     55
     56    pWalk->GCPtr              = GCPtrNested;
     57    pWalk->GCPhysNested       = GCPhysNested;
     58    pWalk->fIsLinearAddrValid = fIsLinearAddrValid;
     59    pWalk->fIsSlat            = true;
    5860
    5961    /*
     
    8284    uint64_t fEffective;
    8385    {
    84         rc = pgmGstGetEptPML4PtrEx(pVCpu, &pWalk->pPml4);
     86        int rc = pgmGstGetEptPML4PtrEx(pVCpu, &pGstWalk->pPml4);
    8587        if (RT_SUCCESS(rc)) { /* probable */ }
    8688        else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 4, rc);
    8789
    8890        PEPTPML4E pPml4e;
    89         pWalk->pPml4e = pPml4e = &pWalk->pPml4->a[(GCPhysNested >> EPT_PML4_SHIFT) & EPT_PML4_MASK];
     91        pGstWalk->pPml4e = pPml4e = &pGstWalk->pPml4->a[(GCPhysNested >> EPT_PML4_SHIFT) & EPT_PML4_MASK];
    9092        EPTPML4E  Pml4e;
    91         pWalk->Pml4e.u = Pml4e.u = pPml4e->u;
     93        pGstWalk->Pml4e.u = Pml4e.u = pPml4e->u;
    9294
    9395        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pml4e)) { /* probable */ }
     
    107109                   | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
    108110                   | fEffectiveEpt;
    109         pWalk->Core.fEffective = fEffective;
    110 
    111         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pml4e.u & EPT_PML4E_PG_MASK, &pWalk->pPdpt);
     111        pWalk->fEffective = fEffective;
     112
     113        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pml4e.u & EPT_PML4E_PG_MASK, &pGstWalk->pPdpt);
    112114        if (RT_SUCCESS(rc)) { /* probable */ }
    113115        else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 3, rc);
     
    115117    {
    116118        PEPTPDPTE pPdpte;
    117         pWalk->pPdpte = pPdpte = &pWalk->pPdpt->a[(GCPhysNested >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
     119        pGstWalk->pPdpte = pPdpte = &pGstWalk->pPdpt->a[(GCPhysNested >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
    118120        EPTPDPTE  Pdpte;
    119         pWalk->Pdpte.u = Pdpte.u = pPdpte->u;
     121        pGstWalk->Pdpte.u = Pdpte.u = pPdpte->u;
    120122
    121123        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pdpte)) { /* probable */ }
     
    134136                        | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
    135137                        | (fEffectiveEpt & fCumulativeEpt);
    136             pWalk->Core.fEffective = fEffective;
     138            pWalk->fEffective = fEffective;
    137139        }
    138140        else if (GST_IS_BIG_PDPE_VALID(pVCpu, Pdpte))
     
    151153            fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    152154                        | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
    153             pWalk->Core.fEffective = fEffective;
    154 
    155             pWalk->Core.fGigantPage  = true;
    156             pWalk->Core.fSucceeded   = true;
    157             pWalk->Core.GCPhys       = GST_GET_BIG_PDPE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pdpte)
     155            pWalk->fEffective = fEffective;
     156
     157            pWalk->fGigantPage  = true;
     158            pWalk->fSucceeded   = true;
     159            pWalk->GCPhys       = GST_GET_BIG_PDPE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pdpte)
    158160                                     | (GCPhysNested & GST_GIGANT_PAGE_OFFSET_MASK);
    159             PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->Core.GCPhys);
     161            PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->GCPhys);
    160162            return VINF_SUCCESS;
    161163        }
     
    164166    {
    165167        PGSTPDE pPde;
    166         pWalk->pPde  = pPde  = &pWalk->pPd->a[(GCPhysNested >> GST_PD_SHIFT) & GST_PD_MASK];
     168        pGstWalk->pPde  = pPde  = &pGstWalk->pPd->a[(GCPhysNested >> GST_PD_SHIFT) & GST_PD_MASK];
    167169        GSTPDE  Pde;
    168         pWalk->Pde.u = Pde.u = pPde->u;
     170        pGstWalk->Pde.u = Pde.u = pPde->u;
     171
    169172        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pde)) { /* probable */ }
    170173        else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, 2);
     174
    171175        if ((Pde.u & X86_PDE_PS) && GST_IS_PSE_ACTIVE(pVCpu))
    172176        {
     
    187191            fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    188192                        | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
    189             pWalk->Core.fEffective = fEffective;
    190 
    191             pWalk->Core.fBigPage     = true;
    192             pWalk->Core.fSucceeded   = true;
    193             pWalk->Core.GCPhys       = GST_GET_BIG_PDE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pde)
     193            pWalk->fEffective = fEffective;
     194
     195            pWalk->fBigPage     = true;
     196            pWalk->fSucceeded   = true;
     197            pWalk->GCPhys       = GST_GET_BIG_PDE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pde)
    194198                                     | (GCPhysNested & GST_BIG_PAGE_OFFSET_MASK);
    195             PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->Core.GCPhys);
     199            PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->GCPhys);
    196200            return VINF_SUCCESS;
    197201        }
     
    209213                    | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
    210214                    | (fEffectiveEpt & fCumulativeEpt);
    211         pWalk->Core.fEffective = fEffective;
    212 
    213         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GST_GET_PDE_GCPHYS(Pde), &pWalk->pPt);
     215        pWalk->fEffective = fEffective;
     216
     217        int const rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GST_GET_PDE_GCPHYS(Pde), &pGstWalk->pPt);
    214218        if (RT_SUCCESS(rc)) { /* probable */ }
    215219        else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 1, rc);
     
    217221    {
    218222        PGSTPTE pPte;
    219         pWalk->pPte  = pPte  = &pWalk->pPt->a[(GCPhysNested >> GST_PT_SHIFT) & GST_PT_MASK];
     223        pGstWalk->pPte  = pPte  = &pGstWalk->pPt->a[(GCPhysNested >> GST_PT_SHIFT) & GST_PT_MASK];
    220224        GSTPTE  Pte;
    221         pWalk->Pte.u = Pte.u = pPte->u;
     225        pGstWalk->Pte.u = Pte.u = pPte->u;
    222226
    223227        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pte)) { /* probable */ }
     
    240244        fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    241245                    | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
    242         pWalk->Core.fEffective = fEffective;
    243 
    244         pWalk->Core.fSucceeded   = true;
    245         pWalk->Core.GCPhys       = GST_GET_PTE_GCPHYS(Pte)
    246                                  | (GCPhysNested & PAGE_OFFSET_MASK);
     246        pWalk->fEffective = fEffective;
     247
     248        pWalk->fSucceeded   = true;
     249        pWalk->GCPhys       = GST_GET_PTE_GCPHYS(Pte) | (GCPhysNested & PAGE_OFFSET_MASK);
    247250        return VINF_SUCCESS;
    248251    }
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r92391 r92426  
    23082308VMMDECL(int) PGMPhysGCPtr2GCPhys(PVMCPUCC pVCpu, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
    23092309{
    2310     int rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtr, NULL, pGCPhys);
     2310    PGMPTWALK Walk;
     2311    int rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtr, &Walk);
    23112312    if (pGCPhys && RT_SUCCESS(rc))
    2312         *pGCPhys |= (RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK;
     2313        *pGCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK);
    23132314    return rc;
    23142315}
     
    23272328VMM_INT_DECL(int) PGMPhysGCPtr2HCPhys(PVMCPUCC pVCpu, RTGCPTR GCPtr, PRTHCPHYS pHCPhys)
    23282329{
    2329     PVMCC pVM = pVCpu->CTX_SUFF(pVM);
    2330     RTGCPHYS GCPhys;
    2331     int rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtr, NULL, &GCPhys);
     2330    PVMCC     pVM = pVCpu->CTX_SUFF(pVM);
     2331    PGMPTWALK Walk;
     2332    int rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtr, &Walk);
    23322333    if (RT_SUCCESS(rc))
    2333         rc = PGMPhysGCPhys2HCPhys(pVM, GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), pHCPhys);
     2334        rc = PGMPhysGCPhys2HCPhys(pVM, Walk.GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), pHCPhys);
    23342335    return rc;
    23352336}
     
    34293430VMMDECL(VBOXSTRICTRC) PGMPhysReadGCPtr(PVMCPUCC pVCpu, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, PGMACCESSORIGIN enmOrigin)
    34303431{
    3431     RTGCPHYS    GCPhys;
    3432     uint64_t    fFlags;
    34333432    int         rc;
    34343433    PVMCC       pVM = pVCpu->CTX_SUFF(pVM);
     
    34493448    {
    34503449        /* Convert virtual to physical address + flags */
    3451         rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrSrc, &fFlags, &GCPhys);
     3450        PGMPTWALK Walk;
     3451        rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrSrc, &Walk);
    34523452        AssertMsgRCReturn(rc, ("GetPage failed with %Rrc for %RGv\n", rc, GCPtrSrc), rc);
    3453         GCPhys |= (RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK;
     3453        RTGCPHYS const GCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK);
    34543454
    34553455        /* mark the guest page as accessed. */
    3456         if (!(fFlags & X86_PTE_A))
     3456        if (!(Walk.fEffective & X86_PTE_A))
    34573457        {
    34583458            rc = PGMGstModifyPage(pVCpu, GCPtrSrc, 1, X86_PTE_A, ~(uint64_t)(X86_PTE_A));
     
    34693469    {
    34703470        /* Convert virtual to physical address + flags */
    3471         rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrSrc, &fFlags, &GCPhys);
     3471        PGMPTWALK Walk;
     3472        rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrSrc, &Walk);
    34723473        AssertMsgRCReturn(rc, ("GetPage failed with %Rrc for %RGv\n", rc, GCPtrSrc), rc);
    3473         GCPhys |= (RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK;
     3474        RTGCPHYS const GCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK);
    34743475
    34753476        /* mark the guest page as accessed. */
    3476         if (!(fFlags & X86_PTE_A))
     3477        if (!(Walk.fEffective & X86_PTE_A))
    34773478        {
    34783479            rc = PGMGstModifyPage(pVCpu, GCPtrSrc, 1, X86_PTE_A, ~(uint64_t)(X86_PTE_A));
     
    35203521VMMDECL(VBOXSTRICTRC) PGMPhysWriteGCPtr(PVMCPUCC pVCpu, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb, PGMACCESSORIGIN enmOrigin)
    35213522{
    3522     RTGCPHYS    GCPhys;
    3523     uint64_t    fFlags;
    35243523    int         rc;
    35253524    PVMCC       pVM = pVCpu->CTX_SUFF(pVM);
     
    35403539    {
    35413540        /* Convert virtual to physical address + flags */
    3542         rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrDst, &fFlags, &GCPhys);
     3541        PGMPTWALK Walk;
     3542        rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrDst, &Walk);
    35433543        AssertMsgRCReturn(rc, ("GetPage failed with %Rrc for %RGv\n", rc, GCPtrDst), rc);
    3544         GCPhys |= (RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK;
     3544        RTGCPHYS const GCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK);
    35453545
    35463546        /* Mention when we ignore X86_PTE_RW... */
    3547         if (!(fFlags & X86_PTE_RW))
     3547        if (!(Walk.fEffective & X86_PTE_RW))
    35483548            Log(("PGMPhysWriteGCPtr: Writing to RO page %RGv %#x\n", GCPtrDst, cb));
    35493549
    35503550        /* Mark the guest page as accessed and dirty if necessary. */
    3551         if ((fFlags & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
     3551        if ((Walk.fEffective & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
    35523552        {
    35533553            rc = PGMGstModifyPage(pVCpu, GCPtrDst, 1, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
     
    35643564    {
    35653565        /* Convert virtual to physical address + flags */
    3566         rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrDst, &fFlags, &GCPhys);
     3566        PGMPTWALK Walk;
     3567        rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrDst, &Walk);
    35673568        AssertMsgRCReturn(rc, ("GetPage failed with %Rrc for %RGv\n", rc, GCPtrDst), rc);
    3568         GCPhys |= (RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK;
     3569        RTGCPHYS const GCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK);
    35693570
    35703571        /* Mention when we ignore X86_PTE_RW... */
    3571         if (!(fFlags & X86_PTE_RW))
     3572        if (!(Walk.fEffective & X86_PTE_RW))
    35723573            Log(("PGMPhysWriteGCPtr: Writing to RO page %RGv %#x\n", GCPtrDst, cb));
    35733574
    35743575        /* Mark the guest page as accessed and dirty if necessary. */
    3575         if ((fFlags & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
     3576        if ((Walk.fEffective & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
    35763577        {
    35773578            rc = PGMGstModifyPage(pVCpu, GCPtrDst, 1, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
  • trunk/src/VBox/VMM/VMMAll/PGMAllShw.h

    r91854 r92426  
    569569                     *        set instead of resolving the guest physical
    570570                     *        address yet again. */
    571                     RTGCPHYS GCPhys;
    572                     uint64_t fGstPte;
    573                     rc = PGMGstGetPage(pVCpu, GCPtr, &fGstPte, &GCPhys);
     571                    PGMPTWALK GstWalk;
     572                    rc = PGMGstGetPage(pVCpu, GCPtr, &GstWalk);
    574573                    AssertRC(rc);
    575574                    if (RT_SUCCESS(rc))
    576575                    {
    577                         Assert((fGstPte & X86_PTE_RW) || !(CPUMGetGuestCR0(pVCpu) & X86_CR0_WP /* allow netware hack */));
    578                         PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
     576                        Assert((GstWalk.fEffective & X86_PTE_RW) || !(CPUMGetGuestCR0(pVCpu) & X86_CR0_WP /* allow netware hack */));
     577                        PPGMPAGE pPage = pgmPhysGetPage(pVM, GstWalk.GCPhys);
    579578                        Assert(pPage);
    580579                        if (pPage)
    581580                        {
    582                             rc = pgmPhysPageMakeWritable(pVM, pPage, GCPhys);
     581                            rc = pgmPhysPageMakeWritable(pVM, pPage, GstWalk.GCPhys);
    583582                            AssertRCReturn(rc, rc);
    584                             Log(("%s: pgmPhysPageMakeWritable on %RGv / %RGp %R[pgmpage]\n", __PRETTY_FUNCTION__, GCPtr, GCPhys, pPage));
     583                            Log(("%s: pgmPhysPageMakeWritable on %RGv / %RGp %R[pgmpage]\n", __PRETTY_FUNCTION__, GCPtr, GstWalk.GCPhys, pPage));
    585584                        }
    586585                    }
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