VirtualBox

Changeset 92480 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Nov 17, 2021 2:01:29 PM (3 years ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:10092 EPT misconfiguration and some fixes and adjustments to EPT SLAT code.

File:
1 edited

Legend:

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

    r92476 r92480  
    1717
    1818#if PGM_GST_TYPE == PGM_TYPE_EPT
     19DECLINLINE(bool) PGM_GST_SLAT_NAME_EPT(WalkIsPermValid)(PCVMCPUCC pVCpu, uint64_t uEntry)
     20{
     21    if (!(uEntry & VMX_BF_EPT_PT_READ_MASK))
     22    {
     23        if (uEntry & VMX_BF_EPT_PT_WRITE_MASK)
     24            return false;
     25
     26        Assert(!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fVmxModeBasedExecuteEpt);
     27        if (   !RT_BF_GET(pVCpu->pgm.s.uEptVpidCapMsr, VMX_BF_EPT_VPID_CAP_EXEC_ONLY)
     28            && (uEntry & VMX_BF_EPT_PT_EXECUTE_MASK))
     29            return false;
     30    }
     31    return true;
     32}
     33
     34
     35DECLINLINE(bool) PGM_GST_SLAT_NAME_EPT(WalkIsMemTypeValid)(uint64_t uEntry, uint8_t uLevel)
     36{
     37    Assert(uLevel >= 3 && uLevel <= 1); NOREF(uLevel);
     38    uint64_t const fEptMemTypeMask = uEntry & VMX_BF_EPT_PT_MEMTYPE_MASK;
     39    if (   fEptMemTypeMask == EPT_E_MEMTYPE_INVALID_2
     40        || fEptMemTypeMask == EPT_E_MEMTYPE_INVALID_3
     41        || fEptMemTypeMask == EPT_E_MEMTYPE_INVALID_7)
     42        return false;
     43    return true;
     44}
     45
     46
    1947DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(PCVMCPUCC pVCpu, PPGMPTWALK pWalk, uint64_t uEntry, uint8_t uLevel)
    2048{
     
    4371{
    4472    NOREF(pVCpu);
    45     pWalk->fRsvdError = true;
    46     pWalk->uLevel     = uLevel;
     73    pWalk->fRsvdError  = true;
     74    pWalk->uLevel      = uLevel;
     75    pWalk->enmSlatFail = PGMSLATFAIL_EPT_MISCONFIG;
    4776    return VERR_PAGE_TABLE_NOT_PRESENT;
    4877}
     
    5281                                            PPGMPTWALK pWalk, PGSTPTWALK pGstWalk)
    5382{
    54     /** @todo implement figuring out fEptMisconfig. */
    5583    /*
    5684     * Init walk structures.
     
    87115     * Do the walk.
    88116     */
     117    int const rc2 = pgmGstGetEptPML4PtrEx(pVCpu, &pGstWalk->pPml4);
     118    if (RT_SUCCESS(rc2))
     119    { /* likely */ }
     120    else
     121        return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 4, rc2);
     122
    89123    uint64_t fEffective;
    90124    {
    91         int rc = pgmGstGetEptPML4PtrEx(pVCpu, &pGstWalk->pPml4);
    92         if (RT_SUCCESS(rc)) { /* probable */ }
    93         else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 4, rc);
    94 
     125        /*
     126         * PML4E.
     127         */
    95128        PEPTPML4E pPml4e;
    96129        pGstWalk->pPml4e = pPml4e = &pGstWalk->pPml4->a[(GCPhysNested >> EPT_PML4_SHIFT) & EPT_PML4_MASK];
     
    116149        pWalk->fEffective = fEffective;
    117150
    118         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pml4e.u & EPT_PML4E_PG_MASK, &pGstWalk->pPdpt);
     151        int const rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pml4e.u & EPT_PML4E_PG_MASK, &pGstWalk->pPdpt);
    119152        if (RT_SUCCESS(rc)) { /* probable */ }
    120153        else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 3, rc);
    121154    }
    122155    {
     156        /*
     157         * PDPTE.
     158         */
    123159        PEPTPDPTE pPdpte;
    124160        pGstWalk->pPdpte = pPdpte = &pGstWalk->pPdpt->a[(GCPhysNested >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
     
    143179            pWalk->fEffective = fEffective;
    144180        }
    145         else if (GST_IS_BIG_PDPE_VALID(pVCpu, Pdpte))
     181        else if (   GST_IS_BIG_PDPE_VALID(pVCpu, Pdpte)
     182                 && PGM_GST_SLAT_NAME_EPT(WalkIsMemTypeValid)(Pdpte.u, 3))
    146183        {
    147184            uint64_t const fEptAttrs     = Pdpte.u & EPT_PDPTE1G_ATTR_MASK;
     
    168205        }
    169206        else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 3);
    170     }
    171     {
     207
     208        int const rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pdpte.u & EPT_PDPTE_PG_MASK, &pGstWalk->pPd);
     209        if (RT_SUCCESS(rc)) { /* probable */ }
     210        else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 3, rc);
     211    }
     212    {
     213        /*
     214         * PDE.
     215         */
    172216        PGSTPDE pPde;
    173217        pGstWalk->pPde  = pPde  = &pGstWalk->pPd->a[(GCPhysNested >> GST_PD_SHIFT) & GST_PD_MASK];
     
    178222        else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, Pde.u, 2);
    179223
    180         if ((Pde.u & X86_PDE_PS) && GST_IS_PSE_ACTIVE(pVCpu))
     224        /* The order of the following 2 "if" statements matter. */
     225        if (GST_IS_PDE_VALID(pVCpu, Pde))
    181226        {
    182             if (RT_LIKELY(GST_IS_BIG_PDE_VALID(pVCpu, Pde))) { /* likely */ }
    183             else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 2);
    184 
     227            uint64_t const fEptAttrs     = Pde.u & EPT_PDE_ATTR_MASK;
     228            uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
     229            uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
     230            uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
     231            uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
     232            fEffective &= RT_BF_MAKE(PGM_PTATTRS_R, fRead)
     233                        | RT_BF_MAKE(PGM_PTATTRS_W, fWrite)
     234                        | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
     235                        | (fEffectiveEpt & fCumulativeEpt);
     236            pWalk->fEffective = fEffective;
     237
     238        }
     239        else if (   GST_IS_BIG_PDE_VALID(pVCpu, Pde)
     240                 && PGM_GST_SLAT_NAME_EPT(WalkIsMemTypeValid)(Pde.u, 2))
     241        {
    185242            uint64_t const fEptAttrs     = Pde.u & EPT_PDE2M_ATTR_MASK;
    186243            uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
     
    205262            return VINF_SUCCESS;
    206263        }
    207 
    208         if (RT_UNLIKELY(!GST_IS_PDE_VALID(pVCpu, Pde)))
    209             return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 2);
    210 
    211         uint64_t const fEptAttrs     = Pde.u & EPT_PDE_ATTR_MASK;
    212         uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
    213         uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    214         uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    215         uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
    216         fEffective &= RT_BF_MAKE(PGM_PTATTRS_R, fRead)
    217                     | RT_BF_MAKE(PGM_PTATTRS_W, fWrite)
    218                     | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
    219                     | (fEffectiveEpt & fCumulativeEpt);
    220         pWalk->fEffective = fEffective;
     264        else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 2);
    221265
    222266        int const rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GST_GET_PDE_GCPHYS(Pde), &pGstWalk->pPt);
     
    225269    }
    226270    {
     271        /*
     272         * PTE.
     273         */
    227274        PGSTPTE pPte;
    228275        pGstWalk->pPte  = pPte  = &pGstWalk->pPt->a[(GCPhysNested >> GST_PT_SHIFT) & GST_PT_MASK];
     
    233280        else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, Pte.u, 1);
    234281
    235         if (RT_LIKELY(GST_IS_PTE_VALID(pVCpu, Pte))) { /* likely */ }
    236         else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 1);
     282        if (   GST_IS_PTE_VALID(pVCpu, Pte)
     283            && PGM_GST_SLAT_NAME_EPT(WalkIsMemTypeValid)(Pte.u, 1))
     284        { /* likely*/  }
     285        else
     286            return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 1);
    237287
    238288        uint64_t const fEptAttrs     = Pte.u & EPT_PTE_ATTR_MASK;
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