Changeset 93716 in vbox for trunk/src/VBox
- Timestamp:
- Feb 14, 2022 10:36:21 AM (3 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r93650 r93716 240 240 const RTGCPHYS GCPhysFault = PGM_A20_APPLY(pVCpu, (RTGCPHYS)pvFault); 241 241 # endif 242 PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhysFault); 243 if (pCur) 242 PPGMPHYSHANDLER pCur; 243 rcStrict = pgmHandlerPhysicalLookup(pVM, GCPhysFault, &pCur); 244 if (RT_SUCCESS(rcStrict)) 244 245 { 245 246 PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE(pVM, pCur); … … 322 323 : (uintptr_t)PDMDeviceRing0IdxToInstance(pVM, pCur->uUser)); 323 324 324 # ifdef VBOX_WITH_STATISTICS 325 pCur = pgmHandlerPhysicalLookup(pVM, GCPhysFault); /* paranoia in case the handler deregistered itself */ 326 if (pCur) 327 STAM_PROFILE_STOP(&pCur->Stat, h); 328 # endif 325 STAM_PROFILE_STOP(&pCur->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */ 329 326 } 330 327 else … … 337 334 rcStrict = pCurType->pfnPfHandler(pVM, pVCpu, uErr, pRegFrame, pvFault, GCPhysFault, uUser); 338 335 339 # ifdef VBOX_WITH_STATISTICS 340 PGM_LOCK_VOID(pVM); 341 pCur = pgmHandlerPhysicalLookup(pVM, GCPhysFault); 342 if (pCur) 343 STAM_PROFILE_STOP(&pCur->Stat, h); 344 PGM_UNLOCK(pVM); 345 # endif 336 STAM_PROFILE_STOP(&pCur->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */ 346 337 } 347 338 } … … 352 343 return rcStrict; 353 344 } 345 AssertMsgReturn(rcStrict == VERR_NOT_FOUND, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)), rcStrict); 354 346 } 355 347 -
trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
r93666 r93716 111 111 112 112 /** 113 * Creates a physical access handler .113 * Creates a physical access handler, allocation part. 114 114 * 115 115 * @returns VBox status code. 116 * @retval VINF_SUCCESS when successfully installed. 117 * @retval VINF_PGM_GCPHYS_ALIASED when the shadow PTs could be updated because 118 * the guest page aliased or/and mapped by multiple PTs. A CR3 sync has been 119 * flagged together with a pool clearing. 120 * @retval VERR_PGM_HANDLER_PHYSICAL_CONFLICT if the range conflicts with an existing 121 * one. A debug assertion is raised. 116 * @retval VERR_OUT_OF_RESOURCES if no more handlers available. 122 117 * 123 118 * @param pVM The cross context VM structure. … … 146 141 * Allocate and initialize the new entry. 147 142 */ 148 PPGMPHYSHANDLER pNew; 149 int rc = MMHyperAlloc(pVM, sizeof(*pNew), 0, MM_TAG_PGM_HANDLERS, (void **)&pNew); 150 if (RT_SUCCESS(rc)) 151 { 152 pNew->Core.Key = NIL_RTGCPHYS; 153 pNew->Core.KeyLast = NIL_RTGCPHYS; 143 int rc = PGM_LOCK(pVM); 144 AssertRCReturn(rc, rc); 145 146 PPGMPHYSHANDLER pNew = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.allocateNode(); 147 if (pNew) 148 { 149 pNew->Key = NIL_RTGCPHYS; 150 pNew->KeyLast = NIL_RTGCPHYS; 154 151 pNew->cPages = 0; 155 152 pNew->cAliasedPages = 0; … … 163 160 : pVM->pgm.s.aPhysHandlerTypes[hType & PGMPHYSHANDLERTYPE_IDX_MASK].pszDesc; 164 161 #endif 162 163 PGM_UNLOCK(pVM); 165 164 *ppPhysHandler = pNew; 166 165 return VINF_SUCCESS; 167 166 } 168 167 169 return rc; 168 PGM_UNLOCK(pVM); 169 return VERR_OUT_OF_RESOURCES; 170 170 } 171 171 … … 194 194 * @returns VBox status code. 195 195 * @retval VINF_SUCCESS when successfully installed. 196 * @retval VINF_PGM_GCPHYS_ALIASED could be returned. 196 197 * 197 198 * @param pVM The cross context VM structure. … … 205 206 * Validate input. 206 207 */ 208 AssertReturn(pPhysHandler, VERR_INVALID_POINTER); 207 209 PGMPHYSHANDLERTYPE const hType = pPhysHandler->hType; 208 210 PCPGMPHYSHANDLERTYPEINT const pType = pgmHandlerPhysicalTypeHandleToPtr(pVM, hType); … … 214 216 Log(("pgmHandlerPhysicalExRegister: GCPhys=%RGp GCPhysLast=%RGp hType=%#x (%d, %s) pszDesc=%RHv:%s\n", GCPhys, GCPhysLast, 215 217 hType, pType->enmKind, pType->pszDesc, pPhysHandler->pszDesc, R3STRING(pPhysHandler->pszDesc))); 216 AssertReturn(pPhysHandler-> Core.Key == NIL_RTGCPHYS, VERR_WRONG_ORDER);218 AssertReturn(pPhysHandler->Key == NIL_RTGCPHYS, VERR_WRONG_ORDER); 217 219 218 220 AssertMsgReturn(GCPhys < GCPhysLast, ("GCPhys >= GCPhysLast (%#x >= %#x)\n", GCPhys, GCPhysLast), VERR_INVALID_PARAMETER); 221 Assert(GCPhysLast - GCPhys < _4G); /* ASSUMPTION in PGMAllPhys.cpp */ 222 219 223 switch (pType->enmKind) 220 224 { … … 252 256 * Try insert into list. 253 257 */ 254 pPhysHandler->Core.Key = GCPhys; 255 pPhysHandler->Core.KeyLast = GCPhysLast; 256 pPhysHandler->cPages = (GCPhysLast - (GCPhys & X86_PTE_PAE_PG_MASK) + GUEST_PAGE_SIZE) >> GUEST_PAGE_SHIFT; 257 258 PGM_LOCK_VOID(pVM); 259 if (RTAvlroGCPhysInsert(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, &pPhysHandler->Core)) 260 { 261 int rc = pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(pVM, pPhysHandler, pRam, NULL /*pvBitmap*/, 0 /*offBitmap*/); 262 if (rc == VINF_PGM_SYNC_CR3) 263 rc = VINF_PGM_GCPHYS_ALIASED; 258 pPhysHandler->Key = GCPhys; 259 pPhysHandler->KeyLast = GCPhysLast; 260 pPhysHandler->cPages = (GCPhysLast - (GCPhys & X86_PTE_PAE_PG_MASK) + GUEST_PAGE_SIZE) >> GUEST_PAGE_SHIFT; 261 262 int rc = PGM_LOCK(pVM); 263 if (RT_SUCCESS(rc)) 264 { 265 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->insert(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, pPhysHandler); 266 if (RT_SUCCESS(rc)) 267 { 268 rc = pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(pVM, pPhysHandler, pRam, NULL /*pvBitmap*/, 0 /*offBitmap*/); 269 if (rc == VINF_PGM_SYNC_CR3) 270 rc = VINF_PGM_GCPHYS_ALIASED; 264 271 265 272 #if defined(IN_RING3) || defined(IN_RING0) 266 NEMHCNotifyHandlerPhysicalRegister(pVM, pType->enmKind, GCPhys, GCPhysLast - GCPhys + 1); 267 #endif 273 NEMHCNotifyHandlerPhysicalRegister(pVM, pType->enmKind, GCPhys, GCPhysLast - GCPhys + 1); 274 #endif 275 PGM_UNLOCK(pVM); 276 277 if (rc != VINF_SUCCESS) 278 Log(("PGMHandlerPhysicalRegisterEx: returns %Rrc (%RGp-%RGp)\n", rc, GCPhys, GCPhysLast)); 279 return rc; 280 } 268 281 PGM_UNLOCK(pVM); 269 270 if (rc != VINF_SUCCESS) 271 Log(("PGMHandlerPhysicalRegisterEx: returns %Rrc (%RGp-%RGp)\n", rc, GCPhys, GCPhysLast)); 272 return rc; 273 } 274 PGM_UNLOCK(pVM); 275 276 pPhysHandler->Core.Key = NIL_RTGCPHYS; 277 pPhysHandler->Core.KeyLast = NIL_RTGCPHYS; 282 } 283 284 pPhysHandler->Key = NIL_RTGCPHYS; 285 pPhysHandler->KeyLast = NIL_RTGCPHYS; 286 287 AssertMsgReturn(rc == VERR_ALREADY_EXISTS, ("%Rrc GCPhys=%RGp GCPhysLast=%RGp\n", rc, GCPhys, GCPhysLast), rc); 278 288 279 289 #if defined(IN_RING3) && defined(VBOX_STRICT) … … 352 362 const unsigned uState = pCurType->uState; 353 363 uint32_t cPages = pCur->cPages; 354 uint32_t i = (pCur-> Core.Key - pRam->GCPhys) >> GUEST_PAGE_SHIFT;364 uint32_t i = (pCur->Key - pRam->GCPhys) >> GUEST_PAGE_SHIFT; 355 365 for (;;) 356 366 { … … 415 425 { 416 426 LogFlow(("pgmHandlerPhysicalExDeregister: Removing Range %RGp-%RGp %s\n", 417 pPhysHandler->Core.Key, pPhysHandler->Core.KeyLast, R3STRING(pPhysHandler->pszDesc))); 418 AssertReturn(pPhysHandler->Core.Key != NIL_RTGCPHYS, VERR_PGM_HANDLER_NOT_FOUND); 427 pPhysHandler->Key, pPhysHandler->KeyLast, R3STRING(pPhysHandler->pszDesc))); 428 429 int rc = PGM_LOCK(pVM); 430 AssertRCReturn(rc, rc); 431 432 RTGCPHYS const GCPhys = pPhysHandler->Key; 433 AssertReturnStmt(GCPhys != NIL_RTGCPHYS, PGM_UNLOCK(pVM), VERR_PGM_HANDLER_NOT_FOUND); 419 434 420 435 /* 421 436 * Remove the handler from the tree. 422 437 */ 423 PGM_LOCK_VOID(pVM); 424 PPGMPHYSHANDLER pRemoved = (PPGMPHYSHANDLER)RTAvlroGCPhysRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, 425 pPhysHandler->Core.Key); 426 if (pRemoved == pPhysHandler) 427 { 438 439 PPGMPHYSHANDLER pRemoved; 440 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->remove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pRemoved); 441 if (RT_SUCCESS(rc)) 442 { 443 if (pRemoved == pPhysHandler) 444 { 445 /* 446 * Clear the page bits, notify the REM about this change and clear 447 * the cache. 448 */ 449 pgmHandlerPhysicalResetRamFlags(pVM, pPhysHandler); 450 if (VM_IS_NEM_ENABLED(pVM)) 451 pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pPhysHandler); 452 pVM->pgm.s.idxLastPhysHandler = 0; 453 454 pPhysHandler->Key = NIL_RTGCPHYS; 455 pPhysHandler->KeyLast = NIL_RTGCPHYS; 456 457 PGM_UNLOCK(pVM); 458 459 return VINF_SUCCESS; 460 } 461 428 462 /* 429 * Clear the page bits, notify the REM about this change and clear 430 * the cache. 463 * Both of the failure conditions here are considered internal processing 464 * errors because they can only be caused by race conditions or corruption. 465 * If we ever need to handle concurrent deregistration, we have to move 466 * the NIL_RTGCPHYS check inside the PGM lock. 431 467 */ 432 pgmHandlerPhysicalResetRamFlags(pVM, pPhysHandler); 433 if (VM_IS_NEM_ENABLED(pVM)) 434 pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pPhysHandler); 435 pVM->pgm.s.pLastPhysHandlerR0 = 0; 436 pVM->pgm.s.pLastPhysHandlerR3 = 0; 437 438 pPhysHandler->Core.Key = NIL_RTGCPHYS; 439 pPhysHandler->Core.KeyLast = NIL_RTGCPHYS; 440 441 PGM_UNLOCK(pVM); 442 443 return VINF_SUCCESS; 444 } 445 446 /* 447 * Both of the failure conditions here are considered internal processing 448 * errors because they can only be caused by race conditions or corruption. 449 * If we ever need to handle concurrent deregistration, we have to move 450 * the NIL_RTGCPHYS check inside the PGM lock. 451 */ 452 if (pRemoved) 453 RTAvlroGCPhysInsert(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, &pRemoved->Core); 468 pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->insert(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, pRemoved); 469 } 454 470 455 471 PGM_UNLOCK(pVM); 456 472 457 if ( !pRemoved)458 AssertMsgFailed(("Didn't find range starting at %RGp in the tree! \n", pPhysHandler->Core.Key));473 if (RT_FAILURE(rc)) 474 AssertMsgFailed(("Didn't find range starting at %RGp in the tree! %Rrc=rc\n", GCPhys, rc)); 459 475 else 460 476 AssertMsgFailed(("Found different handle at %RGp in the tree: got %p insteaded of %p\n", 461 pPhysHandler->Core.Key, pRemoved, pPhysHandler));477 GCPhys, pRemoved, pPhysHandler)); 462 478 return VERR_PGM_HANDLER_IPE_1; 463 479 } … … 478 494 { 479 495 AssertPtr(pHandler); 480 AssertReturn(pHandler->Core.Key == NIL_RTGCPHYS, VERR_WRONG_ORDER); 481 MMHyperFree(pVM, pHandler); 496 AssertReturn(pHandler->Key == NIL_RTGCPHYS, VERR_WRONG_ORDER); 497 498 int rc = PGM_LOCK(pVM); 499 if (RT_SUCCESS(rc)) 500 { 501 rc = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.freeNode(pHandler); 502 PGM_UNLOCK(pVM); 503 } 504 return rc; 482 505 } 483 506 return VINF_SUCCESS; … … 494 517 VMMDECL(int) PGMHandlerPhysicalDeregister(PVMCC pVM, RTGCPHYS GCPhys) 495 518 { 519 AssertReturn(pVM->VMCC_CTX(pgm).s.pPhysHandlerTree, VERR_PGM_HANDLER_IPE_1); 520 496 521 /* 497 522 * Find the handler. 498 523 */ 499 PGM_LOCK_VOID(pVM); 500 PPGMPHYSHANDLER pRemoved = (PPGMPHYSHANDLER)RTAvlroGCPhysRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 501 if (pRemoved) 502 { 524 int rc = PGM_LOCK(pVM); 525 AssertRCReturn(rc, rc); 526 527 PPGMPHYSHANDLER pRemoved; 528 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->remove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pRemoved); 529 if (RT_SUCCESS(rc)) 530 { 531 Assert(pRemoved->Key == GCPhys); 503 532 LogFlow(("PGMHandlerPhysicalDeregister: Removing Range %RGp-%RGp %s\n", 504 pRemoved-> Core.Key, pRemoved->Core.KeyLast, R3STRING(pRemoved->pszDesc)));533 pRemoved->Key, pRemoved->KeyLast, R3STRING(pRemoved->pszDesc))); 505 534 506 535 /* … … 511 540 if (VM_IS_NEM_ENABLED(pVM)) 512 541 pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pRemoved); 513 pVM->pgm.s.pLastPhysHandlerR0 = 0; 514 pVM->pgm.s.pLastPhysHandlerR3 = 0; 542 pVM->pgm.s.idxLastPhysHandler = 0; 543 544 pRemoved->Key = NIL_RTGCPHYS; 545 rc = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.freeNode(pRemoved); 515 546 516 547 PGM_UNLOCK(pVM); 517 518 pRemoved->Core.Key = NIL_RTGCPHYS; 519 pgmHandlerPhysicalExDestroy(pVM, pRemoved); 520 return VINF_SUCCESS; 548 return rc; 521 549 } 522 550 523 551 PGM_UNLOCK(pVM); 524 552 525 AssertMsgFailed(("Didn't find range starting at %RGp\n", GCPhys)); 526 return VERR_PGM_HANDLER_NOT_FOUND; 553 if (rc == VERR_NOT_FOUND) 554 { 555 AssertMsgFailed(("Didn't find range starting at %RGp\n", GCPhys)); 556 rc = VERR_PGM_HANDLER_NOT_FOUND; 557 } 558 return rc; 527 559 } 528 560 … … 535 567 #ifdef VBOX_WITH_NATIVE_NEM 536 568 PCPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur); 537 RTGCPHYS GCPhysStart = pCur-> Core.Key;538 RTGCPHYS GCPhysLast = pCur-> Core.KeyLast;569 RTGCPHYS GCPhysStart = pCur->Key; 570 RTGCPHYS GCPhysLast = pCur->KeyLast; 539 571 540 572 /* … … 545 577 * included in the REM notification or not. 546 578 */ 547 if ( (pCur-> Core.Key & GUEST_PAGE_OFFSET_MASK)548 || ((pCur-> Core.KeyLast + 1) & GUEST_PAGE_OFFSET_MASK))579 if ( (pCur->Key & GUEST_PAGE_OFFSET_MASK) 580 || ((pCur->KeyLast + 1) & GUEST_PAGE_OFFSET_MASK)) 549 581 { 550 582 Assert(pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO); … … 614 646 for (;;) 615 647 { 616 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys, fAbove); 617 if ( !pCur 618 || ((fAbove ? pCur->Core.Key : pCur->Core.KeyLast) >> GUEST_PAGE_SHIFT) != (GCPhys >> GUEST_PAGE_SHIFT)) 648 PPGMPHYSHANDLER pCur; 649 int rc; 650 if (fAbove) 651 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookupMatchingOrAbove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, 652 GCPhys, &pCur); 653 else 654 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookupMatchingOrBelow(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, 655 GCPhys, &pCur); 656 if (rc == VERR_NOT_FOUND) 657 break; 658 AssertRCBreak(rc); 659 if (((fAbove ? pCur->Key : pCur->KeyLast) >> GUEST_PAGE_SHIFT) != (GCPhys >> GUEST_PAGE_SHIFT)) 619 660 break; 620 661 PCPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur); … … 623 664 /* next? */ 624 665 RTGCPHYS GCPhysNext = fAbove 625 ? pCur-> Core.KeyLast + 1626 : pCur-> Core.Key- 1;666 ? pCur->KeyLast + 1 667 : pCur->Key - 1; 627 668 if ((GCPhysNext >> GUEST_PAGE_SHIFT) != (GCPhys >> GUEST_PAGE_SHIFT)) 628 669 break; … … 714 755 if (fDoAccounting) 715 756 { 716 PPGMPHYSHANDLER pHandler = pgmHandlerPhysicalLookup(pVM, GCPhysPage); 717 if (RT_LIKELY(pHandler)) 757 PPGMPHYSHANDLER pHandler; 758 rc = pgmHandlerPhysicalLookup(pVM, GCPhysPage, &pHandler); 759 if (RT_SUCCESS(rc)) 718 760 { 719 761 Assert(pHandler->cAliasedPages > 0); … … 721 763 } 722 764 else 723 Assert Failed();765 AssertMsgFailed(("rc=%Rrc GCPhysPage=%RGp\n", rc, GCPhysPage)); 724 766 } 725 767 … … 760 802 */ 761 803 RTUINT cPages = pCur->cPages; 762 RTGCPHYS GCPhys = pCur-> Core.Key;804 RTGCPHYS GCPhys = pCur->Key; 763 805 PPGMRAMRANGE pRamHint = NULL; 764 806 for (;;) … … 815 857 * Check for partial start and end pages. 816 858 */ 817 if (pCur-> Core.Key & GUEST_PAGE_OFFSET_MASK)818 pgmHandlerPhysicalRecalcPageState(pVM, pCur-> Core.Key - 1, false /* fAbove */, &pRamHint);819 if ((pCur-> Core.KeyLast & GUEST_PAGE_OFFSET_MASK) != GUEST_PAGE_OFFSET_MASK)820 pgmHandlerPhysicalRecalcPageState(pVM, pCur-> Core.KeyLast + 1, true /* fAbove */, &pRamHint);859 if (pCur->Key & GUEST_PAGE_OFFSET_MASK) 860 pgmHandlerPhysicalRecalcPageState(pVM, pCur->Key - 1, false /* fAbove */, &pRamHint); 861 if ((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) != GUEST_PAGE_OFFSET_MASK) 862 pgmHandlerPhysicalRecalcPageState(pVM, pCur->KeyLast + 1, true /* fAbove */, &pRamHint); 821 863 } 822 864 … … 945 987 * Find the handler and make the change. 946 988 */ 947 int rc; 948 PGM_LOCK_VOID(pVM); 949 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 950 if (pCur) 951 { 989 int rc = PGM_LOCK(pVM); 990 AssertRCReturn(rc, rc); 991 992 PPGMPHYSHANDLER pCur; 993 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur); 994 if (RT_SUCCESS(rc)) 995 { 996 Assert(pCur->Key == GCPhys); 952 997 pCur->uUser = uUser; 953 rc = VINF_SUCCESS; 954 } 955 else 998 } 999 else if (rc == VERR_NOT_FOUND) 956 1000 { 957 1001 AssertMsgFailed(("Didn't find range starting at %RGp\n", GCPhys)); … … 1125 1169 { 1126 1170 LogFlow(("PGMHandlerPhysicalReset GCPhys=%RGp\n", GCPhys)); 1127 PGM_LOCK_VOID(pVM); 1171 int rc = PGM_LOCK(pVM); 1172 AssertRCReturn(rc, rc); 1128 1173 1129 1174 /* 1130 1175 * Find the handler. 1131 1176 */ 1132 int rc; 1133 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 1134 if (RT_LIKELY(pCur)) 1135 { 1177 PPGMPHYSHANDLER pCur; 1178 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur); 1179 if (RT_SUCCESS(rc)) 1180 { 1181 Assert(pCur->Key == GCPhys); 1182 1136 1183 /* 1137 1184 * Validate kind. … … 1147 1194 PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys); 1148 1195 Assert(pRam); 1149 Assert(pRam->GCPhys <= pCur-> Core.Key);1150 Assert(pRam->GCPhysLast >= pCur-> Core.KeyLast);1196 Assert(pRam->GCPhys <= pCur->Key); 1197 Assert(pRam->GCPhysLast >= pCur->KeyLast); 1151 1198 1152 1199 if (pCurType->enmKind == PGMPHYSHANDLERKIND_MMIO) … … 1159 1206 if (pCur->cAliasedPages) 1160 1207 { 1161 PPGMPAGE pPage = &pRam->aPages[(pCur-> Core.Key - pRam->GCPhys) >> GUEST_PAGE_SHIFT];1162 RTGCPHYS GCPhysPage = pCur-> Core.Key;1208 PPGMPAGE pPage = &pRam->aPages[(pCur->Key - pRam->GCPhys) >> GUEST_PAGE_SHIFT]; 1209 RTGCPHYS GCPhysPage = pCur->Key; 1163 1210 uint32_t cLeft = pCur->cPages; 1164 1211 while (cLeft-- > 0) … … 1206 1253 } 1207 1254 } 1208 else 1255 else if (rc == VERR_NOT_FOUND) 1209 1256 { 1210 1257 AssertMsgFailed(("Didn't find MMIO Range starting at %#x\n", GCPhys)); … … 1238 1285 * Find the handler. 1239 1286 */ 1240 int rc; 1241 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 1242 if (RT_LIKELY(pCur)) 1243 { 1287 PPGMPHYSHANDLER pCur; 1288 int rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur); 1289 if (RT_SUCCESS(rc)) 1290 { 1291 Assert(pCur->Key == GCPhys); 1292 1244 1293 /* 1245 1294 * Validate kind. … … 1253 1302 PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys); 1254 1303 Assert(pRam); 1255 Assert(pRam->GCPhys <= pCur-> Core.Key);1256 Assert(pRam->GCPhysLast >= pCur-> Core.KeyLast);1304 Assert(pRam->GCPhys <= pCur->Key); 1305 Assert(pRam->GCPhysLast >= pCur->KeyLast); 1257 1306 1258 1307 /* … … 1273 1322 } 1274 1323 } 1275 else 1324 else if (rc == VERR_NOT_FOUND) 1276 1325 { 1277 1326 AssertMsgFailed(("Didn't find MMIO Range starting at %#x\n", GCPhys)); … … 1305 1354 { 1306 1355 LogFlow(("PGMHandlerPhysicalPageTempOff GCPhysPage=%RGp\n", GCPhysPage)); 1307 PGM_LOCK_VOID(pVM); 1356 int rc = PGM_LOCK(pVM); 1357 AssertRCReturn(rc, rc); 1308 1358 1309 1359 /* 1310 1360 * Validate the range. 1311 1361 */ 1312 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 1313 if (RT_LIKELY(pCur)) 1314 { 1315 if (RT_LIKELY( GCPhysPage >= pCur->Core.Key 1316 && GCPhysPage <= pCur->Core.KeyLast)) 1317 { 1318 Assert(!(pCur->Core.Key & GUEST_PAGE_OFFSET_MASK)); 1319 Assert((pCur->Core.KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK); 1362 PPGMPHYSHANDLER pCur; 1363 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur); 1364 if (RT_SUCCESS(rc)) 1365 { 1366 Assert(pCur->Key == GCPhys); 1367 if (RT_LIKELY( GCPhysPage >= pCur->Key 1368 && GCPhysPage <= pCur->KeyLast)) 1369 { 1370 Assert(!(pCur->Key & GUEST_PAGE_OFFSET_MASK)); 1371 Assert((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK); 1320 1372 1321 1373 PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE(pVM, pCur); … … 1330 1382 PPGMPAGE pPage; 1331 1383 PPGMRAMRANGE pRam; 1332 intrc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam);1384 rc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam); 1333 1385 AssertReturnStmt(RT_SUCCESS_NP(rc), PGM_UNLOCK(pVM), rc); 1334 1386 if (PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_DISABLED) … … 1354 1406 } 1355 1407 PGM_UNLOCK(pVM); 1356 AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", 1357 GCPhysPage, pCur->Core.Key, pCur->Core.KeyLast)); 1408 AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", GCPhysPage, pCur->Key, pCur->KeyLast)); 1358 1409 return VERR_INVALID_PARAMETER; 1359 1410 } 1360 1411 PGM_UNLOCK(pVM); 1361 AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys)); 1362 return VERR_PGM_HANDLER_NOT_FOUND; 1412 1413 if (rc == VERR_NOT_FOUND) 1414 { 1415 AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys)); 1416 return VERR_PGM_HANDLER_NOT_FOUND; 1417 } 1418 return rc; 1363 1419 } 1364 1420 … … 1461 1517 AssertReturn(!VM_IS_NEM_ENABLED(pVM) || !pVM->pgm.s.fNemMode, VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE); 1462 1518 #endif 1463 PGM_LOCK_VOID(pVM); 1519 int rc = PGM_LOCK(pVM); 1520 AssertRCReturn(rc, rc); 1464 1521 1465 1522 /* … … 1480 1537 * Lookup and validate the range. 1481 1538 */ 1482 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 1483 if (RT_LIKELY(pCur)) 1484 { 1485 if (RT_LIKELY( GCPhysPage >= pCur->Core.Key 1486 && GCPhysPage <= pCur->Core.KeyLast)) 1539 PPGMPHYSHANDLER pCur; 1540 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur); 1541 if (RT_SUCCESS(rc)) 1542 { 1543 Assert(pCur->Key == GCPhys); 1544 if (RT_LIKELY( GCPhysPage >= pCur->Key 1545 && GCPhysPage <= pCur->KeyLast)) 1487 1546 { 1488 1547 PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur); 1489 1548 AssertReturnStmt(pCurType->enmKind == PGMPHYSHANDLERKIND_MMIO, PGM_UNLOCK(pVM), VERR_ACCESS_DENIED); 1490 AssertReturnStmt(!(pCur-> Core.Key & GUEST_PAGE_OFFSET_MASK), PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER);1491 AssertReturnStmt((pCur-> Core.KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK,1549 AssertReturnStmt(!(pCur->Key & GUEST_PAGE_OFFSET_MASK), PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER); 1550 AssertReturnStmt((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK, 1492 1551 PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER); 1493 1552 … … 1497 1556 PPGMPAGE pPage; 1498 1557 PPGMRAMRANGE pRam; 1499 intrc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam);1558 rc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam); 1500 1559 AssertReturnStmt(RT_SUCCESS_NP(rc), PGM_UNLOCK(pVM), rc); 1501 1560 if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO) … … 1556 1615 1557 1616 PGM_UNLOCK(pVM); 1558 AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", 1559 GCPhysPage, pCur->Core.Key, pCur->Core.KeyLast)); 1617 AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", GCPhysPage, pCur->Key, pCur->KeyLast)); 1560 1618 return VERR_INVALID_PARAMETER; 1561 1619 } 1562 1620 1563 1621 PGM_UNLOCK(pVM); 1564 AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys)); 1565 return VERR_PGM_HANDLER_NOT_FOUND; 1622 if (rc == VERR_NOT_FOUND) 1623 { 1624 AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys)); 1625 return VERR_PGM_HANDLER_NOT_FOUND; 1626 } 1627 return rc; 1566 1628 } 1567 1629 … … 1604 1666 AssertReturn(!VM_IS_NEM_ENABLED(pVM) || !pVM->pgm.s.fNemMode, VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE); 1605 1667 #endif 1606 PGM_LOCK_VOID(pVM); 1668 int rc = PGM_LOCK(pVM); 1669 AssertRCReturn(rc, rc); 1607 1670 1608 1671 /* 1609 1672 * Lookup and validate the range. 1610 1673 */ 1611 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 1612 if (RT_LIKELY(pCur)) 1613 { 1614 if (RT_LIKELY( GCPhysPage >= pCur->Core.Key 1615 && GCPhysPage <= pCur->Core.KeyLast)) 1674 PPGMPHYSHANDLER pCur; 1675 rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pCur); 1676 if (RT_SUCCESS(rc)) 1677 { 1678 Assert(pCur->Key == GCPhys); 1679 if (RT_LIKELY( GCPhysPage >= pCur->Key 1680 && GCPhysPage <= pCur->KeyLast)) 1616 1681 { 1617 1682 PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur); 1618 1683 AssertReturnStmt(pCurType->enmKind == PGMPHYSHANDLERKIND_MMIO, PGM_UNLOCK(pVM), VERR_ACCESS_DENIED); 1619 AssertReturnStmt(!(pCur-> Core.Key & GUEST_PAGE_OFFSET_MASK), PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER);1620 AssertReturnStmt((pCur-> Core.KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK,1684 AssertReturnStmt(!(pCur->Key & GUEST_PAGE_OFFSET_MASK), PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER); 1685 AssertReturnStmt((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK, 1621 1686 PGM_UNLOCK(pVM), VERR_INVALID_PARAMETER); 1622 1687 … … 1625 1690 */ 1626 1691 PPGMPAGE pPage; 1627 intrc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage);1692 rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage); 1628 1693 AssertReturnStmt(RT_SUCCESS_NP(rc), PGM_UNLOCK(pVM), rc); 1629 1694 if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO) … … 1673 1738 } 1674 1739 PGM_UNLOCK(pVM); 1675 AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", 1676 GCPhysPage, pCur->Core.Key, pCur->Core.KeyLast)); 1740 AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", GCPhysPage, pCur->Key, pCur->KeyLast)); 1677 1741 return VERR_INVALID_PARAMETER; 1678 1742 } 1679 1743 PGM_UNLOCK(pVM); 1680 1744 1681 AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys)); 1682 return VERR_PGM_HANDLER_NOT_FOUND; 1745 if (rc == VERR_NOT_FOUND) 1746 { 1747 AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys)); 1748 return VERR_PGM_HANDLER_NOT_FOUND; 1749 } 1750 return rc; 1683 1751 } 1684 1752 … … 1699 1767 */ 1700 1768 PGM_LOCK_VOID(pVM); 1701 PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhys); 1702 if (pCur) 1769 PPGMPHYSHANDLER pCur; 1770 int rc = pgmHandlerPhysicalLookup(pVM, GCPhys, &pCur); 1771 if (RT_SUCCESS(rc)) 1703 1772 { 1704 1773 #ifdef VBOX_STRICT 1705 Assert(GCPhys >= pCur-> Core.Key && GCPhys <= pCur->Core.KeyLast);1774 Assert(GCPhys >= pCur->Key && GCPhys <= pCur->KeyLast); 1706 1775 PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur); 1707 1776 Assert( pCurType->enmKind == PGMPHYSHANDLERKIND_WRITE … … 1731 1800 { 1732 1801 PGM_LOCK_VOID(pVM); 1733 PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhys); 1734 if (!pCur) 1735 { 1736 PGM_UNLOCK(pVM); 1737 AssertFailed(); 1738 return true; 1739 } 1802 PPGMPHYSHANDLER pCur; 1803 int rc = pgmHandlerPhysicalLookup(pVM, GCPhys, &pCur); 1804 AssertRCReturnStmt(rc, PGM_UNLOCK(pVM), true); 1740 1805 1741 1806 /* Only whole pages can be disabled. */ 1742 Assert( pCur-> Core.Key <= (GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK)1743 && pCur-> Core.KeyLast >= (GCPhys | GUEST_PAGE_OFFSET_MASK));1807 Assert( pCur->Key <= (GCPhys & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK) 1808 && pCur->KeyLast >= (GCPhys | GUEST_PAGE_OFFSET_MASK)); 1744 1809 1745 1810 PCPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur); … … 1789 1854 * Check the RAM flags against the handlers. 1790 1855 */ 1856 PPGMPHYSHANDLERTREE const pPhysHandlerTree = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree; 1791 1857 for (PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRangesX); pRam; pRam = pRam->CTX_SUFF(pNext)) 1792 1858 { … … 1806 1872 { 1807 1873 /* the first */ 1808 PPGMPHYSHANDLER pPhys = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pPGM->CTX_SUFF(pTrees)->PhysHandlers, State.GCPhys); 1809 if (!pPhys) 1874 PPGMPHYSHANDLER pPhys; 1875 int rc = pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, State.GCPhys, &pPhys); 1876 if (rc == VERR_NOT_FOUND) 1810 1877 { 1811 pPhys = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pPGM->CTX_SUFF(pTrees)->PhysHandlers, State.GCPhys, true); 1812 if ( pPhys 1813 && pPhys->Core.Key > (State.GCPhys + GUEST_PAGE_SIZE - 1)) 1814 pPhys = NULL; 1815 Assert(!pPhys || pPhys->Core.Key >= State.GCPhys); 1878 rc = pPhysHandlerTree->lookupMatchingOrAbove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, 1879 State.GCPhys, &pPhys); 1880 if (RT_SUCCESS(rc)) 1881 { 1882 Assert(pPhys->Key >= State.GCPhys); 1883 if (pPhys->Key > (State.GCPhys + GUEST_PAGE_SIZE - 1)) 1884 pPhys = NULL; 1885 } 1886 else 1887 AssertLogRelMsgReturn(rc == VERR_NOT_FOUND, ("rc=%Rrc GCPhys=%RGp\n", rc, State.GCPhys), 999); 1816 1888 } 1889 else 1890 AssertLogRelMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc GCPhys=%RGp\n", rc, State.GCPhys), 999); 1891 1817 1892 if (pPhys) 1818 1893 { … … 1821 1896 1822 1897 /* more? */ 1823 while (pPhys-> Core.KeyLast < (State.GCPhys | GUEST_PAGE_OFFSET_MASK))1898 while (pPhys->KeyLast < (State.GCPhys | GUEST_PAGE_OFFSET_MASK)) 1824 1899 { 1825 PPGMPHYSHANDLER pPhys2 = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pPGM->CTX_SUFF(pTrees)->PhysHandlers, 1826 pPhys->Core.KeyLast + 1, true); 1827 if ( !pPhys2 1828 || pPhys2->Core.Key > (State.GCPhys | GUEST_PAGE_OFFSET_MASK)) 1900 PPGMPHYSHANDLER pPhys2; 1901 rc = pPhysHandlerTree->lookupMatchingOrAbove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, 1902 pPhys->KeyLast + 1, &pPhys2); 1903 if (rc == VERR_NOT_FOUND) 1904 break; 1905 AssertLogRelMsgReturn(RT_SUCCESS(rc), ("rc=%Rrc KeyLast+1=%RGp\n", rc, pPhys->KeyLast + 1), 999); 1906 if (pPhys2->Key > (State.GCPhys | GUEST_PAGE_OFFSET_MASK)) 1829 1907 break; 1830 1908 PCPGMPHYSHANDLERTYPEINT pPhysType2 = pgmHandlerPhysicalTypeHandleToPtr(pVM, pPhys2->hType); -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r93650 r93716 112 112 #endif 113 113 114 115 116 /** 117 * Calculate the actual table size. 118 * 119 * The memory is layed out like this: 120 * - PGMPHYSHANDLERTREE (8 bytes) 121 * - Allocation bitmap (8-byte size align) 122 * - Slab of PGMPHYSHANDLER. Start is 64 byte aligned. 123 */ 124 uint32_t pgmHandlerPhysicalCalcTableSizes(uint32_t *pcEntries, uint32_t *pcbTreeAndBitmap) 125 { 126 /* 127 * A minimum of 64 entries and a maximum of ~64K. 128 */ 129 uint32_t cEntries = *pcEntries; 130 if (cEntries <= 64) 131 cEntries = 64; 132 else if (cEntries >= _64K) 133 cEntries = _64K; 134 else 135 cEntries = RT_ALIGN_32(cEntries, 16); 136 137 /* 138 * Do the initial calculation. 139 */ 140 uint32_t cbBitmap = RT_ALIGN_32(cEntries, 64) / 8; 141 uint32_t cbTreeAndBitmap = RT_ALIGN_32(sizeof(PGMPHYSHANDLERTREE) + cbBitmap, 64); 142 uint32_t cbTable = cEntries * sizeof(PGMPHYSHANDLER); 143 uint32_t cbTotal = cbTreeAndBitmap + cbTable; 144 145 /* 146 * Align the total and try use up extra space from that. 147 */ 148 uint32_t cbTotalAligned = RT_ALIGN_32(cbTotal, RT_MAX(HOST_PAGE_SIZE, _16K)); 149 uint32_t cAvail = cbTotalAligned - cbTotal; 150 cAvail /= sizeof(PGMPHYSHANDLER); 151 if (cAvail >= 1) 152 for (;;) 153 { 154 cbBitmap = RT_ALIGN_32(cEntries, 64) / 8; 155 cbTreeAndBitmap = RT_ALIGN_32(sizeof(PGMPHYSHANDLERTREE) + cbBitmap, 64); 156 cbTable = cEntries * sizeof(PGMPHYSHANDLER); 157 cbTotal = cbTreeAndBitmap + cbTable; 158 if (cbTotal <= cbTotalAligned) 159 break; 160 cEntries--; 161 Assert(cEntries >= 16); 162 } 163 164 /* 165 * Return the result. 166 */ 167 *pcbTreeAndBitmap = cbTreeAndBitmap; 168 *pcEntries = cEntries; 169 return cbTotalAligned; 170 } 114 171 115 172 … … 2407 2464 || PGM_PAGE_IS_MMIO_OR_SPECIAL_ALIAS(pPage)) 2408 2465 { 2409 PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhys); 2410 if (pCur) 2411 { 2412 Assert(pCur && GCPhys >= pCur->Core.Key && GCPhys <= pCur->Core.KeyLast); 2413 Assert((pCur->Core.Key & GUEST_PAGE_OFFSET_MASK) == 0); 2414 Assert((pCur->Core.KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK); 2466 PPGMPHYSHANDLER pCur; 2467 rc = pgmHandlerPhysicalLookup(pVM, GCPhys, &pCur); 2468 if (RT_SUCCESS(rc)) 2469 { 2470 Assert(pCur && GCPhys >= pCur->Key && GCPhys <= pCur->KeyLast); 2471 Assert((pCur->Key & GUEST_PAGE_OFFSET_MASK) == 0); 2472 Assert((pCur->KeyLast & GUEST_PAGE_OFFSET_MASK) == GUEST_PAGE_OFFSET_MASK); 2415 2473 #ifndef IN_RING3 2416 2474 if (enmOrigin != PGMACCESSORIGIN_IEM) … … 2435 2493 PGM_LOCK_VOID(pVM); 2436 2494 2437 #ifdef VBOX_WITH_STATISTICS 2438 pCur = pgmHandlerPhysicalLookup(pVM, GCPhys); 2439 if (pCur) 2440 STAM_PROFILE_STOP(&pCur->Stat, h); 2441 #else 2495 STAM_PROFILE_STOP(&pCur->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */ 2442 2496 pCur = NULL; /* might not be valid anymore. */ 2443 #endif2444 2497 AssertLogRelMsg(PGM_HANDLER_PHYS_IS_VALID_STATUS(rcStrict, false), 2445 2498 ("rcStrict=%Rrc GCPhys=%RGp\n", VBOXSTRICTRC_VAL(rcStrict), GCPhys)); … … 2451 2504 } 2452 2505 } 2506 else if (rc == VERR_NOT_FOUND) 2507 AssertLogRelMsgFailed(("rc=%Rrc GCPhys=%RGp cb=%#x\n", rc, GCPhys, cb)); 2453 2508 else 2454 AssertLogRelMsgFailed (("GCPhys=%RGp cb=%#x\n", GCPhys, cb));2509 AssertLogRelMsgFailedReturn(("rc=%Rrc GCPhys=%RGp cb=%#x\n", rc, GCPhys, cb), rc); 2455 2510 } 2456 2511 … … 2646 2701 */ 2647 2702 PVMCPUCC pVCpu = VMMGetCpu(pVM); 2648 PPGMPHYSHANDLER pCur = pgmHandlerPhysicalLookup(pVM, GCPhys); 2649 if (pCur) 2650 { 2651 Assert(GCPhys >= pCur->Core.Key && GCPhys <= pCur->Core.KeyLast); 2703 PPGMPHYSHANDLER pCur; 2704 rcStrict = pgmHandlerPhysicalLookup(pVM, GCPhys, &pCur); 2705 if (RT_SUCCESS(rcStrict)) 2706 { 2707 Assert(GCPhys >= pCur->Key && GCPhys <= pCur->KeyLast); 2652 2708 #ifndef IN_RING3 2653 2709 if (enmOrigin != PGMACCESSORIGIN_IEM) … … 2655 2711 return VERR_PGM_PHYS_WR_HIT_HANDLER; 2656 2712 #endif 2657 size_t cbRange = pCur-> Core.KeyLast - GCPhys + 1;2713 size_t cbRange = pCur->KeyLast - GCPhys + 1; 2658 2714 if (cbRange > cbWrite) 2659 2715 cbRange = cbWrite; … … 2687 2743 } 2688 2744 2689 #ifdef VBOX_WITH_STATISTICS 2690 pCur = pgmHandlerPhysicalLookup(pVM, GCPhys); 2691 if (pCur) 2692 STAM_PROFILE_STOP(&pCur->Stat, h); 2693 #else 2745 STAM_PROFILE_STOP(&pCur->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */ 2694 2746 pCur = NULL; /* might not be valid anymore. */ 2695 #endif2696 2747 if (rcStrict == VINF_PGM_HANDLER_DO_DEFAULT) 2697 2748 { … … 2721 2772 pvDst = (uint8_t *)pvDst + cbRange; 2722 2773 } 2723 else /* The handler is somewhere else in the page, deal with it below. */2774 else if (rcStrict == VERR_NOT_FOUND) /* The handler is somewhere else in the page, deal with it below. */ 2724 2775 rcStrict = VINF_SUCCESS; 2776 else 2777 AssertMsgFailedReturn(("rcStrict=%Rrc GCPhys=%RGp\n", VBOXSTRICTRC_VAL(rcStrict), GCPhys), rcStrict); 2725 2778 Assert(!PGM_PAGE_IS_MMIO_OR_ALIAS(pPage)); /* MMIO handlers are all GUEST_PAGE_SIZEed! */ 2726 2779 … … 2752 2805 if (fMorePhys && !pPhys) 2753 2806 { 2754 pPhys = pgmHandlerPhysicalLookup(pVM, GCPhys);2755 if ( pPhys)2807 rcStrict = pgmHandlerPhysicalLookup(pVM, GCPhys, &pPhys); 2808 if (RT_SUCCESS_NP(rcStrict)) 2756 2809 { 2757 2810 offPhys = 0; 2758 offPhysLast = pPhys-> Core.KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */2811 offPhysLast = pPhys->KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */ 2759 2812 } 2760 2813 else 2761 2814 { 2762 pPhys = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, 2763 GCPhys, true /* fAbove */); 2764 if ( pPhys 2765 && pPhys->Core.Key <= GCPhys + (cbWrite - 1)) 2815 AssertMsgReturn(rcStrict == VERR_NOT_FOUND, ("%Rrc GCPhys=%RGp\n", VBOXSTRICTRC_VAL(rcStrict), GCPhys), rcStrict); 2816 2817 rcStrict = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookupMatchingOrAbove(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, 2818 GCPhys, &pPhys); 2819 AssertMsgReturn(RT_SUCCESS(rcStrict) || rcStrict == VERR_NOT_FOUND, 2820 ("%Rrc GCPhys=%RGp\n", VBOXSTRICTRC_VAL(rcStrict), GCPhys), rcStrict); 2821 2822 if ( RT_SUCCESS(rcStrict) 2823 && pPhys->Key <= GCPhys + (cbWrite - 1)) 2766 2824 { 2767 offPhys = pPhys->Core.Key - GCPhys; 2768 offPhysLast = pPhys->Core.KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */ 2825 offPhys = pPhys->Key - GCPhys; 2826 offPhysLast = pPhys->KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */ 2827 Assert(pPhys->KeyLast - pPhys->Key < _4G); 2769 2828 } 2770 2829 else … … 2818 2877 } 2819 2878 2820 #ifdef VBOX_WITH_STATISTICS 2821 pPhys = pgmHandlerPhysicalLookup(pVM, GCPhys); 2822 if (pPhys) 2823 STAM_PROFILE_STOP(&pPhys->Stat, h); 2824 #else 2879 STAM_PROFILE_STOP(&pPhys->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */ 2825 2880 pPhys = NULL; /* might not be valid anymore. */ 2826 #endif2827 2881 AssertLogRelMsg(PGM_HANDLER_PHYS_IS_VALID_STATUS(rcStrict2, true), 2828 2882 ("rcStrict2=%Rrc (rcStrict=%Rrc) GCPhys=%RGp pPage=%R[pgmpage] %s\n", VBOXSTRICTRC_VAL(rcStrict2), -
trunk/src/VBox/VMM/VMMR0/PGMR0.cpp
r93650 r93716 35 35 #include <iprt/mem.h> 36 36 #include <iprt/memobj.h> 37 #include <iprt/process.h> 37 38 #include <iprt/rand.h> 38 39 #include <iprt/string.h> … … 82 83 pGVM->pgmr0.s.ahPoolMapObjs[i] = NIL_RTR0MEMOBJ; 83 84 } 85 pGVM->pgmr0.s.hPhysHandlerMemObj = NIL_RTR0MEMOBJ; 86 pGVM->pgmr0.s.hPhysHandlerMapObj = NIL_RTR0MEMOBJ; 84 87 85 88 /* … … 251 254 pGVM->pgmr0.s.ahPoolMemObjs[i] = NIL_RTR0MEMOBJ; 252 255 } 256 } 257 258 if (pGVM->pgmr0.s.hPhysHandlerMapObj != NIL_RTR0MEMOBJ) 259 { 260 int rc = RTR0MemObjFree(pGVM->pgmr0.s.hPhysHandlerMapObj, true /*fFreeMappings*/); 261 AssertRC(rc); 262 pGVM->pgmr0.s.hPhysHandlerMapObj = NIL_RTR0MEMOBJ; 263 } 264 265 if (pGVM->pgmr0.s.hPhysHandlerMemObj != NIL_RTR0MEMOBJ) 266 { 267 int rc = RTR0MemObjFree(pGVM->pgmr0.s.hPhysHandlerMemObj, true /*fFreeMappings*/); 268 AssertRC(rc); 269 pGVM->pgmr0.s.hPhysHandlerMemObj = NIL_RTR0MEMOBJ; 253 270 } 254 271 … … 749 766 return SUPR0PageMapKernel(pGVM->pSession, pvR3, (uint32_t)offSub, (uint32_t)cbSub, 0 /*fFlags*/, ppvMapping); 750 767 #endif 768 } 769 770 771 /** 772 * This is called during PGMR3Init to init the physical access handler allocator 773 * and tree. 774 * 775 * @returns VBox status code. 776 * @param pGVM Pointer to the global VM structure. 777 * @param cEntries Desired number of physical access handlers to reserve 778 * space for (will be adjusted). 779 * @thread EMT(0) 780 */ 781 VMMR0_INT_DECL(int) PGMR0PhysHandlerInitReqHandler(PGVM pGVM, uint32_t cEntries) 782 { 783 /* 784 * Validate the input and state. 785 */ 786 int rc = GVMMR0ValidateGVMandEMT(pGVM, 0); 787 AssertRCReturn(rc, rc); 788 VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE); /** @todo ring-0 safe state check. */ 789 790 AssertReturn(pGVM->pgmr0.s.PhysHandlerAllocator.m_paNodes == NULL, VERR_WRONG_ORDER); 791 AssertReturn(pGVM->pgm.s.PhysHandlerAllocator.m_paNodes == NULL, VERR_WRONG_ORDER); 792 793 AssertLogRelMsgReturn(cEntries <= _64K, ("%#x\n", cEntries), VERR_OUT_OF_RANGE); 794 795 /* 796 * Calculate the table size and allocate it. 797 */ 798 uint32_t cbTreeAndBitmap = 0; 799 uint32_t const cbTotalAligned = pgmHandlerPhysicalCalcTableSizes(&cEntries, &cbTreeAndBitmap); 800 RTR0MEMOBJ hMemObj = NIL_RTR0MEMOBJ; 801 rc = RTR0MemObjAllocPage(&hMemObj, cbTotalAligned, false); 802 if (RT_SUCCESS(rc)) 803 { 804 RTR0MEMOBJ hMapObj = NIL_RTR0MEMOBJ; 805 rc = RTR0MemObjMapUser(&hMapObj, hMemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, RTR0ProcHandleSelf()); 806 if (RT_SUCCESS(rc)) 807 { 808 uint8_t *pb = (uint8_t *)RTR0MemObjAddress(hMemObj); 809 if (!RTR0MemObjWasZeroInitialized(hMemObj)) 810 RT_BZERO(pb, cbTotalAligned); 811 812 pGVM->pgmr0.s.PhysHandlerAllocator.initSlabAllocator(cEntries, (PPGMPHYSHANDLER)&pb[cbTreeAndBitmap], 813 (uint64_t *)&pb[sizeof(PGMPHYSHANDLERTREE)]); 814 pGVM->pgmr0.s.pPhysHandlerTree = (PPGMPHYSHANDLERTREE)pb; 815 pGVM->pgmr0.s.pPhysHandlerTree->initWithAllocator(&pGVM->pgmr0.s.PhysHandlerAllocator); 816 pGVM->pgmr0.s.hPhysHandlerMemObj = hMemObj; 817 pGVM->pgmr0.s.hPhysHandlerMapObj = hMapObj; 818 819 AssertCompile(sizeof(pGVM->pgm.s.PhysHandlerAllocator) == sizeof(pGVM->pgmr0.s.PhysHandlerAllocator)); 820 RTR3PTR R3Ptr = RTR0MemObjAddressR3(hMapObj); 821 pGVM->pgm.s.pPhysHandlerTree = R3Ptr; 822 pGVM->pgm.s.PhysHandlerAllocator.m_paNodes = R3Ptr + cbTreeAndBitmap; 823 pGVM->pgm.s.PhysHandlerAllocator.m_pbmAlloc = R3Ptr + sizeof(PGMPHYSHANDLERTREE); 824 pGVM->pgm.s.PhysHandlerAllocator.m_cNodes = cEntries; 825 pGVM->pgm.s.PhysHandlerAllocator.m_cErrors = 0; 826 pGVM->pgm.s.PhysHandlerAllocator.m_idxAllocHint = 0; 827 pGVM->pgm.s.PhysHandlerAllocator.m_uPadding = 0; 828 return VINF_SUCCESS; 829 } 830 831 RTR0MemObjFree(hMemObj, true /*fFreeMappings*/); 832 } 833 return rc; 751 834 } 752 835 … … 1156 1239 */ 1157 1240 PGM_LOCK_VOID(pGVM); 1158 PPGMPHYSHANDLER pHandler = pgmHandlerPhysicalLookup(pGVM, GCPhysFault); 1159 PCPGMPHYSHANDLERTYPEINT pHandlerType = RT_LIKELY(pHandler) ? PGMPHYSHANDLER_GET_TYPE_NO_NULL(pGVM, pHandler) : NULL; 1160 if (RT_LIKELY(pHandler && pHandlerType->enmKind != PGMPHYSHANDLERKIND_WRITE)) 1161 { 1162 /* 1163 * If the handle has aliases page or pages that have been temporarily 1164 * disabled, we'll have to take a detour to make sure we resync them 1165 * to avoid lots of unnecessary exits. 1166 */ 1167 PPGMPAGE pPage; 1168 if ( ( pHandler->cAliasedPages 1169 || pHandler->cTmpOffPages) 1170 && ( (pPage = pgmPhysGetPage(pGVM, GCPhysFault)) == NULL 1171 || PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) == PGM_PAGE_HNDL_PHYS_STATE_DISABLED) 1172 ) 1173 { 1174 Log(("PGMR0Trap0eHandlerNPMisconfig: Resyncing aliases / tmp-off page at %RGp (uErr=%#x) %R[pgmpage]\n", GCPhysFault, uErr, pPage)); 1175 STAM_COUNTER_INC(&pGVCpu->pgm.s.Stats.StatR0NpMiscfgSyncPage); 1176 rc = pgmShwSyncNestedPageLocked(pGVCpu, GCPhysFault, 1 /*cPages*/, enmShwPagingMode); 1177 PGM_UNLOCK(pGVM); 1178 } 1179 else 1180 { 1181 if (pHandlerType->pfnPfHandler) 1241 PPGMPHYSHANDLER pHandler; 1242 rc = pgmHandlerPhysicalLookup(pGVM, GCPhysFault, &pHandler); 1243 if (RT_SUCCESS(rc)) 1244 { 1245 PCPGMPHYSHANDLERTYPEINT pHandlerType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pGVM, pHandler); 1246 if (RT_LIKELY(pHandlerType->enmKind != PGMPHYSHANDLERKIND_WRITE)) 1247 { 1248 /* 1249 * If the handle has aliases page or pages that have been temporarily 1250 * disabled, we'll have to take a detour to make sure we resync them 1251 * to avoid lots of unnecessary exits. 1252 */ 1253 PPGMPAGE pPage; 1254 if ( ( pHandler->cAliasedPages 1255 || pHandler->cTmpOffPages) 1256 && ( (pPage = pgmPhysGetPage(pGVM, GCPhysFault)) == NULL 1257 || PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) == PGM_PAGE_HNDL_PHYS_STATE_DISABLED) 1258 ) 1182 1259 { 1183 uint64_t const uUser = !pHandlerType->fRing0DevInsIdx ? pHandler->uUser1184 : (uintptr_t)PDMDeviceRing0IdxToInstance(pGVM, pHandler->uUser);1185 STAM_PROFILE_START(&pHandler->Stat, h);1260 Log(("PGMR0Trap0eHandlerNPMisconfig: Resyncing aliases / tmp-off page at %RGp (uErr=%#x) %R[pgmpage]\n", GCPhysFault, uErr, pPage)); 1261 STAM_COUNTER_INC(&pGVCpu->pgm.s.Stats.StatR0NpMiscfgSyncPage); 1262 rc = pgmShwSyncNestedPageLocked(pGVCpu, GCPhysFault, 1 /*cPages*/, enmShwPagingMode); 1186 1263 PGM_UNLOCK(pGVM); 1187 1188 Log6(("PGMR0Trap0eHandlerNPMisconfig: calling %p(,%#x,,%RGp,%p)\n", pHandlerType->pfnPfHandler, uErr, GCPhysFault, uUser));1189 rc = pHandlerType->pfnPfHandler(pGVM, pGVCpu, uErr == UINT32_MAX ? RTGCPTR_MAX : uErr, pRegFrame,1190 GCPhysFault, GCPhysFault, uUser);1191 1192 #ifdef VBOX_WITH_STATISTICS1193 PGM_LOCK_VOID(pGVM);1194 pHandler = pgmHandlerPhysicalLookup(pGVM, GCPhysFault);1195 if (pHandler)1196 STAM_PROFILE_STOP(&pHandler->Stat, h);1197 PGM_UNLOCK(pGVM);1198 #endif1199 1264 } 1200 1265 else 1201 1266 { 1202 PGM_UNLOCK(pGVM); 1203 Log(("PGMR0Trap0eHandlerNPMisconfig: %RGp (uErr=%#x) -> R3\n", GCPhysFault, uErr)); 1204 rc = VINF_EM_RAW_EMULATE_INSTR; 1267 if (pHandlerType->pfnPfHandler) 1268 { 1269 uint64_t const uUser = !pHandlerType->fRing0DevInsIdx ? pHandler->uUser 1270 : (uintptr_t)PDMDeviceRing0IdxToInstance(pGVM, pHandler->uUser); 1271 STAM_PROFILE_START(&pHandler->Stat, h); 1272 PGM_UNLOCK(pGVM); 1273 1274 Log6(("PGMR0Trap0eHandlerNPMisconfig: calling %p(,%#x,,%RGp,%p)\n", pHandlerType->pfnPfHandler, uErr, GCPhysFault, uUser)); 1275 rc = pHandlerType->pfnPfHandler(pGVM, pGVCpu, uErr == UINT32_MAX ? RTGCPTR_MAX : uErr, pRegFrame, 1276 GCPhysFault, GCPhysFault, uUser); 1277 1278 STAM_PROFILE_STOP(&pHandler->Stat, h); /* no locking needed, entry is unlikely reused before we get here. */ 1279 } 1280 else 1281 { 1282 PGM_UNLOCK(pGVM); 1283 Log(("PGMR0Trap0eHandlerNPMisconfig: %RGp (uErr=%#x) -> R3\n", GCPhysFault, uErr)); 1284 rc = VINF_EM_RAW_EMULATE_INSTR; 1285 } 1205 1286 } 1287 STAM_PROFILE_STOP(&pGVCpu->pgm.s.Stats.StatR0NpMiscfg, a); 1288 return rc; 1206 1289 } 1207 1290 } 1208 1291 else 1209 {1210 /* 1211 * Must be out of sync, so do a SyncPage and restart the instruction.1212 *1213 * ASSUMES that ALL handlers are page aligned and covers whole pages1214 * (assumption asserted in PGMHandlerPhysicalRegisterEx).1215 */1216 Log(("PGMR0Trap0eHandlerNPMisconfig: Out of sync page at %RGp (uErr=%#x)\n", GCPhysFault, uErr));1217 STAM_COUNTER_INC(&pGVCpu->pgm.s.Stats.StatR0NpMiscfgSyncPage);1218 rc = pgmShwSyncNestedPageLocked(pGVCpu, GCPhysFault, 1 /*cPages*/, enmShwPagingMode);1219 PGM_UNLOCK(pGVM);1220 }1292 AssertMsgReturn(rc == VERR_NOT_FOUND, ("%Rrc GCPhysFault=%RGp\n", VBOXSTRICTRC_VAL(rc), GCPhysFault), rc); 1293 1294 /* 1295 * Must be out of sync, so do a SyncPage and restart the instruction. 1296 * 1297 * ASSUMES that ALL handlers are page aligned and covers whole pages 1298 * (assumption asserted in PGMHandlerPhysicalRegisterEx). 1299 */ 1300 Log(("PGMR0Trap0eHandlerNPMisconfig: Out of sync page at %RGp (uErr=%#x)\n", GCPhysFault, uErr)); 1301 STAM_COUNTER_INC(&pGVCpu->pgm.s.Stats.StatR0NpMiscfgSyncPage); 1302 rc = pgmShwSyncNestedPageLocked(pGVCpu, GCPhysFault, 1 /*cPages*/, enmShwPagingMode); 1303 PGM_UNLOCK(pGVM); 1221 1304 1222 1305 STAM_PROFILE_STOP(&pGVCpu->pgm.s.Stats.StatR0NpMiscfg, a); -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r93650 r93716 1904 1904 break; 1905 1905 1906 case VMMR0_DO_PGM_PHYS_HANDLER_INIT: 1907 if (idCpu != 0 || pReqHdr != NULL || u64Arg > UINT32_MAX) 1908 return VERR_INVALID_PARAMETER; 1909 rc = PGMR0PhysHandlerInitReqHandler(pGVM, (uint32_t)u64Arg); 1910 break; 1911 1906 1912 /* 1907 1913 * GMM wrappers. -
trunk/src/VBox/VMM/VMMR3/PGM.cpp
r93650 r93716 606 606 #include <VBox/vmm/hm.h> 607 607 #include "PGMInternal.h" 608 #include <VBox/vmm/vm .h>608 #include <VBox/vmm/vmcc.h> 609 609 #include <VBox/vmm/uvm.h> 610 610 #include "PGMInline.h" … … 933 933 934 934 /* 935 * Trees936 */937 rc = MMHyperAlloc(pVM, sizeof(PGMTREES), 0, MM_TAG_PGM, (void **)&pVM->pgm.s.pTreesR3);938 if (RT_SUCCESS(rc))939 pVM->pgm.s.pTreesR0 = MMHyperR3ToR0(pVM, pVM->pgm.s.pTreesR3);940 941 /*942 935 * Setup the zero page (HCPHysZeroPg is set by ring-0). 943 936 */ … … 958 951 AssertRelease(pVM->pgm.s.HCPhysMmioPg != 0); 959 952 pVM->pgm.s.HCPhysInvMmioPg = pVM->pgm.s.HCPhysMmioPg; 953 954 /* 955 * Initialize physical access handlers. 956 */ 957 /** @cfgm{/PGM/MaxPhysicalAccessHandlers, uint32_t, 32, 65536, 6144} 958 * Number of physical access handlers allowed (subject to rounding). This is 959 * managed as one time allocation during initializations. The default is 960 * lower for a driverless setup. */ 961 /** @todo can lower it for nested paging too, at least when there is no 962 * nested guest involved. */ 963 uint32_t cAccessHandlers = 0; 964 rc = CFGMR3QueryU32Def(pCfgPGM, "MaxPhysicalAccessHandlers", &cAccessHandlers, !fDriverless ? 6144 : 640); 965 AssertLogRelRCReturn(rc, rc); 966 AssertLogRelMsgStmt(cAccessHandlers >= 32, ("cAccessHandlers=%#x, min 32\n", cAccessHandlers), cAccessHandlers = 32); 967 AssertLogRelMsgStmt(cAccessHandlers <= _64K, ("cAccessHandlers=%#x, max 65536\n", cAccessHandlers), cAccessHandlers = _64K); 968 if (!fDriverless) 969 { 970 rc = VMMR3CallR0(pVM, VMMR0_DO_PGM_PHYS_HANDLER_INIT, cAccessHandlers, NULL); 971 AssertRCReturn(rc, rc); 972 AssertPtr(pVM->pgm.s.pPhysHandlerTree); 973 AssertPtr(pVM->pgm.s.PhysHandlerAllocator.m_paNodes); 974 AssertPtr(pVM->pgm.s.PhysHandlerAllocator.m_pbmAlloc); 975 } 976 else 977 { 978 uint32_t cbTreeAndBitmap = 0; 979 uint32_t const cbTotalAligned = pgmHandlerPhysicalCalcTableSizes(&cAccessHandlers, &cbTreeAndBitmap); 980 uint8_t *pb = NULL; 981 rc = SUPR3PageAlloc(cbTotalAligned >> HOST_PAGE_SHIFT, 0, (void **)&pb); 982 AssertLogRelRCReturn(rc, rc); 983 984 pVM->pgm.s.PhysHandlerAllocator.initSlabAllocator(cAccessHandlers, (PPGMPHYSHANDLER)&pb[cbTreeAndBitmap], 985 (uint64_t *)&pb[sizeof(PGMPHYSHANDLERTREE)]); 986 pVM->pgm.s.pPhysHandlerTree = (PPGMPHYSHANDLERTREE)pb; 987 pVM->pgm.s.pPhysHandlerTree->initWithAllocator(&pVM->pgm.s.PhysHandlerAllocator); 988 } 960 989 961 990 /* … … 1219 1248 AssertRC(rc); 1220 1249 1250 #define PGM_REG_U64(a, b, c) \ 1251 rc = STAMR3RegisterF(pVM, a, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b); \ 1252 AssertRC(rc); 1253 1254 #define PGM_REG_U64_RESET(a, b, c) \ 1255 rc = STAMR3RegisterF(pVM, a, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b); \ 1256 AssertRC(rc); 1257 1258 #define PGM_REG_U32(a, b, c) \ 1259 rc = STAMR3RegisterF(pVM, a, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b); \ 1260 AssertRC(rc); 1261 1221 1262 #define PGM_REG_COUNTER_BYTES(a, b, c) \ 1222 1263 rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, c, b); \ … … 1283 1324 PGM_REG_COUNTER(&pStats->StatRZPhysHandlerLookupMisses, "/PGM/RZ/PhysHandlerLookupMisses", "The number of cache misses when looking up physical handlers."); 1284 1325 PGM_REG_COUNTER(&pStats->StatR3PhysHandlerLookupMisses, "/PGM/R3/PhysHandlerLookupMisses", "The number of cache misses when looking up physical handlers."); 1285 1326 #endif /* VBOX_WITH_STATISTICS */ 1327 PPGMPHYSHANDLERTREE pPhysHndlTree = pVM->pgm.s.pPhysHandlerTree; 1328 PGM_REG_U32(&pPhysHndlTree->m_cErrors, "/PGM/PhysHandlerTree/ErrorsTree", "Physical access handler tree errors."); 1329 PGM_REG_U32(&pVM->pgm.s.PhysHandlerAllocator.m_cErrors, "/PGM/PhysHandlerTree/ErrorsAllocatorR3", "Physical access handler tree allocator errors (ring-3 only)."); 1330 PGM_REG_U64_RESET(&pPhysHndlTree->m_cInserts, "/PGM/PhysHandlerTree/Inserts", "Physical access handler tree inserts."); 1331 PGM_REG_U32(&pVM->pgm.s.PhysHandlerAllocator.m_cNodes, "/PGM/PhysHandlerTree/MaxHandlers", "Max physical access handlers."); 1332 PGM_REG_U64_RESET(&pPhysHndlTree->m_cRemovals, "/PGM/PhysHandlerTree/Removals", "Physical access handler tree removals."); 1333 PGM_REG_U64_RESET(&pPhysHndlTree->m_cRebalancingOperations, "/PGM/PhysHandlerTree/RebalancingOperations", "Physical access handler tree rebalancing transformations."); 1334 1335 #ifdef VBOX_WITH_STATISTICS 1286 1336 PGM_REG_COUNTER(&pStats->StatRZPageReplaceShared, "/PGM/RZ/Page/ReplacedShared", "Times a shared page was replaced."); 1287 1337 PGM_REG_COUNTER(&pStats->StatRZPageReplaceZero, "/PGM/RZ/Page/ReplacedZero", "Times the zero page was replaced."); … … 1323 1373 1324 1374 #undef PGM_REG_COUNTER 1375 #undef PGM_REG_U64 1376 #undef PGM_REG_U64_RESET 1377 #undef PGM_REG_U32 1325 1378 #undef PGM_REG_PROFILE 1326 1379 #undef PGM_REG_PROFILE_NS … … 2104 2157 pszType = "MMIO"; 2105 2158 PGM_LOCK_VOID(pVM); 2106 PPGMPHYSHANDLER pHandler = pgmHandlerPhysicalLookup(pVM, iFirstPage * X86_PAGE_SIZE); 2107 if (pHandler) 2159 PPGMPHYSHANDLER pHandler; 2160 int rc = pgmHandlerPhysicalLookup(pVM, iFirstPage * X86_PAGE_SIZE, &pHandler); 2161 if (RT_SUCCESS(rc)) 2108 2162 pszMore = pHandler->pszDesc; 2109 2163 PGM_UNLOCK(pVM); … … 2537 2591 { 2538 2592 bool fLeftToRight; /**< true: left-to-right; false: right-to-left. */ 2593 uint32_t cErrors; 2539 2594 PPGMPHYSHANDLER pPrevPhys; 2540 2595 PVM pVM; … … 2548 2603 * @param pvUser pVM. 2549 2604 */ 2550 static DECLCALLBACK(int) pgmR3CheckIntegrityPhysHandlerNode(P AVLROGCPHYSNODECOREpNode, void *pvUser)2605 static DECLCALLBACK(int) pgmR3CheckIntegrityPhysHandlerNode(PPGMPHYSHANDLER pNode, void *pvUser) 2551 2606 { 2552 2607 PPGMCHECKINTARGS pArgs = (PPGMCHECKINTARGS)pvUser; 2553 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode; 2554 AssertReleaseReturn(!((uintptr_t)pCur & 7), 1); 2555 AssertReleaseMsg(pCur->Core.Key <= pCur->Core.KeyLast, 2556 ("pCur=%p %RGp-%RGp %s\n", pCur, pCur->Core.Key, pCur->Core.KeyLast, pCur->pszDesc)); 2557 AssertReleaseMsg( !pArgs->pPrevPhys 2558 || ( pArgs->fLeftToRight 2559 ? pArgs->pPrevPhys->Core.KeyLast < pCur->Core.Key 2560 : pArgs->pPrevPhys->Core.KeyLast > pCur->Core.Key), 2561 ("pPrevPhys=%p %RGp-%RGp %s\n" 2562 " pCur=%p %RGp-%RGp %s\n", 2563 pArgs->pPrevPhys, pArgs->pPrevPhys->Core.Key, pArgs->pPrevPhys->Core.KeyLast, pArgs->pPrevPhys->pszDesc, 2564 pCur, pCur->Core.Key, pCur->Core.KeyLast, pCur->pszDesc)); 2565 pArgs->pPrevPhys = pCur; 2608 2609 AssertLogRelMsgReturnStmt(!((uintptr_t)pNode & 7), ("pNode=%p\n", pNode), pArgs->cErrors++, VERR_INVALID_POINTER); 2610 2611 AssertLogRelMsgStmt(pNode->Key <= pNode->KeyLast, 2612 ("pNode=%p %RGp-%RGp %s\n", pNode, pNode->Key, pNode->KeyLast, pNode->pszDesc), 2613 pArgs->cErrors++); 2614 2615 AssertLogRelMsgStmt( !pArgs->pPrevPhys 2616 || ( pArgs->fLeftToRight 2617 ? pArgs->pPrevPhys->KeyLast < pNode->Key 2618 : pArgs->pPrevPhys->KeyLast > pNode->Key), 2619 ("pPrevPhys=%p %RGp-%RGp %s\n" 2620 " pNode=%p %RGp-%RGp %s\n", 2621 pArgs->pPrevPhys, pArgs->pPrevPhys->Key, pArgs->pPrevPhys->KeyLast, pArgs->pPrevPhys->pszDesc, 2622 pNode, pNode->Key, pNode->KeyLast, pNode->pszDesc), 2623 pArgs->cErrors++); 2624 2625 pArgs->pPrevPhys = pNode; 2566 2626 return 0; 2567 2627 } … … 2580 2640 * Check the trees. 2581 2641 */ 2582 int cErrors = 0; 2583 const PGMCHECKINTARGS LeftToRight = { true, NULL, pVM }; 2584 const PGMCHECKINTARGS RightToLeft = { false, NULL, pVM }; 2585 PGMCHECKINTARGS Args = LeftToRight; 2586 cErrors += RTAvlroGCPhysDoWithAll(&pVM->pgm.s.pTreesR3->PhysHandlers, true, pgmR3CheckIntegrityPhysHandlerNode, &Args); 2587 Args = RightToLeft; 2588 cErrors += RTAvlroGCPhysDoWithAll(&pVM->pgm.s.pTreesR3->PhysHandlers, false, pgmR3CheckIntegrityPhysHandlerNode, &Args); 2589 2590 return !cErrors ? VINF_SUCCESS : VERR_INTERNAL_ERROR; 2591 } 2592 2642 PGMCHECKINTARGS Args = { true, 0, NULL, pVM }; 2643 int rc = pVM->pgm.s.pPhysHandlerTree->doWithAllFromLeft(&pVM->pgm.s.PhysHandlerAllocator, 2644 pgmR3CheckIntegrityPhysHandlerNode, &Args); 2645 AssertLogRelRCReturn(rc, rc); 2646 2647 Args.fLeftToRight = false; 2648 Args.pPrevPhys = NULL; 2649 rc = pVM->pgm.s.pPhysHandlerTree->doWithAllFromRight(&pVM->pgm.s.PhysHandlerAllocator, 2650 pgmR3CheckIntegrityPhysHandlerNode, &Args); 2651 AssertLogRelMsgReturn(pVM->pgm.s.pPhysHandlerTree->m_cErrors == 0, 2652 ("m_cErrors=%#x\n", pVM->pgm.s.pPhysHandlerTree->m_cErrors == 0), 2653 VERR_INTERNAL_ERROR); 2654 2655 return Args.cErrors == 0 ? VINF_SUCCESS : VERR_INTERNAL_ERROR; 2656 } 2657 -
trunk/src/VBox/VMM/VMMR3/PGMDbg.cpp
r93554 r93716 25 25 #include <VBox/vmm/stam.h> 26 26 #include "PGMInternal.h" 27 #include <VBox/vmm/vm .h>27 #include <VBox/vmm/vmcc.h> 28 28 #include <VBox/vmm/uvm.h> 29 29 #include "PGMInline.h" -
trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp
r93667 r93716 34 34 #include <VBox/vmm/ssm.h> 35 35 #include "PGMInternal.h" 36 #include <VBox/vmm/vm .h>36 #include <VBox/vmm/vmcc.h> 37 37 #include "PGMInline.h" 38 38 #include <VBox/dbg.h> … … 52 52 * Internal Functions * 53 53 *********************************************************************************************************************************/ 54 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(P AVLROGCPHYSNODECORE pNode, void *pvUser);55 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(P AVLROGCPHYSNODECORE pNode, void *pvUser);56 static DECLCALLBACK(int) pgmR3InfoHandlersPhysicalOne(P AVLROGCPHYSNODECORE pNode, void *pvUser);54 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PPGMPHYSHANDLER pHandler, void *pvUser); 55 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(PPGMPHYSHANDLER pHandler, void *pvUser); 56 static DECLCALLBACK(int) pgmR3InfoHandlersPhysicalOne(PPGMPHYSHANDLER pHandler, void *pvUser); 57 57 58 58 … … 143 143 */ 144 144 PGM_LOCK_VOID(pVM); 145 RTAvlroGCPhysDoWithAll(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, true, pgmR3HandlerPhysicalOneClear, pVM); 146 RTAvlroGCPhysDoWithAll(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, false, pgmR3HandlerPhysicalOneSet, pVM); 145 146 int rc = pVM->pgm.s.pPhysHandlerTree->doWithAllFromLeft(&pVM->pgm.s.PhysHandlerAllocator, pgmR3HandlerPhysicalOneClear, pVM); 147 AssertRC(rc); 148 rc = pVM->pgm.s.pPhysHandlerTree->doWithAllFromRight(&pVM->pgm.s.PhysHandlerAllocator, pgmR3HandlerPhysicalOneSet, pVM); 149 AssertRC(rc); 150 147 151 PGM_UNLOCK(pVM); 148 152 } … … 153 157 * 154 158 * @returns 0 155 * @param pNode Pointer to a PGMPHYSHANDLER. 156 * @param pvUser Pointer to the VM. 157 */ 158 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PAVLROGCPHYSNODECORE pNode, void *pvUser) 159 { 160 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode; 159 * @param pHandler The physical access handler entry. 160 * @param pvUser Pointer to the VM. 161 */ 162 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneClear(PPGMPHYSHANDLER pHandler, void *pvUser) 163 { 161 164 PPGMRAMRANGE pRamHint = NULL; 162 RTGCPHYS GCPhys = p Cur->Core.Key;163 RTUINT cPages = p Cur->cPages;165 RTGCPHYS GCPhys = pHandler->Key; 166 RTUINT cPages = pHandler->cPages; 164 167 PVM pVM = (PVM)pvUser; 165 168 for (;;) … … 198 201 * 199 202 * @returns 0 200 * @param p Node Pointer to a PGMPHYSHANDLER.201 * @param pvUser Pointer to the VM.202 */ 203 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(P AVLROGCPHYSNODECORE pNode, void *pvUser)203 * @param pHandler The physical access handler entry. 204 * @param pvUser Pointer to the VM. 205 */ 206 static DECLCALLBACK(int) pgmR3HandlerPhysicalOneSet(PPGMPHYSHANDLER pHandler, void *pvUser) 204 207 { 205 208 PVM pVM = (PVM)pvUser; 206 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode; 207 PCPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pCur); 208 unsigned uState = pCurType->uState; 209 PCPGMPHYSHANDLERTYPEINT pType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pVM, pHandler); 210 unsigned uState = pType->uState; 209 211 PPGMRAMRANGE pRamHint = NULL; 210 RTGCPHYS GCPhys = p Cur->Core.Key;211 RTUINT cPages = p Cur->cPages;212 RTGCPHYS GCPhys = pHandler->Key; 213 RTUINT cPages = pHandler->cPages; 212 214 for (;;) 213 215 { … … 275 277 */ 276 278 pHlp->pfnPrintf(pHlp, 277 "Physical handlers: (PhysHandlers=%d (%#x))\n"279 "Physical handlers: max %#x, %u allocator error%s, %u tree error%s\n" 278 280 "%*s %*s %*s uUser Type Description\n", 279 pVM->pgm.s.pTreesR3->PhysHandlers, pVM->pgm.s.pTreesR3->PhysHandlers, 281 pVM->pgm.s.PhysHandlerAllocator.m_cNodes, 282 pVM->pgm.s.PhysHandlerAllocator.m_cErrors, pVM->pgm.s.PhysHandlerAllocator.m_cErrors != 0 ? "s" : "", 283 pVM->pgm.s.pPhysHandlerTree->m_cErrors, pVM->pgm.s.pPhysHandlerTree->m_cErrors != 0 ? "s" : "", 280 284 - (int)sizeof(RTGCPHYS) * 2, "From", 281 285 - (int)sizeof(RTGCPHYS) * 2 - 3, "- To (incl)", 282 286 - (int)sizeof(RTHCPTR) * 2 - 1, "Handler (R3)"); 283 RTAvlroGCPhysDoWithAll(&pVM->pgm.s.pTreesR3->PhysHandlers, true, pgmR3InfoHandlersPhysicalOne, &Args);287 pVM->pgm.s.pPhysHandlerTree->doWithAllFromLeft(&pVM->pgm.s.PhysHandlerAllocator, pgmR3InfoHandlersPhysicalOne, &Args); 284 288 } 285 289 … … 289 293 * 290 294 * @returns 0 291 * @param pNode Pointer to a PGMPHYSHANDLER. 292 * @param pvUser Pointer to command helper functions. 293 */ 294 static DECLCALLBACK(int) pgmR3InfoHandlersPhysicalOne(PAVLROGCPHYSNODECORE pNode, void *pvUser) 295 { 296 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)pNode; 297 PPGMHANDLERINFOARG pArgs = (PPGMHANDLERINFOARG)pvUser; 298 PCDBGFINFOHLP pHlp = pArgs->pHlp; 299 PCPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pArgs->pVM, pCur); 295 * @param pHandler The physical access handler entry. 296 * @param pvUser Pointer to command helper functions. 297 */ 298 static DECLCALLBACK(int) pgmR3InfoHandlersPhysicalOne(PPGMPHYSHANDLER pHandler, void *pvUser) 299 { 300 PPGMHANDLERINFOARG pArgs = (PPGMHANDLERINFOARG)pvUser; 301 PCDBGFINFOHLP pHlp = pArgs->pHlp; 302 PCPGMPHYSHANDLERTYPEINT pType = PGMPHYSHANDLER_GET_TYPE_NO_NULL(pArgs->pVM, pHandler); 300 303 const char *pszType; 301 switch (p CurType->enmKind)304 switch (pType->enmKind) 302 305 { 303 306 case PGMPHYSHANDLERKIND_MMIO: pszType = "MMIO "; break; … … 309 312 char szFlags[80]; 310 313 size_t cchFlags = 0; 311 if (p CurType->fKeepPgmLock)314 if (pType->fKeepPgmLock) 312 315 cchFlags = RTStrPrintf(szFlags, sizeof(szFlags), "(keep-pgm-lock"); 313 if (p CurType->fRing0DevInsIdx)316 if (pType->fRing0DevInsIdx) 314 317 cchFlags += RTStrPrintf(&szFlags[cchFlags], sizeof(szFlags) - cchFlags, cchFlags ? ", keep-pgm-lock" : "(keep-pgm-lock"); 315 if (p CurType->fRing0Enabled)318 if (pType->fRing0Enabled) 316 319 cchFlags += RTStrPrintf(&szFlags[cchFlags], sizeof(szFlags) - cchFlags, cchFlags ? ", r0-enabled)" : "(r0-enabled)"); 317 320 else … … 320 323 pHlp->pfnPrintf(pHlp, 321 324 "%RGp - %RGp %p %016RX64 %s %s %s\n", 322 p Cur->Core.Key, pCur->Core.KeyLast, pCurType->pfnHandler, pCur->uUser, pszType, pCur->pszDesc, szFlags);325 pHandler->Key, pHandler->KeyLast, pType->pfnHandler, pHandler->uUser, pszType, pHandler->pszDesc, szFlags); 323 326 #ifdef VBOX_WITH_STATISTICS 324 327 if (pArgs->fStats) 325 328 pHlp->pfnPrintf(pHlp, " cPeriods: %9RU64 cTicks: %11RU64 Min: %11RU64 Avg: %11RU64 Max: %11RU64\n", 326 p Cur->Stat.cPeriods, pCur->Stat.cTicks, pCur->Stat.cTicksMin,327 p Cur->Stat.cPeriods ? pCur->Stat.cTicks / pCur->Stat.cPeriods : 0, pCur->Stat.cTicksMax);329 pHandler->Stat.cPeriods, pHandler->Stat.cTicks, pHandler->Stat.cTicksMin, 330 pHandler->Stat.cPeriods ? pHandler->Stat.cTicks / pHandler->Stat.cPeriods : 0, pHandler->Stat.cTicksMax); 328 331 #endif 329 332 return 0; -
trunk/src/VBox/VMM/VMMR3/PGMPool.cpp
r93650 r93716 101 101 #include <VBox/vmm/mm.h> 102 102 #include "PGMInternal.h" 103 #include <VBox/vmm/vm .h>103 #include <VBox/vmm/vmcc.h> 104 104 #include <VBox/vmm/uvm.h> 105 105 #include "PGMInline.h" -
trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp
r93554 r93716 28 28 #include <VBox/vmm/pdmdev.h> 29 29 #include "PGMInternal.h" 30 #include <VBox/vmm/vm .h>30 #include <VBox/vmm/vmcc.h> 31 31 #include "PGMInline.h" 32 32 -
trunk/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
r93554 r93716 26 26 #include <VBox/vmm/uvm.h> 27 27 #include "PGMInternal.h" 28 #include <VBox/vmm/vm .h>28 #include <VBox/vmm/vmcc.h> 29 29 #include <VBox/sup.h> 30 30 #include <VBox/param.h> -
trunk/src/VBox/VMM/include/PGMInline.h
r93650 r93716 968 968 * Cached physical handler lookup. 969 969 * 970 * @returns Physical handler covering @a GCPhys. 971 * @param pVM The cross context VM structure. 972 * @param GCPhys The lookup address. 973 */ 974 DECLINLINE(PPGMPHYSHANDLER) pgmHandlerPhysicalLookup(PVMCC pVM, RTGCPHYS GCPhys) 975 { 976 PPGMPHYSHANDLER pHandler = pVM->pgm.s.CTX_SUFF(pLastPhysHandler); 970 * @returns VBox status code. 971 * @retval VERR_NOT_FOUND if no handler. 972 * @param pVM The cross context VM structure. 973 * @param GCPhys The lookup address. 974 * @param ppHandler Where to return the handler pointer. 975 */ 976 DECLINLINE(int) pgmHandlerPhysicalLookup(PVMCC pVM, RTGCPHYS GCPhys, PPGMPHYSHANDLER *ppHandler) 977 { 978 PPGMPHYSHANDLER pHandler = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.ptrFromInt(pVM->pgm.s.idxLastPhysHandler); 977 979 if ( pHandler 978 && GCPhys >= pHandler->Core.Key 979 && GCPhys < pHandler->Core.KeyLast) 980 && pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.isPtrRetOkay(pHandler) 981 && GCPhys >= pHandler->Key 982 && GCPhys < pHandler->KeyLast 983 && pHandler->hType != NIL_PGMPHYSHANDLERTYPE 984 && pHandler->hType != 0) 985 980 986 { 981 987 STAM_COUNTER_INC(&pVM->pgm.s.Stats.CTX_MID_Z(Stat,PhysHandlerLookupHits)); 982 return pHandler; 988 *ppHandler = pHandler; 989 return VINF_SUCCESS; 983 990 } 984 991 985 992 STAM_COUNTER_INC(&pVM->pgm.s.Stats.CTX_MID_Z(Stat,PhysHandlerLookupMisses)); 986 pHandler = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 987 if (pHandler) 988 pVM->pgm.s.CTX_SUFF(pLastPhysHandler) = pHandler; 989 return pHandler; 993 AssertPtrReturn(pVM->VMCC_CTX(pgm).s.pPhysHandlerTree, VERR_PGM_HANDLER_IPE_1); 994 int rc = pVM->VMCC_CTX(pgm).s.pPhysHandlerTree->lookup(&pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator, GCPhys, &pHandler); 995 if (RT_SUCCESS(rc)) 996 { 997 *ppHandler = pHandler; 998 pVM->pgm.s.idxLastPhysHandler = pVM->VMCC_CTX(pgm).s.PhysHandlerAllocator.ptrToInt(pHandler); 999 return VINF_SUCCESS; 1000 } 1001 *ppHandler = NULL; 1002 return rc; 990 1003 } 991 1004 -
trunk/src/VBox/VMM/include/PGMInternal.h
r93650 r93716 43 43 #include <iprt/list-off32.h> 44 44 #include <iprt/sha.h> 45 #include <iprt/cpp/hardavlrange.h> 45 46 46 47 … … 563 564 typedef struct PGMPHYSHANDLER 564 565 { 565 AVLROGCPHYSNODECORE Core; 566 /** @name Tree stuff. 567 * @{ */ 568 /** First address. */ 569 RTGCPHYS Key; 570 /** Last address. */ 571 RTGCPHYS KeyLast; 572 uint32_t idxLeft; 573 uint32_t idxRight; 574 uint8_t cHeight; 575 /** @} */ 576 uint8_t abPadding[3]; 566 577 /** Number of pages to update. */ 567 578 uint32_t cPages; … … 570 581 /** Set if we have pages that have temporarily been disabled. */ 571 582 uint32_t cTmpOffPages; 572 uint32_t u32Padding;573 583 /** Registered handler type handle. 574 584 * @note Marked volatile to prevent re-reading after validation. */ … … 578 588 /** Description / Name. For easing debugging. */ 579 589 R3PTRTYPE(const char *) pszDesc; 580 #ifdef VBOX_WITH_STATISTICS 581 /** Profiling of this handler. */590 /** Profiling of this handler. 591 * @note VBOX_WITH_STATISTICS only, but included to keep structure stable. */ 582 592 STAMPROFILE Stat; 583 #endif584 593 } PGMPHYSHANDLER; 594 AssertCompileSize(PGMPHYSHANDLER, 12*8); 585 595 /** Pointer to a physical page access handler structure. */ 586 596 typedef PGMPHYSHANDLER *PPGMPHYSHANDLER; … … 606 616 #define PGMPHYSHANDLER_GET_TYPE_NO_NULL(a_pVM, a_pPhysHandler) \ 607 617 pgmHandlerPhysicalTypeHandleToPtr2(a_pVM, (a_pPhysHandler) ? (a_pPhysHandler)->hType : NIL_PGMPHYSHANDLERTYPE) 618 619 /** Physical access handler allocator. */ 620 typedef RTCHardAvlTreeSlabAllocator<PGMPHYSHANDLER> PGMPHYSHANDLERALLOCATOR; 621 622 /** Physical access handler tree. */ 623 typedef RTCHardAvlRangeTree<PGMPHYSHANDLER, RTGCPHYS> PGMPHYSHANDLERTREE; 624 /** Pointer to a physical access handler tree. */ 625 typedef PGMPHYSHANDLERTREE *PPGMPHYSHANDLERTREE; 608 626 609 627 … … 2361 2379 2362 2380 /** 2363 * Roots and anchors for trees and list employing self relative offsets as2364 * pointers.2365 *2366 * When using self-relative offsets instead of pointers, the offsets needs to be2367 * the same in all offsets. Thus the roots and anchors needs to live on the2368 * hyper heap just like the nodes.2369 */2370 typedef struct PGMTREES2371 {2372 /** Physical access handlers (AVL range+offsetptr tree). */2373 AVLROGCPHYSTREE PhysHandlers;2374 uint32_t u32PaddingTo8Bytes;2375 } PGMTREES;2376 /** Pointer to PGM trees. */2377 typedef PGMTREES *PPGMTREES;2378 2379 2380 /**2381 2381 * Guest page table walk for the AMD64 mode. 2382 2382 */ … … 2957 2957 /** Root of the RAM range search tree for ring-3. */ 2958 2958 R3PTRTYPE(PPGMRAMRANGE) pRamRangeTreeR3; 2959 /** PGM offset based trees - R3 Ptr. */2960 R3PTRTYPE(PPGMTREES) pTreesR3;2961 /** Caching the last physical handler we looked up in R3. */2962 R3PTRTYPE(PPGMPHYSHANDLER) pLastPhysHandlerR3;2963 2959 /** Shadow Page Pool - R3 Ptr. */ 2964 2960 R3PTRTYPE(PPGMPOOL) pPoolR3; … … 2978 2974 /** Root of the RAM range search tree for ring-0. */ 2979 2975 R0PTRTYPE(PPGMRAMRANGE) pRamRangeTreeR0; 2980 /** PGM offset based trees - R0 Ptr. */2981 R0PTRTYPE(PPGMTREES) pTreesR0;2982 /** Caching the last physical handler we looked up in R0. */2983 R0PTRTYPE(PPGMPHYSHANDLER) pLastPhysHandlerR0;2984 2976 /** Shadow Page Pool - R0 Ptr. */ 2985 2977 R0PTRTYPE(PPGMPOOL) pPoolR0; … … 2998 2990 * Initialized to callback causing guru meditations and invalid enmKind. */ 2999 2991 PGMPHYSHANDLERTYPEINTR3 aPhysHandlerTypes[PGMPHYSHANDLERTYPE_COUNT]; 2992 /** Physical handler allocator, ring-3 edition. */ 2993 #ifdef IN_RING3 2994 PGMPHYSHANDLERALLOCATOR PhysHandlerAllocator; 2995 #else 2996 RTCHardAvlTreeSlabAllocatorR3_T PhysHandlerAllocator; 2997 #endif 2998 /** The pointer to the ring-3 mapping of the physical access handler tree. */ 2999 R3PTRTYPE(PPGMPHYSHANDLERTREE) pPhysHandlerTree; 3000 /** Caching the last physical handler we looked. */ 3001 uint32_t idxLastPhysHandler; 3002 3003 uint32_t au64Padding3[5]; 3000 3004 3001 3005 /** PGM critical section. … … 3558 3562 3559 3563 3564 #if defined(IN_RING0) || defined(DOXYGEN_RUNNING) 3565 3560 3566 /** 3561 3567 * PGM GVMCPU instance data. … … 3563 3569 typedef struct PGMR0PERVCPU 3564 3570 { 3565 # ifdef VBOX_WITH_STATISTICS3571 # ifdef VBOX_WITH_STATISTICS 3566 3572 /** R0: Which statistic this \#PF should be attributed to. */ 3567 3573 R0PTRTYPE(PSTAMPROFILE) pStatTrap0eAttributionR0; 3568 # endif3574 # endif 3569 3575 uint64_t u64Dummy; 3570 3576 } PGMR0PERVCPU; … … 3589 3595 * Initialized to callback causing return to ring-3 and invalid enmKind. */ 3590 3596 PGMPHYSHANDLERTYPEINTR0 aPhysHandlerTypes[PGMPHYSHANDLERTYPE_COUNT]; 3597 /** Physical handler allocator, ring-3 edition. */ 3598 PGMPHYSHANDLERALLOCATOR PhysHandlerAllocator; 3599 /** The pointer to the ring-3 mapping of the physical access handler tree. */ 3600 PPGMPHYSHANDLERTREE pPhysHandlerTree; 3601 /** The allocation object for the physical access handler tree. */ 3602 RTR0MEMOBJ hPhysHandlerMemObj; 3603 /** The ring-3 mapping object for the physicall access handler tree. */ 3604 RTR0MEMOBJ hPhysHandlerMapObj; 3591 3605 } PGMR0PERVM; 3606 3607 #endif /* IN_RING0 || DOXYGEN_RUNNING */ 3592 3608 3593 3609 RT_C_DECLS_BEGIN … … 3618 3634 #define PGM_LOCK_ASSERT_OWNER_EX(a_pVM, a_pVCpu) Assert(PDMCritSectIsOwnerEx((a_pVCpu), &(a_pVM)->pgm.s.CritSectX)) 3619 3635 3636 uint32_t pgmHandlerPhysicalCalcTableSizes(uint32_t *pcEntries, uint32_t *pcbTreeAndBitmap); 3620 3637 int pgmHandlerPhysicalExCreate(PVMCC pVM, PGMPHYSHANDLERTYPE hType, uint64_t uUser, 3621 3638 R3PTRTYPE(const char *) pszDesc, PPGMPHYSHANDLER *ppPhysHandler);
Note:
See TracChangeset
for help on using the changeset viewer.