| | 723 | /** |
|---|
| | 724 | * Syncs the SHADOW page directory pointer for the specified address. Allocates |
|---|
| | 725 | * backing pages in case the PDPT entry is missing. |
|---|
| | 726 | * |
|---|
| | 727 | * @returns VBox status. |
|---|
| | 728 | * @param pVM VM handle. |
|---|
| | 729 | * @param GCPtr The address. |
|---|
| | 730 | * @param pGstPdpe Guest PDPT entry |
|---|
| | 731 | * @param ppPD Receives address of page directory |
|---|
| | 732 | */ |
|---|
| | 733 | PGMDECL(int) PGMShwSyncPAEPDPtr(PVM pVM, RTGCUINTPTR GCPtr, PX86PDPE pGstPdpe, PX86PDPAE *ppPD) |
|---|
| | 734 | { |
|---|
| | 735 | PPGM pPGM = &pVM->pgm.s; |
|---|
| | 736 | PPGMPOOL pPool = pPGM->CTXSUFF(pPool); |
|---|
| | 737 | PPGMPOOLPAGE pShwPage; |
|---|
| | 738 | int rc; |
|---|
| | 739 | |
|---|
| | 740 | Assert(!HWACCMIsNestedPagingActive(pVM)); |
|---|
| | 741 | |
|---|
| | 742 | const unsigned iPdPt = (GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_PAE; |
|---|
| | 743 | PX86PDPT pPdpt = pVM->pgm.s.CTXMID(p,PaePDPT); |
|---|
| | 744 | PX86PDPE pPdpe = &pPdpt->a[iPdPt]; |
|---|
| | 745 | |
|---|
| | 746 | /* Allocate page directory if not present. */ |
|---|
| | 747 | if ( !pPdpe->n.u1Present |
|---|
| | 748 | && !(pPdpe->u & X86_PDPE_PG_MASK)) |
|---|
| | 749 | { |
|---|
| | 750 | PX86PDPE pPdptGst = &CTXSUFF(pPGM->pGstPaePDPT)->a[iPdPt]; |
|---|
| | 751 | |
|---|
| | 752 | Assert(!(pPdpe->u & X86_PDPE_PG_MASK)); |
|---|
| | 753 | /* Create a reference back to the PDPT by using the index in its shadow page. */ |
|---|
| | 754 | rc = pgmPoolAlloc(pVM, pPdptGst->u & X86_PDPE_PG_MASK, PGMPOOLKIND_PAE_PD_FOR_PAE_PD, PGMPOOL_IDX_PDPT, iPdPt, &pShwPage); |
|---|
| | 755 | if (rc == VERR_PGM_POOL_FLUSHED) |
|---|
| | 756 | return VINF_PGM_SYNC_CR3; |
|---|
| | 757 | |
|---|
| | 758 | AssertRCReturn(rc, rc); |
|---|
| | 759 | } |
|---|
| | 760 | else |
|---|
| | 761 | { |
|---|
| | 762 | pShwPage = pgmPoolGetPage(pPool, pPdpe->u & X86_PDPE_PG_MASK); |
|---|
| | 763 | AssertReturn(pShwPage, VERR_INTERNAL_ERROR); |
|---|
| | 764 | } |
|---|
| | 765 | /* The PD was cached or created; hook it up now. */ |
|---|
| | 766 | pPdpe->u |= pShwPage->Core.Key |
|---|
| | 767 | | (pGstPdpe->u & ~(X86_PDPE_PG_MASK | X86_PDPE_AVL_MASK | X86_PDPE_PCD | X86_PDPE_PWT)); |
|---|
| | 768 | |
|---|
| | 769 | *ppPD = (PX86PDPAE)PGMPOOL_PAGE_2_PTR(pVM, pShwPage); |
|---|
| | 770 | return VINF_SUCCESS; |
|---|
| | 771 | } |
|---|
| | 772 | |
|---|
| | 773 | /** |
|---|
| | 774 | * Gets the SHADOW page directory pointer for the specified address. |
|---|
| | 775 | * |
|---|
| | 776 | * @returns VBox status. |
|---|
| | 777 | * @param pVM VM handle. |
|---|
| | 778 | * @param GCPtr The address. |
|---|
| | 779 | * @param ppPdpt Receives address of pdpt |
|---|
| | 780 | * @param ppPD Receives address of page directory |
|---|
| | 781 | */ |
|---|
| | 782 | PGMDECL(int) PGMShwGetPAEPDPtr(PVM pVM, RTGCUINTPTR GCPtr, PX86PDPT *ppPdpt, PX86PDPAE *ppPD) |
|---|
| | 783 | { |
|---|
| | 784 | PPGM pPGM = &pVM->pgm.s; |
|---|
| | 785 | PPGMPOOL pPool = pPGM->CTXSUFF(pPool); |
|---|
| | 786 | PPGMPOOLPAGE pShwPage; |
|---|
| | 787 | |
|---|
| | 788 | Assert(!HWACCMIsNestedPagingActive(pVM)); |
|---|
| | 789 | |
|---|
| | 790 | const unsigned iPdPt = (GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_PAE; |
|---|
| | 791 | PX86PDPT pPdpt = pVM->pgm.s.CTXMID(p,PaePDPT); |
|---|
| | 792 | PX86PDPE pPdpe = &pPdpt->a[iPdPt]; |
|---|
| | 793 | |
|---|
| | 794 | *ppPdpt = pPdpt; |
|---|
| | 795 | if (!pPdpe->n.u1Present) |
|---|
| | 796 | return VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT; |
|---|
| | 797 | |
|---|
| | 798 | pShwPage = pgmPoolGetPage(pPool, pPdpe->u & X86_PDPE_PG_MASK); |
|---|
| | 799 | AssertReturn(pShwPage, VERR_INTERNAL_ERROR); |
|---|
| | 800 | |
|---|
| | 801 | *ppPD = (PX86PDPAE)PGMPOOL_PAGE_2_PTR(pVM, pShwPage); |
|---|
| | 802 | return VINF_SUCCESS; |
|---|
| | 803 | } |
|---|
| | 804 | |
|---|