VirtualBox

Changeset 86455 in vbox


Ignore:
Timestamp:
Oct 5, 2020 8:27:12 PM (4 years ago)
Author:
vboxsync
Message:

VMM/pgmShwGetEPTPDPtr: Don't use the bit fields as gcc may sometimes get them wrong (10), use new EPT_E_XXX constants instead. bugref:9841

File:
1 edited

Legend:

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

    r86453 r86455  
    17231723{
    17241724    PVMCC          pVM   = pVCpu->CTX_SUFF(pVM);
    1725     const unsigned iPml4 = (GCPtr >> EPT_PML4_SHIFT) & EPT_PML4_MASK;
    17261725    PPGMPOOL       pPool = pVM->pgm.s.CTX_SUFF(pPool);
    1727     PEPTPML4       pPml4;
    1728     PEPTPML4E      pPml4e;
    1729     PPGMPOOLPAGE   pShwPage;
    17301726    int            rc;
    17311727
     
    17331729    PGM_LOCK_ASSERT_OWNER(pVM);
    17341730
    1735     pPml4 = (PEPTPML4)PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3));
     1731    /*
     1732     * PML4 level.
     1733     */
     1734
     1735    PEPTPML4 pPml4 = (PEPTPML4)PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3));
    17361736    Assert(pPml4);
    17371737
    17381738    /* Allocate page directory pointer table if not present. */
    1739     pPml4e = &pPml4->a[iPml4];
    1740     if (    !pPml4e->n.u1Present
    1741         &&  !(pPml4e->u & EPT_PML4E_PG_MASK))
    1742     {
    1743         Assert(!(pPml4e->u & EPT_PML4E_PG_MASK));
    1744         RTGCPTR64 GCPml4 = (RTGCPTR64)iPml4 << EPT_PML4_SHIFT;
    1745 
    1746         rc = pgmPoolAlloc(pVM, GCPml4, PGMPOOLKIND_EPT_PDPT_FOR_PHYS, PGMPOOLACCESS_DONTCARE, PGM_A20_IS_ENABLED(pVCpu),
    1747                           pVCpu->pgm.s.CTX_SUFF(pShwPageCR3)->idx, iPml4, false /*fLockPage*/,
    1748                           &pShwPage);
    1749         AssertRCReturn(rc, rc);
    1750     }
    1751     else
    1752     {
    1753         pShwPage = pgmPoolGetPage(pPool, pPml4e->u & EPT_PML4E_PG_MASK);
    1754         AssertReturn(pShwPage, VERR_PGM_POOL_GET_PAGE_FAILED);
    1755 
    1756         pgmPoolCacheUsed(pPool, pShwPage);
    1757     }
    1758 
    1759     /* The PDPT was cached or created; hook it up now and fill with the default value. */
    1760 /** @todo r=bird: This is sub-optimal, gcc 10 generates a qword move of the address followed by
    1761  *        a byte write of the 0x7 flag value.  These two writes should be combined, but for that
    1762  *        we need to add/find the EPT flag defines. */
    1763 /** @todo r=bird: use atomic writes here and maybe only update if really needed? */
    1764     pPml4e->u           = pShwPage->Core.Key;
    1765     pPml4e->n.u1Present = 1;
    1766     pPml4e->n.u1Write   = 1;
    1767     pPml4e->n.u1Execute = 1;
    1768 
     1739    PPGMPOOLPAGE pShwPage;
     1740    {
     1741        const unsigned iPml4 = (GCPtr >> EPT_PML4_SHIFT) & EPT_PML4_MASK;
     1742        PEPTPML4E pPml4e = &pPml4->a[iPml4];
     1743        EPTPML4E Pml4e;
     1744        Pml4e.u = pPml4e->u;
     1745        if (!(Pml4e.u & (EPT_E_PG_MASK | EPT_E_READ)))
     1746        {
     1747            RTGCPTR64 GCPml4 = (RTGCPTR64)iPml4 << EPT_PML4_SHIFT;
     1748
     1749            rc = pgmPoolAlloc(pVM, GCPml4, PGMPOOLKIND_EPT_PDPT_FOR_PHYS, PGMPOOLACCESS_DONTCARE, PGM_A20_IS_ENABLED(pVCpu),
     1750                              pVCpu->pgm.s.CTX_SUFF(pShwPageCR3)->idx, iPml4, false /*fLockPage*/,
     1751                              &pShwPage);
     1752            AssertRCReturn(rc, rc);
     1753
     1754            /* Hook up the new PDPT now. */
     1755            ASMAtomicWriteU64(&pPml4e->u, pShwPage->Core.Key | EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE);
     1756        }
     1757        else
     1758        {
     1759            pShwPage = pgmPoolGetPage(pPool, pPml4e->u & EPT_PML4E_PG_MASK);
     1760            AssertReturn(pShwPage, VERR_PGM_POOL_GET_PAGE_FAILED);
     1761
     1762            pgmPoolCacheUsed(pPool, pShwPage);
     1763
     1764            /* Hook up the cached PDPT if needed (probably not given 512*512 PTs to sync). */
     1765            if (Pml4e.u == (pShwPage->Core.Key | EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE))
     1766            { }
     1767            else
     1768                ASMAtomicWriteU64(&pPml4e->u, pShwPage->Core.Key | EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE);
     1769        }
     1770    }
     1771
     1772    /*
     1773     * PDPT level.
     1774     */
    17691775    const unsigned iPdPt = (GCPtr >> EPT_PDPT_SHIFT) & EPT_PDPT_MASK;
    17701776    PEPTPDPT  pPdpt = (PEPTPDPT)PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pShwPage);
     
    17751781
    17761782    /* Allocate page directory if not present. */
    1777     if (    !pPdpe->n.u1Present
    1778         &&  !(pPdpe->u & EPT_PDPTE_PG_MASK))
     1783    EPTPDPTE Pdpe;
     1784    Pdpe.u = pPdpe->u;
     1785    if (!(Pdpe.u & (EPT_E_PG_MASK | EPT_E_READ)))
    17791786    {
    17801787        RTGCPTR64 GCPdPt = (RTGCPTR64)iPdPt << EPT_PDPT_SHIFT;
     
    17831790                          &pShwPage);
    17841791        AssertRCReturn(rc, rc);
     1792
     1793        /* Hook up the new PD now. */
     1794        ASMAtomicWriteU64(&pPdpe->u, pShwPage->Core.Key | EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE);
    17851795    }
    17861796    else
     
    17901800
    17911801        pgmPoolCacheUsed(pPool, pShwPage);
    1792     }
    1793     /* The PD was cached or created; hook it up now and fill with the default value. */
    1794     pPdpe->u            = pShwPage->Core.Key;
    1795     pPdpe->n.u1Present  = 1;
    1796     pPdpe->n.u1Write    = 1;
    1797     pPdpe->n.u1Execute  = 1;
     1802
     1803        /* Hook up the cached PD if needed (probably not given there are 512 PTs we may need sync). */
     1804        if (Pdpe.u == (pShwPage->Core.Key | EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE))
     1805        { }
     1806        else
     1807            ASMAtomicWriteU64(&pPdpe->u, pShwPage->Core.Key | EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE);
     1808    }
    17981809
    17991810    *ppPD = (PEPTPD)PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pShwPage);
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