Changeset 93459 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jan 27, 2022 3:07:57 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h
r93115 r93459 19 19 DECLINLINE(bool) PGM_GST_SLAT_NAME_EPT(WalkIsPermValid)(PCVMCPUCC pVCpu, uint64_t uEntry) 20 20 { 21 if (!(uEntry & VMX_BF_EPT_PT_READ_MASK))22 { 23 if (uEntry & VMX_BF_EPT_PT_WRITE_MASK)21 if (!(uEntry & EPT_E_READ)) 22 { 23 if (uEntry & EPT_E_WRITE) 24 24 return false; 25 26 25 Assert(!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fVmxModeBasedExecuteEpt); 27 26 if ( !RT_BF_GET(pVCpu->pgm.s.uEptVpidCapMsr, VMX_BF_EPT_VPID_CAP_EXEC_ONLY) 28 && (uEntry & VMX_BF_EPT_PT_EXECUTE_MASK))27 && (uEntry & EPT_E_EXECUTE)) 29 28 return false; 30 29 } … … 49 48 static PGMWALKFAIL const s_afEptViolations[] = { PGM_WALKFAIL_EPT_VIOLATION, PGM_WALKFAIL_EPT_VIOLATION_CONVERTIBLE }; 50 49 uint8_t const fEptVeSupported = pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fVmxEptXcptVe; 51 uint8_t const idxViolationType = fEptVeSupported & !RT_BF_GET(uEntry, VMX_BF_EPT_PT_SUPPRESS_VE); 50 uint8_t const fConvertible = RT_BOOL(uLevel == 1 || (uEntry & EPT_E_BIT_LEAF)); 51 uint8_t const idxViolationType = fEptVeSupported & fConvertible & !RT_BF_GET(uEntry, VMX_BF_EPT_PT_SUPPRESS_VE); 52 52 53 53 pWalk->fNotPresent = true; 54 54 pWalk->uLevel = uLevel; 55 pWalk->fFailed |= s_afEptViolations[idxViolationType];55 pWalk->fFailed = s_afEptViolations[idxViolationType]; 56 56 return VERR_PAGE_TABLE_NOT_PRESENT; 57 57 } … … 63 63 pWalk->fBadPhysAddr = true; 64 64 pWalk->uLevel = uLevel; 65 pWalk->fFailed |= PGM_WALKFAIL_EPT_VIOLATION;65 pWalk->fFailed = PGM_WALKFAIL_EPT_VIOLATION; 66 66 return VERR_PAGE_TABLE_NOT_PRESENT; 67 67 } 68 68 69 69 70 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, uint64_t uEntry, uint8_t uLevel) 71 { 72 static PGMWALKFAIL const s_afEptViolations[] = { PGM_WALKFAIL_EPT_VIOLATION, PGM_WALKFAIL_EPT_VIOLATION_CONVERTIBLE }; 73 uint8_t const fEptVeSupported = pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fVmxEptXcptVe; 74 uint8_t const fConvertible = RT_BOOL(uLevel == 1 || (uEntry & EPT_E_BIT_LEAF)); 75 uint8_t const idxViolationType = fEptVeSupported & fConvertible & !RT_BF_GET(uEntry, VMX_BF_EPT_PT_SUPPRESS_VE); 76 77 pWalk->fRsvdError = true; 78 pWalk->uLevel = uLevel; 79 pWalk->fFailed |= s_afEptViolations[idxViolationType]; 70 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, uint8_t uLevel) 71 { 72 NOREF(pVCpu); 73 pWalk->fRsvdError = true; 74 pWalk->uLevel = uLevel; 75 pWalk->fFailed = PGM_WALKFAIL_EPT_MISCONFIG; 80 76 return VERR_PAGE_TABLE_NOT_PRESENT; 81 77 } … … 141 137 { 142 138 /* 143 * Start with reading the EPT PML4E pointer.139 * EPTP. 144 140 * 145 * We currently only support 4 146 * EPT 5 141 * We currently only support 4-level EPT paging. 142 * EPT 5-level paging was documented at some point (bit 7 of MSR_IA32_VMX_EPT_VPID_CAP) 147 143 * but for some reason seems to have been removed from subsequent specs. 148 144 */ … … 165 161 else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, Pml4e.u, 4); 166 162 167 if (RT_LIKELY(GST_IS_PML4E_VALID(pVCpu, Pml4e))) { /* likely */ } 168 else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, Pml4e.u, 4); 163 if (RT_LIKELY( GST_IS_PML4E_VALID(pVCpu, Pml4e) 164 && PGM_GST_SLAT_NAME_EPT(WalkIsPermValid)(pVCpu, Pml4e.u))) 165 { /* likely */ } 166 else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 4); 169 167 170 168 Assert(!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fVmxModeBasedExecuteEpt); … … 196 194 else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, Pdpte.u, 3); 197 195 198 /* The order of the following 2 "if" statements matter. */ 199 if (GST_IS_PDPE_VALID(pVCpu, Pdpte)) 196 /* The order of the following "if" and "else if" statements matter. */ 197 if ( GST_IS_PDPE_VALID(pVCpu, Pdpte) 198 && PGM_GST_SLAT_NAME_EPT(WalkIsPermValid)(pVCpu, Pdpte.u)) 200 199 { 201 200 uint64_t const fEptAttrs = Pdpte.u & EPT_PDPTE_ATTR_MASK; … … 211 210 } 212 211 else if ( GST_IS_BIG_PDPE_VALID(pVCpu, Pdpte) 212 && PGM_GST_SLAT_NAME_EPT(WalkIsPermValid)(pVCpu, Pdpte.u) 213 213 && PGM_GST_SLAT_NAME_EPT(WalkIsMemTypeValid)(Pdpte.u, 3)) 214 214 { … … 235 235 return VINF_SUCCESS; 236 236 } 237 else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, Pdpte.u,3);237 else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 3); 238 238 239 239 int const rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pdpte.u & EPT_PDPTE_PG_MASK, &pGstWalk->pPd); … … 253 253 else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, Pde.u, 2); 254 254 255 /* The order of the following 2 "if" statements matter. */ 256 if (GST_IS_PDE_VALID(pVCpu, Pde)) 255 /* The order of the following "if" and "else if" statements matter. */ 256 if ( GST_IS_PDE_VALID(pVCpu, Pde) 257 && PGM_GST_SLAT_NAME_EPT(WalkIsPermValid)(pVCpu, Pde.u)) 257 258 { 258 259 uint64_t const fEptAttrs = Pde.u & EPT_PDE_ATTR_MASK; … … 269 270 } 270 271 else if ( GST_IS_BIG_PDE_VALID(pVCpu, Pde) 272 && PGM_GST_SLAT_NAME_EPT(WalkIsPermValid)(pVCpu, Pde.u) 271 273 && PGM_GST_SLAT_NAME_EPT(WalkIsMemTypeValid)(Pde.u, 2)) 272 274 { … … 293 295 return VINF_SUCCESS; 294 296 } 295 else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, Pde.u,2);297 else return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 2); 296 298 297 299 int const rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GST_GET_PDE_GCPHYS(Pde), &pGstWalk->pPt); … … 312 314 313 315 if ( GST_IS_PTE_VALID(pVCpu, Pte) 316 && PGM_GST_SLAT_NAME_EPT(WalkIsPermValid)(pVCpu, Pte.u) 314 317 && PGM_GST_SLAT_NAME_EPT(WalkIsMemTypeValid)(Pte.u, 1)) 315 { /* likely*/ 318 { /* likely*/ } 316 319 else 317 return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, Pte.u,1);320 return PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(pVCpu, pWalk, 1); 318 321 319 322 uint64_t const fEptAttrs = Pte.u & EPT_PTE_ATTR_MASK;
Note:
See TracChangeset
for help on using the changeset viewer.