VirtualBox

Changeset 8533 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 2, 2008 4:04:51 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
30437
Message:

Start of 64 bits paging support

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGMInternal.h

    r8500 r8533  
    13761376    /** Shw: 64-bit page directory pointer table;   Gst: 64-bit page directory pointer table. */
    13771377    PGMPOOLKIND_64BIT_PDPT_FOR_64BIT_PDPT,
     1378    /** Shw: 64-bit page directory table;   Gst: 64-bit page directory table. */
     1379    PGMPOOLKIND_64BIT_PD_FOR_64BIT_PD,
    13781380
    13791381    /** Shw: Root 32-bit page directory. */
     
    19401942    /** @} */
    19411943
     1944    /** @name AMD64 Guest Paging.
     1945     * @{ */
     1946    /** The guest's page directory pointer table, HC pointer. */
     1947    R3R0PTRTYPE(PX86PML4)       pGstPaePML4HC;
     1948    /** @} */
    19421949
    19431950    /** @name 32-bit Shadow Paging
     
    33243331#ifndef IN_GC
    33253332/**
     3333 * Gets the page directory pointer entry for the specified address.
     3334 *
     3335 * @returns Pointer to the page directory pointer entry in question.
     3336 * @returns NULL if the page directory is not present or on an invalid page.
     3337 * @param   pPGM        Pointer to the PGM instance data.
     3338 * @param   GCPtr       The address.
     3339 * @param   ppPml4e     Page Map Level-4 Entry (out)
     3340 */
     3341DECLINLINE(PX86PDPE) pgmGstGetLongModePDPTPtr(PPGM pPGM, RTGCUINTPTR64 GCPtr, PX86PML4E *ppPml4e)
     3342{
     3343    const unsigned iPml4e = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
     3344
     3345    *ppPml4e = &pPGM->pGstPaePML4HC->a[iPml4e];
     3346    if ((*ppPml4e)->n.u1Present)
     3347    {
     3348        PX86PDPT pPdpt;
     3349        int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), (*ppPml4e)->u & X86_PML4E_PG_MASK, &pPdpt);
     3350        if (VBOX_FAILURE(rc))
     3351        {
     3352            AssertFailed();
     3353            return NULL;
     3354        }
     3355        const unsigned iPdPt  = (GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64;
     3356        return &pPdpt->a[iPdPt];
     3357    }
     3358    return NULL;
     3359}
     3360
     3361/**
    33263362 * Gets the page directory entry for the specified address.
    33273363 *
     
    33373373    const unsigned iPml4e = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
    33383374
    3339     *ppPml4e = &pPGM->pHCPaePML4->a[iPml4e];
     3375    *ppPml4e = &pPGM->pGstPaePML4HC->a[iPml4e];
    33403376    if ((*ppPml4e)->n.u1Present)
    33413377    {
     
    33793415    const unsigned iPml4e = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
    33803416
    3381     if (pPGM->pHCPaePML4->a[iPml4e].n.u1Present)
     3417    if (pPGM->pGstPaePML4HC->a[iPml4e].n.u1Present)
    33823418    {
    33833419        PX86PDPT pPdptTemp;
    3384         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPGM->pHCPaePML4->a[iPml4e].u & X86_PML4E_PG_MASK, &pPdptTemp);
     3420        int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPGM->pGstPaePML4HC->a[iPml4e].u & X86_PML4E_PG_MASK, &pPdptTemp);
    33853421        if (VBOX_FAILURE(rc))
    33863422        {
     
    34193455    const unsigned iPml4e = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
    34203456
    3421     if (pPGM->pHCPaePML4->a[iPml4e].n.u1Present)
     3457    if (pPGM->pGstPaePML4HC->a[iPml4e].n.u1Present)
    34223458    {
    34233459        PX86PDPT pPdptTemp;
    3424         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPGM->pHCPaePML4->a[iPml4e].u & X86_PML4E_PG_MASK, &pPdptTemp);
     3460        int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPGM->pGstPaePML4HC->a[iPml4e].u & X86_PML4E_PG_MASK, &pPdptTemp);
    34253461        if (VBOX_FAILURE(rc))
    34263462        {
     
    34473483}
    34483484
     3485
     3486/**
     3487 * Gets the GUEST page directory pointer for the specified address.
     3488 *
     3489 * @returns The page directory in question.
     3490 * @returns NULL if the page directory is not present or on an invalid page.
     3491 * @param   pPGM        Pointer to the PGM instance data.
     3492 * @param   GCPtr       The address.
     3493 * @param   ppPml4e     Page Map Level-4 Entry (out)
     3494 * @param   pPdpe       Page directory pointer table entry (out)
     3495 * @param   piPD        Receives the index into the returned page directory
     3496 */
     3497DECLINLINE(PX86PDPAE) pgmGstGetLongModePDPtr(PPGM pPGM, RTGCUINTPTR64 GCPtr, PX86PML4E *ppPml4e, PX86PDPE pPdpe, unsigned *piPD)
     3498{
     3499    const unsigned iPml4e = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
     3500
     3501    *ppPml4e = &pPGM->pGstPaePML4HC->a[iPml4e];
     3502    if ((*ppPml4e)->n.u1Present)
     3503    {
     3504        PX86PDPT pPdptTemp;
     3505        int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), (*ppPml4e)->u & X86_PML4E_PG_MASK, &pPdptTemp);
     3506        if (VBOX_FAILURE(rc))
     3507        {
     3508            AssertFailed();
     3509            return 0ULL;
     3510        }
     3511
     3512        const unsigned iPdPt  = (GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64;
     3513        *pPdpe = pPdptTemp->a[iPdPt];
     3514        if (pPdpe->n.u1Present)
     3515        {
     3516            PX86PDPAE pPD;
     3517
     3518            rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPdpe->u & X86_PDPE_PG_MASK, &pPD);
     3519            if (VBOX_FAILURE(rc))
     3520            {
     3521                AssertFailed();
     3522                return 0ULL;
     3523            }
     3524            *piPD = (GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
     3525            return pPD;
     3526        }
     3527    }
     3528    return 0ULL;
     3529}
    34493530#endif /* !IN_GC */
    34503531
  • trunk/src/VBox/VMM/VMMAll/PGMAll.cpp

    r8386 r8533  
    640640}
    641641
     642#ifndef IN_GC
     643/**
     644 * Gets the SHADOW page directory pointer for the specified address. Allocates
     645 * backing pages in case the PDPT or page dirctory is missing.
     646 *
     647 * @returns VBox status.
     648 * @param   pVM         VM handle.
     649 * @param   GCPtr       The address.
     650 * @param   ppPD        Receives address of page directory
     651 */
     652PGMDECL(int) PGMShwGetLongModePDPtr(PVM pVM, RTGCUINTPTR64 GCPtr, PX86PDPAE *ppPD)
     653{
     654    PPGM           pPGM   = &pVM->pgm.s;
     655    const unsigned iPml4e = (GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK;
     656    PPGMPOOL       pPool  = pPGM->CTXSUFF(pPool);
     657    PX86PML4E      pPml4e;
     658    PPGMPOOLPAGE   pShwPage;
     659    int            rc;
     660
     661    pPml4e = &pPGM->pHCPaePML4->a[iPml4e];
     662    if (    !pPml4e->n.u1Present
     663        &&  !(pPml4e->u & X86_PML4E_PG_MASK))
     664    {
     665        PX86PML4E pPml4eGst = &pPGM->pGstPaePML4HC->a[iPml4e];
     666
     667        Assert(!(pPml4e->u & X86_PML4E_PG_MASK));
     668        rc = pgmPoolAlloc(pVM, pPml4eGst->u & X86_PML4E_PG_MASK, PGMPOOLKIND_64BIT_PDPT_FOR_64BIT_PDPT, PGMPOOL_IDX_PML4, iPml4e, &pShwPage);
     669        if (rc == VERR_PGM_POOL_FLUSHED)
     670            return VINF_PGM_SYNC_CR3;
     671
     672        AssertRCReturn(rc, rc);
     673
     674        /* The PDPT was cached or created; hook it up now. */
     675        pPml4e->u |= pShwPage->Core.Key;
     676    }
     677    else
     678    {
     679        pShwPage = pgmPoolGetPage(pPool, pPml4e->u & X86_PML4E_PG_MASK);
     680        AssertReturn(pShwPage, VERR_INTERNAL_ERROR);
     681    }
     682
     683    const unsigned iPdPt = (GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64;
     684    PX86PDPT  pPdpt = (PX86PDPT)PGMPOOL_PAGE_2_PTR(pVM, pShwPage);   
     685    PX86PDPE  pPdpe = &pPdpt->a[iPdPt];
     686
     687    if (    !pPdpe->n.u1Present
     688        &&  !(pPdpe->u & X86_PDPE_PG_MASK))
     689    {
     690        PX86PML4E pPml4eGst = &pPGM->pGstPaePML4HC->a[iPml4e];       
     691        PX86PDPT  pPdptGst;
     692        rc = PGM_GCPHYS_2_PTR(pVM, pPml4eGst->u & X86_PML4E_PG_MASK, &pPdptGst);
     693        AssertRCReturn(rc, rc);
     694
     695        Assert(!(pPdpe->u & X86_PDPE_PG_MASK));
     696        rc = pgmPoolAlloc(pVM, pPdptGst->a[iPdPt].u & X86_PDPE_PG_MASK, PGMPOOLKIND_64BIT_PD_FOR_64BIT_PD, PGMPOOL_IDX_PDPT, iPdPt, &pShwPage);
     697        if (rc == VERR_PGM_POOL_FLUSHED)
     698            return VINF_PGM_SYNC_CR3;
     699
     700        AssertRCReturn(rc, rc);
     701
     702        /* The PDPT was cached or created; hook it up now. */
     703        pPdpe->u |= pShwPage->Core.Key;
     704    }
     705    else
     706    {
     707        pShwPage = pgmPoolGetPage(pPool, pPdpe->u & X86_PDPE_PG_MASK);
     708        AssertReturn(pShwPage, VERR_INTERNAL_ERROR);
     709    }
     710
     711    *ppPD = (PX86PDPAE)PGMPOOL_PAGE_2_PTR(pVM, pShwPage);
     712    return VINF_SUCCESS;
     713}
     714#endif
    642715
    643716/**
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r8503 r8533  
    7878PGM_BTH_DECL(int, Trap0eHandler)(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault)
    7979{
    80 #if (PGM_GST_TYPE == PGM_TYPE_32BIT ||  PGM_GST_TYPE == PGM_TYPE_REAL ||  PGM_GST_TYPE == PGM_TYPE_PROT || PGM_GST_TYPE == PGM_TYPE_PAE) && PGM_SHW_TYPE != PGM_TYPE_AMD64
     80#if PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_REAL || PGM_GST_TYPE == PGM_TYPE_PROT || PGM_GST_TYPE == PGM_TYPE_PAE || PGM_GST_TYPE == PGM_TYPE_AMD64
    8181
    8282# if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE != PGM_TYPE_PAE
     
    100100    const unsigned  iPDSrc = (RTGCUINTPTR)pvFault >> GST_PD_SHIFT;
    101101    PGSTPD          pPDSrc = CTXSUFF(pVM->pgm.s.pGuestPD);
    102 #  else /* PAE */
     102
     103#  elif PGM_GST_TYPE == PGM_TYPE_PAE || PGM_GST_TYPE == PGM_TYPE_AMD64
     104
     105#   if PGM_GST_TYPE == PGM_TYPE_PAE
    103106    unsigned        iPDSrc;
    104107    PGSTPD          pPDSrc = pgmGstGetPaePDPtr(&pVM->pgm.s, (RTGCUINTPTR)pvFault, &iPDSrc);
    105108
     109#   elif PGM_GST_TYPE == PGM_TYPE_AMD64
     110    unsigned     iPDSrc;
     111    PX86PML4E    pPml4e;
     112    X86PDPE      Pdpe;
     113    PGSTPD       pPDSrc;
     114
     115    pPDSrc = pgmGstGetLongModePDPtr(&pVM->pgm.s, pvFault, &pPml4e, &Pdpe, &iPDSrc);
     116    Assert(pPml4e);
     117#   endif
    106118    /* Quick check for a valid guest trap. */
    107119    if (!pPDSrc)
    108120    {
    109         LogFlow(("Trap0eHandler: guest PDPTR not present CR3=%VGp\n", (uint64_t)(CPUMGetGuestCR3(pVM) & X86_CR3_PAGE_MASK)));
     121        LogFlow(("Trap0eHandler: guest PDPTR not present CR3=%VGp\n", (CPUMGetGuestCR3(pVM) & X86_CR3_PAGE_MASK)));
    110122        STAM_STATS({ pVM->pgm.s.CTXSUFF(pStatTrap0eAttribution) = &pVM->pgm.s.StatTrap0eGuestTrap; });
    111123        TRPMSetErrorCode(pVM, uErr);
     
    118130# endif
    119131
     132# if PGM_SHW_TYPE == PGM_TYPE_32BIT
    120133    const unsigned  iPDDst = (RTGCUINTPTR)pvFault >> SHW_PD_SHIFT;
    121 # if PGM_SHW_TYPE == PGM_TYPE_32BIT
    122134    PX86PD          pPDDst = pVM->pgm.s.CTXMID(p,32BitPD);
    123135# elif PGM_SHW_TYPE == PGM_TYPE_PAE
    124     PX86PDPAE       pPDDst = pVM->pgm.s.CTXMID(ap,PaePDs)[0]; /* We treat this as a PD with 2048 entries. */
     136    const unsigned  iPDDst = (RTGCUINTPTR)pvFault >> SHW_PD_SHIFT;
     137    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 */
    125138
    126139#  if PGM_GST_TYPE == PGM_TYPE_PAE
     
    128141    unsigned iPDPTE = ((RTGCUINTPTR)pvFault >> SHW_PDPT_SHIFT) & SHW_PDPT_MASK;
    129142    if (!pVM->pgm.s.CTXMID(p,PaePDPT)->a[iPDPTE].n.u1Present)
    130     {
    131143        pVM->pgm.s.CTXMID(p,PaePDPT)->a[iPDPTE].n.u1Present = 1;
     144
     145#  endif
     146
     147# elif PGM_SHW_TYPE == PGM_TYPE_AMD64
     148    const unsigned  iPDDst = (((RTGCUINTPTR)pvFault >> SHW_PD_SHIFT) & SHW_PD_MASK);
     149    PX86PDPAE       pPDDst;
     150
     151    rc = PGMShwGetLongModePDPtr(pVM, (RTGCUINTPTR)pvFault, &pPDDst);
     152    if (rc != VINF_SUCCESS)
     153    {
     154        AssertMsg(rc == VINF_PGM_SYNC_CR3, ("Unexpected rc=%Vrc\n", rc));
     155        return rc;
    132156    }
    133 #  endif
    134 # else
    135     AssertFailed();
     157    Assert(pPDDst);
    136158# endif
    137159
     
    16501672#if PGM_WITH_PAGING(PGM_GST_TYPE)
    16511673
    1652 # ifdef PGM_SYNC_DIRTY_BIT
    1653 
    16541674/**
    16551675 * Investigate page fault and handle write protection page faults caused by
     
    16681688    bool fUserLevelFault    = !!(uErr & X86_TRAP_PF_US);
    16691689    bool fWriteFault        = !!(uErr & X86_TRAP_PF_RW);
     1690    bool fBigPagesSupported = !!(CPUMGetGuestCR4(pVM) & X86_CR4_PSE);
    16701691# if PGM_WITH_NX(PGM_GST_TYPE)
    16711692    bool fNoExecuteBitValid = !!(CPUMGetGuestEFER(pVM) & MSR_K6_EFER_NXE);
    16721693# endif
     1694    unsigned uPageFaultLevel;
    16731695
    16741696    STAM_PROFILE_START(&pVM->pgm.s.CTXMID(Stat, DirtyBitTracking), a);
    16751697    LogFlow(("CheckPageFault: GCPtrPage=%VGv uErr=%#x PdeSrc=%08x\n", GCPtrPage, uErr, pPdeSrc->u));
    16761698
    1677 # if PGM_GST_TYPE == PGM_TYPE_AMD64
    1678     AssertFailed();
    1679 # elif PGM_GST_TYPE == PGM_TYPE_PAE
     1699# if    PGM_GST_TYPE == PGM_TYPE_PAE \
     1700     || PGM_GST_TYPE == PGM_TYPE_AMD64
     1701
     1702#  if PGM_GST_TYPE == PGM_TYPE_AMD64
     1703    PX86PML4E    pPml4eSrc;
     1704    PX86PDPE     pPdpeSrc;
     1705
     1706    pPdpeSrc = pgmGstGetLongModePDPTPtr(&pVM->pgm.s, GCPtrPage, &pPml4eSrc);
     1707    Assert(pPml4eSrc);
     1708
     1709    /*
     1710     * Real page fault? (PML4E level)
     1711     */
     1712    if (    (uErr & X86_TRAP_PF_RSVD)
     1713        ||  !pPml4eSrc->n.u1Present
     1714        ||  (fNoExecuteBitValid && (uErr & X86_TRAP_PF_ID) && pPml4eSrc->n.u1NoExecute)
     1715        ||  (fWriteFault && !pPml4eSrc->n.u1Write && (fUserLevelFault || fWriteProtect))
     1716        ||  (fUserLevelFault && !pPml4eSrc->n.u1User)
     1717       )
     1718    {
     1719        uPageFaultLevel = 0;
     1720        goto UpperLevelPageFault;
     1721    }
     1722    Assert(pPdpeSrc);
     1723
     1724#  else /* PAE */
    16801725    PX86PDPE pPdpeSrc = &pVM->pgm.s.CTXSUFF(pGstPaePDPT)->a[(GCPtrPage >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
    1681 
    1682     /*
    1683      * Real page fault?
     1726#  endif
     1727
     1728    /*
     1729     * Real page fault? (PDPE level)
    16841730     */
    16851731    if (    (uErr & X86_TRAP_PF_RSVD)
     
    16921738       )
    16931739    {
    1694 #  ifdef IN_GC
    1695         STAM_COUNTER_INC(&pVM->pgm.s.StatGCDirtyTrackRealPF);
    1696 #  endif
    1697         STAM_PROFILE_STOP(&pVM->pgm.s.CTXMID(Stat, DirtyBitTracking), a);
    1698         LogFlow(("CheckPageFault: real page fault at %VGv (0)\n", GCPtrPage));
    1699 
    1700         if (    pPdpeSrc->n.u1Present
    1701             &&  pPdeSrc->n.u1Present)
    1702         {
    1703             /* Check the present bit as the shadow tables can cause different error codes by being out of sync.
    1704              * See the 2nd case below as well.
    1705              */
    1706             if (pPdeSrc->b.u1Size && (CPUMGetGuestCR4(pVM) & X86_CR4_PSE))
    1707             {
    1708                 TRPMSetErrorCode(pVM, uErr | X86_TRAP_PF_P); /* page-level protection violation */
    1709             }
    1710             else
    1711             {
    1712                 /*
    1713                 * Map the guest page table.
    1714                 */
    1715                 PGSTPT pPTSrc;
    1716                 int rc = PGM_GCPHYS_2_PTR(pVM, pPdeSrc->u & GST_PDE_PG_MASK, &pPTSrc);
    1717                 if (VBOX_SUCCESS(rc))
    1718                 {
    1719                     PGSTPTE         pPteSrc = &pPTSrc->a[(GCPtrPage >> GST_PT_SHIFT) & GST_PT_MASK];
    1720                     const GSTPTE    PteSrc = *pPteSrc;
    1721                     if (pPteSrc->n.u1Present)
    1722                         TRPMSetErrorCode(pVM, uErr | X86_TRAP_PF_P); /* page-level protection violation */
    1723                 }
    1724                 AssertRC(rc);
    1725             }
    1726         }
    1727         return VINF_EM_RAW_GUEST_TRAP;
     1740        uPageFaultLevel = 1;
     1741        goto UpperLevelPageFault;
    17281742    }
    17291743# endif
    17301744
    17311745    /*
    1732      * Real page fault?
     1746     * Real page fault? (PDE level)
    17331747     */
    17341748    if (    (uErr & X86_TRAP_PF_RSVD)
     
    17401754        ||  (fUserLevelFault && !pPdeSrc->n.u1User) )
    17411755    {
    1742 #  ifdef IN_GC
    1743         STAM_COUNTER_INC(&pVM->pgm.s.StatGCDirtyTrackRealPF);
    1744 #  endif
    1745         STAM_PROFILE_STOP(&pVM->pgm.s.CTXMID(Stat, DirtyBitTracking), a);
    1746         LogFlow(("CheckPageFault: real page fault at %VGv (1)\n", GCPtrPage));
    1747 
    1748         if (pPdeSrc->n.u1Present)
    1749         {
    1750             /* Check the present bit as the shadow tables can cause different error codes by being out of sync.
    1751              * See the 2nd case below as well.
    1752              */
    1753             if (pPdeSrc->b.u1Size && (CPUMGetGuestCR4(pVM) & X86_CR4_PSE))
    1754             {
    1755                 TRPMSetErrorCode(pVM, uErr | X86_TRAP_PF_P); /* page-level protection violation */
    1756             }
    1757             else
    1758             {
    1759                 /*
    1760                 * Map the guest page table.
    1761                 */
    1762                 PGSTPT pPTSrc;
    1763                 int rc = PGM_GCPHYS_2_PTR(pVM, pPdeSrc->u & GST_PDE_PG_MASK, &pPTSrc);
    1764                 if (VBOX_SUCCESS(rc))
    1765                 {
    1766                     PGSTPTE         pPteSrc = &pPTSrc->a[(GCPtrPage >> GST_PT_SHIFT) & GST_PT_MASK];
    1767                     const GSTPTE    PteSrc = *pPteSrc;
    1768                     if (pPteSrc->n.u1Present)
    1769                         TRPMSetErrorCode(pVM, uErr | X86_TRAP_PF_P); /* page-level protection violation */
    1770                 }
    1771                 AssertRC(rc);
    1772             }
    1773         }
    1774         return VINF_EM_RAW_GUEST_TRAP;
     1756        uPageFaultLevel = 2;
     1757        goto UpperLevelPageFault;
    17751758    }
    17761759
     
    17791762     * the dirty bit of an emulated BIG page
    17801763     */
    1781     if (pPdeSrc->b.u1Size && (CPUMGetGuestCR4(pVM) & X86_CR4_PSE))
     1764    if (pPdeSrc->b.u1Size && fBigPagesSupported)
    17821765    {
    17831766        /* Mark guest page directory as accessed */
     
    19391922    STAM_PROFILE_STOP(&pVM->pgm.s.CTXMID(Stat,DirtyBitTracking), a);
    19401923    return rc;
     1924
     1925
     1926UpperLevelPageFault:
     1927    /* Pagefault detected while checking the PML4E, PDPE or PDE.
     1928     * Single exit handler to get rid of duplicate code paths.
     1929     */
     1930#  ifdef IN_GC
     1931    STAM_COUNTER_INC(&pVM->pgm.s.StatGCDirtyTrackRealPF);
     1932#  endif
     1933    STAM_PROFILE_STOP(&pVM->pgm.s.CTXMID(Stat, DirtyBitTracking), a);
     1934    LogFlow(("CheckPageFault: real page fault at %VGv (%d)\n", GCPtrPage, uPageFaultLevel));
     1935
     1936    if (   
     1937#  if PGM_GST_TYPE == PGM_TYPE_AMD64
     1938            pPml4eSrc->n.u1Present &&
     1939#  endif
     1940#  if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
     1941            pPdpeSrc->n.u1Present  &&
     1942#  endif
     1943            pPdeSrc->n.u1Present)
     1944    {
     1945        /* Check the present bit as the shadow tables can cause different error codes by being out of sync. */
     1946        if (pPdeSrc->b.u1Size && fBigPagesSupported)
     1947        {
     1948            TRPMSetErrorCode(pVM, uErr | X86_TRAP_PF_P); /* page-level protection violation */
     1949        }
     1950        else
     1951        {
     1952            /*
     1953             * Map the guest page table.
     1954             */
     1955            PGSTPT pPTSrc;
     1956            int rc = PGM_GCPHYS_2_PTR(pVM, pPdeSrc->u & GST_PDE_PG_MASK, &pPTSrc);
     1957            if (VBOX_SUCCESS(rc))
     1958            {
     1959                PGSTPTE         pPteSrc = &pPTSrc->a[(GCPtrPage >> GST_PT_SHIFT) & GST_PT_MASK];
     1960                const GSTPTE    PteSrc = *pPteSrc;
     1961                if (pPteSrc->n.u1Present)
     1962                    TRPMSetErrorCode(pVM, uErr | X86_TRAP_PF_P); /* page-level protection violation */
     1963            }
     1964            AssertRC(rc);
     1965        }
     1966    }
     1967    return VINF_EM_RAW_GUEST_TRAP;
    19411968}
    1942 
    1943 # endif
    19441969
    19451970#endif /* PGM_WITH_PAGING(PGM_GST_TYPE) */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette