Changeset 86455 in vbox
- Timestamp:
- Oct 5, 2020 8:27:12 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
r86453 r86455 1723 1723 { 1724 1724 PVMCC pVM = pVCpu->CTX_SUFF(pVM); 1725 const unsigned iPml4 = (GCPtr >> EPT_PML4_SHIFT) & EPT_PML4_MASK;1726 1725 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool); 1727 PEPTPML4 pPml4;1728 PEPTPML4E pPml4e;1729 PPGMPOOLPAGE pShwPage;1730 1726 int rc; 1731 1727 … … 1733 1729 PGM_LOCK_ASSERT_OWNER(pVM); 1734 1730 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)); 1736 1736 Assert(pPml4); 1737 1737 1738 1738 /* 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 */ 1769 1775 const unsigned iPdPt = (GCPtr >> EPT_PDPT_SHIFT) & EPT_PDPT_MASK; 1770 1776 PEPTPDPT pPdpt = (PEPTPDPT)PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pShwPage); … … 1775 1781 1776 1782 /* 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))) 1779 1786 { 1780 1787 RTGCPTR64 GCPdPt = (RTGCPTR64)iPdPt << EPT_PDPT_SHIFT; … … 1783 1790 &pShwPage); 1784 1791 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); 1785 1795 } 1786 1796 else … … 1790 1800 1791 1801 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 } 1798 1809 1799 1810 *ppPD = (PEPTPD)PGMPOOL_PAGE_2_PTR_V2(pVM, pVCpu, pShwPage);
Note:
See TracChangeset
for help on using the changeset viewer.