Changeset 92157 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Oct 29, 2021 10:03:51 PM (3 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
r92129 r92157 2707 2707 { 2708 2708 Assert(pCur->idMmio2 == hMmio2); 2709 AssertReturn(pCur->fFlags & PGMREGMMIO2RANGE_F_MMIO2, NULL);2710 2709 AssertReturn(pCur->fFlags & PGMREGMMIO2RANGE_F_FIRST_CHUNK, NULL); 2711 2710 return pCur; … … 2717 2716 { 2718 2717 AssertBreak(pCur->pDevInsR3 == pDevIns); 2719 AssertReturn(pCur->fFlags & PGMREGMMIO2RANGE_F_MMIO2, NULL);2720 2718 AssertReturn(pCur->fFlags & PGMREGMMIO2RANGE_F_FIRST_CHUNK, NULL); 2721 2719 return pCur; … … 2938 2936 static void pgmR3PhysMmio2Link(PVM pVM, PPGMREGMMIO2RANGE pNew) 2939 2937 { 2938 Assert(pNew->idMmio2 != UINT8_MAX); 2939 2940 2940 /* 2941 2941 * Link it into the list (order doesn't matter, so insert it at the head). … … 2953 2953 Assert(pLast->pNextR3->iSubDev == pNew->iSubDev); 2954 2954 Assert(pLast->pNextR3->iRegion == pNew->iRegion); 2955 Assert((pLast->pNextR3->fFlags & PGMREGMMIO2RANGE_F_MMIO2) == (pNew->fFlags & PGMREGMMIO2RANGE_F_MMIO2)); 2956 Assert(pLast->pNextR3->idMmio2 == (pLast->fFlags & PGMREGMMIO2RANGE_F_MMIO2 ? pLast->idMmio2 + 1 : UINT8_MAX)); 2955 Assert(pLast->pNextR3->idMmio2 == pLast->idMmio2 + 1); 2957 2956 } 2958 2957 … … 2963 2962 pVM->pgm.s.pRegMmioRangesR3 = pNew; 2964 2963 2965 /* I f MMIO, insert the MMIO2 range/page IDs. */2964 /* Insert the MMIO2 range/page IDs. */ 2966 2965 uint8_t idMmio2 = pNew->idMmio2; 2967 if (idMmio2 != UINT8_MAX) 2968 { 2969 for (;;) 2970 { 2971 Assert(pNew->fFlags & PGMREGMMIO2RANGE_F_MMIO2); 2972 Assert(pVM->pgm.s.apMmio2RangesR3[idMmio2 - 1] == NULL); 2973 Assert(pVM->pgm.s.apMmio2RangesR0[idMmio2 - 1] == NIL_RTR0PTR); 2974 pVM->pgm.s.apMmio2RangesR3[idMmio2 - 1] = pNew; 2975 pVM->pgm.s.apMmio2RangesR0[idMmio2 - 1] = pNew->RamRange.pSelfR0 - RT_UOFFSETOF(PGMREGMMIO2RANGE, RamRange); 2976 if (pNew->fFlags & PGMREGMMIO2RANGE_F_LAST_CHUNK) 2977 break; 2978 pNew = pNew->pNextR3; 2979 idMmio2++; 2980 } 2981 } 2982 else 2983 Assert(!(pNew->fFlags & PGMREGMMIO2RANGE_F_MMIO2)); 2966 for (;;) 2967 { 2968 Assert(pVM->pgm.s.apMmio2RangesR3[idMmio2 - 1] == NULL); 2969 Assert(pVM->pgm.s.apMmio2RangesR0[idMmio2 - 1] == NIL_RTR0PTR); 2970 pVM->pgm.s.apMmio2RangesR3[idMmio2 - 1] = pNew; 2971 pVM->pgm.s.apMmio2RangesR0[idMmio2 - 1] = pNew->RamRange.pSelfR0 - RT_UOFFSETOF(PGMREGMMIO2RANGE, RamRange); 2972 if (pNew->fFlags & PGMREGMMIO2RANGE_F_LAST_CHUNK) 2973 break; 2974 pNew = pNew->pNextR3; 2975 idMmio2++; 2976 } 2984 2977 2985 2978 pgmPhysInvalidatePageMapTLB(pVM); … … 3119 3112 pCur->RamRange.pvR3 = pbCurPages; 3120 3113 pCur->idMmio2 = idMmio2; 3121 pCur->fFlags |= PGMREGMMIO2RANGE_F_MMIO2;3122 3114 3123 3115 uint32_t iDstPage = pCur->RamRange.cb >> X86_PAGE_SHIFT; … … 3198 3190 || pCur->idMmio2 == hMmio2)) 3199 3191 { 3200 Assert(fFlags & PGMREGMMIO2RANGE_F_MMIO2);3201 3192 cFound++; 3202 3193 … … 3233 3224 * Free the memory. 3234 3225 */ 3235 const bool fIsMmio2 = RT_BOOL(fFlags & PGMREGMMIO2RANGE_F_MMIO2);3236 3226 uint32_t const cPages = pCur->cbReal >> PAGE_SHIFT; 3237 if (fIsMmio2) 3238 { 3239 int rc2 = SUPR3PageFreeEx(pCur->pvR3, cPages); 3240 AssertRC(rc2); 3241 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 3242 rc = rc2; 3243 3244 rc2 = MMR3AdjustFixedReservation(pVM, -(int32_t)cPages, pCur->RamRange.pszDesc); 3245 AssertRC(rc2); 3246 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 3247 rc = rc2; 3248 } 3227 int rc2 = SUPR3PageFreeEx(pCur->pvR3, cPages); 3228 AssertRC(rc2); 3229 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 3230 rc = rc2; 3231 3232 rc2 = MMR3AdjustFixedReservation(pVM, -(int32_t)cPages, pCur->RamRange.pszDesc); 3233 AssertRC(rc2); 3234 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 3235 rc = rc2; 3249 3236 3250 3237 /* we're leaking hyper memory here if done at runtime. */ … … 3276 3263 /* update page count stats */ 3277 3264 pVM->pgm.s.cAllPages -= cPages; 3278 if (fIsMmio2) 3279 pVM->pgm.s.cPrivatePages -= cPages; 3280 else 3281 pVM->pgm.s.cPureMmioPages -= cPages; 3265 pVM->pgm.s.cPrivatePages -= cPages; 3282 3266 3283 3267 /* next */ … … 3441 3425 Assert(pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_LAST_CHUNK); /* Only one chunk */ 3442 3426 Assert(pFirstMmio->pvR3 == pFirstMmio->RamRange.pvR3); 3443 Assert(pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 3444 ? pFirstMmio->RamRange.pvR3 != NULL : pFirstMmio->RamRange.pvR3 == NULL); 3427 Assert(pFirstMmio->RamRange.pvR3 != NULL); 3445 3428 3446 3429 #ifdef VBOX_WITH_PGM_NEM_MODE 3447 3430 /* We cannot mix MMIO2 into a RAM range in simplified memory mode because pRam->pvR3 can't point 3448 3431 both at the RAM and MMIO2, so we won't ever write & read from the actual MMIO2 memory if we try. */ 3449 AssertLogRelMsgReturn(!pVM->pgm.s.fNemMode || !(pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2), 3450 ("%s at %RGp-%RGp\n", pFirstMmio->RamRange.pszDesc, GCPhys, GCPhysLast), 3432 AssertLogRelMsgReturn(!pVM->pgm.s.fNemMode, ("%s at %RGp-%RGp\n", pFirstMmio->RamRange.pszDesc, GCPhys, GCPhysLast), 3451 3433 VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE); 3452 3434 #endif … … 3455 3437 AssertRCReturnStmt(rc, PGM_UNLOCK(pVM), rc); 3456 3438 3457 if (pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2) 3458 { 3459 /* replace the pages, freeing all present RAM pages. */ 3460 PPGMPAGE pPageSrc = &pFirstMmio->RamRange.aPages[0]; 3461 PPGMPAGE pPageDst = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; 3462 uint32_t cPagesLeft = pFirstMmio->RamRange.cb >> PAGE_SHIFT; 3463 while (cPagesLeft-- > 0) 3464 { 3465 Assert(PGM_PAGE_IS_MMIO(pPageDst)); 3466 3467 RTHCPHYS const HCPhys = PGM_PAGE_GET_HCPHYS(pPageSrc); 3468 uint32_t const idPage = PGM_PAGE_GET_PAGEID(pPageSrc); 3469 PGM_PAGE_SET_PAGEID(pVM, pPageDst, idPage); 3470 PGM_PAGE_SET_HCPHYS(pVM, pPageDst, HCPhys); 3471 PGM_PAGE_SET_TYPE(pVM, pPageDst, PGMPAGETYPE_MMIO2); 3472 PGM_PAGE_SET_STATE(pVM, pPageDst, PGM_PAGE_STATE_ALLOCATED); 3473 PGM_PAGE_SET_PDE_TYPE(pVM, pPageDst, PGM_PAGE_PDE_TYPE_DONTCARE); 3474 PGM_PAGE_SET_PTE_INDEX(pVM, pPageDst, 0); 3475 PGM_PAGE_SET_TRACKING(pVM, pPageDst, 0); 3476 /* NEM state is set by pgmR3PhysFreePageRange. */ 3477 3478 pVM->pgm.s.cZeroPages--; 3479 GCPhys += PAGE_SIZE; 3480 pPageSrc++; 3481 pPageDst++; 3482 } 3439 /* Replace the pages, freeing all present RAM pages. */ 3440 PPGMPAGE pPageSrc = &pFirstMmio->RamRange.aPages[0]; 3441 PPGMPAGE pPageDst = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; 3442 uint32_t cPagesLeft = pFirstMmio->RamRange.cb >> PAGE_SHIFT; 3443 while (cPagesLeft-- > 0) 3444 { 3445 Assert(PGM_PAGE_IS_MMIO(pPageDst)); 3446 3447 RTHCPHYS const HCPhys = PGM_PAGE_GET_HCPHYS(pPageSrc); 3448 uint32_t const idPage = PGM_PAGE_GET_PAGEID(pPageSrc); 3449 PGM_PAGE_SET_PAGEID(pVM, pPageDst, idPage); 3450 PGM_PAGE_SET_HCPHYS(pVM, pPageDst, HCPhys); 3451 PGM_PAGE_SET_TYPE(pVM, pPageDst, PGMPAGETYPE_MMIO2); 3452 PGM_PAGE_SET_STATE(pVM, pPageDst, PGM_PAGE_STATE_ALLOCATED); 3453 PGM_PAGE_SET_PDE_TYPE(pVM, pPageDst, PGM_PAGE_PDE_TYPE_DONTCARE); 3454 PGM_PAGE_SET_PTE_INDEX(pVM, pPageDst, 0); 3455 PGM_PAGE_SET_TRACKING(pVM, pPageDst, 0); 3456 /* NEM state is set by pgmR3PhysFreePageRange. */ 3457 3458 pVM->pgm.s.cZeroPages--; 3459 GCPhys += PAGE_SIZE; 3460 pPageSrc++; 3461 pPageDst++; 3483 3462 } 3484 3463 … … 3507 3486 int rc = NEMR3NotifyPhysMmioExMapEarly(pVM, pCurMmio->RamRange.GCPhys, 3508 3487 pCurMmio->RamRange.GCPhysLast - pCurMmio->RamRange.GCPhys + 1, 3509 pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 3510 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0, 3511 NULL, pCurMmio->RamRange.pvR3, &u2NemState); 3488 NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2, 3489 NULL /*pvRam*/, pCurMmio->RamRange.pvR3, &u2NemState); 3512 3490 AssertLogRelRCReturnStmt(rc, PGM_UNLOCK(pVM), rc); 3513 3491 } … … 3539 3517 } 3540 3518 3519 #if 0 /* will be reused */ 3541 3520 /* 3542 3521 * Register the access handler if plain MMIO. … … 3597 3576 } 3598 3577 } 3578 #endif 3599 3579 3600 3580 /* … … 3620 3600 { 3621 3601 int rc; 3622 uint32_t fNemFlags = pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0;3602 uint32_t fNemFlags = NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2; 3623 3603 if (fRamExists) 3624 3604 rc = NEMR3NotifyPhysMmioExMapLate(pVM, GCPhys, GCPhysLast - GCPhys + 1, fNemFlags | NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE, … … 3694 3674 AssertReturnStmt(fOldFlags & PGMREGMMIO2RANGE_F_MAPPED, PGM_UNLOCK(pVM), VERR_WRONG_ORDER); 3695 3675 3676 #if 0 /* will be reused */ 3696 3677 /* 3697 3678 * If plain MMIO, we must deregister the handlers first. … … 3711 3692 } 3712 3693 } 3694 #endif 3713 3695 3714 3696 /* … … 3717 3699 int rcRet = VINF_SUCCESS; 3718 3700 #ifdef VBOX_WITH_NATIVE_NEM 3719 uint32_t const fNemFlags = pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0;3701 uint32_t const fNemFlags = NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2; 3720 3702 #endif 3721 3703 if (fOldFlags & PGMREGMMIO2RANGE_F_OVERLAPPING) … … 3738 3720 PPGMPAGE pPageDst = &pRam->aPages[(pFirstMmio->RamRange.GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; 3739 3721 uint32_t cPagesLeft = pFirstMmio->RamRange.cb >> PAGE_SHIFT; 3740 if (fOldFlags & PGMREGMMIO2RANGE_F_MMIO2) 3741 pVM->pgm.s.cZeroPages += cPagesLeft; 3722 pVM->pgm.s.cZeroPages += cPagesLeft; /** @todo not correct for NEM mode */ 3742 3723 3743 3724 #ifdef VBOX_WITH_NATIVE_NEM … … 3912 3893 PGM_UNLOCK(pVM); 3913 3894 AssertReturn(pFirstMmio, VERR_INVALID_HANDLE); 3914 AssertReturn(pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2, VERR_INVALID_HANDLE);3915 3895 AssertReturn(pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_FIRST_CHUNK, VERR_INVALID_HANDLE); 3916 3896 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp
r92007 r92157 644 644 for (PPGMREGMMIO2RANGE pRegMmio = pVM->pgm.s.pRegMmioRangesR3; pRegMmio; pRegMmio = pRegMmio->pNextR3) 645 645 { 646 if (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2) 647 { 648 uint32_t const cPages = pRegMmio->RamRange.cb >> PAGE_SHIFT; 649 PGM_UNLOCK(pVM); 650 651 PPGMLIVESAVEMMIO2PAGE paLSPages = (PPGMLIVESAVEMMIO2PAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, sizeof(PGMLIVESAVEMMIO2PAGE) * cPages); 652 if (!paLSPages) 653 return VERR_NO_MEMORY; 654 for (uint32_t iPage = 0; iPage < cPages; iPage++) 655 { 656 /* Initialize it as a dirty zero page. */ 657 paLSPages[iPage].fDirty = true; 658 paLSPages[iPage].cUnchangedScans = 0; 659 paLSPages[iPage].fZero = true; 660 paLSPages[iPage].u32CrcH1 = PGM_STATE_CRC32_ZERO_HALF_PAGE; 661 paLSPages[iPage].u32CrcH2 = PGM_STATE_CRC32_ZERO_HALF_PAGE; 662 } 663 664 PGM_LOCK_VOID(pVM); 665 pRegMmio->paLSPages = paLSPages; 666 pVM->pgm.s.LiveSave.Mmio2.cDirtyPages += cPages; 667 } 646 uint32_t const cPages = pRegMmio->RamRange.cb >> PAGE_SHIFT; 647 PGM_UNLOCK(pVM); 648 649 PPGMLIVESAVEMMIO2PAGE paLSPages = (PPGMLIVESAVEMMIO2PAGE)MMR3HeapAllocZ(pVM, MM_TAG_PGM, 650 sizeof(PGMLIVESAVEMMIO2PAGE) * cPages); 651 if (!paLSPages) 652 return VERR_NO_MEMORY; 653 for (uint32_t iPage = 0; iPage < cPages; iPage++) 654 { 655 /* Initialize it as a dirty zero page. */ 656 paLSPages[iPage].fDirty = true; 657 paLSPages[iPage].cUnchangedScans = 0; 658 paLSPages[iPage].fZero = true; 659 paLSPages[iPage].u32CrcH1 = PGM_STATE_CRC32_ZERO_HALF_PAGE; 660 paLSPages[iPage].u32CrcH2 = PGM_STATE_CRC32_ZERO_HALF_PAGE; 661 } 662 663 PGM_LOCK_VOID(pVM); 664 pRegMmio->paLSPages = paLSPages; 665 pVM->pgm.s.LiveSave.Mmio2.cDirtyPages += cPages; 668 666 } 669 667 PGM_UNLOCK(pVM); … … 685 683 for (PPGMREGMMIO2RANGE pRegMmio = pVM->pgm.s.pRegMmioRangesR3; pRegMmio; pRegMmio = pRegMmio->pNextR3) 686 684 { 687 if (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2) 688 { 689 pRegMmio->idSavedState = id; 690 SSMR3PutU8(pSSM, id); 691 SSMR3PutStrZ(pSSM, pRegMmio->pDevInsR3->pReg->szName); 692 SSMR3PutU32(pSSM, pRegMmio->pDevInsR3->iInstance); 693 SSMR3PutU8(pSSM, pRegMmio->iRegion); 694 SSMR3PutStrZ(pSSM, pRegMmio->RamRange.pszDesc); 695 int rc = SSMR3PutGCPhys(pSSM, pRegMmio->RamRange.cb); 696 if (RT_FAILURE(rc)) 697 break; 698 id++; 699 } 685 pRegMmio->idSavedState = id; 686 SSMR3PutU8(pSSM, id); 687 SSMR3PutStrZ(pSSM, pRegMmio->pDevInsR3->pReg->szName); 688 SSMR3PutU32(pSSM, pRegMmio->pDevInsR3->iInstance); 689 SSMR3PutU8(pSSM, pRegMmio->iRegion); 690 SSMR3PutStrZ(pSSM, pRegMmio->RamRange.pszDesc); 691 int rc = SSMR3PutGCPhys(pSSM, pRegMmio->RamRange.cb); 692 if (RT_FAILURE(rc)) 693 break; 694 id++; 700 695 } 701 696 PGM_UNLOCK(pVM); … … 717 712 718 713 for (PPGMREGMMIO2RANGE pRegMmio = pVM->pgm.s.pRegMmioRangesR3; pRegMmio; pRegMmio = pRegMmio->pNextR3) 719 if (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2) 720 pRegMmio->idSavedState = UINT8_MAX; 714 pRegMmio->idSavedState = UINT8_MAX; 721 715 722 716 for (;;) … … 732 726 { 733 727 for (PPGMREGMMIO2RANGE pRegMmio = pVM->pgm.s.pRegMmioRangesR3; pRegMmio; pRegMmio = pRegMmio->pNextR3) 734 AssertLogRelMsg( pRegMmio->idSavedState != UINT8_MAX 735 || !(pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2), 736 ("%s\n", pRegMmio->RamRange.pszDesc)); 728 AssertLogRelMsg(pRegMmio->idSavedState != UINT8_MAX, ("%s\n", pRegMmio->RamRange.pszDesc)); 737 729 return VINF_SUCCESS; /* the end */ 738 730 } … … 765 757 && pRegMmio->iRegion == iRegion 766 758 && pRegMmio->pDevInsR3->iInstance == uInstance 767 && (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2)768 759 && !strcmp(pRegMmio->pDevInsR3->pReg->szName, szDevName)) 769 760 { … … 885 876 PGM_LOCK_VOID(pVM); /* paranoia */ 886 877 for (PPGMREGMMIO2RANGE pRegMmio = pVM->pgm.s.pRegMmioRangesR3; pRegMmio; pRegMmio = pRegMmio->pNextR3) 887 if (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2) 888 { 889 PPGMLIVESAVEMMIO2PAGE paLSPages = pRegMmio->paLSPages; 890 uint32_t cPages = pRegMmio->RamRange.cb >> PAGE_SHIFT; 891 PGM_UNLOCK(pVM); 892 893 for (uint32_t iPage = 0; iPage < cPages; iPage++) 894 { 895 uint8_t const *pbPage = (uint8_t const *)pRegMmio->pvR3 + iPage * PAGE_SIZE; 896 pgmR3ScanMmio2Page(pVM, pbPage, &paLSPages[iPage]); 897 } 898 899 PGM_LOCK_VOID(pVM); 900 } 878 { 879 PPGMLIVESAVEMMIO2PAGE paLSPages = pRegMmio->paLSPages; 880 uint32_t cPages = pRegMmio->RamRange.cb >> PAGE_SHIFT; 881 PGM_UNLOCK(pVM); 882 883 for (uint32_t iPage = 0; iPage < cPages; iPage++) 884 { 885 uint8_t const *pbPage = (uint8_t const *)pRegMmio->pvR3 + iPage * PAGE_SIZE; 886 pgmR3ScanMmio2Page(pVM, pbPage, &paLSPages[iPage]); 887 } 888 889 PGM_LOCK_VOID(pVM); 890 } 901 891 PGM_UNLOCK(pVM); 902 892 … … 928 918 pRegMmio && RT_SUCCESS(rc); 929 919 pRegMmio = pRegMmio->pNextR3) 930 if (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2) 920 { 921 PPGMLIVESAVEMMIO2PAGE paLSPages = pRegMmio->paLSPages; 922 uint8_t const *pbPage = (uint8_t const *)pRegMmio->RamRange.pvR3; 923 uint32_t cPages = pRegMmio->RamRange.cb >> PAGE_SHIFT; 924 uint32_t iPageLast = cPages; 925 for (uint32_t iPage = 0; iPage < cPages; iPage++, pbPage += PAGE_SIZE) 931 926 { 932 PPGMLIVESAVEMMIO2PAGE paLSPages = pRegMmio->paLSPages; 933 uint8_t const *pbPage = (uint8_t const *)pRegMmio->RamRange.pvR3; 934 uint32_t cPages = pRegMmio->RamRange.cb >> PAGE_SHIFT; 935 uint32_t iPageLast = cPages; 936 for (uint32_t iPage = 0; iPage < cPages; iPage++, pbPage += PAGE_SIZE) 927 uint8_t u8Type; 928 if (!fLiveSave) 929 u8Type = ASMMemIsZeroPage(pbPage) ? PGM_STATE_REC_MMIO2_ZERO : PGM_STATE_REC_MMIO2_RAW; 930 else 937 931 { 938 uint8_t u8Type; 939 if (!fLiveSave) 940 u8Type = ASMMemIsZeroPage(pbPage) ? PGM_STATE_REC_MMIO2_ZERO : PGM_STATE_REC_MMIO2_RAW; 941 else 932 /* Try figure if it's a clean page, compare the SHA-1 to be really sure. */ 933 if ( !paLSPages[iPage].fDirty 934 && !pgmR3ScanMmio2Page(pVM, pbPage, &paLSPages[iPage])) 942 935 { 943 /* Try figure if it's a clean page, compare the SHA-1 to be really sure. */ 944 if ( !paLSPages[iPage].fDirty 945 && !pgmR3ScanMmio2Page(pVM, pbPage, &paLSPages[iPage])) 946 { 947 if (paLSPages[iPage].fZero) 948 continue; 949 950 uint8_t abSha1Hash[RTSHA1_HASH_SIZE]; 951 RTSha1(pbPage, PAGE_SIZE, abSha1Hash); 952 if (!memcmp(abSha1Hash, paLSPages[iPage].abSha1Saved, sizeof(abSha1Hash))) 953 continue; 954 } 955 u8Type = paLSPages[iPage].fZero ? PGM_STATE_REC_MMIO2_ZERO : PGM_STATE_REC_MMIO2_RAW; 956 pVM->pgm.s.LiveSave.cSavedPages++; 936 if (paLSPages[iPage].fZero) 937 continue; 938 939 uint8_t abSha1Hash[RTSHA1_HASH_SIZE]; 940 RTSha1(pbPage, PAGE_SIZE, abSha1Hash); 941 if (!memcmp(abSha1Hash, paLSPages[iPage].abSha1Saved, sizeof(abSha1Hash))) 942 continue; 957 943 } 958 959 if (iPage != 0 && iPage == iPageLast + 1) 960 rc = SSMR3PutU8(pSSM, u8Type); 961 else 962 { 963 SSMR3PutU8(pSSM, u8Type | PGM_STATE_REC_FLAG_ADDR); 964 SSMR3PutU8(pSSM, pRegMmio->idSavedState); 965 rc = SSMR3PutU32(pSSM, iPage); 966 } 967 if (u8Type == PGM_STATE_REC_MMIO2_RAW) 968 rc = SSMR3PutMem(pSSM, pbPage, PAGE_SIZE); 969 if (RT_FAILURE(rc)) 970 break; 971 iPageLast = iPage; 944 u8Type = paLSPages[iPage].fZero ? PGM_STATE_REC_MMIO2_ZERO : PGM_STATE_REC_MMIO2_RAW; 945 pVM->pgm.s.LiveSave.cSavedPages++; 972 946 } 947 948 if (iPage != 0 && iPage == iPageLast + 1) 949 rc = SSMR3PutU8(pSSM, u8Type); 950 else 951 { 952 SSMR3PutU8(pSSM, u8Type | PGM_STATE_REC_FLAG_ADDR); 953 SSMR3PutU8(pSSM, pRegMmio->idSavedState); 954 rc = SSMR3PutU32(pSSM, iPage); 955 } 956 if (u8Type == PGM_STATE_REC_MMIO2_RAW) 957 rc = SSMR3PutMem(pSSM, pbPage, PAGE_SIZE); 958 if (RT_FAILURE(rc)) 959 break; 960 iPageLast = iPage; 973 961 } 962 } 974 963 PGM_UNLOCK(pVM); 975 964 } … … 986 975 pRegMmio && RT_SUCCESS(rc); 987 976 pRegMmio = pRegMmio->pNextR3) 988 if (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2) 977 { 978 PPGMLIVESAVEMMIO2PAGE paLSPages = pRegMmio->paLSPages; 979 uint8_t const *pbPage = (uint8_t const *)pRegMmio->RamRange.pvR3; 980 uint32_t cPages = pRegMmio->RamRange.cb >> PAGE_SHIFT; 981 uint32_t iPageLast = cPages; 982 PGM_UNLOCK(pVM); 983 984 for (uint32_t iPage = 0; iPage < cPages; iPage++, pbPage += PAGE_SIZE) 989 985 { 990 PPGMLIVESAVEMMIO2PAGE paLSPages = pRegMmio->paLSPages; 991 uint8_t const *pbPage = (uint8_t const *)pRegMmio->RamRange.pvR3; 992 uint32_t cPages = pRegMmio->RamRange.cb >> PAGE_SHIFT; 993 uint32_t iPageLast = cPages; 994 PGM_UNLOCK(pVM); 995 996 for (uint32_t iPage = 0; iPage < cPages; iPage++, pbPage += PAGE_SIZE) 986 /* Skip clean pages and pages which hasn't quiesced. */ 987 if (!paLSPages[iPage].fDirty) 988 continue; 989 if (paLSPages[iPage].cUnchangedScans < 3) 990 continue; 991 if (pgmR3ScanMmio2Page(pVM, pbPage, &paLSPages[iPage])) 992 continue; 993 994 /* Save it. */ 995 bool const fZero = paLSPages[iPage].fZero; 996 uint8_t abPage[PAGE_SIZE]; 997 if (!fZero) 997 998 { 998 /* Skip clean pages and pages which hasn't quiesced. */ 999 if (!paLSPages[iPage].fDirty) 1000 continue; 1001 if (paLSPages[iPage].cUnchangedScans < 3) 1002 continue; 1003 if (pgmR3ScanMmio2Page(pVM, pbPage, &paLSPages[iPage])) 1004 continue; 1005 1006 /* Save it. */ 1007 bool const fZero = paLSPages[iPage].fZero; 1008 uint8_t abPage[PAGE_SIZE]; 1009 if (!fZero) 1010 { 1011 memcpy(abPage, pbPage, PAGE_SIZE); 1012 RTSha1(abPage, PAGE_SIZE, paLSPages[iPage].abSha1Saved); 1013 } 1014 1015 uint8_t u8Type = paLSPages[iPage].fZero ? PGM_STATE_REC_MMIO2_ZERO : PGM_STATE_REC_MMIO2_RAW; 1016 if (iPage != 0 && iPage == iPageLast + 1) 1017 rc = SSMR3PutU8(pSSM, u8Type); 1018 else 1019 { 1020 SSMR3PutU8(pSSM, u8Type | PGM_STATE_REC_FLAG_ADDR); 1021 SSMR3PutU8(pSSM, pRegMmio->idSavedState); 1022 rc = SSMR3PutU32(pSSM, iPage); 1023 } 1024 if (u8Type == PGM_STATE_REC_MMIO2_RAW) 1025 rc = SSMR3PutMem(pSSM, abPage, PAGE_SIZE); 1026 if (RT_FAILURE(rc)) 1027 break; 1028 1029 /* Housekeeping. */ 1030 paLSPages[iPage].fDirty = false; 1031 pVM->pgm.s.LiveSave.Mmio2.cDirtyPages--; 1032 pVM->pgm.s.LiveSave.Mmio2.cReadyPages++; 1033 if (u8Type == PGM_STATE_REC_MMIO2_ZERO) 1034 pVM->pgm.s.LiveSave.Mmio2.cZeroPages++; 1035 pVM->pgm.s.LiveSave.cSavedPages++; 1036 iPageLast = iPage; 999 memcpy(abPage, pbPage, PAGE_SIZE); 1000 RTSha1(abPage, PAGE_SIZE, paLSPages[iPage].abSha1Saved); 1037 1001 } 1038 1002 1039 PGM_LOCK_VOID(pVM); 1003 uint8_t u8Type = paLSPages[iPage].fZero ? PGM_STATE_REC_MMIO2_ZERO : PGM_STATE_REC_MMIO2_RAW; 1004 if (iPage != 0 && iPage == iPageLast + 1) 1005 rc = SSMR3PutU8(pSSM, u8Type); 1006 else 1007 { 1008 SSMR3PutU8(pSSM, u8Type | PGM_STATE_REC_FLAG_ADDR); 1009 SSMR3PutU8(pSSM, pRegMmio->idSavedState); 1010 rc = SSMR3PutU32(pSSM, iPage); 1011 } 1012 if (u8Type == PGM_STATE_REC_MMIO2_RAW) 1013 rc = SSMR3PutMem(pSSM, abPage, PAGE_SIZE); 1014 if (RT_FAILURE(rc)) 1015 break; 1016 1017 /* Housekeeping. */ 1018 paLSPages[iPage].fDirty = false; 1019 pVM->pgm.s.LiveSave.Mmio2.cDirtyPages--; 1020 pVM->pgm.s.LiveSave.Mmio2.cReadyPages++; 1021 if (u8Type == PGM_STATE_REC_MMIO2_ZERO) 1022 pVM->pgm.s.LiveSave.Mmio2.cZeroPages++; 1023 pVM->pgm.s.LiveSave.cSavedPages++; 1024 iPageLast = iPage; 1040 1025 } 1026 1027 PGM_LOCK_VOID(pVM); 1028 } 1041 1029 PGM_UNLOCK(pVM); 1042 1030 } … … 1059 1047 PGM_LOCK_VOID(pVM); 1060 1048 for (PPGMREGMMIO2RANGE pRegMmio = pVM->pgm.s.pRegMmioRangesR3; pRegMmio; pRegMmio = pRegMmio->pNextR3) 1061 if (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2) 1062 { 1063 void *pvMmio2ToFree = pRegMmio->paLSPages; 1064 if (pvMmio2ToFree) 1065 { 1066 pRegMmio->paLSPages = NULL; 1067 PGM_UNLOCK(pVM); 1068 MMR3HeapFree(pvMmio2ToFree); 1069 PGM_LOCK_VOID(pVM); 1070 } 1071 } 1049 { 1050 void *pvMmio2ToFree = pRegMmio->paLSPages; 1051 if (pvMmio2ToFree) 1052 { 1053 pRegMmio->paLSPages = NULL; 1054 PGM_UNLOCK(pVM); 1055 MMR3HeapFree(pvMmio2ToFree); 1056 PGM_LOCK_VOID(pVM); 1057 } 1058 } 1072 1059 PGM_UNLOCK(pVM); 1073 1060 } … … 2787 2774 { 2788 2775 for (pRegMmio = pVM->pgm.s.pRegMmioRangesR3; pRegMmio; pRegMmio = pRegMmio->pNextR3) 2789 if ( pRegMmio->idSavedState == id 2790 && (pRegMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2)) 2776 if (pRegMmio->idSavedState == id) 2791 2777 break; 2792 2778 AssertLogRelMsgReturn(pRegMmio, ("id=%#u iPage=%#x\n", id, iPage), VERR_PGM_SAVED_MMIO2_RANGE_NOT_FOUND);
Note:
See TracChangeset
for help on using the changeset viewer.