VirtualBox

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


Ignore:
Timestamp:
Nov 10, 2021 9:05:02 AM (3 years ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:10092 Use bit 63 for NX in the PGMPTATTRS, adjusted guest page walk template and SLAT EPT page walk template code.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r92297 r92311  
    149149# endif
    150150
    151     uint64_t fEffective = X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A | 1;
     151    uint64_t fEffective = X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A | 1;  /** @todo can this default assignment be removed? */
    152152    {
    153153# if PGM_GST_TYPE == PGM_TYPE_AMD64
     
    170170        else return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 4);
    171171
    172         pWalk->Core.fEffective = fEffective = (Pml4e.u & (X86_PML4E_RW | X86_PML4E_US | X86_PML4E_PWT | X86_PML4E_PCD | X86_PML4E_A))
    173                                             | ((Pml4e.u >> 63) ^ 1) /*NX */;
     172        pWalk->Core.fEffective = fEffective = Pml4e.u & (  X86_PML4E_RW  | X86_PML4E_US | X86_PML4E_PWT
     173                                                         | X86_PML4E_PCD | X86_PML4E_A  | X86_PML4E_NX);
    174174
    175175        /*
     
    205205# if PGM_GST_TYPE == PGM_TYPE_AMD64
    206206        pWalk->Core.fEffective = fEffective &= (Pdpe.u & (X86_PDPE_RW | X86_PDPE_US | X86_PDPE_PWT | X86_PDPE_PCD | X86_PDPE_A))
    207                                              | ((Pdpe.u >> 63) ^ 1) /*NX */;
    208 # else
     207                                             | (Pdpe.u & X86_PDPE_LM_NX);
     208# else
     209        /* NX in the legacy-mode PAE PDPE is reserved. The valid check above ensures the NX bit is not set. */
    209210        pWalk->Core.fEffective = fEffective  = X86_PDPE_RW  | X86_PDPE_US | X86_PDPE_A
    210                                              | (Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD))
    211                                              | ((Pdpe.u >> 63) ^ 1) /*NX */;
     211                                             | (Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD));
    212212# endif
    213213
     
    248248# else
    249249            fEffective &= (Pde.u & (X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A))
    250                         | ((Pde.u >> 63) ^ 1) /*NX */;
     250                        | (Pde.u & X86_PDE2M_PAE_NX);
    251251# endif
    252252            fEffective |= Pde.u & (X86_PDE4M_D | X86_PDE4M_G);
     
    257257            pWalk->Core.fEffectiveUS = !!(fEffective & X86_PTE_US);
    258258# if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
    259             pWalk->Core.fEffectiveNX = !(fEffective & 1) && GST_IS_NX_ACTIVE(pVCpu);
     259            pWalk->Core.fEffectiveNX = (fEffective & X86_PTE_PAE_NX) && GST_IS_NX_ACTIVE(pVCpu);
    260260# else
    261261            pWalk->Core.fEffectiveNX = false;
     
    280280# else
    281281        pWalk->Core.fEffective = fEffective &= (Pde.u & (X86_PDE_RW | X86_PDE_US | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A))
    282                                              | ((Pde.u >> 63) ^ 1) /*NX */;
     282                                             | (Pde.u & X86_PDE_PAE_NX);
    283283# endif
    284284
     
    313313# else
    314314        fEffective &= (Pte.u & (X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A))
    315                    |  ((Pte.u >> 63) ^ 1) /*NX */;
     315                   |  (Pte.u & X86_PTE_PAE_NX);
    316316# endif
    317317        fEffective |= Pte.u & (X86_PTE_D | X86_PTE_PAT | X86_PTE_G);
     
    321321        pWalk->Core.fEffectiveUS = !!(fEffective & X86_PTE_US);
    322322# if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
    323         pWalk->Core.fEffectiveNX = !(fEffective & 1) && GST_IS_NX_ACTIVE(pVCpu);
     323        pWalk->Core.fEffectiveNX = (fEffective & X86_PTE_PAE_NX) && GST_IS_NX_ACTIVE(pVCpu);
    324324# else
    325325        pWalk->Core.fEffectiveNX = false;
     
    327327        pWalk->Core.fSucceeded   = true;
    328328
    329         RTGCPHYS GCPhysPte = GST_GET_PDE_GCPHYS(Pte)        /** @todo This should be GST_GET_PTE_GCPHYS. */
     329        RTGCPHYS GCPhysPte = GST_GET_PTE_GCPHYS(Pte)
    330330                           | (GCPtr & PAGE_OFFSET_MASK);
    331331# ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     
    387387                                                | PGM_PTATTRS_US_MASK))
    388388# if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
    389                      | ((RT_BF_GET(Walk.Core.fEffective, PGM_PTATTRS_X) ^ 1) << X86_PTE_PAE_BIT_NX)
     389                     | (Walk.Core.fEffective & PGM_PTATTRS_NX_MASK)
    390390# endif
    391391                     ;
     
    397397                                                | PGM_PTATTRS_PAT_MASK))
    398398# if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
    399                      | ((RT_BF_GET(Walk.Core.fEffective, PGM_PTATTRS_X) ^ 1) << X86_PTE_PAE_BIT_NX)
     399                     | (Walk.Core.fEffective & PGM_PTATTRS_NX_MASK)
    400400# endif
    401401                     ;
  • trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h

    r92257 r92311  
    4747                                            PGSTPTWALK pWalk)
    4848{
     49    /*
     50     * Init walk structure.
     51     */
    4952    int rc;
    5053    RT_ZERO(*pWalk);
     
    5457    pWalk->Core.fIsLinearAddrValid = fIsLinearAddrValid;
    5558
     59    /*
     60     * Figure out EPT attributes that are cumulative (logical-AND) across page walks.
     61     *   - R, W, X_SUPER are unconditionally cumulative.
     62     *     See Intel spec. Table 26-7 "Exit Qualification for EPT Violations".
     63     *
     64     *   - X_USER is Cumulative but relevant only when mode-based execute control for EPT
     65     *     which we currently don't support it (asserted below).
     66     *
     67     *   - MEMTYPE is not cumulative and only applicable to the final paging entry.
     68     *
     69     *   - A, D EPT bits map to the regular page-table bit positions. Thus, they're not
     70     *     included in the mask below and handled separately. Accessed bits are
     71     *     cumulative but dirty bits are not cumulative as they're only applicable to
     72     *     the final paging entry.
     73     */
     74    Assert(!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fVmxModeBasedExecuteEpt);
     75    uint64_t const fCumulativeEpt = PGM_PTATTRS_EPT_R_MASK
     76                                  | PGM_PTATTRS_EPT_W_MASK
     77                                  | PGM_PTATTRS_EPT_X_SUPER_MASK;
     78
     79    /*
     80     * Do the walk.
     81     */
    5682    uint64_t fEffective;
    5783    {
     
    7399        Assert(!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fVmxModeBasedExecuteEpt);
    74100        uint64_t const fEptAttrs     = Pml4e.u & EPT_PML4E_ATTR_MASK;
    75         uint8_t const fExecute       = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_EXECUTE);
    76         uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
    77         uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    78101        uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    79102        uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
    80         pWalk->Core.fEffective = fEffective = RT_BF_MAKE(PGM_PTATTRS_X,  fExecute)
    81                                             | RT_BF_MAKE(PGM_PTATTRS_RW, fRead & fWrite)
    82                                             | RT_BF_MAKE(PGM_PTATTRS_US, 1)
    83                                             | RT_BF_MAKE(PGM_PTATTRS_A,  fAccessed)
    84                                             | fEffectiveEpt;
     103        fEffective = RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
     104                   | fEffectiveEpt;
     105        pWalk->Core.fEffective = fEffective;
    85106
    86107        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pml4e.u & EPT_PML4E_PG_MASK, &pWalk->pPdpt);
     
    100121        if (GST_IS_PDPE_VALID(pVCpu, Pdpte))
    101122        {
    102             uint64_t const fEptAttrs = Pdpte.u & EPT_PDPTE_ATTR_MASK;
    103             uint8_t const fExecute   = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_EXECUTE);
    104             uint8_t const fWrite     = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    105             uint8_t const fAccessed  = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
     123            uint64_t const fEptAttrs     = Pdpte.u & EPT_PDPTE_ATTR_MASK;
     124            uint8_t const  fAccessed     = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    106125            uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
    107             pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_PTATTRS_X,  fExecute)
    108                                                  | RT_BF_MAKE(PGM_PTATTRS_RW, fWrite)
    109                                                  | RT_BF_MAKE(PGM_PTATTRS_US, 1)
    110                                                  | RT_BF_MAKE(PGM_PTATTRS_A,  fAccessed)
    111                                                  | fEffectiveEpt;
     126            fEffective &= RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
     127                       |  (fEffectiveEpt & fCumulativeEpt);
     128            pWalk->Core.fEffective = fEffective;
    112129        }
    113130        else if (GST_IS_BIG_PDPE_VALID(pVCpu, Pdpte))
    114131        {
    115             uint64_t const fEptAttrs  = Pdpte.u & EPT_PDPTE1G_ATTR_MASK;
    116             uint8_t const fExecute    = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_EXECUTE);
    117             uint8_t const fWrite      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    118             uint8_t const fAccessed   = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    119             uint8_t const fDirty      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
     132            uint64_t const fEptAttrs     = Pdpte.u & EPT_PDPTE1G_ATTR_MASK;
     133            uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
     134            uint8_t const fDirty         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
     135            uint8_t const fMemType       = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_MEMTYPE);
    120136            uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
    121             pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_PTATTRS_X,           fExecute)
    122                                                  | RT_BF_MAKE(PGM_PTATTRS_RW,          fWrite)
    123                                                  | RT_BF_MAKE(PGM_PTATTRS_US,          1)
    124                                                  | RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
    125                                                  | RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    126                                                  | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, 0)
    127                                                  | fEffectiveEpt;
    128             pWalk->Core.fEffectiveRW = !!(fEffective & X86_PTE_RW);
     137            fEffective &= RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
     138                       |  (fEffectiveEpt & fCumulativeEpt);
     139            fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
     140                       |  RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
     141            pWalk->Core.fEffective = fEffective;
     142
     143            pWalk->Core.fEffectiveRW = !!(fEffective & PGM_PTATTRS_RW_MASK);    /** @todo RW isn't copied from EPT R, W. This will break callers who use RW for EPT attributes. */
    129144            pWalk->Core.fEffectiveUS = true;
    130             pWalk->Core.fEffectiveNX = !fExecute;
     145            pWalk->Core.fEffectiveNX = !(fEffective & PGM_PTATTRS_EPT_X_SUPER_MASK);
    131146            pWalk->Core.fGigantPage  = true;
    132147            pWalk->Core.fSucceeded   = true;
     
    150165            else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 2);
    151166
    152             uint64_t const fEptAttrs  = Pde.u & EPT_PDE2M_ATTR_MASK;
    153             uint8_t const fExecute    = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_EXECUTE);
    154             uint8_t const fWrite      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    155             uint8_t const fAccessed   = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    156             uint8_t const fDirty      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
     167            uint64_t const fEptAttrs     = Pde.u & EPT_PDE2M_ATTR_MASK;
     168            uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
     169            uint8_t const fDirty         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
     170            uint8_t const fMemType       = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_MEMTYPE);
    157171            uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
    158             pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_PTATTRS_X,           fExecute)
    159                                                  | RT_BF_MAKE(PGM_PTATTRS_RW,          fWrite)
    160                                                  | RT_BF_MAKE(PGM_PTATTRS_US,          1)
    161                                                  | RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
    162                                                  | RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    163                                                  | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, 0)
    164                                                  | fEffectiveEpt;
    165             pWalk->Core.fEffectiveRW = !!(fEffective & X86_PTE_RW);
     172
     173            fEffective &= RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
     174                       |  (fEffectiveEpt & fCumulativeEpt);
     175            fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
     176                       |  RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
     177            pWalk->Core.fEffective = fEffective;
     178            pWalk->Core.fEffectiveRW = !!(fEffective & PGM_PTATTRS_RW_MASK); /** @todo RW isn't copied from EPT R, W. This will break callers who use RW for EPT attributes. */
    166179            pWalk->Core.fEffectiveUS = true;
    167             pWalk->Core.fEffectiveNX = !fExecute;
     180            pWalk->Core.fEffectiveNX = !(fEffective & PGM_PTATTRS_EPT_X_SUPER_MASK);
    168181            pWalk->Core.fBigPage     = true;
    169182            pWalk->Core.fSucceeded   = true;
     
    177190            return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 2);
    178191
    179         uint64_t const fEptAttrs = Pde.u & EPT_PDE_ATTR_MASK;
    180         uint8_t const fExecute   = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_EXECUTE);
    181         uint8_t const fWrite     = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    182         uint8_t const fAccessed  = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
     192        uint64_t const fEptAttrs     = Pde.u & EPT_PDE_ATTR_MASK;
     193        uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    183194        uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
    184         pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_PTATTRS_X,  fExecute)
    185                                              | RT_BF_MAKE(PGM_PTATTRS_RW, fWrite)
    186                                              | RT_BF_MAKE(PGM_PTATTRS_US, 1)
    187                                              | RT_BF_MAKE(PGM_PTATTRS_A,  fAccessed)
    188                                              | fEffectiveEpt;
     195
     196        fEffective &= RT_BF_MAKE(PGM_PTATTRS_A,  fAccessed)
     197                   |  (fEffectiveEpt & fCumulativeEpt);
     198        pWalk->Core.fEffective = fEffective;
    189199
    190200        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GST_GET_PDE_GCPHYS(Pde), &pWalk->pPt);
     
    204214        else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 1);
    205215
    206         uint64_t const fEptAttrs  = Pte.u & EPT_PTE_ATTR_MASK;
    207         uint8_t const fExecute    = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_EXECUTE);
    208         uint8_t const fWrite      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    209         uint8_t const fAccessed   = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    210         uint8_t const fDirty      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
     216        uint64_t const fEptAttrs     = Pte.u & EPT_PTE_ATTR_MASK;
     217        uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
     218        uint8_t const fDirty         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
     219        uint8_t const fMemType       = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_MEMTYPE);
    211220        uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
    212         pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_PTATTRS_X,           fExecute)
    213                                              | RT_BF_MAKE(PGM_PTATTRS_RW,          fWrite)
    214                                              | RT_BF_MAKE(PGM_PTATTRS_US,          1)
    215                                              | RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
    216                                              | RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    217                                              | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, 0)
    218                                              | fEffectiveEpt;
    219         pWalk->Core.fEffectiveRW = !!(fEffective & X86_PTE_RW);
     221        fEffective &= RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
     222                   |  (fEffectiveEpt & fCumulativeEpt);
     223        fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
     224                   |  RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
     225        pWalk->Core.fEffective = fEffective;
     226
     227        pWalk->Core.fEffectiveRW = !!(fEffective & PGM_PTATTRS_RW_MASK); /** @todo RW isn't copied from EPT R, W. This will break callers who use RW for EPT attributes. */
    220228        pWalk->Core.fEffectiveUS = true;
    221         pWalk->Core.fEffectiveNX = !fExecute;
     229        pWalk->Core.fEffectiveNX = !(fEffective & PGM_PTATTRS_EPT_X_SUPER_MASK);
    222230        pWalk->Core.fSucceeded   = true;
    223231        pWalk->Core.GCPhys       = GST_GET_PTE_GCPHYS(Pte)
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