VirtualBox

Ignore:
Timestamp:
Jul 20, 2018 11:10:04 AM (7 years ago)
Author:
vboxsync
Message:

PGM: Moving guest+shadow mode Enter function to PGMAll. bugref:9044

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r73249 r73262  
    3333*******************************************************************************/
    3434RT_C_DECLS_BEGIN
     35PGM_BTH_DECL(int, Enter)(PVMCPU pVCpu, RTGCPHYS GCPhysCR3);
    3536#ifndef IN_RING3
    3637PGM_BTH_DECL(int, Trap0eHandler)(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, bool *pfLockTaken);
     
    5455PGM_BTH_DECL(int, UnmapCR3)(PVMCPU pVCpu);
    5556
    56 /* currently ring-3 */
    57 PGM_BTH_DECL(int, Enter)(PVMCPU pVCpu, RTGCPHYS GCPhysCR3);
    5857#ifdef IN_RING3
    5958PGM_BTH_DECL(int, Relocate)(PVMCPU pVCpu, RTGCPTR offDelta);
     
    8685# error "Invalid combination; AMD64 guest implies AMD64 shadow and vice versa"
    8786#endif
     87
     88
     89/**
     90 * Enters the shadow+guest mode.
     91 *
     92 * @returns VBox status code.
     93 * @param   pVCpu       The cross context virtual CPU structure.
     94 * @param   GCPhysCR3   The physical address from the CR3 register.
     95 */
     96PGM_BTH_DECL(int, Enter)(PVMCPU pVCpu, RTGCPHYS GCPhysCR3)
     97{
     98    /* Here we deal with allocation of the root shadow page table for real and protected mode during mode switches;
     99     * Other modes rely on MapCR3/UnmapCR3 to setup the shadow root page tables.
     100     */
     101#if  (   (   PGM_SHW_TYPE == PGM_TYPE_32BIT \
     102          || PGM_SHW_TYPE == PGM_TYPE_PAE    \
     103          || PGM_SHW_TYPE == PGM_TYPE_AMD64) \
     104      && (   PGM_GST_TYPE == PGM_TYPE_REAL   \
     105          || PGM_GST_TYPE == PGM_TYPE_PROT))
     106
     107    PVM pVM = pVCpu->CTX_SUFF(pVM);
     108
     109    Assert((HMIsNestedPagingActive(pVM) || VM_IS_NEM_ENABLED(pVM)) == pVM->pgm.s.fNestedPaging);
     110    Assert(!pVM->pgm.s.fNestedPaging);
     111
     112    pgmLock(pVM);
     113    /* Note: we only really need shadow paging in real and protected mode for VT-x and AMD-V (excluding nested paging/EPT modes),
     114     *       but any calls to GC need a proper shadow page setup as well.
     115     */
     116    /* Free the previous root mapping if still active. */
     117    PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
     118    PPGMPOOLPAGE pOldShwPageCR3 = pVCpu->pgm.s.CTX_SUFF(pShwPageCR3);
     119    if (pOldShwPageCR3)
     120    {
     121        Assert(pOldShwPageCR3->enmKind != PGMPOOLKIND_FREE);
     122
     123        /* Mark the page as unlocked; allow flushing again. */
     124        pgmPoolUnlockPage(pPool, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3));
     125
     126# ifndef PGM_WITHOUT_MAPPINGS
     127        /* Remove the hypervisor mappings from the shadow page table. */
     128        pgmMapDeactivateCR3(pVM, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3));
     129# endif
     130
     131        pgmPoolFreeByPage(pPool, pOldShwPageCR3, NIL_PGMPOOL_IDX, UINT32_MAX);
     132        pVCpu->pgm.s.pShwPageCR3R3 = NIL_RTR3PTR;
     133        pVCpu->pgm.s.pShwPageCR3RC = NIL_RTRCPTR;
     134        pVCpu->pgm.s.pShwPageCR3R0 = NIL_RTR0PTR;
     135    }
     136
     137    /* construct a fake address. */
     138    GCPhysCR3 = RT_BIT_64(63);
     139    PPGMPOOLPAGE pNewShwPageCR3;
     140    int rc = pgmPoolAlloc(pVM, GCPhysCR3, BTH_PGMPOOLKIND_ROOT, PGMPOOLACCESS_DONTCARE, PGM_A20_IS_ENABLED(pVCpu),
     141                          NIL_PGMPOOL_IDX, UINT32_MAX, false /*fLockPage*/,
     142                          &pNewShwPageCR3);
     143    if (rc == VERR_PGM_POOL_FLUSHED)
     144    {
     145        Log(("Bth-Enter: PGM pool flushed -> signal sync cr3\n"));
     146        Assert(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
     147        pgmUnlock(pVM);
     148        return VINF_PGM_SYNC_CR3;
     149    }
     150    AssertRCReturn(rc, rc);
     151
     152    pVCpu->pgm.s.pShwPageCR3R3 = (R3PTRTYPE(PPGMPOOLPAGE))MMHyperCCToR3(pVM, pNewShwPageCR3);
     153    pVCpu->pgm.s.pShwPageCR3RC = (RCPTRTYPE(PPGMPOOLPAGE))MMHyperCCToRC(pVM, pNewShwPageCR3);
     154    pVCpu->pgm.s.pShwPageCR3R0 = (R0PTRTYPE(PPGMPOOLPAGE))MMHyperCCToR0(pVM, pNewShwPageCR3);
     155
     156    /* Mark the page as locked; disallow flushing. */
     157    pgmPoolLockPage(pPool, pNewShwPageCR3);
     158
     159    /* Set the current hypervisor CR3. */
     160    CPUMSetHyperCR3(pVCpu, PGMGetHyperCR3(pVCpu));
     161
     162# ifndef PGM_WITHOUT_MAPPINGS
     163    /* Apply all hypervisor mappings to the new CR3. */
     164    rc = pgmMapActivateCR3(pVM, pNewShwPageCR3);
     165# endif
     166
     167    pgmUnlock(pVM);
     168    return rc;
     169#else
     170    NOREF(pVCpu); NOREF(GCPhysCR3);
     171    return VINF_SUCCESS;
     172#endif
     173}
     174
    88175
    89176#ifndef IN_RING3
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