Changeset 92480 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Nov 17, 2021 2:01:29 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h
r92476 r92480 17 17 18 18 #if PGM_GST_TYPE == PGM_TYPE_EPT 19 DECLINLINE(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 35 DECLINLINE(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 19 47 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(PCVMCPUCC pVCpu, PPGMPTWALK pWalk, uint64_t uEntry, uint8_t uLevel) 20 48 { … … 43 71 { 44 72 NOREF(pVCpu); 45 pWalk->fRsvdError = true; 46 pWalk->uLevel = uLevel; 73 pWalk->fRsvdError = true; 74 pWalk->uLevel = uLevel; 75 pWalk->enmSlatFail = PGMSLATFAIL_EPT_MISCONFIG; 47 76 return VERR_PAGE_TABLE_NOT_PRESENT; 48 77 } … … 52 81 PPGMPTWALK pWalk, PGSTPTWALK pGstWalk) 53 82 { 54 /** @todo implement figuring out fEptMisconfig. */55 83 /* 56 84 * Init walk structures. … … 87 115 * Do the walk. 88 116 */ 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 89 123 uint64_t fEffective; 90 124 { 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 */ 95 128 PEPTPML4E pPml4e; 96 129 pGstWalk->pPml4e = pPml4e = &pGstWalk->pPml4->a[(GCPhysNested >> EPT_PML4_SHIFT) & EPT_PML4_MASK]; … … 116 149 pWalk->fEffective = fEffective; 117 150 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); 119 152 if (RT_SUCCESS(rc)) { /* probable */ } 120 153 else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 3, rc); 121 154 } 122 155 { 156 /* 157 * PDPTE. 158 */ 123 159 PEPTPDPTE pPdpte; 124 160 pGstWalk->pPdpte = pPdpte = &pGstWalk->pPdpt->a[(GCPhysNested >> GST_PDPT_SHIFT) & GST_PDPT_MASK]; … … 143 179 pWalk->fEffective = fEffective; 144 180 } 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)) 146 183 { 147 184 uint64_t const fEptAttrs = Pdpte.u & EPT_PDPTE1G_ATTR_MASK; … … 168 205 } 169 206 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 */ 172 216 PGSTPDE pPde; 173 217 pGstWalk->pPde = pPde = &pGstWalk->pPd->a[(GCPhysNested >> GST_PD_SHIFT) & GST_PD_MASK]; … … 178 222 else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, Pde.u, 2); 179 223 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)) 181 226 { 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 { 185 242 uint64_t const fEptAttrs = Pde.u & EPT_PDE2M_ATTR_MASK; 186 243 uint8_t const fRead = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ); … … 205 262 return VINF_SUCCESS; 206 263 } 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); 221 265 222 266 int const rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GST_GET_PDE_GCPHYS(Pde), &pGstWalk->pPt); … … 225 269 } 226 270 { 271 /* 272 * PTE. 273 */ 227 274 PGSTPTE pPte; 228 275 pGstWalk->pPte = pPte = &pGstWalk->pPt->a[(GCPhysNested >> GST_PT_SHIFT) & GST_PT_MASK]; … … 233 280 else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, Pte.u, 1); 234 281 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); 237 287 238 288 uint64_t const fEptAttrs = Pte.u & EPT_PTE_ATTR_MASK;
Note:
See TracChangeset
for help on using the changeset viewer.