Changeset 92480 in vbox
- Timestamp:
- Nov 17, 2021 2:01:29 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 148339
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 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; -
trunk/src/VBox/VMM/VMMR3/PGM.cpp
r92420 r92480 1621 1621 1622 1622 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT 1623 pVCpu->pgm.s.uEptVpidCapMsr = fEptVpidCap; 1623 1624 pVCpu->pgm.s.fGstEptMbzPteMask = fMbzPageFrameMask | EPT_PTE_MBZ_MASK; 1624 1625 pVCpu->pgm.s.fGstEptMbzPdeMask = fMbzPageFrameMask | EPT_PDE_MBZ_MASK; … … 1632 1633 && !pVM->cpum.ro.GuestFeatures.fVmxSppEpt 1633 1634 && !pVM->cpum.ro.GuestFeatures.fVmxEptXcptVe); 1634 pVCpu->pgm.s.fGstEptPresentMask = EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE; 1635 pVCpu->pgm.s.fGstEptShadowedPml4eMask = EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED; 1636 pVCpu->pgm.s.fGstEptShadowedPdpeMask = EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED; 1637 pVCpu->pgm.s.fGstEptShadowedBigPdpeMask = EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED | EPT_E_DIRTY; 1638 pVCpu->pgm.s.fGstEptShadowedPdeMask = EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED; 1639 pVCpu->pgm.s.fGstEptShadowedBigPdeMask = EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED | EPT_E_DIRTY; 1640 pVCpu->pgm.s.fGstEptShadowedPteMask = EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED | EPT_E_DIRTY; 1635 pVCpu->pgm.s.fGstEptPresentMask = EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE; 1641 1636 #endif 1642 1637 } -
trunk/src/VBox/VMM/include/PGMInternal.h
r92426 r92480 3436 3436 /** The guest's EPT pointer (copy of virtual VMCS). */ 3437 3437 uint64_t uEptPtr; 3438 /** Copy of the VM's IA32_VMX_EPT_VPID_CAP VPID MSR for faster access. Doesn't 3439 * change through the lifetime of the VM. */ 3440 uint64_t uEptVpidCapMsr; 3438 3441 /** Mask containing the MBZ PTE bits. */ 3439 3442 uint64_t fGstEptMbzPteMask; … … 3450 3453 /** Mask to determine whether an entry is present. */ 3451 3454 uint64_t fGstEptPresentMask; 3452 /** Mask containing the PML4E bits that we shadow. */3453 uint64_t fGstEptShadowedPml4eMask;3454 /** Mask containing the PDPE bits that we shadow. */3455 uint64_t fGstEptShadowedPdpeMask;3456 /** Mask containing the big page PDPE bits that we shadow. */3457 uint64_t fGstEptShadowedBigPdpeMask;3458 /** Mask containing the PDE bits that we shadow. */3459 uint64_t fGstEptShadowedPdeMask;3460 /** Mask containing the big page PDE bits that we shadow. */3461 uint64_t fGstEptShadowedBigPdeMask;3462 /** Mask containing the PTE bits that we shadow. */3463 uint64_t fGstEptShadowedPteMask;3464 3455 /** @} */ 3465 3456
Note:
See TracChangeset
for help on using the changeset viewer.