Changeset 17432 in vbox for trunk/src/VBox
- Timestamp:
- Mar 6, 2009 2:04:24 AM (16 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/GMM.cpp
r17368 r17432 160 160 return VERR_NO_TMP_MEMORY; 161 161 162 pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;163 pReq->Hdr.cbReq = cb;164 pReq->enmAccount = enmAccount;165 pReq->cPages = cPages;162 pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 163 pReq->Hdr.cbReq = cb; 164 pReq->enmAccount = enmAccount; 165 pReq->cPages = cPages; 166 166 NOREF(pVM); 167 *ppReq = pReq; 167 168 return VINF_SUCCESS; 169 } 170 171 172 /** 173 * Re-prepares a GMMR0FreePages request. 174 * 175 * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY. 176 * @param pVM Pointer to the shared VM structure. 177 * @param pReq A request buffer previously returned by 178 * GMMR3FreePagesPrepare(). 179 * @param cPages The number of pages originally passed to 180 * GMMR3FreePagesPrepare(). 181 * @param enmAccount The account to charge. 182 */ 183 GMMR3DECL(void) GMMR3FreePagesRePrep(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cPages, GMMACCOUNT enmAccount) 184 { 185 Assert(pReq->Hdr.u32Magic == SUPVMMR0REQHDR_MAGIC); 186 pReq->Hdr.cbReq = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cPages]); 187 pReq->enmAccount = enmAccount; 188 pReq->cPages = cPages; 189 NOREF(pVM); 168 190 } 169 191 … … 174 196 * 175 197 * @returns VBox status code. 176 * @param pVM Pointer to the shared VM structure. 177 * @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare). 178 */ 179 GMMR3DECL(int) GMMR3FreePagesPerform(PVM pVM, PGMMFREEPAGESREQ pReq) 180 { 198 * @param pVM Pointer to the shared VM structure. 199 * @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare). 200 * @param cActualPages The number of pages actually freed. 201 */ 202 GMMR3DECL(int) GMMR3FreePagesPerform(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cActualPages) 203 { 204 /* 205 * Adjust the request if we ended up with fewer pages than anticipated. 206 */ 207 if (cActualPages != pReq->cPages) 208 { 209 AssertReturn(cActualPages < pReq->cPages, VERR_INTERNAL_ERROR); 210 if (!cActualPages) 211 return VINF_SUCCESS; 212 pReq->cPages = cActualPages; 213 pReq->Hdr.cbReq = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cActualPages]); 214 } 215 216 /* 217 * Do the job. 218 */ 181 219 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr); 182 220 if (RT_SUCCESS(rc)) -
trunk/src/VBox/VMM/PGMHandler.cpp
r17132 r17432 97 97 if (!pszModRC) 98 98 pszModRC = VMMGC_MAIN_MODULE_NAME; 99 100 99 if (!pszModR0) 101 100 pszModR0 = VMMR0_MAIN_MODULE_NAME; 101 #ifdef VBOX_WITH_NEW_PHYS_CODE 102 AssertPtrReturn(pfnHandlerR3, VERR_INVALID_POINTER); 103 AssertPtrReturn(pszHandlerR0, VERR_INVALID_POINTER); 104 AssertPtrReturn(pszHandlerRC, VERR_INVALID_POINTER); 105 #endif 102 106 103 107 /* … … 106 110 R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0 = NIL_RTR0PTR; 107 111 int rc = VINF_SUCCESS; 108 if (pszHandlerR0) 109 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pszModR0, pszHandlerR0, &pfnHandlerR0); 112 #ifndef VBOX_WITH_NEW_PHYS_CODE 113 if (pszHandlerR0) 114 #endif 115 rc = PDMR3LdrGetSymbolR0Lazy(pVM, pszModR0, pszHandlerR0, &pfnHandlerR0); 110 116 if (RT_SUCCESS(rc)) 111 117 { … … 114 120 */ 115 121 RTRCPTR pfnHandlerRC = NIL_RTRCPTR; 116 if (pszHandlerRC) 117 rc = PDMR3LdrGetSymbolRCLazy(pVM, pszModRC, pszHandlerRC, &pfnHandlerRC); 122 #ifndef VBOX_WITH_NEW_PHYS_CODE 123 if (pszHandlerRC) 124 #endif 125 rc = PDMR3LdrGetSymbolRCLazy(pVM, pszModRC, pszHandlerRC, &pfnHandlerRC); 118 126 119 127 if (RT_SUCCESS(rc)) … … 290 298 { 291 299 case PGMVIRTHANDLERTYPE_ALL: 300 AssertReleaseMsgFailedReturn(("PGMVIRTHANDLERTYPE_ALL: not implemented\n"), VERR_NOT_IMPLEMENTED); 301 break; 292 302 case PGMVIRTHANDLERTYPE_WRITE: 293 303 if (!pfnHandlerR3) -
trunk/src/VBox/VMM/PGMInternal.h
r17421 r17432 1055 1055 typedef PGMRAMRANGE *PPGMRAMRANGE; 1056 1056 1057 #ifndef VBOX_WITH_NEW_PHYS_CODE 1057 1058 /** Return hc ptr corresponding to the ram range and physical offset */ 1058 1059 #define PGMRAMRANGE_GETHCPTR(pRam, off) \ 1059 1060 (pRam->fFlags & MM_RAM_FLAGS_DYNAMIC_ALLOC) ? (RTHCPTR)((pRam)->paChunkR3Ptrs[(off) >> PGM_DYNAMIC_CHUNK_SHIFT] + ((off) & PGM_DYNAMIC_CHUNK_OFFSET_MASK)) \ 1060 1061 : (RTHCPTR)((RTR3UINTPTR)(pRam)->pvR3 + (off)); 1062 #endif 1061 1063 1062 1064 /** … … 3040 3042 3041 3043 3042 void pgmPhysFreePage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys);3043 3044 int pgmPhysPageLoadIntoTlb(PPGM pPGM, RTGCPHYS GCPhys); 3044 3045 int pgmPhysPageLoadIntoTlbWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys); -
trunk/src/VBox/VMM/PGMPhys.cpp
r17421 r17432 47 47 48 48 /******************************************************************************* 49 * Defined Constants And Macros * 50 *******************************************************************************/ 51 /** The number of pages to free in one batch. */ 52 #define PGMPHYS_FREE_PAGE_BATCH_SIZE 128 53 54 55 /******************************************************************************* 49 56 * Internal Functions * 50 57 *******************************************************************************/ 51 58 static DECLCALLBACK(int) pgmR3PhysRomWriteHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser); 52 59 static int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys); 53 60 54 61 … … 284 291 int pgmR3PhysRamReset(PVM pVM) 285 292 { 293 #ifdef VBOX_WITH_NEW_PHYS_CODE 294 /* 295 * We batch up pages before freeing them. 296 */ 297 uint32_t cPendingPages = 0; 298 PGMMFREEPAGESREQ pReq; 299 int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE); 300 AssertLogRelRCReturn(rc, rc); 301 #endif 302 286 303 /* 287 304 * Walk the ram ranges. … … 291 308 uint32_t iPage = pRam->cb >> PAGE_SHIFT; Assert((RTGCPHYS)iPage << PAGE_SHIFT == pRam->cb); 292 309 #ifdef VBOX_WITH_NEW_PHYS_CODE 293 int rc;294 310 if (!pVM->pgm.s.fRamPreAlloc) 295 311 { … … 302 318 case PGMPAGETYPE_RAM: 303 319 if (!PGM_PAGE_IS_ZERO(pPage)) 304 pgmPhysFreePage(pVM, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT)); 320 { 321 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT)); 322 AssertLogRelRCReturn(rc, rc); 323 } 305 324 break; 306 325 … … 379 398 } 380 399 400 #ifdef VBOX_WITH_NEW_PHYS_CODE 401 /* 402 * Finish off any pages pending freeing. 403 */ 404 if (cPendingPages) 405 { 406 rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages); 407 AssertLogRelRCReturn(rc, rc); 408 } 409 GMMR3FreePagesCleanup(pReq); 410 #endif 411 412 381 413 return VINF_SUCCESS; 382 414 } … … 910 942 if (fRamExists) 911 943 { 944 uint32_t cPendingPages = 0; 945 PGMMFREEPAGESREQ pReq; 946 int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE); 947 AssertLogRelRCReturn(rc, rc); 948 912 949 /* replace the pages, freeing all present RAM pages. */ 913 950 PPGMPAGE pPageSrc = &pCur->RamRange.aPages[0]; … … 916 953 while (cPagesLeft-- > 0) 917 954 { 918 pgmPhysFreePage(pVM, pPageDst, GCPhys); 955 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPageDst, GCPhys); 956 AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */ 919 957 920 958 RTHCPHYS const HCPhys = PGM_PAGE_GET_HCPHYS(pPageSrc); … … 927 965 pPageDst++; 928 966 } 967 968 if (cPendingPages) 969 { 970 rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages); 971 AssertLogRelRCReturn(rc, rc); 972 } 973 GMMR3FreePagesCleanup(pReq); 929 974 } 930 975 else … … 981 1026 pRam = pRam->pNextR3; 982 1027 983 #ifdef RT_STRICT984 1028 RTHCPHYS const HCPhysZeroPg = pVM->pgm.s.HCPhysZeroPg; 985 #endif986 1029 Assert(HCPhysZeroPg != 0 && HCPhysZeroPg != NIL_RTHCPHYS); 987 1030 PPGMPAGE pPageDst = &pRam->aPages[(pCur->RamRange.GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; … … 989 1032 while (cPagesLeft-- > 0) 990 1033 { 991 PGM_PAGE_SET_HCPHYS(pPageDst, pVM->pgm.s.HCPhysZeroPg);1034 PGM_PAGE_SET_HCPHYS(pPageDst, HCPhysZeroPg); 992 1035 PGM_PAGE_SET_TYPE(pPageDst, PGMPAGETYPE_RAM); 993 1036 PGM_PAGE_SET_STATE(pPageDst, PGM_PAGE_STATE_ZERO); 1037 PGM_PAGE_SET_PAGEID(pPageDst, NIL_GMM_PAGEID); 994 1038 995 1039 pPageDst++; … … 1454 1498 static DECLCALLBACK(int) pgmR3PhysRomWriteHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser) 1455 1499 { 1456 PPGMROMRANGE pRom = (PPGMROMRANGE)pvUser;1457 const uint32_t iPage = GCPhys - pRom->GCPhys;1500 PPGMROMRANGE pRom = (PPGMROMRANGE)pvUser; 1501 const uint32_t iPage = (GCPhys - pRom->GCPhys) >> PAGE_SHIFT; 1458 1502 Assert(iPage < (pRom->cb >> PAGE_SHIFT)); 1459 1503 PPGMROMPAGE pRomPage = &pRom->aPages[iPage]; … … 1566 1610 } 1567 1611 1568 rc = GMMR3FreePagesPerform(pVM, pReq );1612 rc = GMMR3FreePagesPerform(pVM, pReq, cDirty); 1569 1613 GMMR3FreePagesCleanup(pReq); 1570 1614 AssertRCReturn(rc, rc); … … 2456 2500 2457 2501 /** 2502 * Frees the specified RAM page and replaces it with the ZERO page. 2503 * 2504 * This is used by ballooning, remapping MMIO2 and RAM reset. 2505 * 2506 * @param pVM Pointer to the shared VM structure. 2507 * @param pReq Pointer to the request. 2508 * @param pPage Pointer to the page structure. 2509 * @param GCPhys The guest physical address of the page, if applicable. 2510 * 2511 * @remarks The caller must own the PGM lock. 2512 */ 2513 static int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys) 2514 { 2515 /* 2516 * Assert sanity. 2517 */ 2518 Assert(PDMCritSectIsOwner(&pVM->pgm.s.CritSect)); 2519 if (RT_UNLIKELY(PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_RAM)) 2520 { 2521 AssertMsgFailed(("GCPhys=%RGp pPage=%R[pgmpage]\n", GCPhys, pPage)); 2522 return VMSetError(pVM, VERR_PGM_PHYS_NOT_RAM, RT_SRC_POS, "GCPhys=%RGp type=%d", GCPhys, PGM_PAGE_GET_TYPE(pPage)); 2523 } 2524 2525 if (PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ZERO) 2526 return VINF_SUCCESS; 2527 2528 const uint32_t idPage = PGM_PAGE_GET_PAGEID(pPage); 2529 if (RT_UNLIKELY( idPage == NIL_GMM_PAGEID 2530 || idPage > GMM_PAGEID_LAST 2531 || PGM_PAGE_GET_CHUNKID(pPage) == NIL_GMM_CHUNKID)) 2532 { 2533 AssertMsgFailed(("GCPhys=%RGp pPage=%R[pgmpage]\n", GCPhys, pPage)); 2534 return VMSetError(pVM, VERR_PGM_PHYS_INVALID_PAGE_ID, RT_SRC_POS, "GCPhys=%RGp idPage=%#x", GCPhys, pPage); 2535 } 2536 2537 /* 2538 * pPage = ZERO page. 2539 */ 2540 PGM_PAGE_SET_HCPHYS(pPage, pVM->pgm.s.HCPhysZeroPg); 2541 PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ZERO); 2542 PGM_PAGE_SET_PAGEID(pPage, NIL_GMM_PAGEID); 2543 2544 /* 2545 * Make sure it's not in the handy page array. 2546 */ 2547 uint32_t i = pVM->pgm.s.cHandyPages; 2548 while (i < RT_ELEMENTS(pVM->pgm.s.aHandyPages)) 2549 { 2550 if (pVM->pgm.s.aHandyPages[i].idPage == idPage) 2551 { 2552 pVM->pgm.s.aHandyPages[i].idPage = NIL_GMM_PAGEID; 2553 break; 2554 } 2555 if (pVM->pgm.s.aHandyPages[i].idSharedPage == idPage) 2556 { 2557 pVM->pgm.s.aHandyPages[i].idSharedPage = NIL_GMM_PAGEID; 2558 break; 2559 } 2560 i++; 2561 } 2562 2563 /* 2564 * Push it onto the page array. 2565 */ 2566 uint32_t iPage = *pcPendingPages; 2567 Assert(iPage < PGMPHYS_FREE_PAGE_BATCH_SIZE); 2568 *pcPendingPages += 1; 2569 2570 pReq->aPages[iPage].idPage = idPage; 2571 2572 if (iPage + 1 < PGMPHYS_FREE_PAGE_BATCH_SIZE) 2573 return VINF_SUCCESS; 2574 2575 /* 2576 * Flush the pages. 2577 */ 2578 int rc = GMMR3FreePagesPerform(pVM, pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE); 2579 if (RT_SUCCESS(rc)) 2580 { 2581 GMMR3FreePagesRePrep(pVM, pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE); 2582 *pcPendingPages = 0; 2583 } 2584 return rc; 2585 } 2586 2587 2588 /** 2458 2589 * Converts a GC physical address to a HC ring-3 pointer, with some 2459 2590 * additional checks. … … 2509 2640 { 2510 2641 case PGM_PAGE_STATE_ALLOCATED: 2642 break; 2511 2643 case PGM_PAGE_STATE_ZERO: 2512 break;2513 2644 case PGM_PAGE_STATE_SHARED: 2514 2645 case PGM_PAGE_STATE_WRITE_MONITORED: … … 2525 2656 /** @todo mapping/locking hell; this isn't horribly efficient since 2526 2657 * pgmPhysPageLoadIntoTlb will repeate the lookup we've done here. */ 2527 } 2658 2659 Log6(("PGMR3PhysTlbGCPhys2Ptr: GCPhys=%RGp rc=%Rrc pPage=%R[pgmpage] *ppv=%p\n", GCPhys, rc, pPage, *ppv)); 2660 } 2661 else 2662 Log6(("PGMR3PhysTlbGCPhys2Ptr: GCPhys=%RGp rc=%Rrc pPage=%R[pgmpage]\n", GCPhys, rc, pPage)); 2663 2528 2664 /* else: handler catching all access, no pointer returned. */ 2529 2665 -
trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
r17345 r17432 2462 2462 VMMDECL(int) PGMRegisterStringFormatTypes(void) 2463 2463 { 2464 #if def LOG_ENABLED2464 #if !defined(IN_R0) || defined(LOG_ENABLED) 2465 2465 int rc = VINF_SUCCESS; 2466 2466 unsigned i; … … 2496 2496 VMMDECL(void) PGMDeregisterStringFormatTypes(void) 2497 2497 { 2498 #if def LOG_ENABLED2498 #if !defined(IN_R0) || defined(LOG_ENABLED) 2499 2499 for (unsigned i = 0; i < RT_ELEMENTS(g_aPgmFormatTypes); i++) 2500 2500 RTStrFormatTypeDeregister(g_aPgmFormatTypes[i].szType); -
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r17422 r17432 4509 4509 int rc = VERR_INTERNAL_ERROR; 4510 4510 # else 4511 pgmLock(pVM); 4511 4512 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysCR3); 4512 4513 AssertReturn(pPage, VERR_INTERNAL_ERROR); 4513 4514 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhysCR3 & GST_CR3_PAGE_MASK, (void **)&HCPtrGuestCR3); 4514 4515 HCPhysGuestCR3 = PGM_PAGE_GET_HCPHYS(pPage); 4516 pgmUnlock(pVM); 4515 4517 # endif 4516 4518 # else /* !VBOX_WITH_NEW_PHYS_CODE */ … … 4558 4560 int rc2 = VERR_INTERNAL_ERROR; 4559 4561 # else 4562 pgmLock(pVM); 4560 4563 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys); 4561 4564 AssertReturn(pPage, VERR_INTERNAL_ERROR); 4562 4565 int rc2 = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, (void **)&HCPtr); 4563 4566 HCPhys = PGM_PAGE_GET_HCPHYS(pPage); 4567 pgmUnlock(pVM); 4564 4568 # endif 4565 4569 # else /* !VBOX_WITH_NEW_PHYS_CODE */ -
trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
r17372 r17432 74 74 * @param pfnHandlerR0 The R0 handler. 75 75 * @param pvUserR0 User argument to the R0 handler. 76 * @param pfnHandler GC The RC handler.76 * @param pfnHandlerRC The RC handler. 77 77 * @param pvUserRC User argument to the RC handler. This can be a value 78 78 * less that 0x10000 or a (non-null) pointer that is … … 95 95 switch (enmType) 96 96 { 97 case PGMPHYSHANDLERTYPE_PHYSICAL_WRITE: 98 break; 97 99 case PGMPHYSHANDLERTYPE_MMIO: 98 case PGMPHYSHANDLERTYPE_PHYSICAL_WRITE:99 100 case PGMPHYSHANDLERTYPE_PHYSICAL_ALL: 101 /* Simplification in PGMPhysRead among other places. */ 102 AssertMsgReturn(!(GCPhys & PAGE_OFFSET_MASK), ("%RGp\n", GCPhys), VERR_INVALID_PARAMETER); 103 AssertMsgReturn((GCPhysLast & PAGE_OFFSET_MASK) == PAGE_OFFSET_MASK, ("%RGp\n", GCPhysLast), VERR_INVALID_PARAMETER); 100 104 break; 101 105 default: … … 107 111 ("Not RC pointer! pvUserRC=%RRv\n", pvUserRC), 108 112 VERR_INVALID_PARAMETER); 113 AssertMsgReturn( (RTR0UINTPTR)pvUserR0 < 0x10000 114 || MMHyperR3ToR0(pVM, MMHyperR0ToR3(pVM, pvUserR0)) == pvUserR0, 115 ("Not R0 pointer! pvUserR0=%RHv\n", pvUserR0), 116 VERR_INVALID_PARAMETER); 117 #ifdef VBOX_WITH_NEW_PHYS_CODE 118 AssertPtrReturn(pfnHandlerR3, VERR_INVALID_POINTER); 119 AssertReturn(pfnHandlerR0, VERR_INVALID_PARAMETER); 120 AssertReturn(pfnHandlerRC, VERR_INVALID_PARAMETER); 121 #else 109 122 AssertReturn(pfnHandlerR3 || pfnHandlerR0 || pfnHandlerRC, VERR_INVALID_PARAMETER); 123 #endif 110 124 111 125 /* -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r17423 r17432 258 258 259 259 /** 260 * Frees the specified RAM page.261 *262 * This is used by ballooning and remapping MMIO2.263 *264 * @param pVM Pointer to the shared VM structure.265 * @param pPage Pointer to the page structure.266 * @param GCPhys The guest physical address of the page, if applicable.267 */268 void pgmPhysFreePage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)269 {270 AssertFatal(PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM);271 272 /** @todo implement this... */273 AssertFatalFailed();274 }275 276 277 /**278 260 * Makes sure that there is at least one handy page ready for use. 279 261 * … … 380 362 int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys) 381 363 { 364 LogFlow(("pgmPhysAllocPage: %R[pgmpage] %RGp\n", pPage, GCPhys)); 365 382 366 /* 383 367 * Ensure that we've got a page handy, take it and use it. … … 407 391 */ 408 392 const RTHCPHYS HCPhys = pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys; 409 pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys = GCPhys ;393 pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys = GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK; 410 394 411 395 if (PGM_PAGE_IS_SHARED(pPage)) … … 952 936 PPGMPAGEMAP pMap = pTlbe->pMap; 953 937 pMap->cRefs++; 954 #if 0 /** @ Todo implement locking properly */938 #if 0 /** @todo implement locking properly */ 955 939 if (RT_LIKELY(pPage->cLocks != PGM_PAGE_MAX_LOCKS)) 956 940 if (RT_UNLIKELY(++pPage->cLocks == PGM_PAGE_MAX_LOCKS)) … … 1041 1025 VMMDECL(int) PGMPhysGCPtr2CCPtr(PVM pVM, RTGCPTR GCPtr, void **ppv, PPGMPAGEMAPLOCK pLock) 1042 1026 { 1027 VM_ASSERT_EMT(pVM); 1043 1028 RTGCPHYS GCPhys; 1044 1029 int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, &GCPhys); … … 1074 1059 VMMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void const **ppv, PPGMPAGEMAPLOCK pLock) 1075 1060 { 1061 VM_ASSERT_EMT(pVM); 1076 1062 RTGCPHYS GCPhys; 1077 1063 int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, &GCPhys); … … 1157 1143 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1158 1144 # else 1145 pgmLock(pVM); 1146 1159 1147 PPGMRAMRANGE pRam; 1160 1148 PPGMPAGE pPage; 1161 1149 int rc = pgmPhysGetPageAndRangeEx(&pVM->pgm.s, GCPhys, &pPage, &pRam); 1162 if (RT_FAILURE(rc)) 1163 return rc; 1164 1165 void *pv; 1166 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pv); 1167 if (RT_FAILURE(rc)) 1168 return rc; 1169 *pR3Ptr = (RTR3PTR)pv; 1170 return VINF_SUCCESS; 1150 if (RT_SUCCESS(rc)) 1151 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, (void **)&pR3Ptr); 1152 1153 pgmUnlock(pVM); 1154 Assert(rc <= VINF_SUCCESS); 1155 return rc; 1171 1156 # endif 1172 1157 … … 1283 1268 * @param GCPtr The guest pointer to convert. 1284 1269 * @param pR3Ptr Where to store the R3 virtual address. 1270 * 1271 * @deprecated 1285 1272 */ 1286 1273 VMMDECL(int) PGMPhysGCPtr2R3Ptr(PVM pVM, RTGCPTR GCPtr, PRTR3PTR pR3Ptr) … … 1298 1285 1299 1286 1300 /**1301 * Converts a guest virtual address to a HC ring-3 pointer by specfied CR3 and1302 * flags.1303 *1304 * @returns VBox status code.1305 * @param pVM The VM Handle1306 * @param GCPtr The guest pointer to convert.1307 * @param cr3 The guest CR3.1308 * @param fFlags Flags used for interpreting the PD correctly: X86_CR4_PSE and X86_CR4_PAE1309 * @param pR3Ptr Where to store the R3 pointer.1310 *1311 * @remark This function is used by the REM at a time where PGM could1312 * potentially not be in sync. It could also be used by a1313 * future DBGF API to cpu state independent conversions.1314 */1315 VMMDECL(int) PGMPhysGCPtr2R3PtrByGstCR3(PVM pVM, RTGCPTR GCPtr, uint64_t cr3, unsigned fFlags, PRTR3PTR pR3Ptr)1316 {1317 #ifdef VBOX_WITH_NEW_PHYS_CODE1318 VM_ASSERT_EMT(pVM); /* no longer safe for use outside the EMT thread! */1319 #endif1320 /*1321 * PAE or 32-bit?1322 */1323 Assert(!CPUMIsGuestInLongMode(pVM));1324 1325 int rc;1326 if (!(fFlags & X86_CR4_PAE))1327 {1328 PX86PD pPD;1329 rc = PGM_GCPHYS_2_PTR(pVM, cr3 & X86_CR3_PAGE_MASK, &pPD);1330 if (RT_SUCCESS(rc))1331 {1332 X86PDE Pde = pPD->a[(RTGCUINTPTR)GCPtr >> X86_PD_SHIFT];1333 if (Pde.n.u1Present)1334 {1335 if ((fFlags & X86_CR4_PSE) && Pde.b.u1Size)1336 { /* (big page) */1337 rc = PGMPhysGCPhys2R3Ptr(pVM, pgmGstGet4MBPhysPage(&pVM->pgm.s, Pde) | ((RTGCUINTPTR)GCPtr & X86_PAGE_4M_OFFSET_MASK),1338 1 /* we always stay within one page */, pR3Ptr);1339 }1340 else1341 { /* (normal page) */1342 PX86PT pPT;1343 rc = PGM_GCPHYS_2_PTR(pVM, Pde.u & X86_PDE_PG_MASK, &pPT);1344 if (RT_SUCCESS(rc))1345 {1346 X86PTE Pte = pPT->a[((RTGCUINTPTR)GCPtr >> X86_PT_SHIFT) & X86_PT_MASK];1347 if (Pte.n.u1Present)1348 return PGMPhysGCPhys2R3Ptr(pVM, (Pte.u & X86_PTE_PG_MASK) | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK),1349 1 /* we always stay within one page */, pR3Ptr);1350 rc = VERR_PAGE_NOT_PRESENT;1351 }1352 }1353 }1354 else1355 rc = VERR_PAGE_TABLE_NOT_PRESENT;1356 }1357 }1358 else1359 {1360 /** @todo long mode! */1361 Assert(PGMGetGuestMode(pVM) < PGMMODE_AMD64);1362 1363 PX86PDPT pPdpt;1364 rc = PGM_GCPHYS_2_PTR(pVM, cr3 & X86_CR3_PAE_PAGE_MASK, &pPdpt);1365 if (RT_SUCCESS(rc))1366 {1367 X86PDPE Pdpe = pPdpt->a[((RTGCUINTPTR)GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_PAE];1368 if (Pdpe.n.u1Present)1369 {1370 PX86PDPAE pPD;1371 rc = PGM_GCPHYS_2_PTR(pVM, Pdpe.u & X86_PDPE_PG_MASK, &pPD);1372 if (RT_SUCCESS(rc))1373 {1374 X86PDEPAE Pde = pPD->a[((RTGCUINTPTR)GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK];1375 if (Pde.n.u1Present)1376 {1377 if ((fFlags & X86_CR4_PSE) && Pde.b.u1Size)1378 { /* (big page) */1379 rc = PGMPhysGCPhys2R3Ptr(pVM, (Pde.u & X86_PDE2M_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & X86_PAGE_2M_OFFSET_MASK),1380 1 /* we always stay within one page */, pR3Ptr);1381 }1382 else1383 { /* (normal page) */1384 PX86PTPAE pPT;1385 rc = PGM_GCPHYS_2_PTR(pVM, (Pde.u & X86_PDE_PAE_PG_MASK), &pPT);1386 if (RT_SUCCESS(rc))1387 {1388 X86PTEPAE Pte = pPT->a[((RTGCUINTPTR)GCPtr >> X86_PT_PAE_SHIFT) & X86_PT_PAE_MASK];1389 if (Pte.n.u1Present)1390 return PGMPhysGCPhys2R3Ptr(pVM, (Pte.u & X86_PTE_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK),1391 1 /* we always stay within one page */, pR3Ptr);1392 rc = VERR_PAGE_NOT_PRESENT;1393 }1394 }1395 }1396 else1397 rc = VERR_PAGE_TABLE_NOT_PRESENT;1398 }1399 }1400 else1401 rc = VERR_PAGE_TABLE_NOT_PRESENT;1402 }1403 }1404 return rc;1405 }1406 1407 1287 1408 1288 #undef LOG_GROUP … … 1439 1319 #endif /* IN_RING3 */ 1440 1320 1441 1442 1321 #ifdef VBOX_WITH_NEW_PHYS_CODE 1322 1443 1323 /** 1444 1324 * Deals with reading from a page with one or more ALL access handlers. … … 1448 1328 * @param GCPhys The physical address to start reading at. 1449 1329 * @param pvBuf Where to put the bits we read. 1450 * @param cbRead How much to read - less or equal to a page. 1451 */ 1452 static void pgmPhysReadHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) 1453 { 1454 AssertFailed(); 1330 * @param cb How much to read - less or equal to a page. 1331 */ 1332 static void pgmPhysReadHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void *pvBuf, size_t cb) 1333 { 1334 /* 1335 * The most frequent access here is MMIO and shadowed ROM. 1336 * 1337 * The current code ASSUMES all these access handlers are page sized 1338 * and that we do NOT use any virtual ones. 1339 */ 1340 if ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) == PGM_PAGE_HNDL_PHYS_STATE_ALL 1341 && PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) != PGM_PAGE_HNDL_VIRT_STATE_ALL) 1342 { 1343 #ifdef IN_RING3 1344 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 1345 AssertReleaseMsg(pCur, ("GCPhys=%RGp cb=%#x\n", GCPhys, cb)); 1346 Assert(GCPhys >= pCur->Core.Key && GCPhys <= pCur->Core.KeyLast); 1347 Assert(pCur->CTX_SUFF(pfnHandler)); 1348 1349 const void *pvSrc; 1350 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvSrc); 1351 if (RT_SUCCESS(rc)) 1352 { 1353 STAM_PROFILE_START(&pCur->Stat, h); 1354 int rc = pCur->CTX_SUFF(pfnHandler)(pVM, GCPhys, (void *)pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, pCur->CTX_SUFF(pvUser)); 1355 STAM_PROFILE_STOP(&pCur->Stat, h); 1356 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 1357 memcpy(pvBuf, pvSrc, cb); 1358 else 1359 AssertLogRelMsg(rc == VINF_SUCCESS, ("rc=%Rrc GCPhys=%RGp\n", rc, GCPhys)); 1360 } 1361 else 1362 { 1363 AssertLogRelMsgFailed(("pgmPhysGCPhys2CCPtrInternalReadOnly failed on %RGp / %R[pgmpage] -> %Rrc\n", 1364 GCPhys, pPage, rc)); 1365 memset(pvBuf, 0xff, cb); 1366 } 1367 #else 1368 AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cb=%#x\n", GCPhys, cb)); 1369 #endif 1370 } 1371 else 1372 AssertReleaseMsgFailed(("ALL access virtual handlers are not implemented here\n")); 1455 1373 } 1456 1374 … … 1836 1754 static void pgmPhysWriteHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const *pvBuf, size_t cbWrite) 1837 1755 { 1838 AssertFailed(); 1756 void *pvDst = NULL; 1757 1758 /* 1759 * Give priority to physical handlers (like #PF does). 1760 * 1761 * Hope for a lonely physical handler first that covers the whole 1762 * write area. This should be a pretty frequent case with MMIO and 1763 * the heavy usage of full page handlers in the page pool. 1764 */ 1765 if (!PGM_PAGE_HAS_ACTIVE_VIRTUAL_HANDLERS(pPage)) 1766 { 1767 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 1768 if (pCur) 1769 { 1770 Assert(GCPhys >= pCur->Core.Key && GCPhys <= pCur->Core.KeyLast); 1771 Assert(pCur->CTX_SUFF(pfnHandler)); 1772 1773 size_t cbRange = pCur->Core.KeyLast - GCPhys + 1; 1774 if (cbRange > cbWrite) 1775 cbRange = cbWrite; 1776 1777 #ifdef IN_RING3 1778 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst); 1779 if (RT_SUCCESS(rc)) 1780 { 1781 STAM_PROFILE_START(&pCur->Stat, h); 1782 rc = pCur->CTX_SUFF(pfnHandler)(pVM, GCPhys, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, pCur->CTX_SUFF(pvUser)); 1783 STAM_PROFILE_STOP(&pCur->Stat, h); 1784 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 1785 memcpy(pvDst, pvBuf, cbRange); 1786 else 1787 AssertLogRelMsg(rc == VINF_SUCCESS, ("rc=%Rrc GCPhys=%RGp %s\n", rc, GCPhys, pCur->pszDesc)); 1788 } 1789 else 1790 AssertLogRelMsgFailed(("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", 1791 GCPhys, pPage, rc)); 1792 #else 1793 AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cbRange=%#x\n", GCPhys, cbRange)); 1794 #endif 1795 if (RT_LIKELY(cbRange == cbWrite)) 1796 return; 1797 1798 /* more fun to be had below */ 1799 GCPhys += cbRange; 1800 cbWrite -= cbRange; 1801 pvBuf = (uint8_t *)pvBuf + cbRange; 1802 } 1803 /* else: the handler is somewhere else in the page, deal with it below. */ 1804 } 1805 /* 1806 * A virtual handler without any interfering physical handlers. 1807 * Hopefully it'll conver the whole write. 1808 */ 1809 else if (!PGM_PAGE_HAS_ACTIVE_PHYSICAL_HANDLERS(pPage)) 1810 { 1811 unsigned iPage; 1812 PPGMVIRTHANDLER pCur; 1813 int rc = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pCur, &iPage); 1814 if (RT_SUCCESS(rc)) 1815 { 1816 size_t cbRange = (PAGE_OFFSET_MASK & pCur->Core.KeyLast) - (PAGE_OFFSET_MASK & GCPhys) + 1; 1817 if (cbRange > cbWrite) 1818 cbRange = cbWrite; 1819 1820 #ifdef IN_RING3 1821 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst); 1822 if (RT_SUCCESS(rc)) 1823 { 1824 rc = VINF_PGM_HANDLER_DO_DEFAULT; 1825 if (pCur->pfnHandlerR3) 1826 { 1827 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pCur->Core.Key & PAGE_BASE_GC_MASK) 1828 + (iPage << PAGE_SHIFT) 1829 + (GCPhys & PAGE_OFFSET_MASK); 1830 1831 STAM_PROFILE_START(&pCur->Stat, h); 1832 rc = pCur->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, /*pCur->CTX_SUFF(pvUser)*/ NULL); 1833 STAM_PROFILE_STOP(&pCur->Stat, h); 1834 } 1835 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 1836 memcpy(pvDst, pvBuf, cbRange); 1837 else 1838 AssertLogRelMsg(rc == VINF_SUCCESS, ("rc=%Rrc GCPhys=%RGp %s\n", rc, GCPhys, pCur->pszDesc)); 1839 } 1840 else 1841 AssertLogRelMsgFailed(("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", 1842 GCPhys, pPage, rc)); 1843 #else 1844 AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cb=%#x\n", GCPhys, cbRange)); 1845 #endif 1846 if (RT_LIKELY(cbRange == cbWrite)) 1847 return; 1848 1849 /* more fun to be had below */ 1850 GCPhys += cbRange; 1851 cbWrite -= cbRange; 1852 pvBuf = (uint8_t *)pvBuf + cbRange; 1853 } 1854 /* else: the handler is somewhere else in the page, deal with it below. */ 1855 } 1856 1857 /* 1858 * Deal with all the odd ends. 1859 */ 1860 while (cbWrite > 0) 1861 { 1862 AssertReleaseMsgFailed(("%RGp %#x %R[pgmpage]\n", GCPhys, cbWrite, pPage)); 1863 } 1839 1864 } 1840 1865
Note:
See TracChangeset
for help on using the changeset viewer.