Changeset 91854 in vbox for trunk/src/VBox/VMM/VMMR3/MMHyper.cpp
- Timestamp:
- Oct 20, 2021 12:50:11 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/MMHyper.cpp
r91266 r91854 39 39 * Internal Functions * 40 40 *********************************************************************************************************************************/ 41 #ifndef PGM_WITHOUT_MAPPINGS42 static DECLCALLBACK(bool) mmR3HyperRelocateCallback(PVM pVM, RTGCPTR GCPtrOld, RTGCPTR GCPtrNew, PGMRELOCATECALL enmMode,43 void *pvUser);44 #endif45 41 static int mmR3HyperMap(PVM pVM, const size_t cb, const char *pszDesc, PRTGCPTR pGCPtr, PMMLOOKUPHYPER *ppLookup); 46 42 static int mmR3HyperHeapCreate(PVM pVM, const size_t cb, PMMHYPERHEAP *ppHeap, PRTR0PTR pR0PtrHeap); 47 43 static int mmR3HyperHeapMap(PVM pVM, PMMHYPERHEAP pHeap, PRTGCPTR ppHeapGC); 48 44 static DECLCALLBACK(void) mmR3HyperInfoHma(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 45 static int MMR3HyperReserveFence(PVM pVM); 46 static int MMR3HyperMapPages(PVM pVM, void *pvR3, RTR0PTR pvR0, size_t cPages, PCSUPPAGE paPages, 47 const char *pszDesc, PRTGCPTR pGCPtr); 49 48 50 49 … … 222 221 223 222 /** 224 * Finalizes the HMA mapping .223 * Finalizes the HMA mapping (obsolete). 225 224 * 226 225 * This is called later during init, most (all) HMA allocations should be done … … 239 238 AssertRC(rc); 240 239 241 #ifndef PGM_WITHOUT_MAPPINGS242 /*243 * Adjust and create the HMA mapping.244 */245 while ((RTINT)pVM->mm.s.offHyperNextStatic + 64*_1K < (RTINT)pVM->mm.s.cbHyperArea - _4M)246 pVM->mm.s.cbHyperArea -= _4M;247 rc = PGMR3MapPT(pVM, pVM->mm.s.pvHyperAreaGC, pVM->mm.s.cbHyperArea, 0 /*fFlags*/,248 mmR3HyperRelocateCallback, NULL, "Hypervisor Memory Area");249 if (RT_FAILURE(rc))250 return rc;251 #endif252 240 pVM->mm.s.fPGMInitialized = true; 253 254 #ifndef PGM_WITHOUT_MAPPINGS255 /*256 * Do all the delayed mappings.257 */258 PMMLOOKUPHYPER pLookup = (PMMLOOKUPHYPER)((uintptr_t)pVM->mm.s.pHyperHeapR3 + pVM->mm.s.offLookupHyper);259 for (;;)260 {261 RTGCPTR GCPtr = pVM->mm.s.pvHyperAreaGC + pLookup->off;262 uint32_t cPages = pLookup->cb >> PAGE_SHIFT;263 switch (pLookup->enmType)264 {265 case MMLOOKUPHYPERTYPE_LOCKED:266 {267 PCRTHCPHYS paHCPhysPages = pLookup->u.Locked.paHCPhysPages;268 for (uint32_t i = 0; i < cPages; i++)269 {270 rc = PGMMap(pVM, GCPtr + (i << PAGE_SHIFT), paHCPhysPages[i], PAGE_SIZE, 0);271 AssertRCReturn(rc, rc);272 }273 break;274 }275 276 case MMLOOKUPHYPERTYPE_HCPHYS:277 rc = PGMMap(pVM, GCPtr, pLookup->u.HCPhys.HCPhys, pLookup->cb, 0);278 break;279 280 case MMLOOKUPHYPERTYPE_GCPHYS:281 {282 const RTGCPHYS GCPhys = pLookup->u.GCPhys.GCPhys;283 const uint32_t cb = pLookup->cb;284 for (uint32_t off = 0; off < cb; off += PAGE_SIZE)285 {286 RTHCPHYS HCPhys;287 rc = PGMPhysGCPhys2HCPhys(pVM, GCPhys + off, &HCPhys);288 if (RT_FAILURE(rc))289 break;290 rc = PGMMap(pVM, GCPtr + off, HCPhys, PAGE_SIZE, 0);291 if (RT_FAILURE(rc))292 break;293 }294 break;295 }296 297 case MMLOOKUPHYPERTYPE_MMIO2:298 {299 const RTGCPHYS offEnd = pLookup->u.MMIO2.off + pLookup->cb;300 for (RTGCPHYS offCur = pLookup->u.MMIO2.off; offCur < offEnd; offCur += PAGE_SIZE)301 {302 RTHCPHYS HCPhys;303 rc = PGMR3PhysMMIO2GetHCPhys(pVM, pLookup->u.MMIO2.pDevIns, pLookup->u.MMIO2.iSubDev,304 pLookup->u.MMIO2.iRegion, offCur, &HCPhys);305 if (RT_FAILURE(rc))306 break;307 rc = PGMMap(pVM, GCPtr + (offCur - pLookup->u.MMIO2.off), HCPhys, PAGE_SIZE, 0);308 if (RT_FAILURE(rc))309 break;310 }311 break;312 }313 314 case MMLOOKUPHYPERTYPE_DYNAMIC:315 /* do nothing here since these are either fences or managed by someone else using PGM. */316 break;317 318 default:319 AssertMsgFailed(("enmType=%d\n", pLookup->enmType));320 break;321 }322 323 if (RT_FAILURE(rc))324 {325 AssertMsgFailed(("rc=%Rrc cb=%d off=%#RX32 enmType=%d pszDesc=%s\n",326 rc, pLookup->cb, pLookup->off, pLookup->enmType, pLookup->pszDesc));327 return rc;328 }329 330 /* next */331 if (pLookup->offNext == (int32_t)NIL_OFFSET)332 break;333 pLookup = (PMMLOOKUPHYPER)((uintptr_t)pLookup + pLookup->offNext);334 }335 #endif /* !PGM_WITHOUT_MAPPINGS */336 241 337 242 LogFlow(("MMR3HyperInitFinalize: returns VINF_SUCCESS\n")); … … 339 244 } 340 245 341 342 #ifndef PGM_WITHOUT_MAPPINGS343 /**344 * Callback function which will be called when PGM is trying to find a new345 * location for the mapping.346 *347 * The callback is called in two modes, 1) the check mode and 2) the relocate mode.348 * In 1) the callback should say if it objects to a suggested new location. If it349 * accepts the new location, it is called again for doing it's relocation.350 *351 *352 * @returns true if the location is ok.353 * @returns false if another location should be found.354 * @param pVM The cross context VM structure.355 * @param GCPtrOld The old virtual address.356 * @param GCPtrNew The new virtual address.357 * @param enmMode Used to indicate the callback mode.358 * @param pvUser User argument. Ignored.359 * @remark The return value is no a failure indicator, it's an acceptance360 * indicator. Relocation can not fail!361 */362 static DECLCALLBACK(bool) mmR3HyperRelocateCallback(PVM pVM, RTGCPTR GCPtrOld, RTGCPTR GCPtrNew,363 PGMRELOCATECALL enmMode, void *pvUser)364 {365 NOREF(pvUser);366 switch (enmMode)367 {368 /*369 * Verify location - all locations are good for us.370 */371 case PGMRELOCATECALL_SUGGEST:372 return true;373 374 /*375 * Execute the relocation.376 */377 case PGMRELOCATECALL_RELOCATE:378 {379 /*380 * Accepted!381 */382 AssertMsg(GCPtrOld == pVM->mm.s.pvHyperAreaGC,383 ("GCPtrOld=%RGv pVM->mm.s.pvHyperAreaGC=%RGv\n", GCPtrOld, pVM->mm.s.pvHyperAreaGC));384 Log(("Relocating the hypervisor from %RGv to %RGv\n", GCPtrOld, GCPtrNew));385 386 /*387 * Relocate the VM structure and ourselves.388 */389 RTGCINTPTR offDelta = GCPtrNew - GCPtrOld;390 pVM->pVMRC += offDelta;391 for (VMCPUID i = 0; i < pVM->cCpus; i++)392 pVM->aCpus[i].pVMRC = pVM->pVMRC;393 394 pVM->mm.s.pvHyperAreaGC += offDelta;395 Assert(pVM->mm.s.pvHyperAreaGC < _4G);396 pVM->mm.s.pHyperHeapRC += offDelta;397 pVM->mm.s.pHyperHeapR3->pbHeapRC += offDelta;398 pVM->mm.s.pHyperHeapR3->pVMRC = pVM->pVMRC;399 400 /*401 * Relocate the rest.402 */403 VMR3Relocate(pVM, offDelta);404 return true;405 }406 407 default:408 AssertMsgFailed(("Invalid relocation mode %d\n", enmMode));409 }410 411 return false;412 }413 414 415 /**416 * Maps contiguous HC physical memory into the hypervisor region in the GC.417 *418 * @return VBox status code.419 *420 * @param pVM The cross context VM structure.421 * @param pvR3 Ring-3 address of the memory. Must be page aligned!422 * @param pvR0 Optional ring-0 address of the memory.423 * @param HCPhys Host context physical address of the memory to be424 * mapped. Must be page aligned!425 * @param cb Size of the memory. Will be rounded up to nearest page.426 * @param pszDesc Description.427 * @param pGCPtr Where to store the GC address.428 */429 VMMR3DECL(int) MMR3HyperMapHCPhys(PVM pVM, void *pvR3, RTR0PTR pvR0, RTHCPHYS HCPhys, size_t cb,430 const char *pszDesc, PRTGCPTR pGCPtr)431 {432 LogFlow(("MMR3HyperMapHCPhys: pvR3=%p pvR0=%p HCPhys=%RHp cb=%d pszDesc=%p:{%s} pGCPtr=%p\n",433 pvR3, pvR0, HCPhys, (int)cb, pszDesc, pszDesc, pGCPtr));434 435 /*436 * Validate input.437 */438 AssertReturn(RT_ALIGN_P(pvR3, PAGE_SIZE) == pvR3, VERR_INVALID_PARAMETER);439 AssertReturn(RT_ALIGN_T(pvR0, PAGE_SIZE, RTR0PTR) == pvR0, VERR_INVALID_PARAMETER);440 AssertReturn(RT_ALIGN_T(HCPhys, PAGE_SIZE, RTHCPHYS) == HCPhys, VERR_INVALID_PARAMETER);441 AssertReturn(pszDesc && *pszDesc, VERR_INVALID_PARAMETER);442 443 /*444 * Add the memory to the hypervisor area.445 */446 uint32_t cbAligned = RT_ALIGN_32(cb, PAGE_SIZE);447 AssertReturn(cbAligned >= cb, VERR_INVALID_PARAMETER);448 RTGCPTR GCPtr;449 PMMLOOKUPHYPER pLookup;450 int rc = mmR3HyperMap(pVM, cbAligned, pszDesc, &GCPtr, &pLookup);451 if (RT_SUCCESS(rc))452 {453 pLookup->enmType = MMLOOKUPHYPERTYPE_HCPHYS;454 pLookup->u.HCPhys.pvR3 = pvR3;455 pLookup->u.HCPhys.pvR0 = pvR0;456 pLookup->u.HCPhys.HCPhys = HCPhys;457 458 /*459 * Update the page table.460 */461 if (pVM->mm.s.fPGMInitialized)462 rc = PGMMap(pVM, GCPtr, HCPhys, cbAligned, 0);463 if (RT_SUCCESS(rc))464 *pGCPtr = GCPtr;465 }466 return rc;467 }468 469 470 /**471 * Maps contiguous GC physical memory into the hypervisor region in the GC.472 *473 * @return VBox status code.474 *475 * @param pVM The cross context VM structure.476 * @param GCPhys Guest context physical address of the memory to be mapped. Must be page aligned!477 * @param cb Size of the memory. Will be rounded up to nearest page.478 * @param pszDesc Mapping description.479 * @param pGCPtr Where to store the GC address.480 */481 VMMR3DECL(int) MMR3HyperMapGCPhys(PVM pVM, RTGCPHYS GCPhys, size_t cb, const char *pszDesc, PRTGCPTR pGCPtr)482 {483 LogFlow(("MMR3HyperMapGCPhys: GCPhys=%RGp cb=%d pszDesc=%p:{%s} pGCPtr=%p\n", GCPhys, (int)cb, pszDesc, pszDesc, pGCPtr));484 485 /*486 * Validate input.487 */488 AssertReturn(RT_ALIGN_T(GCPhys, PAGE_SIZE, RTGCPHYS) == GCPhys, VERR_INVALID_PARAMETER);489 AssertReturn(pszDesc && *pszDesc, VERR_INVALID_PARAMETER);490 491 /*492 * Add the memory to the hypervisor area.493 */494 cb = RT_ALIGN_Z(cb, PAGE_SIZE);495 RTGCPTR GCPtr;496 PMMLOOKUPHYPER pLookup;497 int rc = mmR3HyperMap(pVM, cb, pszDesc, &GCPtr, &pLookup);498 if (RT_SUCCESS(rc))499 {500 pLookup->enmType = MMLOOKUPHYPERTYPE_GCPHYS;501 pLookup->u.GCPhys.GCPhys = GCPhys;502 503 /*504 * Update the page table.505 */506 for (unsigned off = 0; off < cb; off += PAGE_SIZE)507 {508 RTHCPHYS HCPhys;509 rc = PGMPhysGCPhys2HCPhys(pVM, GCPhys + off, &HCPhys);510 AssertRC(rc);511 if (RT_FAILURE(rc))512 {513 AssertMsgFailed(("rc=%Rrc GCPhys=%RGp off=%#x %s\n", rc, GCPhys, off, pszDesc));514 break;515 }516 if (pVM->mm.s.fPGMInitialized)517 {518 rc = PGMMap(pVM, GCPtr + off, HCPhys, PAGE_SIZE, 0);519 AssertRC(rc);520 if (RT_FAILURE(rc))521 {522 AssertMsgFailed(("rc=%Rrc GCPhys=%RGp off=%#x %s\n", rc, GCPhys, off, pszDesc));523 break;524 }525 }526 }527 528 if (RT_SUCCESS(rc) && pGCPtr)529 *pGCPtr = GCPtr;530 }531 return rc;532 }533 534 535 /**536 * Maps a portion of an MMIO2 region into the hypervisor region.537 *538 * Callers of this API must never deregister the MMIO2 region before the539 * VM is powered off. If this becomes a requirement MMR3HyperUnmapMMIO2540 * API will be needed to perform cleanups.541 *542 * @return VBox status code.543 *544 * @param pVM The cross context VM structure.545 * @param pDevIns The device owning the MMIO2 memory.546 * @param iSubDev The sub-device number.547 * @param iRegion The region.548 * @param off The offset into the region. Will be rounded down to closest page boundary.549 * @param cb The number of bytes to map. Will be rounded up to the closest page boundary.550 * @param pszDesc Mapping description.551 * @param pRCPtr Where to store the RC address.552 */553 VMMR3DECL(int) MMR3HyperMapMMIO2(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,554 const char *pszDesc, PRTRCPTR pRCPtr)555 {556 LogFlow(("MMR3HyperMapMMIO2: pDevIns=%p iSubDev=%#x iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",557 pDevIns, iSubDev, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));558 int rc;559 560 /*561 * Validate input.562 */563 AssertReturn(pszDesc && *pszDesc, VERR_INVALID_PARAMETER);564 AssertReturn(off + cb > off, VERR_INVALID_PARAMETER);565 uint32_t const offPage = off & PAGE_OFFSET_MASK;566 off &= ~(RTGCPHYS)PAGE_OFFSET_MASK;567 cb += offPage;568 cb = RT_ALIGN_Z(cb, PAGE_SIZE);569 const RTGCPHYS offEnd = off + cb;570 AssertReturn(offEnd > off, VERR_INVALID_PARAMETER);571 for (RTGCPHYS offCur = off; offCur < offEnd; offCur += PAGE_SIZE)572 {573 RTHCPHYS HCPhys;574 rc = PGMR3PhysMMIO2GetHCPhys(pVM, pDevIns, iSubDev, iRegion, offCur, &HCPhys);575 AssertMsgRCReturn(rc, ("rc=%Rrc - iSubDev=%#x iRegion=%#x off=%RGp\n", rc, iSubDev, iRegion, off), rc);576 }577 578 /*579 * Add the memory to the hypervisor area.580 */581 RTGCPTR GCPtr;582 PMMLOOKUPHYPER pLookup;583 rc = mmR3HyperMap(pVM, cb, pszDesc, &GCPtr, &pLookup);584 if (RT_SUCCESS(rc))585 {586 pLookup->enmType = MMLOOKUPHYPERTYPE_MMIO2;587 pLookup->u.MMIO2.pDevIns = pDevIns;588 pLookup->u.MMIO2.iSubDev = iSubDev;589 pLookup->u.MMIO2.iRegion = iRegion;590 pLookup->u.MMIO2.off = off;591 592 /*593 * Update the page table.594 */595 if (pVM->mm.s.fPGMInitialized)596 {597 for (RTGCPHYS offCur = off; offCur < offEnd; offCur += PAGE_SIZE)598 {599 RTHCPHYS HCPhys;600 rc = PGMR3PhysMMIO2GetHCPhys(pVM, pDevIns, iSubDev, iRegion, offCur, &HCPhys);601 AssertRCReturn(rc, rc);602 rc = PGMMap(pVM, GCPtr + (offCur - off), HCPhys, PAGE_SIZE, 0);603 if (RT_FAILURE(rc))604 {605 AssertMsgFailed(("rc=%Rrc offCur=%RGp %s\n", rc, offCur, pszDesc));606 break;607 }608 }609 }610 611 if (RT_SUCCESS(rc))612 {613 GCPtr |= offPage;614 *pRCPtr = GCPtr;615 AssertLogRelReturn(*pRCPtr == GCPtr, VERR_INTERNAL_ERROR);616 }617 }618 return rc;619 }620 621 #endif /* !PGM_WITHOUT_MAPPINGS */622 246 623 247 /** … … 634 258 * @param pGCPtr Where to store the GC address corresponding to pvR3. 635 259 */ 636 VMMR3DECL(int)MMR3HyperMapPages(PVM pVM, void *pvR3, RTR0PTR pvR0, size_t cPages, PCSUPPAGE paPages,637 260 static int MMR3HyperMapPages(PVM pVM, void *pvR3, RTR0PTR pvR0, size_t cPages, PCSUPPAGE paPages, 261 const char *pszDesc, PRTGCPTR pGCPtr) 638 262 { 639 263 LogFlow(("MMR3HyperMapPages: pvR3=%p pvR0=%p cPages=%zu paPages=%p pszDesc=%p:{%s} pGCPtr=%p\n", … … 675 299 } 676 300 677 #ifndef PGM_WITHOUT_MAPPINGS 678 if (pVM->mm.s.fPGMInitialized) 679 { 680 for (size_t i = 0; i < cPages; i++) 681 { 682 rc = PGMMap(pVM, GCPtr + (i << PAGE_SHIFT), paHCPhysPages[i], PAGE_SIZE, 0); 683 AssertRCBreak(rc); 684 } 685 } 686 #endif 687 if (RT_SUCCESS(rc)) 688 { 689 pLookup->enmType = MMLOOKUPHYPERTYPE_LOCKED; 690 pLookup->u.Locked.pvR3 = pvR3; 691 pLookup->u.Locked.pvR0 = pvR0; 692 pLookup->u.Locked.paHCPhysPages = paHCPhysPages; 693 694 /* done. */ 695 *pGCPtr = GCPtr; 696 return rc; 697 } 698 /* Don't care about failure clean, we're screwed if this fails anyway. */ 699 } 301 pLookup->enmType = MMLOOKUPHYPERTYPE_LOCKED; 302 pLookup->u.Locked.pvR3 = pvR3; 303 pLookup->u.Locked.pvR0 = pvR0; 304 pLookup->u.Locked.paHCPhysPages = paHCPhysPages; 305 306 /* done. */ 307 *pGCPtr = GCPtr; 308 return rc; 309 } 310 /* Don't care about failure clean, we're screwed if this fails anyway. */ 700 311 } 701 312 702 313 return rc; 703 314 } 704 705 706 #ifndef PGM_WITHOUT_MAPPINGS707 /**708 * Reserves a hypervisor memory area.709 * Most frequent usage is fence pages and dynamically mappings like the guest PD and PDPT.710 *711 * @return VBox status code.712 *713 * @param pVM The cross context VM structure.714 * @param cb Size of the memory. Will be rounded up to nearest page.715 * @param pszDesc Mapping description.716 * @param pGCPtr Where to store the assigned GC address. Optional.717 */718 VMMR3DECL(int) MMR3HyperReserve(PVM pVM, unsigned cb, const char *pszDesc, PRTGCPTR pGCPtr)719 {720 LogFlow(("MMR3HyperMapHCRam: cb=%d pszDesc=%p:{%s} pGCPtr=%p\n", (int)cb, pszDesc, pszDesc, pGCPtr));721 722 /*723 * Validate input.724 */725 if ( cb <= 0726 || !pszDesc727 || !*pszDesc)728 {729 AssertMsgFailed(("Invalid parameter\n"));730 return VERR_INVALID_PARAMETER;731 }732 733 /*734 * Add the memory to the hypervisor area.735 */736 RTGCPTR GCPtr;737 PMMLOOKUPHYPER pLookup;738 int rc = mmR3HyperMap(pVM, cb, pszDesc, &GCPtr, &pLookup);739 if (RT_SUCCESS(rc))740 {741 pLookup->enmType = MMLOOKUPHYPERTYPE_DYNAMIC;742 if (pGCPtr)743 *pGCPtr = GCPtr;744 return VINF_SUCCESS;745 }746 return rc;747 }748 #endif /* !PGM_WITHOUT_MAPPINGS */749 315 750 316 … … 755 321 * @param pVM The cross context VM structure. 756 322 */ 757 VMMR3DECL(int) MMR3HyperReserveFence(PVM pVM) 758 { 759 #ifndef PGM_WITHOUT_MAPPINGS 760 return MMR3HyperReserve(pVM, cb, "fence", NULL); 761 #else 323 static int MMR3HyperReserveFence(PVM pVM) 324 { 762 325 RT_NOREF(pVM); 763 326 return VINF_SUCCESS; 764 #endif765 327 } 766 328 … … 1139 701 1140 702 /** 1141 * Set / unset guard status on one or more hyper heap pages.1142 *1143 * @returns VBox status code (first failure).1144 * @param pVM The cross context VM structure.1145 * @param pvStart The hyper heap page address. Must be page1146 * aligned.1147 * @param cb The number of bytes. Must be page aligned.1148 * @param fSet Whether to set or unset guard page status.1149 */1150 VMMR3DECL(int) MMR3HyperSetGuard(PVM pVM, void *pvStart, size_t cb, bool fSet)1151 {1152 /*1153 * Validate input.1154 */1155 AssertReturn(!((uintptr_t)pvStart & PAGE_OFFSET_MASK), VERR_INVALID_POINTER);1156 AssertReturn(!(cb & PAGE_OFFSET_MASK), VERR_INVALID_PARAMETER);1157 AssertReturn(cb <= UINT32_MAX, VERR_INVALID_PARAMETER);1158 PMMLOOKUPHYPER pLookup = mmR3HyperLookupR3(pVM, pvStart);1159 AssertReturn(pLookup, VERR_INVALID_PARAMETER);1160 AssertReturn(pLookup->enmType == MMLOOKUPHYPERTYPE_LOCKED, VERR_INVALID_PARAMETER);1161 1162 /*1163 * Get down to business.1164 * Note! We quietly ignore errors from the support library since the1165 * protection stuff isn't possible to implement on all platforms.1166 */1167 uint8_t *pbR3 = (uint8_t *)pLookup->u.Locked.pvR3;1168 RTR0PTR R0Ptr = pLookup->u.Locked.pvR0 != (uintptr_t)pLookup->u.Locked.pvR31169 ? pLookup->u.Locked.pvR01170 : NIL_RTR0PTR;1171 uint32_t off = (uint32_t)((uint8_t *)pvStart - pbR3);1172 int rc;1173 if (fSet)1174 {1175 #ifndef PGM_WITHOUT_MAPPINGS1176 rc = PGMMapSetPage(pVM, MMHyperR3ToRC(pVM, pvStart), cb, 0);1177 #else1178 rc = VINF_SUCCESS;1179 #endif1180 SUPR3PageProtect(pbR3, R0Ptr, off, (uint32_t)cb, RTMEM_PROT_NONE);1181 }1182 else1183 {1184 #ifndef PGM_WITHOUT_MAPPINGS1185 rc = PGMMapSetPage(pVM, MMHyperR3ToRC(pVM, pvStart), cb, X86_PTE_P | X86_PTE_A | X86_PTE_D | X86_PTE_RW);1186 #else1187 rc = VINF_SUCCESS;1188 #endif1189 SUPR3PageProtect(pbR3, R0Ptr, off, (uint32_t)cb, RTMEM_PROT_READ | RTMEM_PROT_WRITE);1190 }1191 return rc;1192 }1193 1194 1195 /**1196 703 * Convert hypervisor HC virtual address to HC physical address. 1197 704 * … … 1244 751 } 1245 752 1246 #ifndef PGM_WITHOUT_MAPPINGS1247 1248 /**1249 * Implements the hcphys-not-found return case of MMR3HyperQueryInfoFromHCPhys.1250 *1251 * @returns VINF_SUCCESS, VINF_BUFFER_OVERFLOW.1252 * @param pVM The cross context VM structure.1253 * @param HCPhys The host physical address to look for.1254 * @param pLookup The HMA lookup entry corresponding to HCPhys.1255 * @param pszWhat Where to return the description.1256 * @param cbWhat Size of the return buffer.1257 * @param pcbAlloc Where to return the size of whatever it is.1258 */1259 static int mmR3HyperQueryInfoFromHCPhysFound(PVM pVM, RTHCPHYS HCPhys, PMMLOOKUPHYPER pLookup,1260 char *pszWhat, size_t cbWhat, uint32_t *pcbAlloc)1261 {1262 NOREF(pVM); NOREF(HCPhys);1263 *pcbAlloc = pLookup->cb;1264 int rc = RTStrCopy(pszWhat, cbWhat, pLookup->pszDesc);1265 return rc == VERR_BUFFER_OVERFLOW ? VINF_BUFFER_OVERFLOW : rc;1266 }1267 1268 1269 /**1270 * Scans the HMA for the physical page and reports back a description if found.1271 *1272 * @returns VINF_SUCCESS, VINF_BUFFER_OVERFLOW, VERR_NOT_FOUND.1273 * @param pVM The cross context VM structure.1274 * @param HCPhys The host physical address to look for.1275 * @param pszWhat Where to return the description.1276 * @param cbWhat Size of the return buffer.1277 * @param pcbAlloc Where to return the size of whatever it is.1278 */1279 VMMR3_INT_DECL(int) MMR3HyperQueryInfoFromHCPhys(PVM pVM, RTHCPHYS HCPhys, char *pszWhat, size_t cbWhat, uint32_t *pcbAlloc)1280 {1281 RTHCPHYS HCPhysPage = HCPhys & ~(RTHCPHYS)PAGE_OFFSET_MASK;1282 PMMLOOKUPHYPER pLookup = (PMMLOOKUPHYPER)((uint8_t *)pVM->mm.s.pHyperHeapR3 + pVM->mm.s.offLookupHyper);1283 for (;;)1284 {1285 switch (pLookup->enmType)1286 {1287 case MMLOOKUPHYPERTYPE_LOCKED:1288 {1289 uint32_t i = pLookup->cb >> PAGE_SHIFT;1290 while (i-- > 0)1291 if (pLookup->u.Locked.paHCPhysPages[i] == HCPhysPage)1292 return mmR3HyperQueryInfoFromHCPhysFound(pVM, HCPhys, pLookup, pszWhat, cbWhat, pcbAlloc);1293 break;1294 }1295 1296 case MMLOOKUPHYPERTYPE_HCPHYS:1297 {1298 if (pLookup->u.HCPhys.HCPhys - HCPhysPage < pLookup->cb)1299 return mmR3HyperQueryInfoFromHCPhysFound(pVM, HCPhys, pLookup, pszWhat, cbWhat, pcbAlloc);1300 break;1301 }1302 1303 case MMLOOKUPHYPERTYPE_MMIO2:1304 case MMLOOKUPHYPERTYPE_GCPHYS:1305 case MMLOOKUPHYPERTYPE_DYNAMIC:1306 {1307 /* brute force. */1308 uint32_t i = pLookup->cb >> PAGE_SHIFT;1309 while (i-- > 0)1310 {1311 RTGCPTR GCPtr = pLookup->off + pVM->mm.s.pvHyperAreaGC;1312 RTHCPHYS HCPhysCur;1313 int rc = PGMMapGetPage(pVM, GCPtr, NULL, &HCPhysCur);1314 if (RT_SUCCESS(rc) && HCPhysCur == HCPhysPage)1315 return mmR3HyperQueryInfoFromHCPhysFound(pVM, HCPhys, pLookup, pszWhat, cbWhat, pcbAlloc);1316 }1317 break;1318 }1319 default:1320 AssertMsgFailed(("enmType=%d\n", pLookup->enmType));1321 break;1322 }1323 1324 /* next */1325 if ((unsigned)pLookup->offNext == NIL_OFFSET)1326 break;1327 pLookup = (PMMLOOKUPHYPER)((uint8_t *)pLookup + pLookup->offNext);1328 }1329 return VERR_NOT_FOUND;1330 }1331 1332 1333 /**1334 * Read hypervisor memory from GC virtual address.1335 *1336 * @returns VBox status code.1337 * @param pVM The cross context VM structure.1338 * @param pvDst Destination address (HC of course).1339 * @param GCPtr GC virtual address.1340 * @param cb Number of bytes to read.1341 *1342 * @remarks For DBGF only.1343 */1344 VMMR3DECL(int) MMR3HyperReadGCVirt(PVM pVM, void *pvDst, RTGCPTR GCPtr, size_t cb)1345 {1346 if (GCPtr - pVM->mm.s.pvHyperAreaGC >= pVM->mm.s.cbHyperArea)1347 return VERR_INVALID_POINTER;1348 return PGMR3MapRead(pVM, pvDst, GCPtr, cb);1349 }1350 1351 #endif /* !PGM_WITHOUT_MAPPINGS */1352 753 1353 754 /**
Note:
See TracChangeset
for help on using the changeset viewer.