Changeset 9869 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jun 23, 2008 12:38:16 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r9864 r9869 3076 3076 } 3077 3077 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3078 for (uint64_t iP ML4E = 0; iPML4E < X86_PG_PAE_ENTRIES; iPML4E++)3078 for (uint64_t iPml4e = 0; iPml4e < X86_PG_PAE_ENTRIES; iPml4e++) 3079 3079 { 3080 3080 PPGMPOOLPAGE pShwPdpt = NULL; … … 3082 3082 RTGCPHYS GCPhysPdptSrc; 3083 3083 3084 pPml4eSrc = &pVM->pgm.s.CTXSUFF(pGstPaePML4)->a[iP ML4E];3085 pPml4eDst = &pVM->pgm.s.CTXMID(p,PaePML4)->a[iP ML4E];3084 pPml4eSrc = &pVM->pgm.s.CTXSUFF(pGstPaePML4)->a[iPml4e]; 3085 pPml4eDst = &pVM->pgm.s.CTXMID(p,PaePML4)->a[iPml4e]; 3086 3086 3087 3087 /* Fetch the pgm pool shadow descriptor if the shadow pml4e is present. */ 3088 if (!pVM->pgm.s.CTXMID(p,PaePML4)->a[iP ML4E].n.u1Present)3088 if (!pVM->pgm.s.CTXMID(p,PaePML4)->a[iPml4e].n.u1Present) 3089 3089 continue; 3090 3090 pShwPdpt = pgmPoolGetPage(pPool, pPml4eDst->u & X86_PML4E_PG_MASK); … … 3098 3098 /* Free it. */ 3099 3099 LogFlow(("SyncCR3: Out-of-sync PML4E (GCPhys) GCPtr=%VGv %VGp vs %VGp PdpeSrc=%RX64 PdpeDst=%RX64\n", 3100 (uint64_t)iP ML4E<< X86_PML4_SHIFT, pShwPdpt->GCPhys, GCPhysPdptSrc, (uint64_t)pPml4eSrc->u, (uint64_t)pPml4eDst->u));3101 pgmPoolFreeByPage(pPool, pShwPdpt, PGMPOOL_IDX_PML4, iP ML4E);3100 (uint64_t)iPml4e << X86_PML4_SHIFT, pShwPdpt->GCPhys, GCPhysPdptSrc, (uint64_t)pPml4eSrc->u, (uint64_t)pPml4eDst->u)); 3101 pgmPoolFreeByPage(pPool, pShwPdpt, PGMPOOL_IDX_PML4, iPml4e); 3102 3102 pPml4eDst->u = 0; 3103 3103 continue; … … 3130 3130 PX86PDPAE pPDDst; 3131 3131 PX86PDEPAE pPDEDst; 3132 RTGCUINTPTR GCPtr = (iP ML4E<< X86_PML4_SHIFT) || (iPDPTE << X86_PDPT_SHIFT);3132 RTGCUINTPTR GCPtr = (iPml4e << X86_PML4_SHIFT) || (iPDPTE << X86_PDPT_SHIFT); 3133 3133 PGSTPD pPDSrc = pgmGstGetLongModePDPtr(&pVM->pgm.s, GCPtr, &pPml4eSrc, &PdpeSrc, &iPDSrc); 3134 3134 … … 3163 3163 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3164 3164 LogFlow(("SyncCR3: Out-of-sync PDPE (GCPhys) GCPtr=%VGv %VGp vs %VGp PdpeSrc=%RX64 PdpeDst=%RX64\n", 3165 ((uint64_t)iP ML4E<< X86_PML4_SHIFT) + ((uint64_t)iPDPTE << X86_PDPT_SHIFT), pShwPde->GCPhys, GCPhysPdeSrc, (uint64_t)PdpeSrc.u, (uint64_t)pPdpeDst->u));3165 ((uint64_t)iPml4e << X86_PML4_SHIFT) + ((uint64_t)iPDPTE << X86_PDPT_SHIFT), pShwPde->GCPhys, GCPhysPdeSrc, (uint64_t)PdpeSrc.u, (uint64_t)pPdpeDst->u)); 3166 3166 # else 3167 3167 LogFlow(("SyncCR3: Out-of-sync PDPE (GCPhys) GCPtr=%VGv %VGp vs %VGp PdpeSrc=%RX64 PdpeDst=%RX64\n", … … 3497 3497 3498 3498 #if PGM_GST_TYPE == PGM_TYPE_32BIT \ 3499 || PGM_GST_TYPE == PGM_TYPE_PAE 3499 || PGM_GST_TYPE == PGM_TYPE_PAE \ 3500 || PGM_GST_TYPE == PGM_TYPE_AMD64 3500 3501 3501 3502 # if PGM_GST_TYPE == PGM_TYPE_AMD64 … … 3536 3537 #endif /* !IN_RING0 */ 3537 3538 3538 # if PGM_GST_TYPE == PGM_TYPE_32BIT3539 const GSTPD *pPDSrc = CTXSUFF(pPGM->pGuestPD);3540 # endif3541 3542 3539 /* 3543 3540 * Get and check the Shadow CR3. 3544 3541 */ 3545 3542 # if PGM_SHW_TYPE == PGM_TYPE_32BIT 3546 const X86PD *pPDDst = pPGM->CTXMID(p,32BitPD); 3547 unsigned cPDEs = ELEMENTS(pPDDst->a); 3548 # else 3549 const X86PDPAE *pPDDst = pPGM->CTXMID(ap,PaePDs[0]); /* use it as a 2048 entry PD */ 3550 unsigned cPDEs = ELEMENTS(pPDDst->a) * ELEMENTS(pPGM->apHCPaePDs); 3543 unsigned cPDEs = X86_PG_ENTRIES; 3544 unsigned ulIncrement = X86_PG_ENTRIES * PAGE_SIZE; 3545 # elif PGM_SHW_TYPE == PGM_TYPE_PAE 3546 # if PGM_GST_TYPE == PGM_TYPE_32BIT 3547 unsigned cPDEs = X86_PG_PAE_ENTRIES * 4; /* treat it as a 2048 entry table. */ 3548 # else 3549 unsigned cPDEs = X86_PG_PAE_ENTRIES; 3550 # endif 3551 unsigned ulIncrement = X86_PG_PAE_ENTRIES * PAGE_SIZE; 3552 # elif PGM_SHW_TYPE == PGM_TYPE_AMD64 3553 unsigned cPDEs = X86_PG_PAE_ENTRIES; 3554 unsigned ulIncrement = X86_PG_PAE_ENTRIES * PAGE_SIZE; 3551 3555 # endif 3552 3556 if (cb != ~(RTGCUINTPTR)0) … … 3555 3559 /** @todo call the other two PGMAssert*() functions. */ 3556 3560 3557 # if PGM_GST_TYPE == PGM_TYPE_PAE 3558 /* 3559 * Check the 4 PDPTs too. 3560 */ 3561 for (unsigned i = 0; i < 4; i++) 3562 { 3563 RTHCPTR HCPtr; 3564 RTHCPHYS HCPhys; 3565 RTGCPHYS GCPhys = pVM->pgm.s.CTXSUFF(pGstPaePDPT)->a[i].u & X86_PDPE_PG_MASK; 3566 int rc2 = pgmRamGCPhys2HCPtrAndHCPhysWithFlags(&pVM->pgm.s, GCPhys, &HCPtr, &HCPhys); 3567 if (VBOX_SUCCESS(rc2)) 3568 { 3569 AssertMsg( pVM->pgm.s.apGstPaePDsHC[i] == (R3R0PTRTYPE(PX86PDPAE))HCPtr 3570 && pVM->pgm.s.aGCPhysGstPaePDs[i] == GCPhys, 3571 ("idx %d apGstPaePDsHC %VHv vs %VHv aGCPhysGstPaePDs %VGp vs %VGp\n", 3572 i, pVM->pgm.s.apGstPaePDsHC[i], HCPtr, pVM->pgm.s.aGCPhysGstPaePDs[i], GCPhys)); 3573 } 3574 } 3575 # endif 3576 3577 /* 3578 * Iterate the shadow page directory. 3579 */ 3580 GCPtr = (GCPtr >> SHW_PD_SHIFT) << SHW_PD_SHIFT; 3581 unsigned iPDDst = GCPtr >> SHW_PD_SHIFT; 3582 cPDEs += iPDDst; 3583 for (; 3584 iPDDst < cPDEs; 3585 iPDDst++, GCPtr += _4G / cPDEs) 3586 { 3587 # if PGM_GST_TYPE == PGM_TYPE_PAE 3588 uint32_t iPDSrc; 3589 PGSTPD pPDSrc = pgmGstGetPaePDPtr(pPGM, (RTGCUINTPTR)GCPtr, &iPDSrc); 3590 if (!pPDSrc) 3591 { 3592 AssertMsg(!pVM->pgm.s.CTXSUFF(pGstPaePDPT)->a[(GCPtr >> GST_PDPT_SHIFT) & GST_PDPT_MASK].n.u1Present, ("Guest PDTPR not present, shadow PDPTR %VX64\n", pVM->pgm.s.CTXSUFF(pGstPaePDPT)->a[(GCPtr >> GST_PDPT_SHIFT) & GST_PDPT_MASK].u)); 3561 # if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE 3562 PPGMPOOL pPool = pVM->pgm.s.CTXSUFF(pPool); 3563 # endif 3564 3565 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3566 unsigned iPml4e = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK; 3567 3568 for (; iPml4e < X86_PG_PAE_ENTRIES; iPml4e++) 3569 { 3570 PPGMPOOLPAGE pShwPdpt = NULL; 3571 PX86PML4E pPml4eSrc, pPml4eDst; 3572 RTGCPHYS GCPhysPdptSrc; 3573 3574 pPml4eSrc = &pVM->pgm.s.CTXSUFF(pGstPaePML4)->a[iPml4e]; 3575 pPml4eDst = &pVM->pgm.s.CTXMID(p,PaePML4)->a[iPml4e]; 3576 3577 /* Fetch the pgm pool shadow descriptor if the shadow pml4e is present. */ 3578 if (!pVM->pgm.s.CTXMID(p,PaePML4)->a[iPml4e].n.u1Present) 3579 { 3580 GCPtr += UINT64_C(_2M * 512 * 512); 3593 3581 continue; 3594 3582 } 3595 #endif 3596 3597 const SHWPDE PdeDst = pPDDst->a[iPDDst]; 3598 if (PdeDst.u & PGM_PDFLAGS_MAPPING) 3599 { 3600 Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s)); 3601 if ((PdeDst.u & X86_PDE_AVL_MASK) != PGM_PDFLAGS_MAPPING) 3583 3584 pShwPdpt = pgmPoolGetPage(pPool, pPml4eDst->u & X86_PML4E_PG_MASK); 3585 GCPhysPdptSrc = pPml4eSrc->u & X86_PML4E_PG_MASK; 3586 3587 if (pPml4eSrc->n.u1Present != pPml4eDst->n.u1Present) 3588 { 3589 AssertMsgFailed(("Present bit doesn't match! pPml4eDst.u=%#RX64 pPml4eSrc.u=%RX64\n", pPml4eDst->u, pPml4eSrc->u)); 3590 GCPtr += UINT64_C(_2M * 512 * 512); 3591 cErrors++; 3592 continue; 3593 } 3594 3595 if (GCPhysPdptSrc != pShwPdpt->GCPhys) 3596 { 3597 AssertMsgFailed(("Physical address doesn't match! pPml4eDst.u=%#RX64 pPml4eSrc.u=%RX64 Phys %RX64 vs RX64\n", pPml4eDst->u, pPml4eSrc->u, pShwPdpt->GCPhys, GCPhysPdptSrc)); 3598 GCPtr += UINT64_C(_2M * 512 * 512); 3599 cErrors++; 3600 continue; 3601 } 3602 3603 if ( pPml4eDst->n.u1User != pPml4eSrc->n.u1User 3604 || pPml4eDst->n.u1Write != pPml4eSrc->n.u1Write 3605 || pPml4eDst->n.u1NoExecute != pPml4eSrc->n.u1NoExecute) 3606 { 3607 AssertMsgFailed(("User/Write/NoExec bits don't match! pPml4eDst.u=%#RX64 pPml4eSrc.u=%RX64\n", pPml4eDst->u, pPml4eSrc->u)); 3608 GCPtr += UINT64_C(_2M * 512 * 512); 3609 cErrors++; 3610 continue; 3611 } 3612 # else 3613 { 3614 # endif 3615 3616 # if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE 3617 /* 3618 * Check the PDPTEs too. 3619 */ 3620 unsigned iPdpte = (GCPtr >> SHW_PDPT_SHIFT) & SHW_PDPT_MASK; 3621 3622 for (;iPdpte <= SHW_PDPT_MASK; iPdpte++) 3623 { 3624 unsigned iPDSrc; 3625 PPGMPOOLPAGE pShwPde = NULL; 3626 PX86PDPE pPdpeDst; 3627 RTGCPHYS GCPhysPdeSrc; 3628 # if PGM_GST_TYPE == PGM_TYPE_PAE 3629 PX86PDPAE pPDDst = pVM->pgm.s.CTXMID(ap,PaePDs)[0]; 3630 PGSTPD pPDSrc = pgmGstGetPaePDPtr(&pVM->pgm.s, GCPtr, &iPDSrc); 3631 PX86PDPT pPdptDst = pVM->pgm.s.CTXMID(p,PaePDPT); 3632 X86PDPE PdpeSrc = CTXSUFF(pVM->pgm.s.pGstPaePDPT)->a[iPdpte]; 3633 # else 3634 PX86PML4E pPml4eSrc; 3635 X86PDPE PdpeSrc; 3636 PX86PDPT pPdptDst; 3637 PX86PDPAE pPDDst; 3638 PGSTPD pPDSrc = pgmGstGetLongModePDPtr(&pVM->pgm.s, GCPtr, &pPml4eSrc, &PdpeSrc, &iPDSrc); 3639 3640 int rc = PGMShwGetLongModePDPtr(pVM, GCPtr, &pPdptDst, &pPDDst); 3641 if (rc != VINF_SUCCESS) 3602 3642 { 3603 AssertMsgFailed(("Mapping shall only have PGM_PDFLAGS_MAPPING set! PdeDst.u=%#RX64\n", (uint64_t)PdeDst.u)); 3643 AssertMsg(rc == VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT, ("Unexpected rc=%Vrc\n", rc)); 3644 GCPtr += 512 * _2M; 3645 continue; /* next PDPTE */ 3646 } 3647 Assert(pPDDst); 3648 # endif 3649 Assert(iPDSrc == 0); 3650 3651 pPdpeDst = &pPdptDst->a[iPdpte]; 3652 3653 if (!pPdpeDst->n.u1Present) 3654 { 3655 GCPtr += 512 * _2M; 3656 continue; /* next PDPTE */ 3657 } 3658 3659 pShwPde = pgmPoolGetPage(pPool, pPdpeDst->u & X86_PDPE_PG_MASK); 3660 GCPhysPdeSrc = PdpeSrc.u & X86_PDPE_PG_MASK; 3661 3662 if (pPdpeDst->n.u1Present != PdpeSrc.n.u1Present) 3663 { 3664 AssertMsgFailed(("Present bit doesn't match! pPdpeDst.u=%#RX64 pPdpeSrc.u=%RX64\n", pPdpeDst->u, PdpeSrc.u)); 3665 GCPtr += 512 * _2M; 3604 3666 cErrors++; 3605 3667 continue; 3606 3668 } 3607 } 3608 else if ( (PdeDst.u & X86_PDE_P) 3609 || ((PdeDst.u & (X86_PDE_P | PGM_PDFLAGS_TRACK_DIRTY)) == (X86_PDE_P | PGM_PDFLAGS_TRACK_DIRTY)) 3610 ) 3611 { 3612 HCPhysShw = PdeDst.u & SHW_PDE_PG_MASK; 3613 PPGMPOOLPAGE pPoolPage = pgmPoolGetPageByHCPhys(pVM, HCPhysShw); 3614 if (!pPoolPage) 3669 3670 if (GCPhysPdeSrc != pShwPde->GCPhys) 3615 3671 { 3616 AssertMsgFailed((" Invalid page table address %VGp at %VGv! PdeDst=%#RX64\n",3617 HCPhysShw, GCPtr, (uint64_t)PdeDst.u));3672 AssertMsgFailed(("Physical address doesn't match! pPdpeDst.u=%#RX64 pPdpeSrc.u=%RX64 Phys %RX64 vs RX64\n", pPdpeDst->u, PdpeSrc.u, pShwPde->GCPhys, GCPhysPdeSrc)); 3673 GCPtr += 512 * _2M; 3618 3674 cErrors++; 3619 3675 continue; 3620 3676 } 3621 const SHWPT *pPTDst = (const SHWPT *)PGMPOOL_PAGE_2_PTR(pVM, pPoolPage); 3622 3623 if (PdeDst.u & (X86_PDE4M_PWT | X86_PDE4M_PCD)) 3677 3678 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3679 if ( pPdpeDst->lm.u1User != PdpeSrc.lm.u1User 3680 || pPdpeDst->lm.u1Write != PdpeSrc.lm.u1Write 3681 || pPdpeDst->lm.u1NoExecute != PdpeSrc.lm.u1NoExecute) 3624 3682 { 3625 AssertMsgFailed(("PDE flags PWT and/or PCD is set at %VGv! These flags are not virtualized! PdeDst=%#RX64\n", 3626 GCPtr, (uint64_t)PdeDst.u)); 3627 cErrors++; 3628 } 3629 3630 if (PdeDst.u & (X86_PDE4M_G | X86_PDE4M_D)) 3631 { 3632 AssertMsgFailed(("4K PDE reserved flags at %VGv! PdeDst=%#RX64\n", 3633 GCPtr, (uint64_t)PdeDst.u)); 3634 cErrors++; 3635 } 3636 3637 const GSTPDE PdeSrc = pPDSrc->a[(iPDDst >> (GST_PD_SHIFT - SHW_PD_SHIFT)) & GST_PD_MASK]; 3638 if (!PdeSrc.n.u1Present) 3639 { 3640 AssertMsgFailed(("Guest PDE at %VGv is not present! PdeDst=%#RX64 PdeSrc=%#RX64\n", 3641 GCPtr, (uint64_t)PdeDst.u, (uint64_t)PdeSrc.u)); 3683 AssertMsgFailed(("User/Write/NoExec bits don't match! pPdpeDst.u=%#RX64 pPdpeSrc.u=%RX64\n", pPdpeDst->u, PdpeSrc.u)); 3684 GCPtr += 512 * _2M; 3642 3685 cErrors++; 3643 3686 continue; 3644 3687 } 3645 3646 if ( !PdeSrc.b.u1Size 3647 || !fBigPagesSupported) 3688 # endif 3689 3690 # else 3691 { 3692 # endif 3693 # if PGM_GST_TYPE == PGM_TYPE_32BIT 3694 const GSTPD *pPDSrc = CTXSUFF(pPGM->pGuestPD); 3695 # if PGM_SHW_TYPE == PGM_TYPE_32BIT 3696 const X86PD *pPDDst = pPGM->CTXMID(p,32BitPD); 3697 # else 3698 const PX86PDPAE pPDDst = pVM->pgm.s.CTXMID(ap,PaePDs)[0]; /* We treat this as a PD with 2048 entries, so no need to and with SHW_PD_MASK to get iPDDst */ 3699 # endif 3700 # endif 3701 /* 3702 * Iterate the shadow page directory. 3703 */ 3704 GCPtr = (GCPtr >> SHW_PD_SHIFT) << SHW_PD_SHIFT; 3705 unsigned iPDDst = (GCPtr >> SHW_PD_SHIFT) & SHW_PD_MASK; 3706 3707 for (; 3708 iPDDst < cPDEs; 3709 iPDDst++, GCPtr += ulIncrement) 3648 3710 { 3649 GCPhysGst = PdeSrc.u & GST_PDE_PG_MASK; 3650 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3651 GCPhysGst |= (iPDDst & 1) * (PAGE_SIZE / 2); 3652 # endif 3653 } 3654 else 3655 { 3656 # if PGM_GST_TYPE == PGM_TYPE_32BIT 3657 if (PdeSrc.u & X86_PDE4M_PG_HIGH_MASK) 3711 const SHWPDE PdeDst = pPDDst->a[iPDDst]; 3712 if (PdeDst.u & PGM_PDFLAGS_MAPPING) 3658 3713 { 3659 AssertMsgFailed(("Guest PDE at %VGv is using PSE36 or similar! PdeSrc=%#RX64\n", 3660 GCPtr, (uint64_t)PdeSrc.u)); 3661 cErrors++; 3662 continue; 3663 } 3664 # endif 3665 GCPhysGst = PdeSrc.u & GST_PDE_BIG_PG_MASK; 3666 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3667 GCPhysGst |= GCPtr & RT_BIT(X86_PAGE_2M_SHIFT); 3668 # endif 3669 } 3670 3671 if ( pPoolPage->enmKind 3672 != (!PdeSrc.b.u1Size || !fBigPagesSupported ? BTH_PGMPOOLKIND_PT_FOR_PT : BTH_PGMPOOLKIND_PT_FOR_BIG)) 3673 { 3674 AssertMsgFailed(("Invalid shadow page table kind %d at %VGv! PdeSrc=%#RX64\n", 3675 pPoolPage->enmKind, GCPtr, (uint64_t)PdeSrc.u)); 3676 cErrors++; 3677 } 3678 3679 PPGMPAGE pPhysPage = pgmPhysGetPage(pPGM, GCPhysGst); 3680 if (!pPhysPage) 3681 { 3682 AssertMsgFailed(("Cannot find guest physical address %VGp in the PDE at %VGv! PdeSrc=%#RX64\n", 3683 GCPhysGst, GCPtr, (uint64_t)PdeSrc.u)); 3684 cErrors++; 3685 continue; 3686 } 3687 3688 if (GCPhysGst != pPoolPage->GCPhys) 3689 { 3690 AssertMsgFailed(("GCPhysGst=%VGp != pPage->GCPhys=%VGp at %VGv\n", 3691 GCPhysGst, pPoolPage->GCPhys, GCPtr)); 3692 cErrors++; 3693 continue; 3694 } 3695 3696 if ( !PdeSrc.b.u1Size 3697 || !fBigPagesSupported) 3698 { 3699 /* 3700 * Page Table. 3701 */ 3702 const GSTPT *pPTSrc; 3703 rc = PGM_GCPHYS_2_PTR(pVM, GCPhysGst & ~(RTGCPHYS)(PAGE_SIZE - 1), &pPTSrc); 3704 if (VBOX_FAILURE(rc)) 3705 { 3706 AssertMsgFailed(("Cannot map/convert guest physical address %VGp in the PDE at %VGv! PdeSrc=%#RX64\n", 3707 GCPhysGst, GCPtr, (uint64_t)PdeSrc.u)); 3708 cErrors++; 3709 continue; 3710 } 3711 if ( (PdeSrc.u & (X86_PDE_P | X86_PDE_US | X86_PDE_RW/* | X86_PDE_A*/)) 3712 != (PdeDst.u & (X86_PDE_P | X86_PDE_US | X86_PDE_RW/* | X86_PDE_A*/))) 3713 { 3714 /// @todo We get here a lot on out-of-sync CR3 entries. The access handler should zap them to avoid false alarms here! 3715 // (This problem will go away when/if we shadow multiple CR3s.) 3716 AssertMsgFailed(("4K PDE flags mismatch at %VGv! PdeSrc=%#RX64 PdeDst=%#RX64\n", 3717 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3718 cErrors++; 3719 continue; 3720 } 3721 if (PdeDst.u & PGM_PDFLAGS_TRACK_DIRTY) 3722 { 3723 AssertMsgFailed(("4K PDEs cannot have PGM_PDFLAGS_TRACK_DIRTY set! GCPtr=%VGv PdeDst=%#RX64\n", 3724 GCPtr, (uint64_t)PdeDst.u)); 3725 cErrors++; 3726 continue; 3727 } 3728 3729 /* iterate the page table. */ 3730 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3731 /* Select the right PDE as we're emulating a 4kb page table with 2 shadow page tables. */ 3732 const unsigned offPTSrc = ((GCPtr >> SHW_PD_SHIFT) & 1) * 512; 3733 # else 3734 const unsigned offPTSrc = 0; 3735 # endif 3736 for (unsigned iPT = 0, off = 0; 3737 iPT < ELEMENTS(pPTDst->a); 3738 iPT++, off += PAGE_SIZE) 3739 { 3740 const SHWPTE PteDst = pPTDst->a[iPT]; 3741 3742 /* skip not-present entries. */ 3743 if (!(PteDst.u & (X86_PTE_P | PGM_PTFLAGS_TRACK_DIRTY))) /** @todo deal with ALL handlers and CSAM !P pages! */ 3744 continue; 3745 Assert(PteDst.n.u1Present); 3746 3747 const GSTPTE PteSrc = pPTSrc->a[iPT + offPTSrc]; 3748 if (!PteSrc.n.u1Present) 3714 Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s)); 3715 if ((PdeDst.u & X86_PDE_AVL_MASK) != PGM_PDFLAGS_MAPPING) 3749 3716 { 3750 #ifdef IN_RING3 3751 PGMAssertHandlerAndFlagsInSync(pVM); 3752 PGMR3DumpHierarchyGC(pVM, cr3, cr4, (PdeSrc.u & GST_PDE_PG_MASK)); 3753 #endif 3754 AssertMsgFailed(("Out of sync (!P) PTE at %VGv! PteSrc=%#RX64 PteDst=%#RX64 pPTSrc=%VGv iPTSrc=%x PdeSrc=%x physpte=%VGp\n", 3755 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u, pPTSrc, iPT + offPTSrc, PdeSrc.au32[0], 3756 (PdeSrc.u & GST_PDE_PG_MASK) + (iPT + offPTSrc)*sizeof(PteSrc))); 3717 AssertMsgFailed(("Mapping shall only have PGM_PDFLAGS_MAPPING set! PdeDst.u=%#RX64\n", (uint64_t)PdeDst.u)); 3757 3718 cErrors++; 3758 3719 continue; 3759 3720 } 3760 3761 uint64_t fIgnoreFlags = GST_PTE_PG_MASK | X86_PTE_AVL_MASK | X86_PTE_G | X86_PTE_D | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_PAT; 3762 # if 1 /** @todo sync accessed bit properly... */ 3763 fIgnoreFlags |= X86_PTE_A; 3764 # endif 3765 3766 /* match the physical addresses */ 3767 HCPhysShw = PteDst.u & SHW_PTE_PG_MASK; 3768 GCPhysGst = PteSrc.u & GST_PTE_PG_MASK; 3769 3770 # ifdef IN_RING3 3771 rc = PGMPhysGCPhys2HCPhys(pVM, GCPhysGst, &HCPhys); 3772 if (VBOX_FAILURE(rc)) 3721 } 3722 else if ( (PdeDst.u & X86_PDE_P) 3723 || ((PdeDst.u & (X86_PDE_P | PGM_PDFLAGS_TRACK_DIRTY)) == (X86_PDE_P | PGM_PDFLAGS_TRACK_DIRTY)) 3724 ) 3725 { 3726 HCPhysShw = PdeDst.u & SHW_PDE_PG_MASK; 3727 PPGMPOOLPAGE pPoolPage = pgmPoolGetPageByHCPhys(pVM, HCPhysShw); 3728 if (!pPoolPage) 3773 3729 { 3774 if (HCPhysShw != MMR3PageDummyHCPhys(pVM)) 3730 AssertMsgFailed(("Invalid page table address %VGp at %VGv! PdeDst=%#RX64\n", 3731 HCPhysShw, GCPtr, (uint64_t)PdeDst.u)); 3732 cErrors++; 3733 continue; 3734 } 3735 const SHWPT *pPTDst = (const SHWPT *)PGMPOOL_PAGE_2_PTR(pVM, pPoolPage); 3736 3737 if (PdeDst.u & (X86_PDE4M_PWT | X86_PDE4M_PCD)) 3738 { 3739 AssertMsgFailed(("PDE flags PWT and/or PCD is set at %VGv! These flags are not virtualized! PdeDst=%#RX64\n", 3740 GCPtr, (uint64_t)PdeDst.u)); 3741 cErrors++; 3742 } 3743 3744 if (PdeDst.u & (X86_PDE4M_G | X86_PDE4M_D)) 3745 { 3746 AssertMsgFailed(("4K PDE reserved flags at %VGv! PdeDst=%#RX64\n", 3747 GCPtr, (uint64_t)PdeDst.u)); 3748 cErrors++; 3749 } 3750 3751 const GSTPDE PdeSrc = pPDSrc->a[(iPDDst >> (GST_PD_SHIFT - SHW_PD_SHIFT)) & GST_PD_MASK]; 3752 if (!PdeSrc.n.u1Present) 3753 { 3754 AssertMsgFailed(("Guest PDE at %VGv is not present! PdeDst=%#RX64 PdeSrc=%#RX64\n", 3755 GCPtr, (uint64_t)PdeDst.u, (uint64_t)PdeSrc.u)); 3756 cErrors++; 3757 continue; 3758 } 3759 3760 if ( !PdeSrc.b.u1Size 3761 || !fBigPagesSupported) 3762 { 3763 GCPhysGst = PdeSrc.u & GST_PDE_PG_MASK; 3764 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3765 GCPhysGst |= (iPDDst & 1) * (PAGE_SIZE / 2); 3766 # endif 3767 } 3768 else 3769 { 3770 # if PGM_GST_TYPE == PGM_TYPE_32BIT 3771 if (PdeSrc.u & X86_PDE4M_PG_HIGH_MASK) 3775 3772 { 3776 AssertMsgFailed((" Cannot find guest physical address %VGp at %VGv! PteSrc=%#RX64 PteDst=%#RX64\n",3777 GCPhysGst, GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u));3773 AssertMsgFailed(("Guest PDE at %VGv is using PSE36 or similar! PdeSrc=%#RX64\n", 3774 GCPtr, (uint64_t)PdeSrc.u)); 3778 3775 cErrors++; 3779 3776 continue; 3780 3777 } 3778 # endif 3779 GCPhysGst = PdeSrc.u & GST_PDE_BIG_PG_MASK; 3780 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3781 GCPhysGst |= GCPtr & RT_BIT(X86_PAGE_2M_SHIFT); 3782 # endif 3781 3783 } 3782 else if (HCPhysShw != (HCPhys & SHW_PTE_PG_MASK)) 3784 3785 if ( pPoolPage->enmKind 3786 != (!PdeSrc.b.u1Size || !fBigPagesSupported ? BTH_PGMPOOLKIND_PT_FOR_PT : BTH_PGMPOOLKIND_PT_FOR_BIG)) 3783 3787 { 3784 AssertMsgFailed(("Out of sync (phys) at %VGv! HCPhysShw=%VHp HCPhys=%VHp GCPhysGst=%VGp PteSrc=%#RX64 PteDst=%#RX64\n", 3785 GCPtr + off, HCPhysShw, HCPhys, GCPhysGst, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3788 AssertMsgFailed(("Invalid shadow page table kind %d at %VGv! PdeSrc=%#RX64\n", 3789 pPoolPage->enmKind, GCPtr, (uint64_t)PdeSrc.u)); 3790 cErrors++; 3791 } 3792 3793 PPGMPAGE pPhysPage = pgmPhysGetPage(pPGM, GCPhysGst); 3794 if (!pPhysPage) 3795 { 3796 AssertMsgFailed(("Cannot find guest physical address %VGp in the PDE at %VGv! PdeSrc=%#RX64\n", 3797 GCPhysGst, GCPtr, (uint64_t)PdeSrc.u)); 3786 3798 cErrors++; 3787 3799 continue; 3788 3800 } 3789 # endif 3790 3791 pPhysPage = pgmPhysGetPage(pPGM, GCPhysGst); 3792 if (!pPhysPage) 3801 3802 if (GCPhysGst != pPoolPage->GCPhys) 3793 3803 { 3794 # ifdef IN_RING3 /** @todo make MMR3PageDummyHCPhys an 'All' function! */ 3795 if (HCPhysShw != MMR3PageDummyHCPhys(pVM)) 3804 AssertMsgFailed(("GCPhysGst=%VGp != pPage->GCPhys=%VGp at %VGv\n", 3805 GCPhysGst, pPoolPage->GCPhys, GCPtr)); 3806 cErrors++; 3807 continue; 3808 } 3809 3810 if ( !PdeSrc.b.u1Size 3811 || !fBigPagesSupported) 3812 { 3813 /* 3814 * Page Table. 3815 */ 3816 const GSTPT *pPTSrc; 3817 rc = PGM_GCPHYS_2_PTR(pVM, GCPhysGst & ~(RTGCPHYS)(PAGE_SIZE - 1), &pPTSrc); 3818 if (VBOX_FAILURE(rc)) 3796 3819 { 3797 AssertMsgFailed(("Cannot find guest physical address %VGp at %VGv! PteSrc=%#RX64 PteDst=%#RX64\n",3798 GCPhysGst, GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u));3820 AssertMsgFailed(("Cannot map/convert guest physical address %VGp in the PDE at %VGv! PdeSrc=%#RX64\n", 3821 GCPhysGst, GCPtr, (uint64_t)PdeSrc.u)); 3799 3822 cErrors++; 3800 3823 continue; 3801 3824 } 3802 # endif 3803 if (PteDst.n.u1Write)3825 if ( (PdeSrc.u & (X86_PDE_P | X86_PDE_US | X86_PDE_RW/* | X86_PDE_A*/)) 3826 != (PdeDst.u & (X86_PDE_P | X86_PDE_US | X86_PDE_RW/* | X86_PDE_A*/))) 3804 3827 { 3805 AssertMsgFailed(("Invalid guest page at %VGv is writable! GCPhysGst=%VGp PteSrc=%#RX64 PteDst=%#RX64\n", 3806 GCPtr + off, GCPhysGst, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3828 /// @todo We get here a lot on out-of-sync CR3 entries. The access handler should zap them to avoid false alarms here! 3829 // (This problem will go away when/if we shadow multiple CR3s.) 3830 AssertMsgFailed(("4K PDE flags mismatch at %VGv! PdeSrc=%#RX64 PdeDst=%#RX64\n", 3831 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3807 3832 cErrors++; 3833 continue; 3808 3834 } 3809 fIgnoreFlags |= X86_PTE_RW; 3810 } 3811 else if (HCPhysShw != (PGM_PAGE_GET_HCPHYS(pPhysPage) & SHW_PTE_PG_MASK)) 3812 { 3813 AssertMsgFailed(("Out of sync (phys) at %VGv! HCPhysShw=%VHp HCPhys=%VHp GCPhysGst=%VGp PteSrc=%#RX64 PteDst=%#RX64\n", 3814 GCPtr + off, HCPhysShw, pPhysPage->HCPhys, GCPhysGst, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3815 cErrors++; 3816 continue; 3817 } 3818 3819 /* flags */ 3820 if (PGM_PAGE_HAS_ACTIVE_HANDLERS(pPhysPage)) 3821 { 3822 if (!PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPhysPage)) 3835 if (PdeDst.u & PGM_PDFLAGS_TRACK_DIRTY) 3823 3836 { 3824 if (PteDst.n.u1Write) 3837 AssertMsgFailed(("4K PDEs cannot have PGM_PDFLAGS_TRACK_DIRTY set! GCPtr=%VGv PdeDst=%#RX64\n", 3838 GCPtr, (uint64_t)PdeDst.u)); 3839 cErrors++; 3840 continue; 3841 } 3842 3843 /* iterate the page table. */ 3844 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3845 /* Select the right PDE as we're emulating a 4kb page table with 2 shadow page tables. */ 3846 const unsigned offPTSrc = ((GCPtr >> SHW_PD_SHIFT) & 1) * 512; 3847 # else 3848 const unsigned offPTSrc = 0; 3849 # endif 3850 for (unsigned iPT = 0, off = 0; 3851 iPT < ELEMENTS(pPTDst->a); 3852 iPT++, off += PAGE_SIZE) 3853 { 3854 const SHWPTE PteDst = pPTDst->a[iPT]; 3855 3856 /* skip not-present entries. */ 3857 if (!(PteDst.u & (X86_PTE_P | PGM_PTFLAGS_TRACK_DIRTY))) /** @todo deal with ALL handlers and CSAM !P pages! */ 3858 continue; 3859 Assert(PteDst.n.u1Present); 3860 3861 const GSTPTE PteSrc = pPTSrc->a[iPT + offPTSrc]; 3862 if (!PteSrc.n.u1Present) 3825 3863 { 3826 AssertMsgFailed(("WRITE access flagged at %VGv but the page is writable! HCPhys=%VGv PteSrc=%#RX64 PteDst=%#RX64\n", 3827 GCPtr + off, pPhysPage->HCPhys, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3864 # ifdef IN_RING3 3865 PGMAssertHandlerAndFlagsInSync(pVM); 3866 PGMR3DumpHierarchyGC(pVM, cr3, cr4, (PdeSrc.u & GST_PDE_PG_MASK)); 3867 # endif 3868 AssertMsgFailed(("Out of sync (!P) PTE at %VGv! PteSrc=%#RX64 PteDst=%#RX64 pPTSrc=%VGv iPTSrc=%x PdeSrc=%x physpte=%VGp\n", 3869 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u, pPTSrc, iPT + offPTSrc, PdeSrc.au32[0], 3870 (PdeSrc.u & GST_PDE_PG_MASK) + (iPT + offPTSrc)*sizeof(PteSrc))); 3828 3871 cErrors++; 3829 3872 continue; 3830 3873 } 3831 fIgnoreFlags |= X86_PTE_RW; 3832 } 3833 else 3834 { 3835 if (PteDst.n.u1Present) 3874 3875 uint64_t fIgnoreFlags = GST_PTE_PG_MASK | X86_PTE_AVL_MASK | X86_PTE_G | X86_PTE_D | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_PAT; 3876 # if 1 /** @todo sync accessed bit properly... */ 3877 fIgnoreFlags |= X86_PTE_A; 3878 # endif 3879 3880 /* match the physical addresses */ 3881 HCPhysShw = PteDst.u & SHW_PTE_PG_MASK; 3882 GCPhysGst = PteSrc.u & GST_PTE_PG_MASK; 3883 3884 # ifdef IN_RING3 3885 rc = PGMPhysGCPhys2HCPhys(pVM, GCPhysGst, &HCPhys); 3886 if (VBOX_FAILURE(rc)) 3836 3887 { 3837 AssertMsgFailed(("ALL access flagged at %VGv but the page is present! HCPhys=%VHp PteSrc=%#RX64 PteDst=%#RX64\n", 3838 GCPtr + off, pPhysPage->HCPhys, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3888 if (HCPhysShw != MMR3PageDummyHCPhys(pVM)) 3889 { 3890 AssertMsgFailed(("Cannot find guest physical address %VGp at %VGv! PteSrc=%#RX64 PteDst=%#RX64\n", 3891 GCPhysGst, GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3892 cErrors++; 3893 continue; 3894 } 3895 } 3896 else if (HCPhysShw != (HCPhys & SHW_PTE_PG_MASK)) 3897 { 3898 AssertMsgFailed(("Out of sync (phys) at %VGv! HCPhysShw=%VHp HCPhys=%VHp GCPhysGst=%VGp PteSrc=%#RX64 PteDst=%#RX64\n", 3899 GCPtr + off, HCPhysShw, HCPhys, GCPhysGst, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3839 3900 cErrors++; 3840 3901 continue; 3841 3902 } 3842 fIgnoreFlags |= X86_PTE_P; 3843 } 3903 # endif 3904 3905 pPhysPage = pgmPhysGetPage(pPGM, GCPhysGst); 3906 if (!pPhysPage) 3907 { 3908 # ifdef IN_RING3 /** @todo make MMR3PageDummyHCPhys an 'All' function! */ 3909 if (HCPhysShw != MMR3PageDummyHCPhys(pVM)) 3910 { 3911 AssertMsgFailed(("Cannot find guest physical address %VGp at %VGv! PteSrc=%#RX64 PteDst=%#RX64\n", 3912 GCPhysGst, GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3913 cErrors++; 3914 continue; 3915 } 3916 # endif 3917 if (PteDst.n.u1Write) 3918 { 3919 AssertMsgFailed(("Invalid guest page at %VGv is writable! GCPhysGst=%VGp PteSrc=%#RX64 PteDst=%#RX64\n", 3920 GCPtr + off, GCPhysGst, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3921 cErrors++; 3922 } 3923 fIgnoreFlags |= X86_PTE_RW; 3924 } 3925 else if (HCPhysShw != (PGM_PAGE_GET_HCPHYS(pPhysPage) & SHW_PTE_PG_MASK)) 3926 { 3927 AssertMsgFailed(("Out of sync (phys) at %VGv! HCPhysShw=%VHp HCPhys=%VHp GCPhysGst=%VGp PteSrc=%#RX64 PteDst=%#RX64\n", 3928 GCPtr + off, HCPhysShw, pPhysPage->HCPhys, GCPhysGst, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3929 cErrors++; 3930 continue; 3931 } 3932 3933 /* flags */ 3934 if (PGM_PAGE_HAS_ACTIVE_HANDLERS(pPhysPage)) 3935 { 3936 if (!PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPhysPage)) 3937 { 3938 if (PteDst.n.u1Write) 3939 { 3940 AssertMsgFailed(("WRITE access flagged at %VGv but the page is writable! HCPhys=%VGv PteSrc=%#RX64 PteDst=%#RX64\n", 3941 GCPtr + off, pPhysPage->HCPhys, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3942 cErrors++; 3943 continue; 3944 } 3945 fIgnoreFlags |= X86_PTE_RW; 3946 } 3947 else 3948 { 3949 if (PteDst.n.u1Present) 3950 { 3951 AssertMsgFailed(("ALL access flagged at %VGv but the page is present! HCPhys=%VHp PteSrc=%#RX64 PteDst=%#RX64\n", 3952 GCPtr + off, pPhysPage->HCPhys, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3953 cErrors++; 3954 continue; 3955 } 3956 fIgnoreFlags |= X86_PTE_P; 3957 } 3958 } 3959 else 3960 { 3961 if (!PteSrc.n.u1Dirty && PteSrc.n.u1Write) 3962 { 3963 if (PteDst.n.u1Write) 3964 { 3965 AssertMsgFailed(("!DIRTY page at %VGv is writable! PteSrc=%#RX64 PteDst=%#RX64\n", 3966 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3967 cErrors++; 3968 continue; 3969 } 3970 if (!(PteDst.u & PGM_PTFLAGS_TRACK_DIRTY)) 3971 { 3972 AssertMsgFailed(("!DIRTY page at %VGv is not marked TRACK_DIRTY! PteSrc=%#RX64 PteDst=%#RX64\n", 3973 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3974 cErrors++; 3975 continue; 3976 } 3977 if (PteDst.n.u1Dirty) 3978 { 3979 AssertMsgFailed(("!DIRTY page at %VGv is marked DIRTY! PteSrc=%#RX64 PteDst=%#RX64\n", 3980 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3981 cErrors++; 3982 } 3983 # if 0 /** @todo sync access bit properly... */ 3984 if (PteDst.n.u1Accessed != PteSrc.n.u1Accessed) 3985 { 3986 AssertMsgFailed(("!DIRTY page at %VGv is has mismatching accessed bit! PteSrc=%#RX64 PteDst=%#RX64\n", 3987 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3988 cErrors++; 3989 } 3990 fIgnoreFlags |= X86_PTE_RW; 3991 # else 3992 fIgnoreFlags |= X86_PTE_RW | X86_PTE_A; 3993 # endif 3994 } 3995 else if (PteDst.u & PGM_PTFLAGS_TRACK_DIRTY) 3996 { 3997 /* access bit emulation (not implemented). */ 3998 if (PteSrc.n.u1Accessed || PteDst.n.u1Present) 3999 { 4000 AssertMsgFailed(("PGM_PTFLAGS_TRACK_DIRTY set at %VGv but no accessed bit emulation! PteSrc=%#RX64 PteDst=%#RX64\n", 4001 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 4002 cErrors++; 4003 continue; 4004 } 4005 if (!PteDst.n.u1Accessed) 4006 { 4007 AssertMsgFailed(("!ACCESSED page at %VGv is has the accessed bit set! PteSrc=%#RX64 PteDst=%#RX64\n", 4008 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 4009 cErrors++; 4010 } 4011 fIgnoreFlags |= X86_PTE_P; 4012 } 4013 # ifdef DEBUG_sandervl 4014 fIgnoreFlags |= X86_PTE_D | X86_PTE_A; 4015 # endif 4016 } 4017 4018 if ( (PteSrc.u & ~fIgnoreFlags) != (PteDst.u & ~fIgnoreFlags) 4019 && (PteSrc.u & ~(fIgnoreFlags | X86_PTE_RW)) != (PteDst.u & ~fIgnoreFlags) 4020 ) 4021 { 4022 AssertMsgFailed(("Flags mismatch at %VGv! %#RX64 != %#RX64 fIgnoreFlags=%#RX64 PteSrc=%#RX64 PteDst=%#RX64\n", 4023 GCPtr + off, (uint64_t)PteSrc.u & ~fIgnoreFlags, (uint64_t)PteDst.u & ~fIgnoreFlags, 4024 fIgnoreFlags, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 4025 cErrors++; 4026 continue; 4027 } 4028 } /* foreach PTE */ 3844 4029 } 3845 4030 else 3846 4031 { 3847 if (!PteSrc.n.u1Dirty && PteSrc.n.u1Write) 4032 /* 4033 * Big Page. 4034 */ 4035 uint64_t fIgnoreFlags = X86_PDE_AVL_MASK | GST_PDE_PG_MASK | X86_PDE4M_G | X86_PDE4M_D | X86_PDE4M_PS | X86_PDE4M_PWT | X86_PDE4M_PCD; 4036 if (!PdeSrc.b.u1Dirty && PdeSrc.b.u1Write) 3848 4037 { 3849 if (P teDst.n.u1Write)4038 if (PdeDst.n.u1Write) 3850 4039 { 3851 AssertMsgFailed(("!DIRTY page at %VGv is writable! P teSrc=%#RX64 PteDst=%#RX64\n",3852 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u));4040 AssertMsgFailed(("!DIRTY page at %VGv is writable! PdeSrc=%#RX64 PdeDst=%#RX64\n", 4041 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3853 4042 cErrors++; 3854 4043 continue; 3855 4044 } 3856 if (!(P teDst.u & PGM_PTFLAGS_TRACK_DIRTY))4045 if (!(PdeDst.u & PGM_PDFLAGS_TRACK_DIRTY)) 3857 4046 { 3858 4047 AssertMsgFailed(("!DIRTY page at %VGv is not marked TRACK_DIRTY! PteSrc=%#RX64 PteDst=%#RX64\n", 3859 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u));4048 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3860 4049 cErrors++; 3861 4050 continue; 3862 4051 } 3863 if (PteDst.n.u1Dirty)3864 {3865 AssertMsgFailed(("!DIRTY page at %VGv is marked DIRTY! PteSrc=%#RX64 PteDst=%#RX64\n",3866 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u));3867 cErrors++;3868 }3869 4052 # if 0 /** @todo sync access bit properly... */ 3870 if (P teDst.n.u1Accessed != PteSrc.n.u1Accessed)4053 if (PdeDst.n.u1Accessed != PdeSrc.b.u1Accessed) 3871 4054 { 3872 4055 AssertMsgFailed(("!DIRTY page at %VGv is has mismatching accessed bit! PteSrc=%#RX64 PteDst=%#RX64\n", 3873 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u));4056 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3874 4057 cErrors++; 3875 4058 } … … 3879 4062 # endif 3880 4063 } 3881 else if (P teDst.u & PGM_PTFLAGS_TRACK_DIRTY)4064 else if (PdeDst.u & PGM_PDFLAGS_TRACK_DIRTY) 3882 4065 { 3883 4066 /* access bit emulation (not implemented). */ 3884 if (P teSrc.n.u1Accessed || PteDst.n.u1Present)4067 if (PdeSrc.b.u1Accessed || PdeDst.n.u1Present) 3885 4068 { 3886 AssertMsgFailed(("PGM_P TFLAGS_TRACK_DIRTY set at %VGv but no accessed bit emulation! PteSrc=%#RX64 PteDst=%#RX64\n",3887 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u));4069 AssertMsgFailed(("PGM_PDFLAGS_TRACK_DIRTY set at %VGv but no accessed bit emulation! PdeSrc=%#RX64 PdeDst=%#RX64\n", 4070 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3888 4071 cErrors++; 3889 4072 continue; 3890 4073 } 3891 if (!P teDst.n.u1Accessed)4074 if (!PdeDst.n.u1Accessed) 3892 4075 { 3893 AssertMsgFailed(("!ACCESSED page at %VGv is has the accessed bit set! P teSrc=%#RX64 PteDst=%#RX64\n",3894 GCPtr + off, (uint64_t)PteSrc.u, (uint64_t)PteDst.u));4076 AssertMsgFailed(("!ACCESSED page at %VGv is has the accessed bit set! PdeSrc=%#RX64 PdeDst=%#RX64\n", 4077 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3895 4078 cErrors++; 3896 4079 } 3897 4080 fIgnoreFlags |= X86_PTE_P; 3898 4081 } 3899 # ifdef DEBUG_sandervl 3900 fIgnoreFlags |= X86_PTE_D | X86_PTE_A; 3901 # endif 3902 } 3903 3904 if ( (PteSrc.u & ~fIgnoreFlags) != (PteDst.u & ~fIgnoreFlags) 3905 && (PteSrc.u & ~(fIgnoreFlags | X86_PTE_RW)) != (PteDst.u & ~fIgnoreFlags) 3906 ) 3907 { 3908 AssertMsgFailed(("Flags mismatch at %VGv! %#RX64 != %#RX64 fIgnoreFlags=%#RX64 PteSrc=%#RX64 PteDst=%#RX64\n", 3909 GCPtr + off, (uint64_t)PteSrc.u & ~fIgnoreFlags, (uint64_t)PteDst.u & ~fIgnoreFlags, 3910 fIgnoreFlags, (uint64_t)PteSrc.u, (uint64_t)PteDst.u)); 3911 cErrors++; 3912 continue; 3913 } 3914 } /* foreach PTE */ 3915 } 3916 else 3917 { 3918 /* 3919 * Big Page. 3920 */ 3921 uint64_t fIgnoreFlags = X86_PDE_AVL_MASK | GST_PDE_PG_MASK | X86_PDE4M_G | X86_PDE4M_D | X86_PDE4M_PS | X86_PDE4M_PWT | X86_PDE4M_PCD; 3922 if (!PdeSrc.b.u1Dirty && PdeSrc.b.u1Write) 3923 { 3924 if (PdeDst.n.u1Write) 3925 { 3926 AssertMsgFailed(("!DIRTY page at %VGv is writable! PdeSrc=%#RX64 PdeDst=%#RX64\n", 3927 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3928 cErrors++; 3929 continue; 3930 } 3931 if (!(PdeDst.u & PGM_PDFLAGS_TRACK_DIRTY)) 3932 { 3933 AssertMsgFailed(("!DIRTY page at %VGv is not marked TRACK_DIRTY! PteSrc=%#RX64 PteDst=%#RX64\n", 3934 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3935 cErrors++; 3936 continue; 3937 } 3938 # if 0 /** @todo sync access bit properly... */ 3939 if (PdeDst.n.u1Accessed != PdeSrc.b.u1Accessed) 3940 { 3941 AssertMsgFailed(("!DIRTY page at %VGv is has mismatching accessed bit! PteSrc=%#RX64 PteDst=%#RX64\n", 3942 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3943 cErrors++; 3944 } 3945 fIgnoreFlags |= X86_PTE_RW; 3946 # else 3947 fIgnoreFlags |= X86_PTE_RW | X86_PTE_A; 3948 # endif 3949 } 3950 else if (PdeDst.u & PGM_PDFLAGS_TRACK_DIRTY) 3951 { 3952 /* access bit emulation (not implemented). */ 3953 if (PdeSrc.b.u1Accessed || PdeDst.n.u1Present) 3954 { 3955 AssertMsgFailed(("PGM_PDFLAGS_TRACK_DIRTY set at %VGv but no accessed bit emulation! PdeSrc=%#RX64 PdeDst=%#RX64\n", 3956 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3957 cErrors++; 3958 continue; 3959 } 3960 if (!PdeDst.n.u1Accessed) 3961 { 3962 AssertMsgFailed(("!ACCESSED page at %VGv is has the accessed bit set! PdeSrc=%#RX64 PdeDst=%#RX64\n", 3963 GCPtr, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3964 cErrors++; 3965 } 3966 fIgnoreFlags |= X86_PTE_P; 3967 } 3968 3969 if ((PdeSrc.u & ~fIgnoreFlags) != (PdeDst.u & ~fIgnoreFlags)) 3970 { 3971 AssertMsgFailed(("Flags mismatch (B) at %VGv! %#RX64 != %#RX64 fIgnoreFlags=%#RX64 PdeSrc=%#RX64 PdeDst=%#RX64\n", 3972 GCPtr, (uint64_t)PdeSrc.u & ~fIgnoreFlags, (uint64_t)PdeDst.u & ~fIgnoreFlags, 3973 fIgnoreFlags, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 3974 cErrors++; 3975 } 3976 3977 /* iterate the page table. */ 3978 for (unsigned iPT = 0, off = 0; 3979 iPT < ELEMENTS(pPTDst->a); 3980 iPT++, off += PAGE_SIZE, GCPhysGst += PAGE_SIZE) 3981 { 3982 const SHWPTE PteDst = pPTDst->a[iPT]; 3983 3984 if (PteDst.u & PGM_PTFLAGS_TRACK_DIRTY) 3985 { 3986 AssertMsgFailed(("The PTE at %VGv emulating a 2/4M page is marked TRACK_DIRTY! PdeSrc=%#RX64 PteDst=%#RX64\n", 3987 GCPtr + off, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 3988 cErrors++; 3989 } 3990 3991 /* skip not-present entries. */ 3992 if (!PteDst.n.u1Present) /** @todo deal with ALL handlers and CSAM !P pages! */ 3993 continue; 3994 3995 fIgnoreFlags = X86_PTE_PAE_PG_MASK | X86_PTE_AVL_MASK | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_PAT; 3996 3997 /* match the physical addresses */ 3998 HCPhysShw = PteDst.u & X86_PTE_PAE_PG_MASK; 3999 4000 # ifdef IN_RING3 4001 rc = PGMPhysGCPhys2HCPhys(pVM, GCPhysGst, &HCPhys); 4002 if (VBOX_FAILURE(rc)) 4003 { 4004 if (HCPhysShw != MMR3PageDummyHCPhys(pVM)) 4082 4083 if ((PdeSrc.u & ~fIgnoreFlags) != (PdeDst.u & ~fIgnoreFlags)) 4005 4084 { 4006 AssertMsgFailed(("Cannot find guest physical address %VGp at %VGv! PdeSrc=%#RX64 PteDst=%#RX64\n", 4007 GCPhysGst, GCPtr + off, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4085 AssertMsgFailed(("Flags mismatch (B) at %VGv! %#RX64 != %#RX64 fIgnoreFlags=%#RX64 PdeSrc=%#RX64 PdeDst=%#RX64\n", 4086 GCPtr, (uint64_t)PdeSrc.u & ~fIgnoreFlags, (uint64_t)PdeDst.u & ~fIgnoreFlags, 4087 fIgnoreFlags, (uint64_t)PdeSrc.u, (uint64_t)PdeDst.u)); 4008 4088 cErrors++; 4009 4089 } 4010 } 4011 else if (HCPhysShw != (HCPhys & X86_PTE_PAE_PG_MASK)) 4012 { 4013 AssertMsgFailed(("Out of sync (phys) at %VGv! HCPhysShw=%VHp HCPhys=%VHp GCPhysGst=%VGp PdeSrc=%#RX64 PteDst=%#RX64\n", 4014 GCPtr + off, HCPhysShw, HCPhys, GCPhysGst, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4015 cErrors++; 4016 continue; 4017 } 4018 # endif 4019 4020 pPhysPage = pgmPhysGetPage(pPGM, GCPhysGst); 4021 if (!pPhysPage) 4022 { 4090 4091 /* iterate the page table. */ 4092 for (unsigned iPT = 0, off = 0; 4093 iPT < ELEMENTS(pPTDst->a); 4094 iPT++, off += PAGE_SIZE, GCPhysGst += PAGE_SIZE) 4095 { 4096 const SHWPTE PteDst = pPTDst->a[iPT]; 4097 4098 if (PteDst.u & PGM_PTFLAGS_TRACK_DIRTY) 4099 { 4100 AssertMsgFailed(("The PTE at %VGv emulating a 2/4M page is marked TRACK_DIRTY! PdeSrc=%#RX64 PteDst=%#RX64\n", 4101 GCPtr + off, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4102 cErrors++; 4103 } 4104 4105 /* skip not-present entries. */ 4106 if (!PteDst.n.u1Present) /** @todo deal with ALL handlers and CSAM !P pages! */ 4107 continue; 4108 4109 fIgnoreFlags = X86_PTE_PAE_PG_MASK | X86_PTE_AVL_MASK | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_PAT; 4110 4111 /* match the physical addresses */ 4112 HCPhysShw = PteDst.u & X86_PTE_PAE_PG_MASK; 4113 4114 # ifdef IN_RING3 4115 rc = PGMPhysGCPhys2HCPhys(pVM, GCPhysGst, &HCPhys); 4116 if (VBOX_FAILURE(rc)) 4117 { 4118 if (HCPhysShw != MMR3PageDummyHCPhys(pVM)) 4119 { 4120 AssertMsgFailed(("Cannot find guest physical address %VGp at %VGv! PdeSrc=%#RX64 PteDst=%#RX64\n", 4121 GCPhysGst, GCPtr + off, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4122 cErrors++; 4123 } 4124 } 4125 else if (HCPhysShw != (HCPhys & X86_PTE_PAE_PG_MASK)) 4126 { 4127 AssertMsgFailed(("Out of sync (phys) at %VGv! HCPhysShw=%VHp HCPhys=%VHp GCPhysGst=%VGp PdeSrc=%#RX64 PteDst=%#RX64\n", 4128 GCPtr + off, HCPhysShw, HCPhys, GCPhysGst, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4129 cErrors++; 4130 continue; 4131 } 4132 # endif 4133 pPhysPage = pgmPhysGetPage(pPGM, GCPhysGst); 4134 if (!pPhysPage) 4135 { 4023 4136 # ifdef IN_RING3 /** @todo make MMR3PageDummyHCPhys an 'All' function! */ 4024 if (HCPhysShw != MMR3PageDummyHCPhys(pVM)) 4025 { 4026 AssertMsgFailed(("Cannot find guest physical address %VGp at %VGv! PdeSrc=%#RX64 PteDst=%#RX64\n", 4027 GCPhysGst, GCPtr + off, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4028 cErrors++; 4029 continue; 4030 } 4031 # endif 4032 if (PteDst.n.u1Write) 4033 { 4034 AssertMsgFailed(("Invalid guest page at %VGv is writable! GCPhysGst=%VGp PdeSrc=%#RX64 PteDst=%#RX64\n", 4035 GCPtr + off, GCPhysGst, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4036 cErrors++; 4037 } 4038 fIgnoreFlags |= X86_PTE_RW; 4039 } 4040 else if (HCPhysShw != (pPhysPage->HCPhys & X86_PTE_PAE_PG_MASK)) 4041 { 4042 AssertMsgFailed(("Out of sync (phys) at %VGv! HCPhysShw=%VHp HCPhys=%VHp GCPhysGst=%VGp PdeSrc=%#RX64 PteDst=%#RX64\n", 4043 GCPtr + off, HCPhysShw, pPhysPage->HCPhys, GCPhysGst, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4044 cErrors++; 4045 continue; 4046 } 4047 4048 /* flags */ 4049 if (PGM_PAGE_HAS_ACTIVE_HANDLERS(pPhysPage)) 4050 { 4051 if (!PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPhysPage)) 4052 { 4053 if (PGM_PAGE_GET_HNDL_PHYS_STATE(pPhysPage) != PGM_PAGE_HNDL_PHYS_STATE_DISABLED) 4054 { 4055 if (PteDst.n.u1Write) 4137 if (HCPhysShw != MMR3PageDummyHCPhys(pVM)) 4056 4138 { 4057 AssertMsgFailed((" WRITE access flagged at %VGv but the page is writable! HCPhys=%VGvPdeSrc=%#RX64 PteDst=%#RX64\n",4058 GCPtr + off, pPhysPage->HCPhys, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u));4139 AssertMsgFailed(("Cannot find guest physical address %VGp at %VGv! PdeSrc=%#RX64 PteDst=%#RX64\n", 4140 GCPhysGst, GCPtr + off, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4059 4141 cErrors++; 4060 4142 continue; 4061 4143 } 4144 # endif 4145 if (PteDst.n.u1Write) 4146 { 4147 AssertMsgFailed(("Invalid guest page at %VGv is writable! GCPhysGst=%VGp PdeSrc=%#RX64 PteDst=%#RX64\n", 4148 GCPtr + off, GCPhysGst, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4149 cErrors++; 4150 } 4062 4151 fIgnoreFlags |= X86_PTE_RW; 4063 4152 } 4064 } 4065 else 4066 { 4067 if (PteDst.n.u1Present) 4153 else if (HCPhysShw != (pPhysPage->HCPhys & X86_PTE_PAE_PG_MASK)) 4068 4154 { 4069 AssertMsgFailed((" ALL access flagged at %VGv but the page is present! HCPhys=%VGvPdeSrc=%#RX64 PteDst=%#RX64\n",4070 GCPtr + off, pPhysPage->HCPhys, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u));4155 AssertMsgFailed(("Out of sync (phys) at %VGv! HCPhysShw=%VHp HCPhys=%VHp GCPhysGst=%VGp PdeSrc=%#RX64 PteDst=%#RX64\n", 4156 GCPtr + off, HCPhysShw, pPhysPage->HCPhys, GCPhysGst, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4071 4157 cErrors++; 4072 4158 continue; 4073 4159 } 4074 fIgnoreFlags |= X86_PTE_P; 4075 } 4160 4161 /* flags */ 4162 if (PGM_PAGE_HAS_ACTIVE_HANDLERS(pPhysPage)) 4163 { 4164 if (!PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPhysPage)) 4165 { 4166 if (PGM_PAGE_GET_HNDL_PHYS_STATE(pPhysPage) != PGM_PAGE_HNDL_PHYS_STATE_DISABLED) 4167 { 4168 if (PteDst.n.u1Write) 4169 { 4170 AssertMsgFailed(("WRITE access flagged at %VGv but the page is writable! HCPhys=%VGv PdeSrc=%#RX64 PteDst=%#RX64\n", 4171 GCPtr + off, pPhysPage->HCPhys, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4172 cErrors++; 4173 continue; 4174 } 4175 fIgnoreFlags |= X86_PTE_RW; 4176 } 4177 } 4178 else 4179 { 4180 if (PteDst.n.u1Present) 4181 { 4182 AssertMsgFailed(("ALL access flagged at %VGv but the page is present! HCPhys=%VGv PdeSrc=%#RX64 PteDst=%#RX64\n", 4183 GCPtr + off, pPhysPage->HCPhys, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4184 cErrors++; 4185 continue; 4186 } 4187 fIgnoreFlags |= X86_PTE_P; 4188 } 4189 } 4190 4191 if ( (PdeSrc.u & ~fIgnoreFlags) != (PteDst.u & ~fIgnoreFlags) 4192 && (PdeSrc.u & ~(fIgnoreFlags | X86_PTE_RW)) != (PteDst.u & ~fIgnoreFlags) /* lazy phys handler dereg. */ 4193 ) 4194 { 4195 AssertMsgFailed(("Flags mismatch (BT) at %VGv! %#RX64 != %#RX64 fIgnoreFlags=%#RX64 PdeSrc=%#RX64 PteDst=%#RX64\n", 4196 GCPtr + off, (uint64_t)PdeSrc.u & ~fIgnoreFlags, (uint64_t)PteDst.u & ~fIgnoreFlags, 4197 fIgnoreFlags, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4198 cErrors++; 4199 continue; 4200 } 4201 } /* for each PTE */ 4076 4202 } 4077 4078 if ( (PdeSrc.u & ~fIgnoreFlags) != (PteDst.u & ~fIgnoreFlags) 4079 && (PdeSrc.u & ~(fIgnoreFlags | X86_PTE_RW)) != (PteDst.u & ~fIgnoreFlags) /* lazy phys handler dereg. */ 4080 ) 4081 { 4082 AssertMsgFailed(("Flags mismatch (BT) at %VGv! %#RX64 != %#RX64 fIgnoreFlags=%#RX64 PdeSrc=%#RX64 PteDst=%#RX64\n", 4083 GCPtr + off, (uint64_t)PdeSrc.u & ~fIgnoreFlags, (uint64_t)PteDst.u & ~fIgnoreFlags, 4084 fIgnoreFlags, (uint64_t)PdeSrc.u, (uint64_t)PteDst.u)); 4085 cErrors++; 4086 continue; 4087 } 4088 } /* foreach PTE */ 4089 } 4090 } 4091 /* not present */ 4092 4093 } /* forearch PDE */ 4203 } 4204 /* not present */ 4205 4206 } /* for each PDE */ 4207 4208 } /* for each PDPTE */ 4209 4210 } /* for each PML4E */ 4094 4211 4095 4212 # ifdef DEBUG … … 4098 4215 # endif 4099 4216 4100 #elif PGM_GST_TYPE == PGM_TYPE_PAE4101 //# error not implemented4102 4103 4104 #elif PGM_GST_TYPE == PGM_TYPE_AMD644105 //# error not implemented4106 4107 /*#else: guest real and protected mode */4108 4217 #endif 4109 4218 return cErrors;
Note:
See TracChangeset
for help on using the changeset viewer.