Changeset 14099 in vbox
- Timestamp:
- Nov 11, 2008 5:10:24 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r14096 r14099 3144 3144 3145 3145 #if PGM_SHW_TYPE == PGM_TYPE_NESTED || PGM_SHW_TYPE == PGM_TYPE_EPT 3146 /* 3147 * Nested / EPT - almost no work. 3148 */ 3146 3149 /** @todo check if this is really necessary */ 3147 3150 HWACCMFlushTLB(pVM); … … 3149 3152 3150 3153 #elif PGM_SHW_TYPE == PGM_TYPE_AMD64 3151 /* No need to check all paging levels; we zero out the shadow parts when the guest modifies its tables. */ 3154 /* 3155 * AMD64 (Shw & Gst) - No need to check all paging levels; we zero 3156 * out the shadow parts when the guest modifies its tables. 3157 */ 3152 3158 return VINF_SUCCESS; 3153 #else /* PGM_SHW_TYPE != PGM_TYPE_AMD64 */ 3154 3159 3160 #else /* PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT && PGM_SHW_TYPE != PGM_TYPE_AMD64 */ 3161 /* 3162 * PAE and 32-bit legacy mode (shadow). 3163 * (Guest PAE, 32-bit legacy, protected and real modes.) 3164 */ 3155 3165 Assert(fGlobal || (cr4 & X86_CR4_PGE)); 3156 3166 MY_STAM_COUNTER_INC(fGlobal ? &pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3Global) : &pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3NotGlobal)); 3157 3167 3158 # if PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_PAE || PGM_GST_TYPE == PGM_TYPE_AMD64 3159 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3160 bool fBigPagesSupported = true; 3161 # error "We should not be here!" 3162 # else 3163 bool fBigPagesSupported = !!(CPUMGetGuestCR4(pVM) & X86_CR4_PSE); 3164 # endif 3168 # if PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_PAE 3169 bool const fBigPagesSupported = !!(CPUMGetGuestCR4(pVM) & X86_CR4_PSE); 3165 3170 3166 3171 /* … … 3169 3174 # if PGM_SHW_TYPE == PGM_TYPE_32BIT 3170 3175 PX86PDE pPDEDst = &pVM->pgm.s.CTXMID(p,32BitPD)->a[0]; 3171 # else /* PGM_SHW_TYPE == PGM_TYPE_PAE || PGM_SHW_TYPE == PGM_TYPE_AMD64*/3176 # else /* PGM_SHW_TYPE == PGM_TYPE_PAE */ 3172 3177 # if PGM_GST_TYPE == PGM_TYPE_32BIT 3173 3178 PX86PDEPAE pPDEDst = &pVM->pgm.s.CTXMID(ap,PaePDs)[0]->a[0]; … … 3202 3207 iPdNoMapping = ~0U; 3203 3208 } 3204 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3205 # error "We should not be here!" 3206 for (uint64_t iPml4 = 0; iPml4 < X86_PG_PAE_ENTRIES; iPml4++) 3207 { 3208 PPGMPOOLPAGE pShwPdpt = NULL; 3209 PX86PML4E pPml4eSrc, pPml4eDst; 3210 RTGCPHYS GCPhysPdptSrc; 3211 3212 pPml4eSrc = &pVM->pgm.s.CTXSUFF(pGstPaePML4)->a[iPml4]; 3213 pPml4eDst = &pVM->pgm.s.CTXMID(p,PaePML4)->a[iPml4]; 3214 3215 /* Fetch the pgm pool shadow descriptor if the shadow pml4e is present. */ 3216 if (!pPml4eDst->n.u1Present) 3217 continue; 3218 pShwPdpt = pgmPoolGetPage(pPool, pPml4eDst->u & X86_PML4E_PG_MASK); 3219 3220 GCPhysPdptSrc = pPml4eSrc->u & X86_PML4E_PG_MASK_FULL; 3221 3222 /* Anything significant changed? */ 3223 if ( pPml4eSrc->n.u1Present != pPml4eDst->n.u1Present 3224 || GCPhysPdptSrc != pShwPdpt->GCPhys) 3209 # if PGM_GST_TYPE == PGM_TYPE_PAE 3210 for (uint64_t iPdpt = 0; iPdpt < GST_PDPE_ENTRIES; iPdpt++) 3211 { 3212 unsigned iPDSrc; 3213 X86PDPE PdpeSrc; 3214 PGSTPD pPDSrc = pgmGstGetPaePDPtr(&pVM->pgm.s, iPdpt << X86_PDPT_SHIFT, &iPDSrc, &PdpeSrc); 3215 PX86PDPAE pPDPAE = pVM->pgm.s.CTXMID(ap,PaePDs)[0]; 3216 PX86PDEPAE pPDEDst = &pPDPAE->a[iPdpt * X86_PG_PAE_ENTRIES]; 3217 PX86PDPT pPdptDst = pgmShwGetPaePDPTPtr(&pVM->pgm.s); 3218 3219 if (pPDSrc == NULL) 3225 3220 { 3226 /* Free it. */ 3227 LogFlow(("SyncCR3: Out-of-sync PML4E (GCPhys) GCPtr=%RX64 %RGp vs %RGp PdpeSrc=%RX64 PdpeDst=%RX64\n", 3228 (uint64_t)iPml4 << X86_PML4_SHIFT, pShwPdpt->GCPhys, GCPhysPdptSrc, (uint64_t)pPml4eSrc->u, (uint64_t)pPml4eDst->u)); 3229 pgmPoolFreeByPage(pPool, pShwPdpt, pVM->pgm.s.pHCShwAmd64CR3->idx, iPml4); 3230 pPml4eDst->u = 0; 3221 /* PDPE not present */ 3222 if (pPdptDst->a[iPdpt].n.u1Present) 3223 { 3224 LogFlow(("SyncCR3: guest PDPE %lld not present; clear shw pdpe\n", iPdpt)); 3225 /* for each page directory entry */ 3226 for (unsigned iPD = 0; iPD < RT_ELEMENTS(pPDSrc->a); iPD++) 3227 { 3228 if ( pPDEDst[iPD].n.u1Present 3229 && !(pPDEDst[iPD].u & PGM_PDFLAGS_MAPPING)) 3230 { 3231 pgmPoolFreeByPage(pPool, pgmPoolGetPage(pPool, pPDEDst[iPD].u & SHW_PDE_PG_MASK), SHW_POOL_ROOT_IDX, iPdpt * X86_PG_PAE_ENTRIES + iPD); 3232 pPDEDst[iPD].u = 0; 3233 } 3234 } 3235 } 3236 if (!(pPdptDst->a[iPdpt].u & PGM_PLXFLAGS_MAPPING)) 3237 pPdptDst->a[iPdpt].n.u1Present = 0; 3231 3238 continue; 3232 3239 } 3233 /* Force an attribute sync. */ 3234 pPml4eDst->n.u1User = pPml4eSrc->n.u1User; 3235 pPml4eDst->n.u1Write = pPml4eSrc->n.u1Write; 3236 pPml4eDst->n.u1NoExecute = pPml4eSrc->n.u1NoExecute; 3237 3238 # else /* PGM_GST_TYPE != PGM_TYPE_AMD64 */ 3239 { 3240 # endif /* PGM_GST_TYPE != PGM_TYPE_AMD64 */ 3241 # if PGM_GST_TYPE == PGM_TYPE_PAE || PGM_GST_TYPE == PGM_TYPE_AMD64 3242 for (uint64_t iPdpt = 0; iPdpt < GST_PDPE_ENTRIES; iPdpt++) 3240 # else /* PGM_GST_TYPE != PGM_TYPE_PAE */ 3241 { 3242 # endif /* PGM_GST_TYPE != PGM_TYPE_PAE */ 3243 for (unsigned iPD = 0; iPD < RT_ELEMENTS(pPDSrc->a); iPD++) 3243 3244 { 3244 unsigned iPDSrc; 3245 # if PGM_GST_TYPE == PGM_TYPE_PAE 3246 X86PDPE PdpeSrc; 3247 PGSTPD pPDSrc = pgmGstGetPaePDPtr(&pVM->pgm.s, iPdpt << X86_PDPT_SHIFT, &iPDSrc, &PdpeSrc); 3248 PX86PDPAE pPDPAE = pVM->pgm.s.CTXMID(ap,PaePDs)[0]; 3249 PX86PDEPAE pPDEDst = &pPDPAE->a[iPdpt * X86_PG_PAE_ENTRIES]; 3250 PX86PDPT pPdptDst = pgmShwGetPaePDPTPtr(&pVM->pgm.s); 3251 3252 if (pPDSrc == NULL) 3245 # if PGM_SHW_TYPE == PGM_TYPE_32BIT 3246 Assert(&pVM->pgm.s.CTXMID(p,32BitPD)->a[iPD] == pPDEDst); 3247 # elif PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3248 AssertMsg(&pVM->pgm.s.CTXMID(ap,PaePDs)[iPD * 2 / 512]->a[iPD * 2 % 512] == pPDEDst, ("%p vs %p\n", &pVM->pgm.s.CTXMID(ap,PaePDs)[iPD * 2 / 512]->a[iPD * 2 % 512], pPDEDst)); 3249 # endif 3250 GSTPDE PdeSrc = pPDSrc->a[iPD]; 3251 if ( PdeSrc.n.u1Present 3252 && (PdeSrc.n.u1User || fRawR0Enabled)) 3253 3253 { 3254 /* PDPE not present */3255 if (pPdptDst->a[iPdpt].n.u1Present)3256 {3257 LogFlow(("SyncCR3: guest PDPE %lld not present; clear shw pdpe\n", iPdpt));3258 /* for each page directory entry */3259 for (unsigned iPD = 0; iPD < RT_ELEMENTS(pPDSrc->a); iPD++)3260 {3261 if ( pPDEDst[iPD].n.u1Present3262 && !(pPDEDst[iPD].u & PGM_PDFLAGS_MAPPING))3263 {3264 pgmPoolFreeByPage(pPool, pgmPoolGetPage(pPool, pPDEDst[iPD].u & SHW_PDE_PG_MASK), SHW_POOL_ROOT_IDX, iPdpt * X86_PG_PAE_ENTRIES + iPD);3265 pPDEDst[iPD].u = 0;3266 }3267 }3268 }3269 if (!(pPdptDst->a[iPdpt].u & PGM_PLXFLAGS_MAPPING))3270 pPdptDst->a[iPdpt].n.u1Present = 0;3271 continue;3272 }3273 # else /* PGM_GST_TYPE != PGM_TYPE_PAE */3274 PPGMPOOLPAGE pShwPde = NULL;3275 RTGCPHYS GCPhysPdeSrc;3276 PX86PDPE pPdpeDst;3277 PX86PML4E pPml4eSrc;3278 X86PDPE PdpeSrc;3279 PX86PDPT pPdptDst;3280 PX86PDPAE pPDDst;3281 PX86PDEPAE pPDEDst;3282 RTGCPTR GCPtr = (iPml4 << X86_PML4_SHIFT) || (iPdpt << X86_PDPT_SHIFT);3283 PGSTPD pPDSrc = pgmGstGetLongModePDPtr(&pVM->pgm.s, GCPtr, &pPml4eSrc, &PdpeSrc, &iPDSrc);3284 3285 int rc = pgmShwGetLongModePDPtr(pVM, GCPtr, NULL, &pPdptDst, &pPDDst);3286 if (rc != VINF_SUCCESS)3287 {3288 if (rc == VERR_PAGE_MAP_LEVEL4_NOT_PRESENT)3289 break; /* next PML4E */3290 3291 AssertMsg(rc == VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT, ("Unexpected rc=%Rrc\n", rc));3292 continue; /* next PDPTE */3293 }3294 Assert(pPDDst);3295 pPDEDst = &pPDDst->a[0];3296 Assert(iPDSrc == 0);3297 3298 pPdpeDst = &pPdptDst->a[iPdpt];3299 3300 /* Fetch the pgm pool shadow descriptor if the shadow pdpte is present. */3301 if (!pPdpeDst->n.u1Present)3302 continue; /* next PDPTE */3303 3304 pShwPde = pgmPoolGetPage(pPool, pPdpeDst->u & X86_PDPE_PG_MASK);3305 GCPhysPdeSrc = PdpeSrc.u & X86_PDPE_PG_MASK;3306 3307 /* Anything significant changed? */3308 if ( PdpeSrc.n.u1Present != pPdpeDst->n.u1Present3309 || GCPhysPdeSrc != pShwPde->GCPhys)3310 {3311 /* Free it. */3312 LogFlow(("SyncCR3: Out-of-sync PDPE (GCPhys) GCPtr=%RX64 %RGp vs %RGp PdpeSrc=%RX64 PdpeDst=%RX64\n",3313 ((uint64_t)iPml4 << X86_PML4_SHIFT) + ((uint64_t)iPdpt << X86_PDPT_SHIFT), pShwPde->GCPhys, GCPhysPdeSrc, (uint64_t)PdpeSrc.u, (uint64_t)pPdpeDst->u));3314 3315 /* Mark it as not present if there's no hypervisor mapping present. (bit flipped at the top of Trap0eHandler) */3316 Assert(!(pPdpeDst->u & PGM_PLXFLAGS_MAPPING));3317 pgmPoolFreeByPage(pPool, pShwPde, pShwPde->idx, iPdpt);3318 pPdpeDst->u = 0;3319 continue; /* next guest PDPTE */3320 }3321 /* Force an attribute sync. */3322 pPdpeDst->lm.u1User = PdpeSrc.lm.u1User;3323 pPdpeDst->lm.u1Write = PdpeSrc.lm.u1Write;3324 pPdpeDst->lm.u1NoExecute = PdpeSrc.lm.u1NoExecute;3325 # endif /* PGM_GST_TYPE != PGM_TYPE_PAE */3326 3327 # else /* PGM_GST_TYPE != PGM_TYPE_PAE && PGM_GST_TYPE != PGM_TYPE_AMD64 */3328 {3329 # endif /* PGM_GST_TYPE != PGM_TYPE_PAE && PGM_GST_TYPE != PGM_TYPE_AMD64 */3330 for (unsigned iPD = 0; iPD < RT_ELEMENTS(pPDSrc->a); iPD++)3331 {3332 # if PGM_SHW_TYPE == PGM_TYPE_32BIT3333 Assert(&pVM->pgm.s.CTXMID(p,32BitPD)->a[iPD] == pPDEDst);3334 # elif PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT3335 AssertMsg(&pVM->pgm.s.CTXMID(ap,PaePDs)[iPD * 2 / 512]->a[iPD * 2 % 512] == pPDEDst, ("%p vs %p\n", &pVM->pgm.s.CTXMID(ap,PaePDs)[iPD * 2 / 512]->a[iPD * 2 % 512], pPDEDst));3336 # endif3337 GSTPDE PdeSrc = pPDSrc->a[iPD];3338 if ( PdeSrc.n.u1Present3339 && (PdeSrc.n.u1User || fRawR0Enabled))3340 {3341 3254 # if ( PGM_GST_TYPE == PGM_TYPE_32BIT \ 3342 3255 || PGM_GST_TYPE == PGM_TYPE_PAE) \ 3343 3256 && !defined(PGM_WITHOUT_MAPPINGS) 3344 3257 3345 3346 3347 3258 /* 3259 * Check for conflicts with GC mappings. 3260 */ 3348 3261 # if PGM_GST_TYPE == PGM_TYPE_PAE 3349 3262 if (iPD + iPdpt * X86_PG_PAE_ENTRIES == iPdNoMapping) 3350 3263 # else 3351 3264 if (iPD == iPdNoMapping) 3352 3265 # endif 3266 { 3267 if (pVM->pgm.s.fMappingsFixed) 3353 3268 { 3354 if (pVM->pgm.s.fMappingsFixed) 3355 { 3356 /* It's fixed, just skip the mapping. */ 3357 const unsigned cPTs = pMapping->cb >> GST_PD_SHIFT; 3358 iPD += cPTs - 1; 3359 pPDEDst += cPTs + (PGM_GST_TYPE != PGM_SHW_TYPE) * cPTs; /* Only applies to the pae shadow and 32 bits guest case */ 3360 pMapping = pMapping->CTX_SUFF(pNext); 3361 iPdNoMapping = pMapping ? pMapping->GCPtr >> GST_PD_SHIFT : ~0U; 3362 continue; 3363 } 3269 /* It's fixed, just skip the mapping. */ 3270 const unsigned cPTs = pMapping->cb >> GST_PD_SHIFT; 3271 iPD += cPTs - 1; 3272 pPDEDst += cPTs + (PGM_GST_TYPE != PGM_SHW_TYPE) * cPTs; /* Only applies to the pae shadow and 32 bits guest case */ 3273 pMapping = pMapping->CTX_SUFF(pNext); 3274 iPdNoMapping = pMapping ? pMapping->GCPtr >> GST_PD_SHIFT : ~0U; 3275 continue; 3276 } 3364 3277 # ifdef IN_RING3 3365 3278 # if PGM_GST_TYPE == PGM_TYPE_32BIT 3366 3279 int rc = pgmR3SyncPTResolveConflict(pVM, pMapping, pPDSrc, iPD << GST_PD_SHIFT); 3367 3280 # elif PGM_GST_TYPE == PGM_TYPE_PAE 3368 3281 int rc = pgmR3SyncPTResolveConflictPAE(pVM, pMapping, (iPdpt << GST_PDPT_SHIFT) + (iPD << GST_PD_SHIFT)); 3369 3282 # endif 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3283 if (RT_FAILURE(rc)) 3284 return rc; 3285 3286 /* 3287 * Update iPdNoMapping and pMapping. 3288 */ 3289 pMapping = pVM->pgm.s.pMappingsR3; 3290 while (pMapping && pMapping->GCPtr < (iPD << GST_PD_SHIFT)) 3291 pMapping = pMapping->pNextR3; 3292 iPdNoMapping = pMapping ? pMapping->GCPtr >> GST_PD_SHIFT : ~0U; 3380 3293 # else 3381 3382 3294 LogFlow(("SyncCR3: detected conflict -> VINF_PGM_SYNC_CR3\n")); 3295 return VINF_PGM_SYNC_CR3; 3383 3296 # endif 3384 3297 } 3385 3298 # else /* (PGM_GST_TYPE != PGM_TYPE_32BIT && PGM_GST_TYPE != PGM_TYPE_PAE) || PGM_WITHOUT_MAPPINGS */ 3386 3299 Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s)); 3387 3300 # endif /* (PGM_GST_TYPE != PGM_TYPE_32BIT && PGM_GST_TYPE != PGM_TYPE_PAE) || PGM_WITHOUT_MAPPINGS */ 3388 3301 3389 3390 3391 3392 3393 3394 3395 3302 /* 3303 * Sync page directory entry. 3304 * 3305 * The current approach is to allocated the page table but to set 3306 * the entry to not-present and postpone the page table synching till 3307 * it's actually used. 3308 */ 3396 3309 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3397 3310 for (unsigned i = 0, iPdShw = iPD * 2; i < 2; i++, iPdShw++) /* pray that the compiler unrolls this */ 3398 3311 # elif PGM_GST_TYPE == PGM_TYPE_PAE 3399 3312 const unsigned iPdShw = iPD + iPdpt * X86_PG_PAE_ENTRIES; NOREF(iPdShw); 3400 3313 # else 3401 3314 const unsigned iPdShw = iPD; NOREF(iPdShw); 3402 3315 # endif 3316 { 3317 SHWPDE PdeDst = *pPDEDst; 3318 if (PdeDst.n.u1Present) 3403 3319 { 3404 SHWPDE PdeDst = *pPDEDst; 3405 if (PdeDst.n.u1Present) 3320 PPGMPOOLPAGE pShwPage = pgmPoolGetPage(pPool, PdeDst.u & SHW_PDE_PG_MASK); 3321 RTGCPHYS GCPhys; 3322 if ( !PdeSrc.b.u1Size 3323 || !fBigPagesSupported) 3406 3324 { 3407 PPGMPOOLPAGE pShwPage = pgmPoolGetPage(pPool, PdeDst.u & SHW_PDE_PG_MASK); 3408 RTGCPHYS GCPhys; 3409 if ( !PdeSrc.b.u1Size 3410 || !fBigPagesSupported) 3411 { 3412 GCPhys = PdeSrc.u & GST_PDE_PG_MASK; 3325 GCPhys = PdeSrc.u & GST_PDE_PG_MASK; 3413 3326 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3414 3415 3327 /* Select the right PDE as we're emulating a 4kb page table with 2 shadow page tables. */ 3328 GCPhys |= i * (PAGE_SIZE / 2); 3416 3329 # endif 3417 3418 3419 3420 3330 } 3331 else 3332 { 3333 GCPhys = GST_GET_PDE_BIG_PG_GCPHYS(PdeSrc); 3421 3334 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3422 3423 3335 /* Select the right PDE as we're emulating a 4MB page directory with two 2 MB shadow PDEs.*/ 3336 GCPhys |= i * X86_PAGE_2M_SIZE; 3424 3337 # endif 3425 3426 3427 3428 3429 3430 3431 3338 } 3339 3340 if ( pShwPage->GCPhys == GCPhys 3341 && pShwPage->enmKind == PGM_BTH_NAME(CalcPageKind)(&PdeSrc, cr4) 3342 && ( pShwPage->fCached 3343 || ( !fGlobal 3344 && ( false 3432 3345 # ifdef PGM_SKIP_GLOBAL_PAGEDIRS_ON_NONGLOBAL_FLUSH 3433 || ( (PdeSrc.u & (X86_PDE4M_PS | X86_PDE4M_G)) == (X86_PDE4M_PS | X86_PDE4M_G) 3434 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3435 # error "We should not be here!" 3436 && (cr4 & X86_CR4_PGE)) /* global 2/4MB page. */ 3437 # else 3438 && (cr4 & (X86_CR4_PGE | X86_CR4_PSE)) == (X86_CR4_PGE | X86_CR4_PSE)) /* global 2/4MB page. */ 3439 # endif 3440 || ( !pShwPage->fSeenNonGlobal 3441 && (cr4 & X86_CR4_PGE)) 3346 || ( (PdeSrc.u & (X86_PDE4M_PS | X86_PDE4M_G)) == (X86_PDE4M_PS | X86_PDE4M_G) 3347 && (cr4 & (X86_CR4_PGE | X86_CR4_PSE)) == (X86_CR4_PGE | X86_CR4_PSE)) /* global 2/4MB page. */ 3348 || ( !pShwPage->fSeenNonGlobal 3349 && (cr4 & X86_CR4_PGE)) 3442 3350 # endif 3443 )3444 3351 ) 3445 3352 ) 3446 && ( (PdeSrc.u & (X86_PDE_US | X86_PDE_RW)) == (PdeDst.u & (X86_PDE_US | X86_PDE_RW)) 3447 || ( fBigPagesSupported 3448 && ((PdeSrc.u & (X86_PDE_US | X86_PDE4M_PS | X86_PDE4M_D)) | PGM_PDFLAGS_TRACK_DIRTY) 3449 == ((PdeDst.u & (X86_PDE_US | X86_PDE_RW | PGM_PDFLAGS_TRACK_DIRTY)) | X86_PDE4M_PS)) 3450 ) 3451 ) 3452 { 3353 ) 3354 && ( (PdeSrc.u & (X86_PDE_US | X86_PDE_RW)) == (PdeDst.u & (X86_PDE_US | X86_PDE_RW)) 3355 || ( fBigPagesSupported 3356 && ((PdeSrc.u & (X86_PDE_US | X86_PDE4M_PS | X86_PDE4M_D)) | PGM_PDFLAGS_TRACK_DIRTY) 3357 == ((PdeDst.u & (X86_PDE_US | X86_PDE_RW | PGM_PDFLAGS_TRACK_DIRTY)) | X86_PDE4M_PS)) 3358 ) 3359 ) 3360 { 3453 3361 # ifdef VBOX_WITH_STATISTICS 3454 if ( !fGlobal 3455 && (PdeSrc.u & (X86_PDE4M_PS | X86_PDE4M_G)) == (X86_PDE4M_PS | X86_PDE4M_G) 3456 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3457 # error "We should not be here!" 3458 && (cr4 & X86_CR4_PGE)) /* global 2/4MB page. */ 3459 # else 3460 && (cr4 & (X86_CR4_PGE | X86_CR4_PSE)) == (X86_CR4_PGE | X86_CR4_PSE)) 3461 # endif 3462 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstSkippedGlobalPD)); 3463 else if (!fGlobal && !pShwPage->fSeenNonGlobal && (cr4 & X86_CR4_PGE)) 3464 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstSkippedGlobalPT)); 3465 else 3466 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstCacheHit)); 3362 if ( !fGlobal 3363 && (PdeSrc.u & (X86_PDE4M_PS | X86_PDE4M_G)) == (X86_PDE4M_PS | X86_PDE4M_G) 3364 && (cr4 & (X86_CR4_PGE | X86_CR4_PSE)) == (X86_CR4_PGE | X86_CR4_PSE)) 3365 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstSkippedGlobalPD)); 3366 else if (!fGlobal && !pShwPage->fSeenNonGlobal && (cr4 & X86_CR4_PGE)) 3367 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstSkippedGlobalPT)); 3368 else 3369 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstCacheHit)); 3467 3370 # endif /* VBOX_WITH_STATISTICS */ 3468 /** @todo a replacement strategy isn't really needed unless we're using a very small pool < 512 pages. 3469 * The whole ageing stuff should be put in yet another set of #ifdefs. For now, let's just skip it. */ 3470 //# ifdef PGMPOOL_WITH_CACHE 3471 // pgmPoolCacheUsed(pPool, pShwPage); 3472 //# endif 3473 } 3474 else 3475 { 3476 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3477 # error "We should not be here!" 3478 pgmPoolFreeByPage(pPool, pShwPage, pShwPde->idx, iPdShw); 3479 # else 3480 pgmPoolFreeByPage(pPool, pShwPage, SHW_POOL_ROOT_IDX, iPdShw); 3481 # endif 3482 pPDEDst->u = 0; 3483 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstFreed)); 3484 } 3371 /** @todo a replacement strategy isn't really needed unless we're using a very small pool < 512 pages. 3372 * The whole ageing stuff should be put in yet another set of #ifdefs. For now, let's just skip it. */ 3373 //# ifdef PGMPOOL_WITH_CACHE 3374 // pgmPoolCacheUsed(pPool, pShwPage); 3375 //# endif 3485 3376 } 3486 3377 else 3487 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstNotPresent)); 3488 pPDEDst++; 3378 { 3379 pgmPoolFreeByPage(pPool, pShwPage, SHW_POOL_ROOT_IDX, iPdShw); 3380 pPDEDst->u = 0; 3381 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstFreed)); 3382 } 3489 3383 } 3384 else 3385 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstNotPresent)); 3386 pPDEDst++; 3490 3387 } 3388 } 3491 3389 # if PGM_GST_TYPE == PGM_TYPE_PAE 3492 3390 else if (iPD + iPdpt * X86_PG_PAE_ENTRIES != iPdNoMapping) 3493 3391 # else 3494 else if (iPD != iPdNoMapping) 3392 else if (iPD != iPdNoMapping) 3393 # endif 3394 { 3395 /* 3396 * Check if there is any page directory to mark not present here. 3397 */ 3398 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3399 for (unsigned i = 0, iPdShw = iPD * 2; i < 2; i++, iPdShw++) /* pray that the compiler unrolls this */ 3400 # elif PGM_GST_TYPE == PGM_TYPE_PAE 3401 const unsigned iPdShw = iPD + iPdpt * X86_PG_PAE_ENTRIES; NOREF(iPdShw); 3402 # else 3403 const unsigned iPdShw = iPD; NOREF(iPdShw); 3495 3404 # endif 3496 3405 { 3497 /* 3498 * Check if there is any page directory to mark not present here. 3499 */ 3500 # if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT 3501 for (unsigned i = 0, iPdShw = iPD * 2; i < 2; i++, iPdShw++) /* pray that the compiler unrolls this */ 3502 # elif PGM_GST_TYPE == PGM_TYPE_PAE 3503 const unsigned iPdShw = iPD + iPdpt * X86_PG_PAE_ENTRIES; NOREF(iPdShw); 3504 # else 3505 const unsigned iPdShw = iPD; NOREF(iPdShw); 3506 # endif 3406 if (pPDEDst->n.u1Present) 3507 3407 { 3508 if (pPDEDst->n.u1Present) 3509 { 3510 # if PGM_GST_TYPE == PGM_TYPE_AMD64 3511 # error "We should not be here!" 3512 pgmPoolFreeByPage(pPool, pgmPoolGetPage(pPool, pPDEDst->u & SHW_PDE_PG_MASK), pShwPde->idx, iPdShw); 3513 # else 3514 pgmPoolFreeByPage(pPool, pgmPoolGetPage(pPool, pPDEDst->u & SHW_PDE_PG_MASK), SHW_POOL_ROOT_IDX, iPdShw); 3515 # endif 3516 pPDEDst->u = 0; 3517 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstFreedSrcNP)); 3518 } 3519 pPDEDst++; 3408 pgmPoolFreeByPage(pPool, pgmPoolGetPage(pPool, pPDEDst->u & SHW_PDE_PG_MASK), SHW_POOL_ROOT_IDX, iPdShw); 3409 pPDEDst->u = 0; 3410 MY_STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3DstFreedSrcNP)); 3520 3411 } 3412 pPDEDst++; 3413 } 3414 } 3415 else 3416 { 3417 # if ( PGM_GST_TYPE == PGM_TYPE_32BIT \ 3418 || PGM_GST_TYPE == PGM_TYPE_PAE) \ 3419 && !defined(PGM_WITHOUT_MAPPINGS) 3420 3421 const unsigned cPTs = pMapping->cb >> GST_PD_SHIFT; 3422 3423 Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s)); 3424 if (pVM->pgm.s.fMappingsFixed) 3425 { 3426 /* It's fixed, just skip the mapping. */ 3427 pMapping = pMapping->CTX_SUFF(pNext); 3428 iPdNoMapping = pMapping ? pMapping->GCPtr >> GST_PD_SHIFT : ~0U; 3521 3429 } 3522 3430 else 3523 3431 { 3524 # if ( PGM_GST_TYPE == PGM_TYPE_32BIT \ 3525 || PGM_GST_TYPE == PGM_TYPE_PAE) \ 3526 && !defined(PGM_WITHOUT_MAPPINGS) 3527 3528 const unsigned cPTs = pMapping->cb >> GST_PD_SHIFT; 3529 3530 Assert(pgmMapAreMappingsEnabled(&pVM->pgm.s)); 3531 if (pVM->pgm.s.fMappingsFixed) 3432 /* 3433 * Check for conflicts for subsequent pagetables 3434 * and advance to the next mapping. 3435 */ 3436 iPdNoMapping = ~0U; 3437 unsigned iPT = cPTs; 3438 while (iPT-- > 1) 3532 3439 { 3533 /* It's fixed, just skip the mapping. */ 3534 pMapping = pMapping->CTX_SUFF(pNext); 3535 iPdNoMapping = pMapping ? pMapping->GCPtr >> GST_PD_SHIFT : ~0U; 3536 } 3537 else 3538 { 3539 /* 3540 * Check for conflicts for subsequent pagetables 3541 * and advance to the next mapping. 3542 */ 3543 iPdNoMapping = ~0U; 3544 unsigned iPT = cPTs; 3545 while (iPT-- > 1) 3440 if ( pPDSrc->a[iPD + iPT].n.u1Present 3441 && (pPDSrc->a[iPD + iPT].n.u1User || fRawR0Enabled)) 3546 3442 { 3547 if ( pPDSrc->a[iPD + iPT].n.u1Present3548 && (pPDSrc->a[iPD + iPT].n.u1User || fRawR0Enabled))3549 {3550 3443 # ifdef IN_RING3 3551 3444 # if PGM_GST_TYPE == PGM_TYPE_32BIT 3552 3445 int rc = pgmR3SyncPTResolveConflict(pVM, pMapping, pPDSrc, iPD << GST_PD_SHIFT); 3553 3446 # elif PGM_GST_TYPE == PGM_TYPE_PAE 3554 3447 int rc = pgmR3SyncPTResolveConflictPAE(pVM, pMapping, (iPdpt << GST_PDPT_SHIFT) + (iPD << GST_PD_SHIFT)); 3555 3448 # endif 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3449 if (RT_FAILURE(rc)) 3450 return rc; 3451 3452 /* 3453 * Update iPdNoMapping and pMapping. 3454 */ 3455 pMapping = pVM->pgm.s.CTX_SUFF(pMappings); 3456 while (pMapping && pMapping->GCPtr < (iPD << GST_PD_SHIFT)) 3457 pMapping = pMapping->CTX_SUFF(pNext); 3458 iPdNoMapping = pMapping ? pMapping->GCPtr >> GST_PD_SHIFT : ~0U; 3459 break; 3567 3460 # else 3568 3569 3461 LogFlow(("SyncCR3: detected conflict -> VINF_PGM_SYNC_CR3\n")); 3462 return VINF_PGM_SYNC_CR3; 3570 3463 # endif 3571 }3572 }3573 if (iPdNoMapping == ~0U && pMapping)3574 {3575 pMapping = pMapping->CTX_SUFF(pNext);3576 if (pMapping)3577 iPdNoMapping = pMapping->GCPtr >> GST_PD_SHIFT;3578 3464 } 3579 3465 } 3580 3581 /* advance. */ 3582 iPD += cPTs - 1; 3583 pPDEDst += cPTs + (PGM_GST_TYPE != PGM_SHW_TYPE) * cPTs; /* Only applies to the pae shadow and 32 bits guest case */ 3466 if (iPdNoMapping == ~0U && pMapping) 3467 { 3468 pMapping = pMapping->CTX_SUFF(pNext); 3469 if (pMapping) 3470 iPdNoMapping = pMapping->GCPtr >> GST_PD_SHIFT; 3471 } 3472 } 3473 3474 /* advance. */ 3475 iPD += cPTs - 1; 3476 pPDEDst += cPTs + (PGM_GST_TYPE != PGM_SHW_TYPE) * cPTs; /* Only applies to the pae shadow and 32 bits guest case */ 3584 3477 # if PGM_GST_TYPE != PGM_SHW_TYPE 3585 3478 AssertCompile(PGM_GST_TYPE == PGM_TYPE_32BIT && PGM_SHW_TYPE == PGM_TYPE_PAE); 3586 3479 # endif 3587 3480 # else /* (PGM_GST_TYPE != PGM_TYPE_32BIT && PGM_GST_TYPE != PGM_TYPE_PAE) || PGM_WITHOUT_MAPPINGS */ 3588 3481 Assert(!pgmMapAreMappingsEnabled(&pVM->pgm.s)); 3589 3482 # endif /* (PGM_GST_TYPE != PGM_TYPE_32BIT && PGM_GST_TYPE != PGM_TYPE_PAE) || PGM_WITHOUT_MAPPINGS */ 3590 } 3591 3592 } /* for iPD */ 3593 } /* for each PDPTE (PAE) */ 3594 } /* for each page map level 4 entry (amd64) */ 3483 } 3484 3485 } /* for iPD */ 3486 } /* for each PDPTE (PAE) */ 3595 3487 return VINF_SUCCESS; 3596 3488 … … 3598 3490 return VINF_SUCCESS; 3599 3491 # endif 3600 #endif /* PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT */3492 #endif /* PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT && PGM_SHW_TYPE != PGM_TYPE_AMD64 */ 3601 3493 } 3602 3494
Note:
See TracChangeset
for help on using the changeset viewer.