Changeset 23415 in vbox
- Timestamp:
- Sep 29, 2009 3:40:39 PM (15 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r23307 r23415 54 54 ifdef VBOX_WITH_PDM_ASYNC_COMPLETION 55 55 VMMR3_DEFS += VBOX_WITH_PDM_ASYNC_COMPLETION 56 endif 57 ifdef VBOX_WITH_LIVE_MIGRATION 58 VMMR3_DEFS += VBOX_WITH_LIVE_MIGRATION 56 59 endif 57 60 VMMR3_DEFS.darwin = VMM_R0_SWITCH_STACK -
trunk/src/VBox/VMM/PGMInternal.h
r23398 r23415 687 687 (pPage)->fSomethingElse = 0; \ 688 688 (pPage)->idPageX = (_idPage); \ 689 /*(pPage)->u3Type = (_uType); - later */ \ 690 PGM_PAGE_SET_TYPE(pPage, _uType); \ 689 (pPage)->u3Type = (_uType); \ 691 690 (pPage)->u29B = 0; \ 692 691 } while (0) … … 697 696 */ 698 697 #define PGM_PAGE_INIT_ZERO(pPage, pVM, _uType) \ 699 PGM_PAGE_INIT(pPage, (pVM)->pgm.s.HCPhysZeroPg, NIL_GMM_PAGEID, (_uType), PGM_PAGE_STATE_ZERO)700 /** Temporary hack. Replaced by PGM_PAGE_INIT_ZERO once the old code is kicked out. */701 # define PGM_PAGE_INIT_ZERO_REAL(pPage, pVM, _uType) \702 698 PGM_PAGE_INIT(pPage, (pVM)->pgm.s.HCPhysZeroPg, NIL_GMM_PAGEID, (_uType), PGM_PAGE_STATE_ZERO) 703 699 … … 1192 1188 * 1193 1189 * There are a few reason why we need to keep track of these 1194 * registrations. One of them is the deregistration & cleanup1195 * stuff, while another is that the PGMRAMRANGE associated with1196 * such a region mayhave to be removed from the ram range list.1197 * 1198 * Overlapping with a RAM range has to be 100% or none at all. The1199 * pages in the existing RAM range must not be ROM nor MMIO. A guru1200 * meditation will be raised if a partial overlap or an overlap of1201 * ROM pages is encountered. On an overlap we will free all the1202 * existing RAM pages andput in the ram range pages instead.1190 * registrations. One of them is the deregistration & cleanup stuff, 1191 * while another is that the PGMRAMRANGE associated with such a region may 1192 * have to be removed from the ram range list. 1193 * 1194 * Overlapping with a RAM range has to be 100% or none at all. The pages 1195 * in the existing RAM range must not be ROM nor MMIO. A guru meditation 1196 * will be raised if a partial overlap or an overlap of ROM pages is 1197 * encountered. On an overlap we will free all the existing RAM pages and 1198 * put in the ram range pages instead. 1203 1199 */ 1204 1200 typedef struct PGMMMIO2RANGE … … 2608 2604 /** The number of monitored pages. */ 2609 2605 uint32_t cMonitoredPages; 2606 /** Indicates that a live save operation is active. */ 2607 bool fActive; 2608 /** Padding. */ 2609 bool afReserved[7]; 2610 2610 } LiveSave; 2611 2611 -
trunk/src/VBox/VMM/PGMPhys.cpp
r23398 r23415 1335 1335 uint32_t iPage = cPages; 1336 1336 while (iPage-- > 0) 1337 PGM_PAGE_INIT_ZERO _REAL(&pNew->aPages[iPage], pVM, PGMPAGETYPE_MMIO);1337 PGM_PAGE_INIT_ZERO(&pNew->aPages[iPage], pVM, PGMPAGETYPE_MMIO); 1338 1338 Assert(PGM_PAGE_GET_TYPE(&pNew->aPages[0]) == PGMPAGETYPE_MMIO); 1339 1339 … … 2354 2354 PPGMROMPAGE pPage = &pRomNew->aPages[iPage]; 2355 2355 pPage->enmProt = PGMROMPROT_READ_ROM_WRITE_IGNORE; 2356 PGM_PAGE_INIT_ZERO _REAL(&pPage->Shadow, pVM, PGMPAGETYPE_ROM_SHADOW);2356 PGM_PAGE_INIT_ZERO(&pPage->Shadow, pVM, PGMPAGETYPE_ROM_SHADOW); 2357 2357 } 2358 2358 -
trunk/src/VBox/VMM/PGMSavedState.cpp
r23398 r23415 176 176 177 177 /** 178 * Save zero indicator + bits for the specified page.179 *180 * @returns VBox status code, errors are logged/asserted before returning.181 * @param pVM The VM handle.182 * @param pSSH The saved state handle.183 * @param pPage The page to save.184 * @param GCPhys The address of the page.185 * @param pRam The ram range (for error logging).186 */187 static int pgmR3SavePage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)188 {189 int rc;190 if (PGM_PAGE_IS_ZERO(pPage))191 rc = SSMR3PutU8(pSSM, 0);192 else193 {194 void const *pvPage;195 rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvPage);196 AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s\n", pPage, GCPhys, pRam->pszDesc), rc);197 198 SSMR3PutU8(pSSM, 1);199 rc = SSMR3PutMem(pSSM, pvPage, PAGE_SIZE);200 }201 return rc;202 }203 204 205 /**206 * Save a shadowed ROM page.207 *208 * Format: Type, protection, and two pages with zero indicators.209 *210 * @returns VBox status code, errors are logged/asserted before returning.211 * @param pVM The VM handle.212 * @param pSSH The saved state handle.213 * @param pPage The page to save.214 * @param GCPhys The address of the page.215 * @param pRam The ram range (for error logging).216 */217 static int pgmR3SaveShadowedRomPage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)218 {219 /* Need to save both pages and the current state. */220 PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, GCPhys);221 AssertLogRelMsgReturn(pRomPage, ("GCPhys=%RGp %s\n", GCPhys, pRam->pszDesc), VERR_INTERNAL_ERROR);222 223 SSMR3PutU8(pSSM, PGMPAGETYPE_ROM_SHADOW);224 SSMR3PutU8(pSSM, pRomPage->enmProt);225 226 int rc = pgmR3SavePage(pVM, pSSM, pPage, GCPhys, pRam);227 if (RT_SUCCESS(rc))228 {229 PPGMPAGE pPagePassive = PGMROMPROT_IS_ROM(pRomPage->enmProt) ? &pRomPage->Shadow : &pRomPage->Virgin;230 rc = pgmR3SavePage(pVM, pSSM, pPagePassive, GCPhys, pRam);231 }232 return rc;233 }234 235 236 /**237 178 * Prepare for a live save operation. 238 179 * … … 267 208 pVM->pgm.s.LiveSave.cDirtyPages = 0; 268 209 pVM->pgm.s.LiveSave.cMmioPages = 0; 210 pVM->pgm.s.LiveSave.fActive = true; 269 211 270 212 /* … … 512 454 /* Process the page. */ 513 455 if (paLSPages[iPage].fMmio) 456 continue; 457 switch (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage])) 514 458 { 515 switch (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]))459 case PGMPAGETYPE_RAM: 516 460 { 517 case PGMPAGETYPE_RAM:461 switch (PGM_PAGE_GET_STATE(&pCur->aPages[iPage])) 518 462 { 519 switch (PGM_PAGE_GET_STATE(&pCur->aPages[iPage])) 520 { 521 case PGM_PAGE_STATE_ALLOCATED: 522 /** @todo Optimize this: Don't always re-enable write 523 * monitoring if the page is known to be very busy. */ 524 if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage])) 525 { 526 Assert(paLSPages[iPage].fWriteMonitored); 527 PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]); 528 Assert(pVM->pgm.s.cWrittenToPages > 0); 529 pVM->pgm.s.cWrittenToPages--; 530 } 531 else 532 { 533 Assert(!paLSPages[iPage].fWriteMonitored); 534 pVM->pgm.s.LiveSave.cMonitoredPages++; 535 } 536 537 if (!paLSPages[iPage].fDirty) 538 { 539 pVM->pgm.s.LiveSave.cDirtyPages++; 540 pVM->pgm.s.LiveSave.cReadyPages--; 541 if (++paLSPages[iPage].cDirtied > PGMLIVSAVEPAGE_MAX_DIRTIED) 542 paLSPages[iPage].cDirtied = PGMLIVSAVEPAGE_MAX_DIRTIED; 543 } 544 545 PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_WRITE_MONITORED); 546 pVM->pgm.s.cMonitoredPages++; 547 paLSPages[iPage].fWriteMonitored = 1; 548 paLSPages[iPage].fWriteMonitoredJustNow = 1; 549 paLSPages[iPage].fDirty = 1; 550 paLSPages[iPage].fZero = 0; 551 paLSPages[iPage].fShared = 0; 552 break; 553 554 case PGM_PAGE_STATE_WRITE_MONITORED: 463 case PGM_PAGE_STATE_ALLOCATED: 464 /** @todo Optimize this: Don't always re-enable write 465 * monitoring if the page is known to be very busy. */ 466 if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage])) 467 { 555 468 Assert(paLSPages[iPage].fWriteMonitored); 556 paLSPages[iPage].fWriteMonitoredJustNow = 0; 557 break; 558 559 case PGM_PAGE_STATE_ZERO: 560 if (!paLSPages[iPage].fZero) 561 { 562 paLSPages[iPage].fZero = 1; 563 paLSPages[iPage].fShared = 0; 564 if (!paLSPages[iPage].fDirty) 565 { 566 paLSPages[iPage].fDirty = 1; 567 pVM->pgm.s.LiveSave.cReadyPages--; 568 pVM->pgm.s.LiveSave.cDirtyPages++; 569 } 570 } 571 break; 572 573 case PGM_PAGE_STATE_SHARED: 574 if (!paLSPages[iPage].fShared) 575 { 576 paLSPages[iPage].fZero = 0; 577 paLSPages[iPage].fShared = 1; 578 if (!paLSPages[iPage].fDirty) 579 { 580 paLSPages[iPage].fDirty = 1; 581 pVM->pgm.s.LiveSave.cReadyPages--; 582 pVM->pgm.s.LiveSave.cDirtyPages++; 583 } 584 } 585 break; 586 } 587 break; 588 } 589 590 /* All writes to the shadow page are intercepted. */ 591 case PGMPAGETYPE_ROM_SHADOW: /* (The shadow page is active.) */ 592 case PGMPAGETYPE_ROM: /* (The virgin page is active.) */ 593 { 594 PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT)); 595 if (!pRomPage->LiveSave.fDone) 596 { 597 if (pRomPage->LiveSave.fWrittenTo) 469 PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]); 470 Assert(pVM->pgm.s.cWrittenToPages > 0); 471 pVM->pgm.s.cWrittenToPages--; 472 } 473 else 598 474 { 599 pRomPage->LiveSave.fWrittenTo = false; 475 Assert(!paLSPages[iPage].fWriteMonitored); 476 pVM->pgm.s.LiveSave.cMonitoredPages++; 477 } 478 479 if (!paLSPages[iPage].fDirty) 480 { 481 pVM->pgm.s.LiveSave.cDirtyPages++; 482 pVM->pgm.s.LiveSave.cReadyPages--; 483 if (++paLSPages[iPage].cDirtied > PGMLIVSAVEPAGE_MAX_DIRTIED) 484 paLSPages[iPage].cDirtied = PGMLIVSAVEPAGE_MAX_DIRTIED; 485 } 486 487 PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_WRITE_MONITORED); 488 pVM->pgm.s.cMonitoredPages++; 489 paLSPages[iPage].fWriteMonitored = 1; 490 paLSPages[iPage].fWriteMonitoredJustNow = 1; 491 paLSPages[iPage].fDirty = 1; 492 paLSPages[iPage].fZero = 0; 493 paLSPages[iPage].fShared = 0; 494 break; 495 496 case PGM_PAGE_STATE_WRITE_MONITORED: 497 Assert(paLSPages[iPage].fWriteMonitored); 498 paLSPages[iPage].fWriteMonitoredJustNow = 0; 499 break; 500 501 case PGM_PAGE_STATE_ZERO: 502 if (!paLSPages[iPage].fZero) 503 { 504 paLSPages[iPage].fZero = 1; 505 paLSPages[iPage].fShared = 0; 600 506 if (!paLSPages[iPage].fDirty) 601 507 { … … 604 510 pVM->pgm.s.LiveSave.cDirtyPages++; 605 511 } 606 paLSPages[iPage].fWriteMonitoredJustNow = 1;607 512 } 608 else 609 paLSPages[iPage].fWriteMonitoredJustNow = 0; 610 paLSPages[iPage].fWriteMonitored = 1; 513 break; 514 515 case PGM_PAGE_STATE_SHARED: 516 if (!paLSPages[iPage].fShared) 517 { 518 paLSPages[iPage].fZero = 0; 519 paLSPages[iPage].fShared = 1; 520 if (!paLSPages[iPage].fDirty) 521 { 522 paLSPages[iPage].fDirty = 1; 523 pVM->pgm.s.LiveSave.cReadyPages--; 524 pVM->pgm.s.LiveSave.cDirtyPages++; 525 } 526 } 527 break; 528 } 529 break; 530 } 531 532 /* All writes to the shadow page are intercepted. */ 533 case PGMPAGETYPE_ROM_SHADOW: /* (The shadow page is active.) */ 534 case PGMPAGETYPE_ROM: /* (The virgin page is active.) */ 535 { 536 PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT)); 537 if (!pRomPage->LiveSave.fDone) 538 { 539 if (pRomPage->LiveSave.fWrittenTo) 540 { 541 pRomPage->LiveSave.fWrittenTo = false; 542 if (!paLSPages[iPage].fDirty) 543 { 544 paLSPages[iPage].fDirty = 1; 545 pVM->pgm.s.LiveSave.cReadyPages--; 546 pVM->pgm.s.LiveSave.cDirtyPages++; 547 } 548 paLSPages[iPage].fWriteMonitoredJustNow = 1; 611 549 } 612 550 else 551 paLSPages[iPage].fWriteMonitoredJustNow = 0; 552 paLSPages[iPage].fWriteMonitored = 1; 553 } 554 else 555 { 556 Assert(PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) == PGMPAGETYPE_ROM); 557 Assert(!paLSPages[iPage].fDirty); 558 } 559 break; 560 } 561 562 default: 563 AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage])); 564 case PGMPAGETYPE_MMIO2: 565 case PGMPAGETYPE_MMIO2_ALIAS_MMIO: 566 case PGMPAGETYPE_MMIO: 567 if (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) == PGMPAGETYPE_MMIO) 568 { 569 paLSPages[iPage].fZero = 0; 570 paLSPages[iPage].fDirty = 1; 571 paLSPages[iPage].fMmio = 1; 572 } 573 else 574 { 575 paLSPages[iPage].fZero = 1; 576 paLSPages[iPage].fDirty = 1; 577 paLSPages[iPage].fMmio = 1; 578 } 579 if (paLSPages[iPage].fWriteMonitored) 580 { 581 if (RT_UNLIKELY(PGM_PAGE_GET_STATE(&pCur->aPages[iPage]) == PGM_PAGE_STATE_WRITE_MONITORED)) 613 582 { 614 Assert(PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) == PGMPAGETYPE_ROM); 615 Assert(!paLSPages[iPage].fDirty); 583 AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage])); /* shouldn't happen. */ 584 PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_ALLOCATED); 585 Assert(pVM->pgm.s.cMonitoredPages > 0); 586 pVM->pgm.s.cMonitoredPages--; 616 587 } 617 break; 588 if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage])) 589 { 590 PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]); 591 Assert(pVM->pgm.s.cWrittenToPages > 0); 592 pVM->pgm.s.cWrittenToPages--; 593 } 594 pVM->pgm.s.LiveSave.cMonitoredPages--; 618 595 } 619 620 default: 621 AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage])); 622 case PGMPAGETYPE_MMIO2: 623 case PGMPAGETYPE_MMIO2_ALIAS_MMIO: 624 case PGMPAGETYPE_MMIO: 625 if (PGM_PAGE_GET_TYPE(&pCur->aPages[iPage]) == PGMPAGETYPE_MMIO) 626 { 627 paLSPages[iPage].fZero = 0; 628 paLSPages[iPage].fDirty = 1; 629 paLSPages[iPage].fMmio = 1; 630 } 631 else 632 { 633 paLSPages[iPage].fZero = 1; 634 paLSPages[iPage].fDirty = 1; 635 paLSPages[iPage].fMmio = 1; 636 } 637 if (paLSPages[iPage].fWriteMonitored) 638 { 639 if (RT_UNLIKELY(PGM_PAGE_GET_STATE(&pCur->aPages[iPage]) == PGM_PAGE_STATE_WRITE_MONITORED)) 640 { 641 AssertMsgFailed(("%R[pgmpage]", &pCur->aPages[iPage])); /* shouldn't happen. */ 642 PGM_PAGE_SET_STATE(&pCur->aPages[iPage], PGM_PAGE_STATE_ALLOCATED); 643 Assert(pVM->pgm.s.cMonitoredPages > 0); 644 pVM->pgm.s.cMonitoredPages--; 645 } 646 if (PGM_PAGE_IS_WRITTEN_TO(&pCur->aPages[iPage])) 647 { 648 PGM_PAGE_CLEAR_WRITTEN_TO(&pCur->aPages[iPage]); 649 Assert(pVM->pgm.s.cWrittenToPages > 0); 650 pVM->pgm.s.cWrittenToPages--; 651 } 652 pVM->pgm.s.LiveSave.cMonitoredPages--; 653 } 654 pVM->pgm.s.LiveSave.cMmioPages++; 655 break; 656 } 657 } 596 pVM->pgm.s.LiveSave.cMmioPages++; 597 break; 598 } /* switch on page type */ 658 599 } /* for each page in range */ 659 600 … … 868 809 } 869 810 811 #ifdef VBOX_WITH_LIVE_MIGRATION 812 813 /** 814 * Worker for pgmR3SaveExec that saves the memory. 815 * 816 * @returns VBox status code. 817 * 818 * @param pVM The VM handle. 819 * @param pSSM The SSM handle. 820 * @param fLiveSave Whether we're in a live save or not. 821 * 822 */ 823 static int pgmR3SaveExecMemory(PVM pVM, PSSMHANDLE pSSM, bool fLiveSave) 824 { 825 /* 826 * Save all ROM pages. 827 */ 828 829 /* 830 * Save all MMIO2 pages (including unmapped ones). 831 */ 832 833 /* 834 * Save all normal RAM pages. 835 */ 836 return VINF_SUCCESS; 837 } 838 839 #else /* !VBOX_WITH_LIVE_MIGRATION */ 840 841 /** 842 * Save zero indicator + bits for the specified page. 843 * 844 * @returns VBox status code, errors are logged/asserted before returning. 845 * @param pVM The VM handle. 846 * @param pSSH The saved state handle. 847 * @param pPage The page to save. 848 * @param GCPhys The address of the page. 849 * @param pRam The ram range (for error logging). 850 */ 851 static int pgmR3SavePage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam) 852 { 853 int rc; 854 if (PGM_PAGE_IS_ZERO(pPage)) 855 rc = SSMR3PutU8(pSSM, 0); 856 else 857 { 858 void const *pvPage; 859 rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, GCPhys, &pvPage); 860 AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s\n", pPage, GCPhys, pRam->pszDesc), rc); 861 862 SSMR3PutU8(pSSM, 1); 863 rc = SSMR3PutMem(pSSM, pvPage, PAGE_SIZE); 864 } 865 return rc; 866 } 867 868 869 /** 870 * Save a shadowed ROM page. 871 * 872 * Format: Type, protection, and two pages with zero indicators. 873 * 874 * @returns VBox status code, errors are logged/asserted before returning. 875 * @param pVM The VM handle. 876 * @param pSSH The saved state handle. 877 * @param pPage The page to save. 878 * @param GCPhys The address of the page. 879 * @param pRam The ram range (for error logging). 880 */ 881 static int pgmR3SaveShadowedRomPage(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam) 882 { 883 /* Need to save both pages and the current state. */ 884 PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, GCPhys); 885 AssertLogRelMsgReturn(pRomPage, ("GCPhys=%RGp %s\n", GCPhys, pRam->pszDesc), VERR_INTERNAL_ERROR); 886 887 SSMR3PutU8(pSSM, PGMPAGETYPE_ROM_SHADOW); 888 SSMR3PutU8(pSSM, pRomPage->enmProt); 889 890 int rc = pgmR3SavePage(pVM, pSSM, pPage, GCPhys, pRam); 891 if (RT_SUCCESS(rc)) 892 { 893 PPGMPAGE pPagePassive = PGMROMPROT_IS_ROM(pRomPage->enmProt) ? &pRomPage->Shadow : &pRomPage->Virgin; 894 rc = pgmR3SavePage(pVM, pSSM, pPagePassive, GCPhys, pRam); 895 } 896 return rc; 897 } 898 899 #endif /* !VBOX_WITH_LIVE_MIGRATION */ 870 900 871 901 /** … … 912 942 rc = SSMR3PutU32(pSSM, ~0); /* terminator. */ 913 943 944 #ifdef VBOX_WITH_LIVE_MIGRATION 945 /* 946 * Save the (remainder of the) memory. 947 */ 948 if (RT_SUCCESS(rc)) 949 { 950 if (pVM->pgm.s.LiveSave.fActive) 951 pgmR3LiveExecPart1(pVM); 952 rc = pgmR3SaveExecMemory(pVM, pSSM, pVM->pgm.s.LiveSave.fActive); 953 } 954 955 #else /* !VBOX_WITH_LIVE_MIGRATION */ 914 956 /* 915 957 * Ram ranges and the memory they describe. … … 938 980 uint8_t uType = PGM_PAGE_GET_TYPE(pPage); 939 981 940 if (uType == PGMPAGETYPE_ROM_SHADOW) 982 if (uType == PGMPAGETYPE_ROM_SHADOW) /** @todo This isn't right, but it doesn't currently matter. */ 941 983 rc = pgmR3SaveShadowedRomPage(pVM, pSSM, pPage, GCPhysPage, pRam); 942 984 else if (uType == PGMPAGETYPE_MMIO2_ALIAS_MMIO) … … 958 1000 } 959 1001 1002 rc = SSMR3PutU32(pSSM, ~0); /* terminator. */ 1003 #endif /* !VBOX_WITH_LIVE_MIGRATION */ 1004 960 1005 pgmUnlock(pVM); 961 return SSMR3PutU32(pSSM, ~0); /* terminator. */1006 return rc; 962 1007 } 963 1008 … … 1019 1064 } while (pCur); 1020 1065 1066 pVM->pgm.s.LiveSave.fActive = false; 1067 1021 1068 /** @todo this is blindly assuming that we're the only user of write 1022 1069 * monitoring. Fix this when more users are added. */ … … 1032 1079 1033 1080 /** 1034 * Worker for pgmR3Load and pgmR3LoadLocked.1081 * Prepare state load operation. 1035 1082 * 1036 1083 * @returns VBox status code. 1037 * 1038 * @param pVM The VM handle. 1039 * @param pSSM The SSM handle. 1040 * @param uVersion The saved state version. 1041 */ 1042 static int pgmR3LoadLockedMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) 1043 { 1044 /* 1045 * Process page records until we hit the terminator. 1046 */ 1047 PPGMRAMRANGE pRamHint = NULL; 1048 RTGCPHYS GCPhysLast = NIL_RTGCPHYS; 1049 for (;;) 1050 { 1051 /* Get the record type and flags. */ 1052 uint8_t u8; 1053 int rc = SSMR3GetU8(pSSM, &u8); 1054 if (RT_FAILURE(rc)) 1055 return rc; 1056 if (u8 == PGM_STATE_REC_END) 1057 return VINF_SUCCESS; 1058 AssertLogRelMsgReturn((u8 & ~PGM_STATE_REC_FLAG_ADDR) <= PGM_STATE_REC_LAST, ("%#x\n", u8), VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 1059 1060 /* Get the address. */ 1061 RTGCPHYS GCPhys; 1062 if (!(u8 & PGM_STATE_REC_FLAG_ADDR)) 1063 { 1064 AssertLogRelReturn(GCPhysLast != NIL_RTGCPHYS, VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 1065 GCPhys = GCPhysLast + PAGE_SIZE; 1066 } 1067 else 1068 { 1069 rc = SSMR3GetGCPhys(pSSM, &GCPhys); 1070 if (RT_FAILURE(rc)) 1071 return rc; 1072 AssertLogRelMsgReturn(GCPhys & PAGE_OFFSET_MASK, ("%RGp\n", GCPhys), VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 1073 } 1074 1075 /* Get the ram range and page. */ 1076 PPGMPAGE pPage; 1077 rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pPage, &pRamHint); 1078 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc %RGp\n", rc, GCPhys), rc); 1079 1080 /* 1081 * Take action according to the record type. 1082 */ 1083 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) 1084 { 1085 case PGM_STATE_REC_ZERO: 1086 { 1087 if (PGM_PAGE_IS_ZERO(pPage)) 1088 break; 1089 /** @todo implement zero page replacing. */ 1090 AssertLogRelMsgReturn(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED, ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_INTERNAL_ERROR_5); 1091 void *pvDstPage; 1092 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage); 1093 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc); 1094 ASMMemZeroPage(pvDstPage); 1095 break; 1096 } 1097 1098 case PGM_STATE_REC_RAW: 1099 { 1100 void *pvDstPage; 1101 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage); 1102 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc); 1103 rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE); 1104 if (RT_FAILURE(rc)) 1105 return rc; 1106 break; 1107 } 1108 1109 case PGM_STATE_REC_ROM_VIRGIN: 1110 case PGM_STATE_REC_ROM_SHADOW: 1111 case PGM_STATE_REC_ROM_SHADOW_ZERO: 1112 case PGM_STATE_REC_ROM_PROT: 1113 { 1114 PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, GCPhys); 1115 AssertLogRelMsgReturn(pRomPage, ("GCPhys=%RGp\n", GCPhys), VERR_INTERNAL_ERROR); 1116 1117 uint8_t u8Prot; 1118 rc = SSMR3GetU8(pSSM, &u8Prot); 1119 if (RT_FAILURE(rc)) 1120 return rc; 1121 PGMROMPROT enmProt = (PGMROMPROT)u8Prot; 1122 AssertLogRelMsgReturn(enmProt > PGMROMPROT_INVALID && enmProt < PGMROMPROT_END, ("GCPhys=%RGp enmProt=%d\n", GCPhys, enmProt), VERR_INTERNAL_ERROR); 1123 1124 /* Make the protection change. */ 1125 if (enmProt != pRomPage->enmProt) 1126 { 1127 rc = PGMR3PhysRomProtect(pVM, GCPhys, PAGE_SIZE, enmProt); 1128 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc); 1129 AssertLogRelReturn(pRomPage->enmProt == enmProt, VERR_INTERNAL_ERROR); 1130 } 1131 1132 /* Get the right page descriptor. */ 1133 PPGMPAGE pRealPage; 1134 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) 1135 { 1136 case PGM_STATE_REC_ROM_VIRGIN: 1137 if (!PGMROMPROT_IS_ROM(enmProt)) 1138 pRealPage = &pRomPage->Virgin; 1139 else 1140 pRealPage = pPage; 1141 break; 1142 1143 case PGM_STATE_REC_ROM_SHADOW: 1144 case PGM_STATE_REC_ROM_SHADOW_ZERO: 1145 if (PGMROMPROT_IS_ROM(enmProt)) 1146 pRealPage = &pRomPage->Shadow; 1147 else 1148 pRealPage = pPage; 1149 break; 1150 1151 case PGM_STATE_REC_ROM_PROT: 1152 pRealPage = NULL; 1153 break; 1154 1155 default: 1156 AssertMsgFailedReturn(("%#x\n", u8), VERR_INTERNAL_ERROR); 1157 } 1158 1159 /* Map it if necessary. */ 1160 void *pvDstPage = NULL; 1161 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) 1162 { 1163 case PGM_STATE_REC_ROM_SHADOW_ZERO: 1164 if (PGM_PAGE_IS_ZERO(pRealPage)) 1165 break; 1166 /** @todo implement zero page replacing. */ 1167 /* fall thru */ 1168 case PGM_STATE_REC_ROM_VIRGIN: 1169 case PGM_STATE_REC_ROM_SHADOW: 1170 { 1171 if (RT_UNLIKELY(PGM_PAGE_GET_STATE(pRealPage) != PGM_PAGE_STATE_ALLOCATED)) 1172 { 1173 rc = pgmPhysPageMakeWritable(pVM, pRealPage, GCPhys); 1174 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc); 1175 } 1176 PPGMPAGEMAP pMapIgnored; 1177 rc = pgmPhysPageMap(pVM, pRealPage, GCPhys, &pMapIgnored, &pvDstPage); 1178 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc); 1179 break; 1180 } 1181 1182 case PGM_STATE_REC_ROM_PROT: 1183 break; 1184 } 1185 1186 /* Load the bits. */ 1187 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) 1188 { 1189 case PGM_STATE_REC_ROM_SHADOW_ZERO: 1190 if (pvDstPage) 1191 ASMMemZeroPage(pvDstPage); 1192 break; 1193 1194 case PGM_STATE_REC_ROM_VIRGIN: 1195 case PGM_STATE_REC_ROM_SHADOW: 1196 { 1197 rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE); 1198 if (RT_FAILURE(rc)) 1199 return rc; 1200 break; 1201 } 1202 1203 case PGM_STATE_REC_ROM_PROT: 1204 break; 1205 } 1206 break; 1207 } 1208 1209 default: 1210 AssertMsgFailedReturn(("%#x\n", u8), VERR_INTERNAL_ERROR); 1211 } 1212 } 1084 * @param pVM VM Handle. 1085 * @param pSSM SSM operation handle. 1086 */ 1087 static DECLCALLBACK(int) pgmR3LoadPrep(PVM pVM, PSSMHANDLE pSSM) 1088 { 1089 /* 1090 * Call the reset function to make sure all the memory is cleared. 1091 */ 1092 PGMR3Reset(pVM); 1093 NOREF(pSSM); 1094 return VINF_SUCCESS; 1213 1095 } 1214 1096 … … 1220 1102 * @param pSSM The saved state handle. 1221 1103 */ 1222 static int pgmR3LoadPageToDevNull (PSSMHANDLE pSSM)1104 static int pgmR3LoadPageToDevNullOld(PSSMHANDLE pSSM) 1223 1105 { 1224 1106 uint8_t abPage[PAGE_SIZE]; … … 1239 1121 * @param pRam The ram range (logging). 1240 1122 */ 1241 static int pgmR3LoadPageZero (PVM pVM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)1123 static int pgmR3LoadPageZeroOld(PVM pVM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam) 1242 1124 { 1243 1125 if ( PGM_PAGE_GET_TYPE(pPage) != uType … … 1268 1150 * @param pRam The ram range (logging). 1269 1151 */ 1270 static int pgmR3LoadPageBits (PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)1152 static int pgmR3LoadPageBitsOld(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam) 1271 1153 { 1272 1154 int rc; … … 1303 1185 * @param pRam The RAM range (for error messages). 1304 1186 */ 1305 static int pgmR3LoadPage (PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)1187 static int pgmR3LoadPageOld(PVM pVM, PSSMHANDLE pSSM, uint8_t uType, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam) 1306 1188 { 1307 1189 uint8_t uState; … … 1309 1191 AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] GCPhys=%#x %s rc=%Rrc\n", pPage, GCPhys, pRam->pszDesc, rc), rc); 1310 1192 if (uState == 0 /* zero */) 1311 rc = pgmR3LoadPageZero (pVM, uType, pPage, GCPhys, pRam);1193 rc = pgmR3LoadPageZeroOld(pVM, uType, pPage, GCPhys, pRam); 1312 1194 else if (uState == 1) 1313 rc = pgmR3LoadPageBits (pVM, pSSM, uType, pPage, GCPhys, pRam);1195 rc = pgmR3LoadPageBitsOld(pVM, pSSM, uType, pPage, GCPhys, pRam); 1314 1196 else 1315 1197 rc = VERR_INTERNAL_ERROR; … … 1331 1213 * @param pRam The RAM range (for error messages). 1332 1214 */ 1333 static int pgmR3LoadShadowedRomPage (PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam)1215 static int pgmR3LoadShadowedRomPageOld(PVM pVM, PSSMHANDLE pSSM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPGMRAMRANGE pRam) 1334 1216 { 1335 1217 /* … … 1361 1243 uint8_t u8PassiveType= PGMROMPROT_IS_ROM(enmProt) ? PGMPAGETYPE_ROM_SHADOW : PGMPAGETYPE_ROM; 1362 1244 1363 rc = pgmR3LoadPage(pVM, pSSM, u8ActiveType, pPage, GCPhys, pRam); 1245 /** @todo this isn't entirely correct as long as pgmPhysGCPhys2CCPtrInternal is 1246 * used down the line (will the 2nd page will be written to the first 1247 * one because of a false TLB hit since the TLB is using GCPhys and 1248 * doesn't check the HCPhys of the desired page). */ 1249 rc = pgmR3LoadPageOld(pVM, pSSM, u8ActiveType, pPage, GCPhys, pRam); 1364 1250 if (RT_SUCCESS(rc)) 1365 1251 { 1366 1252 *pPageActive = *pPage; 1367 rc = pgmR3LoadPage (pVM, pSSM, u8PassiveType, pPagePassive, GCPhys, pRam);1253 rc = pgmR3LoadPageOld(pVM, pSSM, u8PassiveType, pPagePassive, GCPhys, pRam); 1368 1254 } 1369 1255 return rc; … … 1379 1265 * @param uVersion The saved state version. 1380 1266 */ 1381 static int pgmR3Load LockedMemoryOld(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion)1267 static int pgmR3LoadMemoryOld(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion) 1382 1268 { 1383 1269 PPGM pPGM = &pVM->pgm.s; … … 1484 1370 AssertLogRelMsgRCReturn(rc, ("pPage=%R[pgmpage] iPage=%#x GCPhysPage=%#x %s\n", pPage, iPage, GCPhysPage, pRam->pszDesc), rc); 1485 1371 if (uType == PGMPAGETYPE_ROM_SHADOW) 1486 rc = pgmR3LoadShadowedRomPage (pVM, pSSM, pPage, GCPhysPage, pRam);1372 rc = pgmR3LoadShadowedRomPageOld(pVM, pSSM, pPage, GCPhysPage, pRam); 1487 1373 else 1488 rc = pgmR3LoadPage (pVM, pSSM, uType, pPage, GCPhysPage, pRam);1374 rc = pgmR3LoadPageOld(pVM, pSSM, uType, pPage, GCPhysPage, pRam); 1489 1375 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhysPage=%#x %s\n", rc, iPage, GCPhysPage, pRam->pszDesc), rc); 1490 1376 } … … 1536 1422 { 1537 1423 if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO) 1538 rc = pgmR3LoadPageToDevNull (pSSM);1424 rc = pgmR3LoadPageToDevNullOld(pSSM); 1539 1425 else 1540 rc = pgmR3LoadPageBits (pVM, pSSM, PGMPAGETYPE_INVALID, pPage, GCPhysPage, pRam);1426 rc = pgmR3LoadPageBitsOld(pVM, pSSM, PGMPAGETYPE_INVALID, pPage, GCPhysPage, pRam); 1541 1427 } 1542 1428 else 1543 rc = pgmR3LoadPageZero (pVM, PGMPAGETYPE_INVALID, pPage, GCPhysPage, pRam);1429 rc = pgmR3LoadPageZeroOld(pVM, PGMPAGETYPE_INVALID, pPage, GCPhysPage, pRam); 1544 1430 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhysPage=%#x %s\n", rc, iPage, GCPhysPage, pRam->pszDesc), rc); 1545 1431 } … … 1585 1471 while (GCPhys < pRam->GCPhys) 1586 1472 { 1587 rc = pgmR3LoadPageToDevNull (pSSM);1473 rc = pgmR3LoadPageToDevNullOld(pSSM); 1588 1474 GCPhys += PAGE_SIZE; 1589 1475 } … … 1599 1485 ("GCPhys=%RGp pPage=%R[pgmpage]\n", GCPhys, GCPhys), 1600 1486 VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 1601 rc = pgmR3LoadPageBits (pVM, pSSM, PGMPAGETYPE_ROM, pPage, GCPhysPage, pRam);1487 rc = pgmR3LoadPageBitsOld(pVM, pSSM, PGMPAGETYPE_ROM, pPage, GCPhysPage, pRam); 1602 1488 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc iPage=%#x GCPhys=%#x %s\n", rc, iPage, pRam->GCPhys, pRam->pszDesc), rc); 1603 1489 } … … 1607 1493 1608 1494 return VINF_SUCCESS; 1495 } 1496 1497 1498 /** 1499 * Worker for pgmR3Load and pgmR3LoadLocked. 1500 * 1501 * @returns VBox status code. 1502 * 1503 * @param pVM The VM handle. 1504 * @param pSSM The SSM handle. 1505 * @param uVersion The saved state version. 1506 */ 1507 static int pgmR3LoadMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) 1508 { 1509 /* 1510 * Process page records until we hit the terminator. 1511 */ 1512 PPGMRAMRANGE pRamHint = NULL; 1513 RTGCPHYS GCPhysLast = NIL_RTGCPHYS; 1514 for (;;) 1515 { 1516 /* Get the record type and flags. */ 1517 uint8_t u8; 1518 int rc = SSMR3GetU8(pSSM, &u8); 1519 if (RT_FAILURE(rc)) 1520 return rc; 1521 if (u8 == PGM_STATE_REC_END) 1522 return VINF_SUCCESS; 1523 AssertLogRelMsgReturn((u8 & ~PGM_STATE_REC_FLAG_ADDR) <= PGM_STATE_REC_LAST, ("%#x\n", u8), VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 1524 1525 /* Get the address. */ 1526 RTGCPHYS GCPhys; 1527 if (!(u8 & PGM_STATE_REC_FLAG_ADDR)) 1528 { 1529 AssertLogRelReturn(GCPhysLast != NIL_RTGCPHYS, VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 1530 GCPhys = GCPhysLast + PAGE_SIZE; 1531 } 1532 else 1533 { 1534 rc = SSMR3GetGCPhys(pSSM, &GCPhys); 1535 if (RT_FAILURE(rc)) 1536 return rc; 1537 AssertLogRelMsgReturn(GCPhys & PAGE_OFFSET_MASK, ("%RGp\n", GCPhys), VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 1538 } 1539 1540 /* Get the ram range and page. */ 1541 PPGMPAGE pPage; 1542 rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, GCPhys, &pPage, &pRamHint); 1543 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc %RGp\n", rc, GCPhys), rc); 1544 1545 /* 1546 * Take action according to the record type. 1547 */ 1548 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) 1549 { 1550 case PGM_STATE_REC_ZERO: 1551 { 1552 if (PGM_PAGE_IS_ZERO(pPage)) 1553 break; 1554 /** @todo implement zero page replacing. */ 1555 AssertLogRelMsgReturn(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED, ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_INTERNAL_ERROR_5); 1556 void *pvDstPage; 1557 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage); 1558 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc); 1559 ASMMemZeroPage(pvDstPage); 1560 break; 1561 } 1562 1563 case PGM_STATE_REC_RAW: 1564 { 1565 void *pvDstPage; 1566 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage); 1567 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc); 1568 rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE); 1569 if (RT_FAILURE(rc)) 1570 return rc; 1571 break; 1572 } 1573 1574 case PGM_STATE_REC_ROM_VIRGIN: 1575 case PGM_STATE_REC_ROM_SHADOW: 1576 case PGM_STATE_REC_ROM_SHADOW_ZERO: 1577 case PGM_STATE_REC_ROM_PROT: 1578 { 1579 PPGMROMPAGE pRomPage = pgmR3GetRomPage(pVM, GCPhys); 1580 AssertLogRelMsgReturn(pRomPage, ("GCPhys=%RGp\n", GCPhys), VERR_INTERNAL_ERROR); 1581 1582 uint8_t u8Prot; 1583 rc = SSMR3GetU8(pSSM, &u8Prot); 1584 if (RT_FAILURE(rc)) 1585 return rc; 1586 PGMROMPROT enmProt = (PGMROMPROT)u8Prot; 1587 AssertLogRelMsgReturn(enmProt > PGMROMPROT_INVALID && enmProt < PGMROMPROT_END, ("GCPhys=%RGp enmProt=%d\n", GCPhys, enmProt), VERR_INTERNAL_ERROR); 1588 1589 /* Make the protection change. */ 1590 if (enmProt != pRomPage->enmProt) 1591 { 1592 rc = PGMR3PhysRomProtect(pVM, GCPhys, PAGE_SIZE, enmProt); 1593 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc); 1594 AssertLogRelReturn(pRomPage->enmProt == enmProt, VERR_INTERNAL_ERROR); 1595 } 1596 if ((u8 & ~PGM_STATE_REC_FLAG_ADDR) == PGM_STATE_REC_ROM_PROT) 1597 break; /* done */ 1598 1599 /* Get the right page descriptor. */ 1600 PPGMPAGE pRealPage; 1601 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) 1602 { 1603 case PGM_STATE_REC_ROM_VIRGIN: 1604 if (!PGMROMPROT_IS_ROM(enmProt)) 1605 pRealPage = &pRomPage->Virgin; 1606 else 1607 pRealPage = pPage; 1608 break; 1609 1610 case PGM_STATE_REC_ROM_SHADOW: 1611 case PGM_STATE_REC_ROM_SHADOW_ZERO: 1612 if (PGMROMPROT_IS_ROM(enmProt)) 1613 pRealPage = &pRomPage->Shadow; 1614 else 1615 pRealPage = pPage; 1616 break; 1617 } 1618 1619 /* Map it if necessary. */ 1620 void *pvDstPage = NULL; 1621 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) 1622 { 1623 case PGM_STATE_REC_ROM_SHADOW_ZERO: 1624 if (PGM_PAGE_IS_ZERO(pRealPage)) 1625 break; 1626 /** @todo implement zero page replacing. */ 1627 /* fall thru */ 1628 case PGM_STATE_REC_ROM_VIRGIN: 1629 case PGM_STATE_REC_ROM_SHADOW: 1630 { 1631 if (RT_UNLIKELY(PGM_PAGE_GET_STATE(pRealPage) != PGM_PAGE_STATE_ALLOCATED)) 1632 { 1633 rc = pgmPhysPageMakeWritable(pVM, pRealPage, GCPhys); 1634 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc); 1635 } 1636 PPGMPAGEMAP pMapIgnored; 1637 rc = pgmPhysPageMap(pVM, pRealPage, GCPhys, &pMapIgnored, &pvDstPage); 1638 AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp rc=%Rrc\n", GCPhys, rc), rc); 1639 break; 1640 } 1641 } 1642 1643 /* Load the bits. */ 1644 switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) 1645 { 1646 case PGM_STATE_REC_ROM_SHADOW_ZERO: 1647 if (pvDstPage) 1648 ASMMemZeroPage(pvDstPage); 1649 break; 1650 1651 case PGM_STATE_REC_ROM_VIRGIN: 1652 case PGM_STATE_REC_ROM_SHADOW: 1653 rc = SSMR3GetMem(pSSM, pvDstPage, PAGE_SIZE); 1654 if (RT_FAILURE(rc)) 1655 return rc; 1656 break; 1657 } 1658 break; 1659 } 1660 1661 default: 1662 AssertMsgFailedReturn(("%#x\n", u8), VERR_INTERNAL_ERROR); 1663 } 1664 } 1609 1665 } 1610 1666 … … 1743 1799 */ 1744 1800 if (uVersion > PGM_SAVED_STATE_VERSION_3_0_0) 1745 return pgmR3LoadLockedMemory(pVM, pSSM, SSM_PASS_FINAL); 1746 return pgmR3LoadLockedMemoryOld(pVM, pSSM, uVersion); 1747 } 1748 1749 1750 /** 1751 * Prepare state load operation. 1752 * 1753 * @returns VBox status code. 1754 * @param pVM VM Handle. 1755 * @param pSSM SSM operation handle. 1756 */ 1757 static DECLCALLBACK(int) pgmR3LoadPrep(PVM pVM, PSSMHANDLE pSSM) 1758 { 1759 /* 1760 * Call the reset function to make sure all the memory is cleared. 1761 */ 1762 PGMR3Reset(pVM); 1763 NOREF(pSSM); 1764 return VINF_SUCCESS; 1801 return pgmR3LoadMemory(pVM, pSSM, SSM_PASS_FINAL); 1802 return pgmR3LoadMemoryOld(pVM, pSSM, uVersion); 1765 1803 } 1766 1804 … … 1803 1841 */ 1804 1842 pgmLock(pVM); 1805 rc = pgmR3Load LockedMemory(pVM, pSSM, uPass);1843 rc = pgmR3LoadMemory(pVM, pSSM, uPass); 1806 1844 pgmUnlock(pVM); 1807 1845 }
Note:
See TracChangeset
for help on using the changeset viewer.