VirtualBox

Changeset 92257 in vbox for trunk/src


Ignore:
Timestamp:
Nov 8, 2021 9:04:38 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
148097
Message:

VMM: Nested VMX: bugref:10092 Defined a combined layout for regular page table and extended page table (Intel EPT) attributes. Adjusted EPT SLAT code accordingly.

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

Legend:

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

    r92186 r92257  
    149149# endif
    150150
    151     uint32_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;
    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 = ((uint32_t)Pml4e.u & (X86_PML4E_RW | X86_PML4E_US | X86_PML4E_PWT | X86_PML4E_PCD | X86_PML4E_A))
    173                                             | ((uint32_t)(Pml4e.u >> 63) ^ 1) /*NX */;
     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 */;
    174174
    175175        /*
     
    204204
    205205# if PGM_GST_TYPE == PGM_TYPE_AMD64
    206         pWalk->Core.fEffective = fEffective &= ((uint32_t)Pdpe.u & (X86_PDPE_RW | X86_PDPE_US | X86_PDPE_PWT | X86_PDPE_PCD | X86_PDPE_A))
    207                                              | ((uint32_t)(Pdpe.u >> 63) ^ 1) /*NX */;
     206        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 */;
    208208# else
    209209        pWalk->Core.fEffective = fEffective  = X86_PDPE_RW  | X86_PDPE_US | X86_PDPE_A
    210                                              | ((uint32_t)Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD))
    211                                              | ((uint32_t)(Pdpe.u >> 63) ^ 1) /*NX */;
     210                                             | (Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD))
     211                                             | ((Pdpe.u >> 63) ^ 1) /*NX */;
    212212# endif
    213213
     
    245245             */
    246246# if PGM_GST_TYPE == PGM_TYPE_32BIT
    247             fEffective &= Pde.u & (X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A);
    248 # else
    249             fEffective &= ((uint32_t)Pde.u & (X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A))
    250                         | ((uint32_t)(Pde.u >> 63) ^ 1) /*NX */;
    251 # endif
    252             fEffective |= (uint32_t)Pde.u & (X86_PDE4M_D | X86_PDE4M_G);
    253             fEffective |= (uint32_t)(Pde.u & X86_PDE4M_PAT) >> X86_PDE4M_PAT_SHIFT;
     247            fEffective &=  Pde.u & (X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A);
     248# else
     249            fEffective &= (Pde.u & (X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A))
     250                        | ((Pde.u >> 63) ^ 1) /*NX */;
     251# endif
     252            fEffective |= Pde.u & (X86_PDE4M_D | X86_PDE4M_G);
     253            fEffective |= (Pde.u & X86_PDE4M_PAT) >> X86_PDE4M_PAT_SHIFT;
    254254            pWalk->Core.fEffective = fEffective;
    255255
     
    277277            return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 2);
    278278# if PGM_GST_TYPE == PGM_TYPE_32BIT
    279         pWalk->Core.fEffective = fEffective &= Pde.u & (X86_PDE_RW  | X86_PDE_US | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A);
    280 # else
    281         pWalk->Core.fEffective = fEffective &= ((uint32_t)Pde.u & (X86_PDE_RW | X86_PDE_US | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A))
    282                                              | ((uint32_t)(Pde.u >> 63) ^ 1) /*NX */;
     279        pWalk->Core.fEffective = fEffective &= Pde.u & (X86_PDE_RW | X86_PDE_US | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A);
     280# else
     281        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 */;
    283283# endif
    284284
     
    310310         */
    311311# if PGM_GST_TYPE == PGM_TYPE_32BIT
    312         fEffective &= Pte.u & (X86_PTE_RW  | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A);
    313 # else
    314         fEffective &= ((uint32_t)Pte.u & (X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A))
    315                    | ((uint32_t)(Pte.u >> 63) ^ 1) /*NX */;
    316 # endif
    317         fEffective |= (uint32_t)Pte.u & (X86_PTE_D | X86_PTE_PAT | X86_PTE_G);
     312        fEffective &= Pte.u & (X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A);
     313# else
     314        fEffective &= (Pte.u & (X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A))
     315                   |  ((Pte.u >> 63) ^ 1) /*NX */;
     316# endif
     317        fEffective |= Pte.u & (X86_PTE_D | X86_PTE_PAT | X86_PTE_G);
    318318        pWalk->Core.fEffective = fEffective;
    319319
  • trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h

    r92190 r92257  
    5454    pWalk->Core.fIsLinearAddrValid = fIsLinearAddrValid;
    5555
    56     uint32_t fEffective;
     56    uint64_t fEffective;
    5757    {
    5858        rc = pgmGstGetEptPML4PtrEx(pVCpu, &pWalk->pPml4);
     
    7777        uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    7878        uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    79         uint32_t const fEffectiveEpt = ((uint32_t)fEptAttrs << PGMPTWALK_EFF_EPT_ATTR_SHIFT) & PGMPTWALK_EFF_EPT_ATTR_MASK;
    80         pWalk->Core.fEffective = fEffective = RT_BF_MAKE(PGM_BF_PTWALK_EFF_X,  fExecute)
    81                                             | RT_BF_MAKE(PGM_BF_PTWALK_EFF_RW, fRead & fWrite)
    82                                             | RT_BF_MAKE(PGM_BF_PTWALK_EFF_US, 1)
    83                                             | RT_BF_MAKE(PGM_BF_PTWALK_EFF_A,  fAccessed)
     79        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)
    8484                                            | fEffectiveEpt;
    8585
     
    104104            uint8_t const fWrite     = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    105105            uint8_t const fAccessed  = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    106             uint32_t const fEffectiveEpt = ((uint32_t)fEptAttrs << PGMPTWALK_EFF_EPT_ATTR_SHIFT) & PGMPTWALK_EFF_EPT_ATTR_MASK;
    107             pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_BF_PTWALK_EFF_X,  fExecute)
    108                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_RW, fWrite)
    109                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_US, 1)
    110                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_A,  fAccessed)
     106            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)
    111111                                                 | fEffectiveEpt;
    112112        }
     
    118118            uint8_t const fAccessed   = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    119119            uint8_t const fDirty      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
    120             uint32_t const fEffectiveEpt = ((uint32_t)fEptAttrs << PGMPTWALK_EFF_EPT_ATTR_SHIFT) & PGMPTWALK_EFF_EPT_ATTR_MASK;
    121             pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_BF_PTWALK_EFF_X,       fExecute)
    122                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_RW,      fWrite)
    123                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_US,      1)
    124                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_A,       fAccessed)
    125                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_D,       fDirty)
    126                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_MEMTYPE, 0)
     120            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)
    127127                                                 | fEffectiveEpt;
    128128            pWalk->Core.fEffectiveRW = !!(fEffective & X86_PTE_RW);
     
    155155            uint8_t const fAccessed   = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    156156            uint8_t const fDirty      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
    157             uint32_t fEffectiveEpt = ((uint32_t)fEptAttrs << PGMPTWALK_EFF_EPT_ATTR_SHIFT) & PGMPTWALK_EFF_EPT_ATTR_MASK;
    158             pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_BF_PTWALK_EFF_X,       fExecute)
    159                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_RW,      fWrite)
    160                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_US,      1)
    161                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_A,       fAccessed)
    162                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_D,       fDirty)
    163                                                  | RT_BF_MAKE(PGM_BF_PTWALK_EFF_MEMTYPE, 0)
     157            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)
    164164                                                 | fEffectiveEpt;
    165165            pWalk->Core.fEffectiveRW = !!(fEffective & X86_PTE_RW);
     
    181181        uint8_t const fWrite     = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
    182182        uint8_t const fAccessed  = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    183         uint32_t const fEffectiveEpt = ((uint32_t)fEptAttrs << PGMPTWALK_EFF_EPT_ATTR_SHIFT) & PGMPTWALK_EFF_EPT_ATTR_MASK;
    184         pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_BF_PTWALK_EFF_X,  fExecute)
    185                                              | RT_BF_MAKE(PGM_BF_PTWALK_EFF_RW, fWrite)
    186                                              | RT_BF_MAKE(PGM_BF_PTWALK_EFF_US, 1)
    187                                              | RT_BF_MAKE(PGM_BF_PTWALK_EFF_A,  fAccessed)
     183        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)
    188188                                             | fEffectiveEpt;
    189189
     
    209209        uint8_t const fAccessed   = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
    210210        uint8_t const fDirty      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
    211         uint32_t fEffectiveEpt = ((uint32_t)fEptAttrs << PGMPTWALK_EFF_EPT_ATTR_SHIFT) & PGMPTWALK_EFF_EPT_ATTR_MASK;
    212         pWalk->Core.fEffective = fEffective &= RT_BF_MAKE(PGM_BF_PTWALK_EFF_X,       fExecute)
    213                                              | RT_BF_MAKE(PGM_BF_PTWALK_EFF_RW,      fWrite)
    214                                              | RT_BF_MAKE(PGM_BF_PTWALK_EFF_US,      1)
    215                                              | RT_BF_MAKE(PGM_BF_PTWALK_EFF_A,       fAccessed)
    216                                              | RT_BF_MAKE(PGM_BF_PTWALK_EFF_D,       fDirty)
    217                                              | RT_BF_MAKE(PGM_BF_PTWALK_EFF_MEMTYPE, 0)
     211        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)
    218218                                             | fEffectiveEpt;
    219219        pWalk->Core.fEffectiveRW = !!(fEffective & X86_PTE_RW);
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r92186 r92257  
    23312331
    23322332
     2333/** @name PGMPTATTRS
     2334 *
     2335 * PGM page-table attributes.
     2336 *
     2337 * This is VirtualBox's combined page table attributes. It combines regular page
     2338 * table and Intel EPT attributes. It's 64-bit in size so there's ample room for
     2339 * bits added in the future to EPT or regular page tables (for e.g. Protection Key).
     2340 *
     2341 * The following bits map 1:1 (shifted by PGM_PTATTRS_EPT_SHIFT) to the Intel EPT
     2342 * attributes as these are unique to EPT and fit within 64-bits despite the shift:
     2343 *   - R           (Read access).
     2344 *   - W           (Write access).
     2345 *   - X_SUPER     (Execute or execute access for supervisor-mode linear addresses).
     2346 *   - EPT_MEMTYPE (EPT memory type).
     2347 *   - IGNORE_PAT  (Ignore PAT memory type).
     2348 *   - X_USER      (Execute access for user-mode linear addresses).
     2349 *
     2350 * The following EPT attributes are mapped to the following positions because they
     2351 * exist in the regular page tables at these positions OR are exclusive to EPT and
     2352 * have been mapped to arbitrarily chosen positions:
     2353 *   - A                (Accessed)                - EPT bit  8 maps to bit  5.
     2354 *   - D                (Dirty)                   - EPT bit  9 maps to bit  6.
     2355 *   - SUPER_SHW_STACK  (Supervisor Shadow Stack) - EPT bit 60 maps to bit 24.
     2356 *   - SUPPRESS_VE_XCPT (Suppress \#VE exception) - EPT bit 63 maps to bit 25.
     2357 *
     2358 * Bits 11:9 and bit 43 are deliberately kept unused (they correspond to bits 11:9
     2359 * in the page-table structures and to bit 11 in the EPT structures respectively) as
     2360 * they're reserved for use by software and we may want to preserve them in the
     2361 * future.
     2362 *
     2363 * @{ */
     2364typedef uint64_t PGMPTATTRS;
     2365/** Pointer to a PGMPTATTRS type. */
     2366typedef PGMPTATTRS *PPGMPTATTRS;
     2367
     2368/** Execute bit (!NX). */
     2369#define PGM_PTATTRS_X_SHIFT                         0
     2370#define PGM_PTATTRS_X_MASK                          RT_BIT_64(PGM_PTATTRS_X_SHIFT)
     2371/** Read and write access bit. */
     2372#define PGM_PTATTRS_RW_SHIFT                        1
     2373#define PGM_PTATTRS_RW_MASK                         RT_BIT_64(PGM_PTATTRS_RW_SHIFT)
     2374/** User-mode access bit. */
     2375#define PGM_PTATTRS_US_SHIFT                        2
     2376#define PGM_PTATTRS_US_MASK                         RT_BIT_64(PGM_PTATTRS_US_SHIFT)
     2377/** Write through cache bit. */
     2378#define PGM_PTATTRS_PWT_SHIFT                       3
     2379#define PGM_PTATTRS_PWT_MASK                        RT_BIT_64(PGM_PTATTRS_PWT_SHIFT)
     2380/** Cache disabled bit. */
     2381#define PGM_PTATTRS_PCD_SHIFT                       4
     2382#define PGM_PTATTRS_PCD_MASK                        RT_BIT_64(PGM_PTATTRS_PCD_SHIFT)
     2383/** Accessed bit. */
     2384#define PGM_PTATTRS_A_SHIFT                         5
     2385#define PGM_PTATTRS_A_MASK                          RT_BIT_64(PGM_PTATTRS_A_SHIFT)
     2386/** Dirty bit. */
     2387#define PGM_PTATTRS_D_SHIFT                         6
     2388#define PGM_PTATTRS_D_MASK                          RT_BIT_64(PGM_PTATTRS_D_SHIFT)
     2389/** The PAT bit. */
     2390#define PGM_PTATTRS_PAT_SHIFT                       7
     2391#define PGM_PTATTRS_PAT_MASK                        RT_BIT_64(PGM_PTATTRS_PAT_SHIFT)
     2392/** The global bit. */
     2393#define PGM_PTATTRS_G_SHIFT                         8
     2394#define PGM_PTATTRS_G_MASK                          RT_BIT_64(PGM_PTATTRS_G_SHIFT)
     2395/** Reserved (bits 11:9) unused. */
     2396#define PGM_PTATTRS_RSVD_11_9_SHIFT                 9
     2397#define PGM_PTATTRS_RSVD_11_9_MASK                  UINT64_C(0x0000000000000e00)
     2398/** Read access bit - EPT only. */
     2399#define PGM_PTATTRS_EPT_R_SHIFT                     12
     2400#define PGM_PTATTRS_EPT_R_MASK                      RT_BIT_64(PGM_PTATTRS_EPT_R_SHIFT)
     2401/** Write access bit - EPT only. */
     2402#define PGM_PTATTRS_EPT_W_SHIFT                     13
     2403#define PGM_PTATTRS_EPT_W_MASK                      RT_BIT_64(PGM_PTATTRS_EPT_W_SHIFT)
     2404/** Execute or execute access for supervisor-mode linear addresses - EPT only. */
     2405#define PGM_PTATTRS_EPT_X_SUPER_SHIFT               14
     2406#define PGM_PTATTRS_EPT_X_SUPER_MASK                RT_BIT_64(PGM_PTATTRS_EPT_X_SUPER_SHIFT)
     2407/** EPT memory type - EPT only. */
     2408#define PGM_PTATTRS_EPT_MEMTYPE_SHIFT               15
     2409#define PGM_PTATTRS_EPT_MEMTYPE_MASK                UINT64_C(0x0000000000038000)
     2410/** Ignore PAT memory type - EPT only. */
     2411#define PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT            18
     2412#define PGM_PTATTRS_EPT_IGNORE_PAT_MASK             RT_BIT_64(PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT)
     2413/** Reserved (bits 21:19) unused. */
     2414#define PGM_PTATTRS_RSVD_21_19_SHIFT                19
     2415#define PGM_PTATTRS_RSVD_21_19_MASK                 UINT64_C(0x0000000000380000)
     2416/** Execute access for user-mode linear addresses - EPT only. */
     2417#define PGM_PTATTRS_EPT_X_USER_SHIFT                22
     2418#define PGM_PTATTRS_EPT_X_USER_MASK                 RT_BIT_64(PGM_PTATTRS_EPT_X_USER_SHIFT)
     2419/** Reserved (bit 23) - unused. */
     2420#define PGM_PTATTRS_RSVD_23_SHIFT                   23
     2421#define PGM_PTATTRS_RSVD_23_MASK                    UINT64_C(0x0000000000800000)
     2422/** Supervisor shadow stack - EPT only. */
     2423#define PGM_PTATTRS_EPT_SUPER_SHW_STACK_SHIFT       24
     2424#define PGM_PTATTRS_EPT_SUPER_SHW_STACK_MASK        RT_BIT_64(PGM_PTATTRS_EPT_SUPER_SHW_STACK_SHIFT)
     2425/** Suppress \#VE exception - EPT only. */
     2426#define PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_SHIFT      25
     2427#define PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_MASK       RT_BIT_64(PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_SHIFT)
     2428/** Reserved (bits 63:26) - unused. */
     2429#define PGM_PTATTRS_RSVD_63_26_SHIFT                26
     2430#define PGM_PTATTRS_RSVD_63_26_MASK                 UINT64_C(0xfffffffffc000000)
     2431RT_BF_ASSERT_COMPILE_CHECKS(PGM_PTATTRS_, UINT64_C(0), UINT64_MAX,
     2432                            (X, RW, US, PWT, PCD, A, D, PAT, G, RSVD_11_9, EPT_R, EPT_W, EPT_X_SUPER, EPT_MEMTYPE, EPT_IGNORE_PAT,
     2433                             RSVD_21_19, EPT_X_USER, RSVD_23, EPT_SUPER_SHW_STACK, EPT_SUPPRESS_VE_XCPT, RSVD_63_26));
     2434
     2435/** The bit position where the EPT specific attributes begin. */
     2436#define PGM_PTATTRS_EPT_SHIFT                   PGM_PTATTRS_EPT_R_SHIFT
     2437/** The mask of EPT bits (bits 63:ATTR_SHIFT). In the future we might choose to
     2438 *  use higher unused bits for something else, in that case adjust this mask. */
     2439#define PGM_PTATTRS_EPT_MASK                        UINT64_C(0xfffffffffffff000)
     2440
     2441/** The mask of all PGM page attribute bits for regular page-tables. */
     2442#define PGM_PTATTRS_PT_VALID_MASK                   (  PGM_PTATTRS_X_MASK \
     2443                                                     | PGM_PTATTRS_RW_MASK \
     2444                                                     | PGM_PTATTRS_US_MASK \
     2445                                                     | PGM_PTATTRS_PWT_MASK \
     2446                                                     | PGM_PTATTRS_PCD_MASK \
     2447                                                     | PGM_PTATTRS_A_MASK \
     2448                                                     | PGM_PTATTRS_D_MASK \
     2449                                                     | PGM_PTATTRS_PAT_MASK \
     2450                                                     | PGM_PTATTRS_G_MASK)
     2451
     2452/** The mask of all PGM page attribute bits for EPT. */
     2453#define PGM_PTATTRS_EPT_VALID_MASK                  (  PGM_PTATTRS_X_MASK \
     2454                                                     | PGM_PTATTRS_RW_MASK \
     2455                                                     | PGM_PTATTRS_US_MASK \
     2456                                                     | PGM_PTATTRS_A_MASK \
     2457                                                     | PGM_PTATTRS_D_MASK \
     2458                                                     | PGM_PTATTRS_R_MASK \
     2459                                                     | PGM_PTATTRS_W_MASK \
     2460                                                     | PGM_PTATTRS_EPT_X_SUPER \
     2461                                                     | PGM_PTATTRS_EPT_MEMTYPE \
     2462                                                     | PGM_PTATTRS_EPT_IGNORE_PAT \
     2463                                                     | PGM_PTATTRS_EPT_X_USER \
     2464                                                     | PGM_PTATTRS_EPT_SUPER_SHW_STACK \
     2465                                                     | PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT)
     2466
     2467/* The mask of all PGM page attribute bits (combined). */
     2468#define PGM_PTATTRS_VALID_MASK                      (PGM_PTATTRS_PT_VALID_MASK | PGM_PTATTRS_PT_VALID_MASK)
     2469
     2470/* Verify bits match the regular PT bits. */
     2471AssertCompile(PGM_PTATTRS_RW_SHIFT  == X86_PTE_BIT_RW);
     2472AssertCompile(PGM_PTATTRS_US_SHIFT  == X86_PTE_BIT_US);
     2473AssertCompile(PGM_PTATTRS_PWT_SHIFT == X86_PTE_BIT_PWT);
     2474AssertCompile(PGM_PTATTRS_PCD_SHIFT == X86_PTE_BIT_PCD);
     2475AssertCompile(PGM_PTATTRS_A_SHIFT   == X86_PTE_BIT_A);
     2476AssertCompile(PGM_PTATTRS_D_SHIFT   == X86_PTE_BIT_D);
     2477AssertCompile(PGM_PTATTRS_PAT_SHIFT == X86_PTE_BIT_PAT);
     2478AssertCompile(PGM_PTATTRS_G_SHIFT   == X86_PTE_BIT_G);
     2479AssertCompile(PGM_PTATTRS_RW_MASK   == X86_PTE_RW);
     2480AssertCompile(PGM_PTATTRS_US_MASK   == X86_PTE_US);
     2481AssertCompile(PGM_PTATTRS_PWT_MASK  == X86_PTE_PWT);
     2482AssertCompile(PGM_PTATTRS_PCD_MASK  == X86_PTE_PCD);
     2483AssertCompile(PGM_PTATTRS_A_MASK    == X86_PTE_A);
     2484AssertCompile(PGM_PTATTRS_D_MASK    == X86_PTE_D);
     2485AssertCompile(PGM_PTATTRS_PAT_MASK  == X86_PTE_PAT);
     2486AssertCompile(PGM_PTATTRS_G_MASK    == X86_PTE_G);
     2487
     2488/* Verify those EPT bits that must map 1:1 (after shifting). */
     2489AssertCompile(PGM_PTATTRS_EPT_R_SHIFT          - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_READ);
     2490AssertCompile(PGM_PTATTRS_EPT_W_SHIFT          - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_WRITE);
     2491AssertCompile(PGM_PTATTRS_EPT_X_SUPER_SHIFT    - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_EXECUTE);
     2492AssertCompile(PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_IGNORE_PAT);
     2493AssertCompile(PGM_PTATTRS_EPT_X_USER_SHIFT     - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_USER_EXECUTE);
     2494/** @} */
     2495
     2496
    23332497/**
    23342498 * Page fault guest state for the AMD64 paging mode.
     
    23762540    /** The effective X86_PTE_NX flag for the address. */
    23772541    bool            fEffectiveNX;
     2542    bool            afPadding[4];
    23782543    /** Effective flags thus far: RW, US, PWT, PCD, A, ~NX >> 63.
    23792544     * The NX bit is inverted and shifted down 63 places to bit 0. */
    2380     uint32_t        fEffective;
     2545    PGMPTATTRS      fEffective;
    23812546} PGMPTWALKCORE;
    2382 
    2383 /** @name PGMPTWALKCORE::fEffective bits.
    2384  * @{ */
    2385 #if 0
    2386 /** Effective execute bit (!NX).   */
    2387 #define PGMPTWALK_EFF_X     UINT32_C(1)
    2388 /** Effective read+write access bit. */
    2389 #define PGMPTWALK_EFF_RW    X86_PTE_RW
    2390 /** Effective user-mode access bit. */
    2391 #define PGMPTWALK_EFF_US    X86_PTE_US
    2392 /** Effective write through cache bit. */
    2393 #define PGMPTWALK_EFF_PWT   X86_PTE_PWT
    2394 /** Effective cache disabled bit. */
    2395 #define PGMPTWALK_EFF_PCD   X86_PTE_PCD
    2396 /** Effective accessed bit. */
    2397 #define PGMPTWALK_EFF_A     X86_PTE_A
    2398 /** The dirty bit of the final entry. */
    2399 #define PGMPTWALK_EFF_D     X86_PTE_D
    2400 /** The PAT bit of the final entry. */
    2401 #define PGMPTWALK_EFF_PAT   X86_PTE_PAT
    2402 /** The global bit of the final entry. */
    2403 #define PGMPTWALK_EFF_G     X86_PTE_G
    2404 #endif
    2405 /** Effective execute bit (!NX). */
    2406 #define PGM_BF_PTWALK_EFF_X_SHIFT                   0
    2407 #define PGM_BF_PTWALK_EFF_X_MASK                    UINT32_C(0x00000001)
    2408 /** Effective read+write access bit. */
    2409 #define PGM_BF_PTWALK_EFF_RW_SHIFT                  1
    2410 #define PGM_BF_PTWALK_EFF_RW_MASK                   UINT32_C(0x00000002)
    2411 /** Effective user-mode access bit. */
    2412 #define PGM_BF_PTWALK_EFF_US_SHIFT                  2
    2413 #define PGM_BF_PTWALK_EFF_US_MASK                   UINT32_C(0x00000004)
    2414 /** Effective write through cache bit. */
    2415 #define PGM_BF_PTWALK_EFF_PWT_SHIFT                 3
    2416 #define PGM_BF_PTWALK_EFF_PWT_MASK                  UINT32_C(0x00000008)
    2417 /** Effective cache disabled bit. */
    2418 #define PGM_BF_PTWALK_EFF_PCD_SHIFT                 4
    2419 #define PGM_BF_PTWALK_EFF_PCD_MASK                  UINT32_C(0x00000010)
    2420 /** Effective accessed bit. */
    2421 #define PGM_BF_PTWALK_EFF_A_SHIFT                   5
    2422 #define PGM_BF_PTWALK_EFF_A_MASK                    UINT32_C(0x00000020)
    2423 /** The dirty bit of the final entry. */
    2424 #define PGM_BF_PTWALK_EFF_D_SHIFT                   6
    2425 #define PGM_BF_PTWALK_EFF_D_MASK                    UINT32_C(0x00000040)
    2426 /** The PAT bit of the final entry. */
    2427 #define PGM_BF_PTWALK_EFF_PAT_SHIFT                 7
    2428 #define PGM_BF_PTWALK_EFF_PAT_MASK                  UINT32_C(0x00000080)
    2429 /** The global bit of the final entry. */
    2430 #define PGM_BF_PTWALK_EFF_G_SHIFT                   8
    2431 #define PGM_BF_PTWALK_EFF_G_MASK                    UINT32_C(0x00000100)
    2432 /** Reserved (bits 11:9) unused. */
    2433 #define PGM_BF_PTWALK_EFF_RSVD_11_9_SHIFT           9
    2434 #define PGM_BF_PTWALK_EFF_RSVD_11_9_MASK            UINT32_C(0x00000e00)
    2435 /** Effective read access bit - EPT only. */
    2436 #define PGM_BF_PTWALK_EFF_R_SHIFT                   12
    2437 #define PGM_BF_PTWALK_EFF_R_MASK                    UINT32_C(0x00001000)
    2438 /** Effective write access bit - EPT only. */
    2439 #define PGM_BF_PTWALK_EFF_W_SHIFT                   13
    2440 #define PGM_BF_PTWALK_EFF_W_MASK                    UINT32_C(0x00002000)
    2441 /** Effective execute access for supervisor-mode - EPT only. */
    2442 #define PGM_BF_PTWALK_EFF_X_SUPER_SHIFT             14
    2443 #define PGM_BF_PTWALK_EFF_X_SUPER_MASK              UINT32_C(0x00004000)
    2444 /** Effective EPT memory type - EPT only. */
    2445 #define PGM_BF_PTWALK_EFF_MEMTYPE_SHIFT             15
    2446 #define PGM_BF_PTWALK_EFF_MEMTYPE_MASK              UINT32_C(0x00038000)
    2447 /** Effective ignore PAT memory type - EPT only. */
    2448 #define PGM_BF_PTWALK_EFF_IGNORE_PAT_SHIFT          18
    2449 #define PGM_BF_PTWALK_EFF_IGNORE_PAT_MASK           UINT32_C(0x00040000)
    2450 /** Reserved (bits 21:19) unused. */
    2451 #define PGM_BF_PTWALK_EFF_RSVD_21_19_SHIFT          19
    2452 #define PGM_BF_PTWALK_EFF_RSVD_21_19_MASK           UINT32_C(0x00380000)
    2453 /** Effective execute access for user-mode - EPT only. */
    2454 #define PGM_BF_PTWALK_EFF_X_USER_SHIFT              22
    2455 #define PGM_BF_PTWALK_EFF_X_USER_MASK               UINT32_C(0x00400000)
    2456 /** Reserved (bits 31:23) - unused. */  /** @todo When implementing SUPER_SHW_STACK, Suppress \#VE put them in bits 24, 25 which corresponds to bit 12, 13 of EPT attributes. */
    2457 #define PGM_BF_PTWALK_EFF_RSVD_31_23_SHIFT          23
    2458 #define PGM_BF_PTWALK_EFF_RSVD_31_23_MASK           UINT32_C(0xff800000)
    2459 RT_BF_ASSERT_COMPILE_CHECKS(PGM_BF_PTWALK_EFF_, UINT32_C(0), UINT32_MAX,
    2460                             (X, RW, US, PWT, PCD, A, D, PAT, G, RSVD_11_9, R, W, X_SUPER, MEMTYPE, IGNORE_PAT, RSVD_21_19,
    2461                              X_USER, RSVD_31_23));
    2462 
    2463 /** The bit count where the EPT specific bits begin. */
    2464 #define PGMPTWALK_EFF_EPT_ATTR_SHIFT                PGM_BF_PTWALK_EFF_R_SHIFT
    2465 /** The mask of EPT bits (bits 31:ATTR_SHIFT). In the future we might choose to
    2466  *  use higher unused EPT bits for something else, in that case reduce this mask. */
    2467 #define PGMPTWALK_EFF_EPT_ATTR_MASK                 UINT32_C(0xfffff000)
    2468 
    2469 /* Verify bits match the regular PT bits. */
    2470 AssertCompile(PGM_BF_PTWALK_EFF_RW_SHIFT  == X86_PTE_BIT_RW);
    2471 AssertCompile(PGM_BF_PTWALK_EFF_US_SHIFT  == X86_PTE_BIT_US);
    2472 AssertCompile(PGM_BF_PTWALK_EFF_PWT_SHIFT == X86_PTE_BIT_PWT);
    2473 AssertCompile(PGM_BF_PTWALK_EFF_PCD_SHIFT == X86_PTE_BIT_PCD);
    2474 AssertCompile(PGM_BF_PTWALK_EFF_A_SHIFT   == X86_PTE_BIT_A);
    2475 AssertCompile(PGM_BF_PTWALK_EFF_D_SHIFT   == X86_PTE_BIT_D);
    2476 AssertCompile(PGM_BF_PTWALK_EFF_PAT_SHIFT == X86_PTE_BIT_PAT);
    2477 AssertCompile(PGM_BF_PTWALK_EFF_G_SHIFT   == X86_PTE_BIT_G);
    2478 AssertCompile(PGM_BF_PTWALK_EFF_RW_MASK   == X86_PTE_RW);
    2479 AssertCompile(PGM_BF_PTWALK_EFF_US_MASK   == X86_PTE_US);
    2480 AssertCompile(PGM_BF_PTWALK_EFF_PWT_MASK  == X86_PTE_PWT);
    2481 AssertCompile(PGM_BF_PTWALK_EFF_PCD_MASK  == X86_PTE_PCD);
    2482 AssertCompile(PGM_BF_PTWALK_EFF_A_MASK    == X86_PTE_A);
    2483 AssertCompile(PGM_BF_PTWALK_EFF_D_MASK    == X86_PTE_D);
    2484 AssertCompile(PGM_BF_PTWALK_EFF_PAT_MASK  == X86_PTE_PAT);
    2485 AssertCompile(PGM_BF_PTWALK_EFF_G_MASK    == X86_PTE_G);
    2486 
    2487 /*
    2488  * The following bits map 1:1 (left shifted by PGMPTWALK_EFF_EPT_ATTR_SHIFT bits) with
    2489  * VMX EPT attribute bits because these are unique to EPT and fit within 32-bits:
    2490  *   - R, W, X_SUPER, MEMTYPE, IGNORE_PAT, X_USER.
    2491  *
    2492  * The following bits are moved to the regular PT bit positions because they already
    2493  * exist for regular page tables:
    2494  *   - A, D.
    2495  */
    2496 AssertCompile(PGM_BF_PTWALK_EFF_R_SHIFT          - PGMPTWALK_EFF_EPT_ATTR_SHIFT == EPT_E_BIT_READ);
    2497 AssertCompile(PGM_BF_PTWALK_EFF_W_SHIFT          - PGMPTWALK_EFF_EPT_ATTR_SHIFT == EPT_E_BIT_WRITE);
    2498 AssertCompile(PGM_BF_PTWALK_EFF_X_SUPER_SHIFT    - PGMPTWALK_EFF_EPT_ATTR_SHIFT == EPT_E_BIT_EXECUTE);
    2499 AssertCompile(PGM_BF_PTWALK_EFF_IGNORE_PAT_SHIFT - PGMPTWALK_EFF_EPT_ATTR_SHIFT == EPT_E_BIT_IGNORE_PAT);
    2500 AssertCompile(PGM_BF_PTWALK_EFF_X_USER_SHIFT     - PGMPTWALK_EFF_EPT_ATTR_SHIFT == EPT_E_BIT_USER_EXECUTE);
    2501 /** @} */
    2502 
    25032547
    25042548/**
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