Changeset 91848 in vbox
- Timestamp:
- Oct 19, 2021 11:18:13 PM (3 years ago)
- Location:
- trunk
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/err.h
r91587 r91848 653 653 /** One or more PAE PDPEs are invalid due to reserved bits being set. */ 654 654 #define VERR_PGM_PAE_PDPE_RSVD (-1688) 655 /** Attemted illegal operation in simplified memory management mode. */ 656 #define VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE (-1689) 655 657 /** @} */ 656 658 -
trunk/include/VBox/vmm/nem.h
r91676 r91848 62 62 VMMR3_INT_DECL(void) NEMR3NotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags); 63 63 64 VMMR3_INT_DECL(int) NEMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb); 65 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2); 66 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags); 64 VMMR3_INT_DECL(int) NEMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, void *pvR3); 65 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExMapEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, 66 void *pvRam, void *pvMmio2, uint8_t *pu2State); 67 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExMapLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, 68 void *pvRam, void *pvMmio2); 69 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, 70 void *pvRam, void *pvMmio2, uint8_t *pu2State); 67 71 /** @name Flags for NEMR3NotifyPhysMmioExMap and NEMR3NotifyPhysMmioExUnmap. 68 72 * @{ */ … … 73 77 /** @} */ 74 78 75 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags); 76 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags); 79 /** 80 * Called very early during ROM registration, basically so an existing RAM range 81 * can be adjusted if desired. 82 * 83 * It will be succeeded by a number of NEMHCNotifyPhysPageProtChanged() 84 * calls and finally a call to NEMR3NotifyPhysRomRegisterLate(). 85 * 86 * @returns VBox status code 87 * @param pVM The cross context VM structure. 88 * @param GCPhys The ROM address (page aligned). 89 * @param cb The size (page aligned). 90 * @param pvPages Pointer to the ROM (RAM) pages in simplified mode 91 * when NEM_NOTIFY_PHYS_ROM_F_REPLACE is set, otherwise 92 * NULL. 93 * @param fFlags NEM_NOTIFY_PHYS_ROM_F_XXX. 94 * @param pu2State New page state or UINT8_MAX to leave as-is. 95 */ 96 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, void *pvPages, 97 uint32_t fFlags, uint8_t *pu2State); 98 99 /** 100 * Called after the ROM range has been fully completed. 101 * 102 * This will be preceeded by a NEMR3NotifyPhysRomRegisterEarly() call as well a 103 * number of NEMHCNotifyPhysPageProtChanged calls. 104 * 105 * @returns VBox status code 106 * @param pVM The cross context VM structure. 107 * @param GCPhys The ROM address (page aligned). 108 * @param cb The size (page aligned). 109 * @param pvPages Pointer to the ROM pages. 110 * @param fFlags NEM_NOTIFY_PHYS_ROM_F_XXX. 111 * @param pu2State Where to return the new NEM page state, UINT8_MAX 112 * for unchanged. 113 */ 114 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, void *pvPages, 115 uint32_t fFlags, uint8_t *pu2State); 116 77 117 /** @name Flags for NEMR3NotifyPhysRomRegisterEarly and NEMR3NotifyPhysRomRegisterLate. 78 118 * @{ */ … … 117 157 VMM_INT_DECL(void) NEMHCNotifyHandlerPhysicalRegister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb); 118 158 VMM_INT_DECL(void) NEMHCNotifyHandlerPhysicalDeregister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb, 119 int fRestoreAsRAM, bool fRestoreAsRAM2);159 RTR3PTR pvMemR3, uint8_t *pu2State); 120 160 VMM_INT_DECL(void) NEMHCNotifyHandlerPhysicalModify(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld, 121 161 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM); … … 123 163 VMM_INT_DECL(int) NEMHCNotifyPhysPageAllocated(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt, 124 164 PGMPAGETYPE enmType, uint8_t *pu2State); 125 VMM_INT_DECL(void) NEMHCNotifyPhysPageProtChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,165 VMM_INT_DECL(void) NEMHCNotifyPhysPageProtChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, RTR3PTR pvR3, uint32_t fPageProt, 126 166 PGMPAGETYPE enmType, uint8_t *pu2State); 127 167 VMM_INT_DECL(void) NEMHCNotifyPhysPageChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, 128 uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State);168 RTR3PTR pvNewR3, uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State); 129 169 /** @name NEM_PAGE_PROT_XXX - Page protection 130 170 * @{ */ -
trunk/include/VBox/vmm/pgm.h
r91580 r91848 692 692 * @{ 693 693 */ 694 VMMR3_INT_DECL(void) PGMR3EnableNemMode(PVM pVM); 694 695 VMMR3DECL(int) PGMR3Init(PVM pVM); 695 696 VMMR3DECL(int) PGMR3InitDynMap(PVM pVM); … … 730 731 * @{ */ 731 732 /** Inidicates that ROM shadowing should be enabled. */ 732 #define PGMPHYS_ROM_FLAGS_SHADOWED RT_BIT_32(0)733 #define PGMPHYS_ROM_FLAGS_SHADOWED UINT8_C(0x01) 733 734 /** Indicates that what pvBinary points to won't go away 734 735 * and can be used for strictness checks. */ 735 #define PGMPHYS_ROM_FLAGS_PERMANENT_BINARY RT_BIT_32(1)736 #define PGMPHYS_ROM_FLAGS_PERMANENT_BINARY UINT8_C(0x02) 736 737 /** Indicates that the ROM is allowed to be missing from saved state. 737 738 * @note This is a hack for EFI, see @bugref{6940} */ 738 #define PGMPHYS_ROM_FLAGS_MAYBE_MISSING_FROM_STATE RT_BIT_32(2)739 #define PGMPHYS_ROM_FLAGS_MAYBE_MISSING_FROM_STATE UINT8_C(0x04) 739 740 /** Valid flags. */ 740 #define PGMPHYS_ROM_FLAGS_VALID_MASK UINT 32_C(0x00000007)741 #define PGMPHYS_ROM_FLAGS_VALID_MASK UINT8_C(0x07) 741 742 /** @} */ 742 743 743 744 VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb, 744 const void *pvBinary, uint32_t cbBinary, uint 32_t fFlags, const char *pszDesc);745 const void *pvBinary, uint32_t cbBinary, uint8_t fFlags, const char *pszDesc); 745 746 VMMR3DECL(int) PGMR3PhysRomProtect(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, PGMROMPROT enmProt); 746 747 VMMR3DECL(int) PGMR3PhysRegister(PVM pVM, void *pvRam, RTGCPHYS GCPhys, size_t cb, unsigned fFlags, const SUPPAGE *paPages, const char *pszDesc); -
trunk/src/VBox/VMM/Config.kmk
r91786 r91848 69 69 ifdef VBOX_WITH_NATIVE_NEM 70 70 if1of ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH), win.amd64) 71 VMM_COMMON_DEFS += VBOX_WITH_NATIVE_NEM VBOX_WITH_NEM_R0 71 VMM_COMMON_DEFS += VBOX_WITH_NATIVE_NEM VBOX_WITH_NEM_R0 #VBOX_WITH_PGM_NEM_MODE 72 72 endif 73 73 endif -
trunk/src/VBox/VMM/VMMAll/NEMAll.cpp
r82968 r91848 63 63 64 64 65 VMM_INT_DECL(void) NEMHCNotifyHandlerPhysicalDeregister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb,66 int fRestoreAsRAM, bool fRestoreAsRAM2)67 {68 #ifdef VBOX_WITH_NATIVE_NEM69 if (VM_IS_NEM_ENABLED(pVM))70 nemHCNativeNotifyHandlerPhysicalDeregister(pVM, enmKind, GCPhys, cb, fRestoreAsRAM, fRestoreAsRAM2);71 #else72 RT_NOREF(pVM, enmKind, GCPhys, cb, fRestoreAsRAM, fRestoreAsRAM2);73 #endif74 }75 76 77 65 VMM_INT_DECL(void) NEMHCNotifyHandlerPhysicalModify(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld, 78 66 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM) … … 96 84 RT_NOREF(pVM, GCPhys, HCPhys, fPageProt, enmType, pu2State); 97 85 return VINF_SUCCESS; 98 #endif99 }100 101 102 VMM_INT_DECL(void) NEMHCNotifyPhysPageProtChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,103 PGMPAGETYPE enmType, uint8_t *pu2State)104 {105 Assert(VM_IS_NEM_ENABLED(pVM));106 #ifdef VBOX_WITH_NATIVE_NEM107 nemHCNativeNotifyPhysPageProtChanged(pVM, GCPhys, HCPhys, fPageProt, enmType, pu2State);108 #else109 RT_NOREF(pVM, GCPhys, HCPhys, fPageProt, enmType, pu2State);110 #endif111 }112 113 114 VMM_INT_DECL(void) NEMHCNotifyPhysPageChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew,115 uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State)116 {117 Assert(VM_IS_NEM_ENABLED(pVM));118 #ifdef VBOX_WITH_NATIVE_NEM119 nemHCNativeNotifyPhysPageChanged(pVM, GCPhys, HCPhysPrev, HCPhysNew, fPageProt, enmType, pu2State);120 #else121 RT_NOREF(pVM, GCPhys, HCPhysPrev, HCPhysNew, fPageProt, enmType, pu2State);122 86 #endif 123 87 } -
trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h
r91702 r91848 4592 4592 4593 4593 4594 void nemHCNativeNotifyHandlerPhysicalDeregister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb, 4595 int fRestoreAsRAM, bool fRestoreAsRAM2) 4596 { 4597 Log5(("nemHCNativeNotifyHandlerPhysicalDeregister: %RGp LB %RGp enmKind=%d fRestoreAsRAM=%d fRestoreAsRAM2=%d\n", 4598 GCPhys, cb, enmKind, fRestoreAsRAM, fRestoreAsRAM2)); 4599 NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb); NOREF(fRestoreAsRAM); NOREF(fRestoreAsRAM2); 4594 VMM_INT_DECL(void) NEMHCNotifyHandlerPhysicalDeregister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb, 4595 RTR3PTR pvMemR3, uint8_t *pu2State) 4596 { 4597 Log5(("NEMHCNotifyHandlerPhysicalDeregister: %RGp LB %RGp enmKind=%d pvMemR3=%p pu2State=%p (%d)\n", 4598 GCPhys, cb, enmKind, pvMemR3, pu2State, *pu2State)); 4599 4600 *pu2State = UINT8_MAX; 4601 #if !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) && defined(VBOX_WITH_PGM_NEM_MODE) && defined(IN_RING3) 4602 if (pvMemR3) 4603 { 4604 HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, pvMemR3, GCPhys, cb, 4605 WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute | WHvMapGpaRangeFlagWrite); 4606 if (SUCCEEDED(hrc)) 4607 *pu2State = NEM_WIN_PAGE_STATE_WRITABLE; 4608 else 4609 AssertLogRelMsgFailed(("NEMHCNotifyHandlerPhysicalDeregister: WHvMapGpaRange(,%p,%RGp,%RGp,) -> %Rhrc\n", 4610 pvMemR3, GCPhys, cb, hrc)); 4611 } 4612 RT_NOREF(enmKind); 4613 #else 4614 RT_NOREF(pVM, enmKind, GCPhys, cb, pvMemR3); 4615 #endif 4600 4616 } 4601 4617 … … 4957 4973 4958 4974 4959 void nemHCNativeNotifyPhysPageProtChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,4960 PGMPAGETYPE enmType, uint8_t *pu2State)4961 { 4962 Log5((" nemHCNativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",4975 VMM_INT_DECL(void) NEMHCNotifyPhysPageProtChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, RTR3PTR pvR3, uint32_t fPageProt, 4976 PGMPAGETYPE enmType, uint8_t *pu2State) 4977 { 4978 Log5(("NEMHCNotifyPhysPageProtChanged: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n", 4963 4979 GCPhys, HCPhys, fPageProt, enmType, *pu2State)); 4964 RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType); 4980 Assert(VM_IS_NEM_ENABLED(pVM)); 4981 RT_NOREF(HCPhys, enmType, pvR3); 4965 4982 4966 4983 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES … … 4988 5005 4989 5006 4990 void nemHCNativeNotifyPhysPageChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, 4991 uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State) 4992 { 4993 Log5(("nemHCNativeNotifyPhysPageChanged: %RGp HCPhys=%RHp->%RHp fPageProt=%#x enmType=%d *pu2State=%d\n", 4994 GCPhys, HCPhysPrev, HCPhysNew, fPageProt, enmType, *pu2State)); 4995 RT_NOREF_PV(HCPhysPrev); RT_NOREF_PV(HCPhysNew); RT_NOREF_PV(enmType); 5007 VMM_INT_DECL(void) NEMHCNotifyPhysPageChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, 5008 RTR3PTR pvNewR3, uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State) 5009 { 5010 Log5(("nemHCNativeNotifyPhysPageChanged: %RGp HCPhys=%RHp->%RHp pvNewR3=%p fPageProt=%#x enmType=%d *pu2State=%d\n", 5011 GCPhys, HCPhysPrev, HCPhysNew, pvNewR3, fPageProt, enmType, *pu2State)); 5012 Assert(VM_IS_NEM_ENABLED(pVM)); 5013 RT_NOREF(HCPhysPrev, HCPhysNew, pvNewR3, enmType); 4996 5014 4997 5015 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES -
trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
r91733 r91848 50 50 *********************************************************************************************************************************/ 51 51 static int pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(PVMCC pVM, PPGMPHYSHANDLER pCur, PPGMRAMRANGE pRam); 52 static void pgmHandlerPhysicalDeregisterNotify REMAndNEM(PVMCC pVM, PPGMPHYSHANDLER pCur, int fRestoreRAM);52 static void pgmHandlerPhysicalDeregisterNotifyNEM(PVMCC pVM, PPGMPHYSHANDLER pCur); 53 53 static void pgmHandlerPhysicalResetRamFlags(PVMCC pVM, PPGMPHYSHANDLER pCur); 54 54 … … 394 394 rc = rc2; 395 395 396 #ifdef VBOX_WITH_NATIVE_NEM 396 397 /* Tell NEM about the protection update. */ 397 398 if (VM_IS_NEM_ENABLED(pVM)) … … 400 401 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 401 402 NEMHCNotifyPhysPageProtChanged(pVM, GCPhysPage, PGM_PAGE_GET_HCPHYS(pPage), 403 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysPage), 402 404 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 403 405 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 404 406 } 407 #endif 405 408 } 406 409 … … 429 432 * @param pVM The cross context VM structure. 430 433 * @param pPhysHandler The handler to deregister (but not free). 431 * @param fRestoreAsRAM How this will likely be restored, if we know (true, 432 * false, or if we don't know -1). 433 */ 434 int pgmHandlerPhysicalExDeregister(PVMCC pVM, PPGMPHYSHANDLER pPhysHandler, int fRestoreAsRAM) 434 */ 435 int pgmHandlerPhysicalExDeregister(PVMCC pVM, PPGMPHYSHANDLER pPhysHandler) 435 436 { 436 437 LogFlow(("pgmHandlerPhysicalExDeregister: Removing Range %RGp-%RGp %s fRestoreAsRAM=%d\n", 437 pPhysHandler->Core.Key, pPhysHandler->Core.KeyLast, R3STRING(pPhysHandler->pszDesc) , fRestoreAsRAM));438 pPhysHandler->Core.Key, pPhysHandler->Core.KeyLast, R3STRING(pPhysHandler->pszDesc))); 438 439 AssertReturn(pPhysHandler->Core.Key != NIL_RTGCPHYS, VERR_PGM_HANDLER_NOT_FOUND); 439 440 … … 451 452 */ 452 453 pgmHandlerPhysicalResetRamFlags(pVM, pPhysHandler); 453 pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pPhysHandler, fRestoreAsRAM); 454 if (VM_IS_NEM_ENABLED(pVM)) 455 pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pPhysHandler); 454 456 pVM->pgm.s.pLastPhysHandlerR0 = 0; 455 457 pVM->pgm.s.pLastPhysHandlerR3 = 0; … … 529 531 */ 530 532 pgmHandlerPhysicalResetRamFlags(pVM, pRemoved); 531 pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pRemoved, -1); 533 if (VM_IS_NEM_ENABLED(pVM)) 534 pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pRemoved); 532 535 pVM->pgm.s.pLastPhysHandlerR0 = 0; 533 536 pVM->pgm.s.pLastPhysHandlerR3 = 0; … … 550 553 * Shared code with modify. 551 554 */ 552 static void pgmHandlerPhysicalDeregisterNotify REMAndNEM(PVMCC pVM, PPGMPHYSHANDLER pCur, int fRestoreAsRAM)555 static void pgmHandlerPhysicalDeregisterNotifyNEM(PVMCC pVM, PPGMPHYSHANDLER pCur) 553 556 { 554 557 PPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE(pVM, pCur); … … 604 607 605 608 /* 606 * Tell REM and NEM. 607 */ 608 const bool fRestoreAsRAM2 = pCurType->pfnHandlerR3 609 && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO; /** @todo this isn't entirely correct. */ 610 /** @todo do we need this notification? */ 611 NEMHCNotifyHandlerPhysicalDeregister(pVM, pCurType->enmKind, GCPhysStart, GCPhysLast - GCPhysStart + 1, 612 fRestoreAsRAM, fRestoreAsRAM2); 609 * Tell NEM. 610 */ 611 PPGMRAMRANGE const pRam = pgmPhysGetRange(pVM, GCPhysStart); 612 RTGCPHYS const cb = GCPhysLast - GCPhysStart + 1; 613 uint8_t u2State = UINT8_MAX; 614 NEMHCNotifyHandlerPhysicalDeregister(pVM, pCurType->enmKind, GCPhysStart, cb, 615 pRam ? PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysStart) : NULL, &u2State); 616 if (u2State != UINT8_MAX && pRam) 617 pgmPhysSetNemStateForPages(&pRam->aPages[(GCPhysStart - pRam->GCPhys) >> PAGE_SHIFT], cb >> PAGE_SHIFT, u2State); 613 618 } 614 619 … … 662 667 AssertRC(rc); 663 668 669 #ifdef VBOX_WITH_NATIVE_NEM 664 670 /* Tell NEM about the protection update. */ 665 671 if (VM_IS_NEM_ENABLED(pVM)) … … 668 674 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 669 675 NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 676 PGM_RAMRANGE_CALC_PAGE_R3PTR(*ppRamHint, GCPhys), 670 677 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 671 678 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 672 679 } 680 #endif 673 681 } 674 682 else … … 684 692 * @param pPage The page. 685 693 * @param GCPhysPage The page address in case it comes in handy. 694 * @param pRam The RAM range the page is associated with (for NEM 695 * notifications). 686 696 * @param fDoAccounting Whether to perform accounting. (Only set during 687 697 * reset where pgmR3PhysRamReset doesn't have the 688 698 * handler structure handy.) 689 699 */ 690 void pgmHandlerPhysicalResetAliasedPage(PVMCC pVM, PPGMPAGE pPage, RTGCPHYS GCPhysPage, bool fDoAccounting)700 void pgmHandlerPhysicalResetAliasedPage(PVMCC pVM, PPGMPAGE pPage, RTGCPHYS GCPhysPage, PPGMRAMRANGE pRam, bool fDoAccounting) 691 701 { 692 702 Assert( PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO2_ALIAS_MMIO … … 730 740 } 731 741 742 #ifdef VBOX_WITH_NATIVE_NEM 732 743 /* 733 744 * Tell NEM about the protection change. … … 737 748 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 738 749 NEMHCNotifyPhysPageChanged(pVM, GCPhysPage, HCPhysPrev, pVM->pgm.s.HCPhysZeroPg, 750 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysPage), 739 751 NEM_PAGE_PROT_NONE, PGMPAGETYPE_MMIO, &u2State); 740 752 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 741 753 } 754 #endif 742 755 } 743 756 … … 776 789 { 777 790 Assert(pCur->cAliasedPages > 0); 778 pgmHandlerPhysicalResetAliasedPage(pVM, pPage, GCPhys, false /*fDoAccounting*/);791 pgmHandlerPhysicalResetAliasedPage(pVM, pPage, GCPhys, pRamHint, false /*fDoAccounting*/); 779 792 pCur->cAliasedPages--; 780 793 fNemNotifiedAlready = true; … … 786 799 PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_NONE); 787 800 801 #ifdef VBOX_WITH_NATIVE_NEM 788 802 /* Tell NEM about the protection change. */ 789 803 if (VM_IS_NEM_ENABLED(pVM) && !fNemNotifiedAlready) … … 792 806 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 793 807 NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 808 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRamHint, GCPhys), 794 809 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 795 810 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 796 811 } 812 #endif 813 RT_NOREF(fNemNotifiedAlready); 797 814 } 798 815 else … … 818 835 819 836 837 #if 0 /* unused */ 820 838 /** 821 839 * Modify a physical page access handler. … … 907 925 * We've only gotta notify REM and free the memory. 908 926 */ 909 pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pCur, -1); 927 if (VM_IS_NEM_ENABLED(pVM)) 928 pgmHandlerPhysicalDeregisterNotifyNEM(pVM, pCur); 910 929 pVM->pgm.s.pLastPhysHandlerR0 = 0; 911 930 pVM->pgm.s.pLastPhysHandlerR3 = 0; … … 922 941 return rc; 923 942 } 943 #endif /* unused */ 924 944 925 945 … … 959 979 } 960 980 981 #if 0 /* unused */ 961 982 962 983 /** … … 1101 1122 } 1102 1123 1124 #endif /* unused */ 1103 1125 1104 1126 /** … … 1162 1184 { 1163 1185 Assert(pCur->cAliasedPages > 0); 1164 pgmHandlerPhysicalResetAliasedPage(pVM, pPage, GCPhysPage, false /*fDoAccounting*/);1186 pgmHandlerPhysicalResetAliasedPage(pVM, pPage, GCPhysPage, pRam, false /*fDoAccounting*/); 1165 1187 --pCur->cAliasedPages; 1166 1188 #ifndef VBOX_STRICT … … 1255 1277 * Change the page status. 1256 1278 */ 1257 PPGMPAGE pPage; 1258 int rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage); 1279 PPGMPAGE pPage; 1280 PPGMRAMRANGE pRam; 1281 int rc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam); 1259 1282 AssertReturnStmt(RT_SUCCESS_NP(rc), PGM_UNLOCK(pVM), rc); 1260 1283 if (PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_DISABLED) … … 1263 1286 pCur->cTmpOffPages++; 1264 1287 1288 #ifdef VBOX_WITH_NATIVE_NEM 1265 1289 /* Tell NEM about the protection change (VGA is using this to track dirty pages). */ 1266 1290 if (VM_IS_NEM_ENABLED(pVM)) … … 1269 1293 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 1270 1294 NEMHCNotifyPhysPageProtChanged(pVM, GCPhysPage, PGM_PAGE_GET_HCPHYS(pPage), 1295 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysPage), 1271 1296 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 1272 1297 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 1273 1298 } 1299 #endif 1274 1300 } 1275 1301 PGM_UNLOCK(pVM); … … 1382 1408 PPDMDEVINS pDevIns, PGMMMIO2HANDLE hMmio2, RTGCPHYS offMmio2PageRemap) 1383 1409 { 1410 #ifdef VBOX_WITH_PGM_NEM_MODE 1411 AssertReturn(!VM_IS_NEM_ENABLED(pVM) || !pVM->pgm.s.fNemMode, VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE); 1412 #endif 1384 1413 PGM_LOCK_VOID(pVM); 1385 1414 … … 1415 1444 * Validate the page. 1416 1445 */ 1417 PPGMPAGE pPage; 1418 int rc = pgmPhysGetPageEx(pVM, GCPhysPage, &pPage); 1446 PPGMPAGE pPage; 1447 PPGMRAMRANGE pRam; 1448 int rc = pgmPhysGetPageAndRangeEx(pVM, GCPhysPage, &pPage, &pRam); 1419 1449 AssertReturnStmt(RT_SUCCESS_NP(rc), PGM_UNLOCK(pVM), rc); 1420 1450 if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO) … … 1435 1465 Log(("PGMHandlerPhysicalPageAliasMmio2: GCPhysPage=%RGp (%R[pgmpage]; %RHp -> %RHp\n", 1436 1466 GCPhysPage, pPage, PGM_PAGE_GET_HCPHYS(pPage), PGM_PAGE_GET_HCPHYS(pPageRemap))); 1437 pgmHandlerPhysicalResetAliasedPage(pVM, pPage, GCPhysPage, false /*fDoAccounting*/);1467 pgmHandlerPhysicalResetAliasedPage(pVM, pPage, GCPhysPage, pRam, false /*fDoAccounting*/); 1438 1468 pCur->cAliasedPages--; 1439 1469 } … … 1457 1487 pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhysPage); 1458 1488 1489 #ifdef VBOX_WITH_NATIVE_NEM 1459 1490 /* Tell NEM about the backing and protection change. */ 1460 1491 if (VM_IS_NEM_ENABLED(pVM)) … … 1462 1493 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 1463 1494 NEMHCNotifyPhysPageChanged(pVM, GCPhysPage, pVM->pgm.s.HCPhysZeroPg, PGM_PAGE_GET_HCPHYS(pPage), 1495 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysPage), 1464 1496 pgmPhysPageCalcNemProtection(pPage, PGMPAGETYPE_MMIO2_ALIAS_MMIO), 1465 1497 PGMPAGETYPE_MMIO2_ALIAS_MMIO, &u2State); 1466 1498 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 1467 1499 } 1500 #endif 1468 1501 LogFlow(("PGMHandlerPhysicalPageAliasMmio2: => %R[pgmpage]\n", pPage)); 1469 1502 PGM_UNLOCK(pVM); … … 1517 1550 { 1518 1551 /// Assert(!IOMIsLockOwner(pVM)); /* We mustn't own any other locks when calling this */ 1552 #ifdef VBOX_WITH_PGM_NEM_MODE 1553 AssertReturn(!VM_IS_NEM_ENABLED(pVM) || !pVM->pgm.s.fNemMode, VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE); 1554 #endif 1519 1555 PGM_LOCK_VOID(pVM); 1520 1556 … … 1567 1603 pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhysPage); 1568 1604 1605 #ifdef VBOX_WITH_NATIVE_NEM 1569 1606 /* Tell NEM about the backing and protection change. */ 1570 1607 if (VM_IS_NEM_ENABLED(pVM)) 1571 1608 { 1572 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 1609 PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhysPage); 1610 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 1573 1611 NEMHCNotifyPhysPageChanged(pVM, GCPhysPage, pVM->pgm.s.HCPhysZeroPg, PGM_PAGE_GET_HCPHYS(pPage), 1612 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysPage), 1574 1613 pgmPhysPageCalcNemProtection(pPage, PGMPAGETYPE_SPECIAL_ALIAS_MMIO), 1575 1614 PGMPAGETYPE_SPECIAL_ALIAS_MMIO, &u2State); 1576 1615 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 1577 1616 } 1617 #endif 1578 1618 LogFlow(("PGMHandlerPhysicalPageAliasHC: => %R[pgmpage]\n", pPage)); 1579 1619 PGM_UNLOCK(pVM); -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r91587 r91848 282 282 { 283 283 pShadowPage = pgmPhysGetPage(pVM, GCPhys); 284 AssertLogRel Return(pShadowPage, VERR_PGM_PHYS_PAGE_GET_IPE);284 AssertLogRelMsgReturnStmt(pShadowPage, ("%RGp\n", GCPhys), PGM_UNLOCK(pVM), VERR_PGM_PHYS_PAGE_GET_IPE); 285 285 } 286 286 287 287 void *pvDstPage; 288 int rc = pgmPhysPageMakeWritableAndMap(pVM, pShadowPage, GCPhys & X86_PTE_PG_MASK, &pvDstPage); 288 int rc; 289 #if defined(VBOX_WITH_PGM_NEM_MODE) && defined(IN_RING3) 290 if (PGM_IS_IN_NEM_MODE(pVM) && PGMROMPROT_IS_ROM(pRomPage->enmProt)) 291 { 292 pvDstPage = &pRom->pbR3Alternate[GCPhys - pRom->GCPhys]; 293 rc = VINF_SUCCESS; 294 } 295 else 296 #endif 297 { 298 rc = pgmPhysPageMakeWritableAndMap(pVM, pShadowPage, GCPhys & X86_PTE_PG_MASK, &pvDstPage); 299 if (RT_SUCCESS(rc)) 300 pvDstPage = (uint8_t *)pvDstPage + (GCPhys & PAGE_OFFSET_MASK); 301 } 289 302 if (RT_SUCCESS(rc)) 290 303 { … … 1059 1072 pVM->pgm.s.cWrittenToPages++; 1060 1073 1074 #ifdef VBOX_WITH_NATIVE_NEM 1061 1075 /* 1062 1076 * Notify NEM about the protection change so we won't spin forever. … … 1067 1081 if (VM_IS_NEM_ENABLED(pVM) && GCPhys != NIL_RTGCPHYS) 1068 1082 { 1069 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 1070 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 1083 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 1084 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 1085 PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhys); 1071 1086 NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 1087 pRam ? PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhys) : NULL, 1072 1088 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 1073 1089 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 1074 1090 } 1091 #endif 1075 1092 } 1076 1093 … … 1244 1261 # endif 1245 1262 } 1263 1264 # ifdef VBOX_WITH_PGM_NEM_MODE 1265 if (pVM->pgm.s.fNemMode) 1266 { 1267 # ifdef IN_RING3 1268 /* 1269 * Find the corresponding RAM range and use that to locate the mapping address. 1270 */ 1271 /** @todo Use the page ID for some kind of indexing as we do with MMIO2 above. */ 1272 PPGMRAMRANGE const pRam = pgmPhysGetRange(pVM, GCPhys); 1273 AssertLogRelMsgReturn(pRam, ("%RTGp\n", GCPhys), VERR_INTERNAL_ERROR_3); 1274 size_t const idxPage = (GCPhys - pRam->GCPhys) >> PAGE_SHIFT; 1275 Assert(pPage == &pRam->aPages[idxPage]); 1276 *ppMap = NULL; 1277 *ppv = (uint8_t *)pRam->pvR3 + (idxPage << PAGE_SHIFT); 1278 return VINF_SUCCESS; 1279 # else 1280 AssertFailedReturn(VERR_INTERNAL_ERROR_2); 1281 # endif 1282 } 1283 # endif 1246 1284 1247 1285 const uint32_t idChunk = PGM_PAGE_GET_CHUNKID(pPage); … … 4351 4389 } 4352 4390 4391 #ifdef VBOX_WITH_NATIVE_NEM 4353 4392 4354 4393 /** … … 4494 4533 } 4495 4534 4535 4536 /** 4537 * Helper for setting the NEM state for a range of pages. 4538 * 4539 * @param paPages Array of pages to modify. 4540 * @param cPages How many pages to modify. 4541 * @param u2State The new state value. 4542 */ 4543 void pgmPhysSetNemStateForPages(PPGMPAGE paPages, RTGCPHYS cPages, uint8_t u2State) 4544 { 4545 PPGMPAGE pPage = paPages; 4546 while (cPages-- > 0) 4547 { 4548 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 4549 pPage++; 4550 } 4551 } 4552 4553 #endif /* VBOX_WITH_NATIVE_NEM */ 4554 4555 -
trunk/src/VBox/VMM/VMMR3/NEMR3.cpp
r86117 r91848 441 441 442 442 443 444 445 VMMR3_INT_DECL(int) NEMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb)446 {447 int rc = VINF_SUCCESS;448 #ifdef VBOX_WITH_NATIVE_NEM449 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)450 rc = nemR3NativeNotifyPhysRamRegister(pVM, GCPhys, cb);451 #else452 NOREF(pVM); NOREF(GCPhys); NOREF(cb);453 #endif454 return rc;455 }456 457 458 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2)459 {460 int rc = VINF_SUCCESS;461 #ifdef VBOX_WITH_NATIVE_NEM462 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)463 rc = nemR3NativeNotifyPhysMmioExMap(pVM, GCPhys, cb, fFlags, pvMmio2);464 #else465 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); NOREF(pvMmio2);466 #endif467 return rc;468 }469 470 471 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)472 {473 int rc = VINF_SUCCESS;474 #ifdef VBOX_WITH_NATIVE_NEM475 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)476 rc = nemR3NativeNotifyPhysMmioExUnmap(pVM, GCPhys, cb, fFlags);477 #else478 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);479 #endif480 return rc;481 }482 483 484 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)485 {486 int rc = VINF_SUCCESS;487 #ifdef VBOX_WITH_NATIVE_NEM488 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)489 rc = nemR3NativeNotifyPhysRomRegisterEarly(pVM, GCPhys, cb, fFlags);490 #else491 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);492 #endif493 return rc;494 }495 496 497 /**498 * Called after the ROM range has been fully completed.499 *500 * This will be preceeded by a NEMR3NotifyPhysRomRegisterEarly() call as well a501 * number of NEMHCNotifyPhysPageProtChanged calls.502 *503 * @returns VBox status code504 * @param pVM The cross context VM structure.505 * @param GCPhys The ROM address (page aligned).506 * @param cb The size (page aligned).507 * @param fFlags NEM_NOTIFY_PHYS_ROM_F_XXX.508 */509 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)510 {511 int rc = VINF_SUCCESS;512 #ifdef VBOX_WITH_NATIVE_NEM513 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API)514 rc = nemR3NativeNotifyPhysRomRegisterLate(pVM, GCPhys, cb, fFlags);515 #else516 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);517 #endif518 return rc;519 }520 521 522 443 VMMR3_INT_DECL(void) NEMR3NotifySetA20(PVMCPU pVCpu, bool fEnabled) 523 444 { -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r91702 r91848 1336 1336 if (RT_SUCCESS(rc)) 1337 1337 { 1338 /* 1339 * Set ourselves as the execution engine and make config adjustments. 1340 */ 1338 1341 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API); 1339 1342 Log(("NEM: Marked active!\n")); 1340 1343 nemR3WinDisableX2Apic(pVM); 1341 1342 /* Register release statistics */ 1344 #if !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) && defined(VBOX_WITH_PGM_NEM_MODE) 1345 PGMR3EnableNemMode(pVM); 1346 #endif 1347 1348 /* 1349 * Register release statistics 1350 */ 1343 1351 STAMR3Register(pVM, (void *)&pVM->nem.s.cMappedPages, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, 1344 1352 "/NEM/PagesCurrentlyMapped", STAMUNIT_PAGES, "Number guest pages currently mapped by the VM"); … … 1403 1411 STAMUNIT_PAGES, STAM_REFRESH_GRP_NEM, "Pages in use by hypervisor", 1404 1412 "/NEM/R0Stats/cPagesInUse"); 1413 1405 1414 } 1406 1415 } … … 1942 1951 1943 1952 1944 int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb) 1945 { 1946 Log5(("nemR3NativeNotifyPhysRamRegister: %RGp LB %RGp\n", GCPhys, cb)); 1947 NOREF(pVM); NOREF(GCPhys); NOREF(cb); 1953 VMMR3_INT_DECL(int) NEMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, void *pvR3) 1954 { 1955 Log5(("NEMR3NotifyPhysRamRegister: %RGp LB %RGp, pvR3=%p\n", GCPhys, cb, pvR3)); 1956 #if !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) && defined(VBOX_WITH_PGM_NEM_MODE) 1957 if (pvR3) 1958 { 1959 HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, pvR3, GCPhys, cb, 1960 WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagWrite | WHvMapGpaRangeFlagExecute); 1961 if (SUCCEEDED(hrc)) 1962 { /* likely */ } 1963 else 1964 { 1965 LogRel(("NEMR3NotifyPhysRamRegister: GCPhys=%RGp LB %RGp pvR3=%p hrc=%Rhrc (%#x) Last=%#x/%u\n", 1966 GCPhys, cb, pvR3, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 1967 return VERR_NEM_MAP_PAGES_FAILED; 1968 } 1969 } 1970 #else 1971 RT_NOREF(pVM, GCPhys, cb, pvR3); 1972 #endif 1948 1973 return VINF_SUCCESS; 1949 1974 } 1950 1975 1951 1976 1952 int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2) 1953 { 1954 Log5(("nemR3NativeNotifyPhysMmioExMap: %RGp LB %RGp fFlags=%#x pvMmio2=%p\n", GCPhys, cb, fFlags, pvMmio2)); 1955 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); NOREF(pvMmio2); 1977 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExMapEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, 1978 void *pvRam, void *pvMmio2, uint8_t *pu2State) 1979 { 1980 Log5(("NEMR3NotifyPhysMmioExMapEarly: %RGp LB %RGp fFlags=%#x pvRam=%p pvMmio2=%p pu2State=%p (%d)\n", 1981 GCPhys, cb, fFlags, pvRam, pvMmio2, pu2State, *pu2State)); 1982 1983 #if !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) && defined(VBOX_WITH_PGM_NEM_MODE) 1984 /* 1985 * Unmap the RAM we're replacing. 1986 */ 1987 if (fFlags & NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE) 1988 { 1989 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, cb); 1990 if (SUCCEEDED(hrc)) 1991 { /* likely */ } 1992 else if (pvMmio2) 1993 LogRel(("NEMR3NotifyPhysMmioExMapEarly: GCPhys=%RGp LB %RGp fFlags=%#x: Unmap -> hrc=%Rhrc (%#x) Last=%#x/%u (ignored)\n", 1994 GCPhys, cb, fFlags, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 1995 else 1996 { 1997 LogRel(("NEMR3NotifyPhysMmioExMapEarly: GCPhys=%RGp LB %RGp fFlags=%#x: Unmap -> hrc=%Rhrc (%#x) Last=%#x/%u\n", 1998 GCPhys, cb, fFlags, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 1999 return VERR_NEM_UNMAP_PAGES_FAILED; 2000 } 2001 } 2002 2003 /* 2004 * Map MMIO2 if any. 2005 */ 2006 if (pvMmio2) 2007 { 2008 Assert(fFlags & NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2); 2009 HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, pvMmio2, GCPhys, cb, 2010 WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagWrite | WHvMapGpaRangeFlagExecute); 2011 if (SUCCEEDED(hrc)) 2012 *pu2State = NEM_WIN_PAGE_STATE_WRITABLE; 2013 else 2014 { 2015 LogRel(("NEMR3NotifyPhysMmioExMapEarly: GCPhys=%RGp LB %RGp fFlags=%#x pvMmio2=%p: Map -> hrc=%Rhrc (%#x) Last=%#x/%u\n", 2016 GCPhys, cb, fFlags, pvMmio2, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2017 return VERR_NEM_MAP_PAGES_FAILED; 2018 } 2019 } 2020 else 2021 { 2022 Assert(!(fFlags & NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2)); 2023 *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED; 2024 } 2025 2026 #else 2027 RT_NOREF(pVM, GCPhys, cb, pvRam, pvMmio2); 2028 *pu2State = (fFlags & NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE) ? UINT8_MAX : NEM_WIN_PAGE_STATE_UNMAPPED; 2029 #endif 1956 2030 return VINF_SUCCESS; 1957 2031 } 1958 2032 1959 2033 1960 int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 1961 { 1962 Log5(("nemR3NativeNotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 1963 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);2034 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExMapLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, 2035 void *pvRam, void *pvMmio2) 2036 { 2037 RT_NOREF(pVM, GCPhys, cb, fFlags, pvRam, pvMmio2); 1964 2038 return VINF_SUCCESS; 1965 2039 } 1966 2040 1967 2041 1968 /** 1969 * Called early during ROM registration, right after the pages have been 1970 * allocated and the RAM range updated. 1971 * 1972 * This will be succeeded by a number of NEMHCNotifyPhysPageProtChanged() calls 1973 * and finally a NEMR3NotifyPhysRomRegisterEarly(). 1974 * 1975 * @returns VBox status code 1976 * @param pVM The cross context VM structure. 1977 * @param GCPhys The ROM address (page aligned). 1978 * @param cb The size (page aligned). 1979 * @param fFlags NEM_NOTIFY_PHYS_ROM_F_XXX. 1980 */ 1981 int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 1982 { 1983 Log5(("nemR3NativeNotifyPhysRomRegisterEarly: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 2042 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvRam, 2043 void *pvMmio2, uint8_t *pu2State) 2044 { 2045 Log5(("NEMR3NotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x pvRam=%p pvMmio2=%p pu2State=%p\n", 2046 GCPhys, cb, fFlags, pvRam, pvMmio2, pu2State)); 2047 2048 int rc = VINF_SUCCESS; 2049 #if !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) && defined(VBOX_WITH_PGM_NEM_MODE) 2050 /* 2051 * Unmap the MMIO2 pages. 2052 */ 2053 /** @todo If we implement aliasing (MMIO2 page aliased into MMIO range), 2054 * we may have more stuff to unmap even in case of pure MMIO... */ 2055 if (fFlags & NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2) 2056 { 2057 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, cb); 2058 if (FAILED(hrc)) 2059 { 2060 LogRel2(("NEMR3NotifyPhysMmioExUnmap: GCPhys=%RGp LB %RGp fFlags=%#x: Unmap -> hrc=%Rhrc (%#x) Last=%#x/%u (ignored)\n", 2061 GCPhys, cb, fFlags, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2062 rc = VERR_NEM_UNMAP_PAGES_FAILED; 2063 } 2064 } 2065 2066 /* 2067 * Restore the RAM we replaced. 2068 */ 2069 if (fFlags & NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE) 2070 { 2071 AssertPtr(pvRam); 2072 HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, pvRam, GCPhys, cb, 2073 WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagWrite | WHvMapGpaRangeFlagExecute); 2074 if (SUCCEEDED(hrc)) 2075 { /* likely */ } 2076 else 2077 { 2078 LogRel(("NEMR3NotifyPhysMmioExUnmap: GCPhys=%RGp LB %RGp pvMmio2=%p hrc=%Rhrc (%#x) Last=%#x/%u\n", 2079 GCPhys, cb, pvMmio2, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2080 rc = VERR_NEM_MAP_PAGES_FAILED; 2081 } 2082 if (pu2State) 2083 *pu2State = NEM_WIN_PAGE_STATE_WRITABLE; 2084 } 2085 /* Mark the pages as unmapped if relevant. */ 2086 else if (pu2State) 2087 *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED; 2088 2089 RT_NOREF(pvMmio2); 2090 #else 2091 RT_NOREF(pVM, GCPhys, cb, fFlags, pvRam, pvMmio2, pu2State); 2092 if (pu2State) 2093 *pu2State = UINT8_MAX; 2094 #endif 2095 return rc; 2096 } 2097 2098 2099 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, void *pvPages, uint32_t fFlags, 2100 uint8_t *pu2State) 2101 { 2102 Log5(("nemR3NativeNotifyPhysRomRegisterEarly: %RGp LB %RGp pvPages=%p fFlags=%#x\n", GCPhys, cb, pvPages, fFlags)); 2103 *pu2State = UINT8_MAX; 2104 1984 2105 #if 0 /* Let's not do this after all. We'll protection change notifications for each page and if not we'll map them lazily. */ 1985 2106 RTGCPHYS const cPages = cb >> X86_PAGE_SHIFT; … … 2007 2128 } 2008 2129 } 2130 RT_NOREF_PV(fFlags); 2009 2131 #else 2010 NOREF(pVM); NOREF(GCPhys); NOREF(cb); 2011 #endif 2012 RT_NOREF_PV(fFlags); 2132 RT_NOREF(pVM, GCPhys, cb, pvPages, fFlags); 2133 #endif 2013 2134 return VINF_SUCCESS; 2014 2135 } 2015 2136 2016 2137 2017 /** 2018 * Called after the ROM range has been fully completed. 2019 * 2020 * This will be preceeded by a NEMR3NotifyPhysRomRegisterEarly() call as well a 2021 * number of NEMHCNotifyPhysPageProtChanged calls. 2022 * 2023 * @returns VBox status code 2024 * @param pVM The cross context VM structure. 2025 * @param GCPhys The ROM address (page aligned). 2026 * @param cb The size (page aligned). 2027 * @param fFlags NEM_NOTIFY_PHYS_ROM_F_XXX. 2028 */ 2029 int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 2030 { 2031 Log5(("nemR3NativeNotifyPhysRomRegisterLate: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 2032 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 2138 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, void *pvPages, 2139 uint32_t fFlags, uint8_t *pu2State) 2140 { 2141 Log5(("nemR3NativeNotifyPhysRomRegisterLate: %RGp LB %RGp pvPages=%p fFlags=%#x pu2State=%p\n", 2142 GCPhys, cb, pvPages, fFlags, pu2State)); 2143 *pu2State = UINT8_MAX; 2144 2145 #if !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) && defined(VBOX_WITH_PGM_NEM_MODE) 2146 /* 2147 * (Re-)map readonly. 2148 */ 2149 AssertPtrReturn(pvPages, VERR_INVALID_POINTER); 2150 HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, pvPages, GCPhys, cb, WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute); 2151 if (SUCCEEDED(hrc)) 2152 *pu2State = NEM_WIN_PAGE_STATE_READABLE; 2153 else 2154 { 2155 LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: GCPhys=%RGp LB %RGp pvPages=%p fFlags=%#x hrc=%Rhrc (%#x) Last=%#x/%u\n", 2156 GCPhys, cb, pvPages, fFlags, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2157 return VERR_NEM_MAP_PAGES_FAILED; 2158 } 2159 RT_NOREF(fFlags); 2160 #else 2161 RT_NOREF(pVM, GCPhys, cb, pvPages, fFlags); 2162 #endif 2033 2163 return VINF_SUCCESS; 2034 2164 } -
trunk/src/VBox/VMM/VMMR3/PGM.cpp
r91580 r91848 736 736 737 737 738 #ifdef VBOX_WITH_PGM_NEM_MODE 739 /** 740 * Interface that NEM uses to switch PGM into simplified memory managment mode. 741 * 742 * This call occurs before PGMR3Init. 743 * 744 * @param pVM The cross context VM structure. 745 */ 746 VMMR3_INT_DECL(void) PGMR3EnableNemMode(PVM pVM) 747 { 748 AssertFatal(!PDMCritSectIsInitialized(&pVM->pgm.s.CritSectX)); 749 pVM->pgm.s.fNemMode = true; 750 } 751 #endif 738 752 739 753 … … 810 824 pVM->pgm.s.enmHostMode = SUPPAGINGMODE_INVALID; 811 825 pVM->pgm.s.GCPhys4MBPSEMask = RT_BIT_64(32) - 1; /* default; checked later */ 826 #ifndef PGM_WITHOUT_MAPPINGS 812 827 pVM->pgm.s.GCPtrPrevRamRangeMapping = MM_HYPER_AREA_ADDRESS; 828 #endif 813 829 814 830 rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "RamPreAlloc", &pVM->pgm.s.fRamPreAlloc, -
trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp
r90439 r91848 252 252 PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_NONE); 253 253 254 #ifdef VBOX_WITH_NATIVE_NEM 254 255 /* Tell NEM about the protection change. */ 255 256 if (VM_IS_NEM_ENABLED(pVM)) … … 258 259 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 259 260 NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 261 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRamHint, GCPhys), 260 262 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 261 263 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 262 264 } 265 #endif 263 266 } 264 267 else … … 296 299 PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, uState); 297 300 301 #ifdef VBOX_WITH_NATIVE_NEM 298 302 /* Tell NEM about the protection change. */ 299 303 if (VM_IS_NEM_ENABLED(pVM)) … … 302 306 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 303 307 NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 308 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRamHint, GCPhys), 304 309 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 305 310 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 306 311 } 312 #endif 307 313 } 308 314 else -
trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
r91732 r91848 1158 1158 * @param GCPhys The address of the first page. 1159 1159 * @param GCPhysLast The address of the last page. 1160 * @param enmType The page type to replace then with. 1161 */ 1162 static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, PGMPAGETYPE enmType) 1160 * @param pvMmio2 Pointer to the ring-3 mapping of any MMIO2 memory that 1161 * will replace the pages we're freeing up. 1162 */ 1163 static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, void *pvMmio2) 1163 1164 { 1164 1165 PGM_LOCK_ASSERT_OWNER(pVM); 1166 1167 #ifdef VBOX_WITH_PGM_NEM_MODE 1168 /* 1169 * In simplified memory mode we don't actually free the memory, 1170 * we just unmap it and let NEM do any unlocking of it. 1171 */ 1172 if (pVM->pgm.s.fNemMode) 1173 { 1174 Assert(VM_IS_NEM_ENABLED(pVM)); 1175 uint32_t const fNemNotify = (pvMmio2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0) | NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE; 1176 uint8_t u2State = 0; /* (We don't support UINT8_MAX here.) */ 1177 int rc = NEMR3NotifyPhysMmioExMapEarly(pVM, GCPhys, GCPhysLast - GCPhys + 1, fNemNotify, 1178 pRam->pvR3 ? (uint8_t *)pRam->pvR3 + GCPhys - pRam->GCPhys : NULL, 1179 pvMmio2, &u2State); 1180 AssertLogRelRCReturn(rc, rc); 1181 1182 /* Iterate the pages. */ 1183 PPGMPAGE pPageDst = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; 1184 uint32_t cPagesLeft = ((GCPhysLast - GCPhys) >> PAGE_SHIFT) + 1; 1185 while (cPagesLeft-- > 0) 1186 { 1187 rc = pgmPhysFreePage(pVM, NULL, NULL, pPageDst, GCPhys, PGMPAGETYPE_MMIO); 1188 AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */ 1189 1190 PGM_PAGE_SET_TYPE(pVM, pPageDst, PGMPAGETYPE_MMIO); 1191 PGM_PAGE_SET_NEM_STATE(pPageDst, u2State); 1192 1193 GCPhys += PAGE_SIZE; 1194 pPageDst++; 1195 } 1196 return rc; 1197 } 1198 #endif /* VBOX_WITH_PGM_NEM_MODE */ 1199 1200 /* 1201 * Regular mode. 1202 */ 1203 /* Prepare. */ 1165 1204 uint32_t cPendingPages = 0; 1166 1205 PGMMFREEPAGESREQ pReq; … … 1168 1207 AssertLogRelRCReturn(rc, rc); 1169 1208 1209 #ifdef VBOX_WITH_NATIVE_NEM 1210 /* Tell NEM up-front. */ 1211 uint8_t u2State = UINT8_MAX; 1212 if (VM_IS_NEM_ENABLED(pVM)) 1213 { 1214 uint32_t const fNemNotify = (pvMmio2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0) | NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE; 1215 rc = NEMR3NotifyPhysMmioExMapEarly(pVM, GCPhys, GCPhysLast - GCPhys + 1, fNemNotify, NULL, pvMmio2, &u2State); 1216 AssertLogRelRCReturnStmt(rc, GMMR3FreePagesCleanup(pReq), rc); 1217 } 1218 #endif 1219 1170 1220 /* Iterate the pages. */ 1171 1221 PPGMPAGE pPageDst = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; … … 1173 1223 while (cPagesLeft-- > 0) 1174 1224 { 1175 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPageDst, GCPhys, enmType);1225 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPageDst, GCPhys, PGMPAGETYPE_MMIO); 1176 1226 AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */ 1177 1227 1178 PGM_PAGE_SET_TYPE(pVM, pPageDst, enmType); 1228 PGM_PAGE_SET_TYPE(pVM, pPageDst, PGMPAGETYPE_MMIO); 1229 #ifdef VBOX_WITH_NATIVE_NEM 1230 if (u2State != UINT8_MAX) 1231 PGM_PAGE_SET_NEM_STATE(pPageDst, u2State); 1232 #endif 1179 1233 1180 1234 GCPhys += PAGE_SIZE; … … 1182 1236 } 1183 1237 1238 /* Finish pending and cleanup. */ 1184 1239 if (cPendingPages) 1185 1240 { … … 1634 1689 * PGMR3PhysRegisterRam worker that initializes and links a RAM range. 1635 1690 * 1691 * In NEM mode, this will allocate the pages backing the RAM range and this may 1692 * fail. NEM registration may also fail. (In regular HM mode it won't fail.) 1693 * 1694 * @returns VBox status code. 1636 1695 * @param pVM The cross context VM structure. 1637 1696 * @param pNew The new RAM range. … … 1644 1703 * @param pPrev The previous RAM range (for linking). 1645 1704 */ 1646 static voidpgmR3PhysInitAndLinkRamRange(PVM pVM, PPGMRAMRANGE pNew, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,1647 1705 static int pgmR3PhysInitAndLinkRamRange(PVM pVM, PPGMRAMRANGE pNew, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, 1706 RTRCPTR RCPtrNew, RTR0PTR R0PtrNew, const char *pszDesc, PPGMRAMRANGE pPrev) 1648 1707 { 1649 1708 /* 1650 1709 * Initialize the range. 1651 1710 */ 1652 pNew->pSelfR0 = R0PtrNew != NIL_RTR0PTR ? R0PtrNew : MMHyperCCToR0(pVM, pNew);1711 pNew->pSelfR0 = R0PtrNew; 1653 1712 pNew->GCPhys = GCPhys; 1654 1713 pNew->GCPhysLast = GCPhysLast; 1655 1714 pNew->cb = GCPhysLast - GCPhys + 1; 1656 1715 pNew->pszDesc = pszDesc; 1657 pNew->fFlags = RCPtrNew != NIL_RTRCPTR ? PGM_RAM_RANGE_FLAGS_FLOATING : 0;1658 1716 pNew->pvR3 = NULL; 1659 1717 pNew->paLSPages = NULL; 1718 pNew->fFlags = 0; 1719 #ifndef PGM_WITHOUT_MAPPINGS 1720 if (RCPtrNew != NIL_RTRCPTR) 1721 pNew->fFlags |= PGM_RAM_RANGE_FLAGS_FLOATING; 1722 #else 1723 NOREF(RCPtrNew); 1724 #endif 1660 1725 1661 1726 uint32_t const cPages = pNew->cb >> PAGE_SHIFT; 1662 RTGCPHYS iPage = cPages; 1663 while (iPage-- > 0) 1664 PGM_PAGE_INIT_ZERO(&pNew->aPages[iPage], pVM, PGMPAGETYPE_RAM); 1665 1666 /* Update the page count stats. */ 1667 pVM->pgm.s.cZeroPages += cPages; 1668 pVM->pgm.s.cAllPages += cPages; 1727 #ifdef VBOX_WITH_PGM_NEM_MODE 1728 if (!pVM->pgm.s.fNemMode) 1729 #endif 1730 { 1731 RTGCPHYS iPage = cPages; 1732 while (iPage-- > 0) 1733 PGM_PAGE_INIT_ZERO(&pNew->aPages[iPage], pVM, PGMPAGETYPE_RAM); 1734 1735 /* Update the page count stats. */ 1736 pVM->pgm.s.cZeroPages += cPages; 1737 pVM->pgm.s.cAllPages += cPages; 1738 } 1739 #ifdef VBOX_WITH_PGM_NEM_MODE 1740 else 1741 { 1742 int rc = SUPR3PageAlloc(cPages, &pNew->pvR3); 1743 if (RT_FAILURE(rc)) 1744 return rc; 1745 1746 RTGCPHYS iPage = cPages; 1747 while (iPage-- > 0) 1748 PGM_PAGE_INIT(&pNew->aPages[iPage], UINT64_C(0x0000fffffffff000), NIL_GMM_PAGEID, 1749 PGMPAGETYPE_RAM, PGM_PAGE_STATE_ALLOCATED); 1750 1751 /* Update the page count stats. */ 1752 pVM->pgm.s.cPrivatePages += cPages; 1753 pVM->pgm.s.cAllPages += cPages; 1754 } 1755 #endif 1669 1756 1670 1757 /* … … 1672 1759 */ 1673 1760 pgmR3PhysLinkRamRange(pVM, pNew, pPrev); 1761 1762 /* 1763 * Notify NEM now that it has been linked. 1764 */ 1765 int rc = NEMR3NotifyPhysRamRegister(pVM, GCPhys, pNew->cb, pNew->pvR3); 1766 if (RT_FAILURE(rc)) 1767 pgmR3PhysUnlinkRamRange2(pVM, pNew, pPrev); 1768 return rc; 1674 1769 } 1675 1770 … … 1757 1852 * We push these in below the HMA. 1758 1853 */ 1759 RTGCPTR GCPtrChunkMap = pVM->pgm.s.GCPtrPrevRamRangeMapping - cbChunk; 1760 #ifndef PGM_WITHOUT_MAPPINGS 1854 #ifdef PGM_WITHOUT_MAPPINGS 1855 RTGCPTR const GCPtrChunk = NIL_RTGCPTR; 1856 RT_NOREF(cbChunk); 1857 #else 1858 RTGCPTR const GCPtrChunkMap = pVM->pgm.s.GCPtrPrevRamRangeMapping - cbChunk; 1761 1859 rc = PGMR3MapPT(pVM, GCPtrChunkMap, cbChunk, 0 /*fFlags*/, pgmR3PhysRamRangeRelocate, pNew, pszDescChunk); 1762 1860 if (RT_SUCCESS(rc)) 1763 #endif /* !PGM_WITHOUT_MAPPINGS */1764 1861 { 1765 1862 pVM->pgm.s.GCPtrPrevRamRangeMapping = GCPtrChunkMap; 1766 1863 1767 1864 RTGCPTR const GCPtrChunk = GCPtrChunkMap + PAGE_SIZE; 1768 #ifndef PGM_WITHOUT_MAPPINGS1769 1865 RTGCPTR GCPtrPage = GCPtrChunk; 1770 1866 for (uint32_t iPage = 0; iPage < cChunkPages && RT_SUCCESS(rc); iPage++, GCPtrPage += PAGE_SIZE) … … 1776 1872 * Ok, init and link the range. 1777 1873 */ 1778 pgmR3PhysInitAndLinkRamRange(pVM, pNew, GCPhys, GCPhys + ((RTGCPHYS)cRamPages << PAGE_SHIFT) - 1, 1779 (RTRCPTR)GCPtrChunk, R0PtrChunk, pszDescChunk, *ppPrev); 1780 *ppPrev = pNew; 1874 rc = pgmR3PhysInitAndLinkRamRange(pVM, pNew, GCPhys, GCPhys + ((RTGCPHYS)cRamPages << PAGE_SHIFT) - 1, 1875 (RTRCPTR)GCPtrChunk, R0PtrChunk, pszDescChunk, *ppPrev); 1876 if (RT_SUCCESS(rc)) 1877 *ppPrev = pNew; 1781 1878 } 1782 } 1879 #ifndef PGM_WITHOUT_MAPPINGS 1880 } 1881 #endif 1783 1882 1784 1883 if (RT_FAILURE(rc)) … … 1897 1996 PPGMRAMRANGE pNew; 1898 1997 rc = MMR3HyperAllocOnceNoRel(pVM, cbRamRange, 0, MM_TAG_PGM_PHYS, (void **)&pNew); 1899 AssertLogRelMsgRCReturn(rc, ("cbRamRange=%zu\n", cbRamRange), rc); 1900 1901 pgmR3PhysInitAndLinkRamRange(pVM, pNew, GCPhys, GCPhysLast, NIL_RTRCPTR, NIL_RTR0PTR, pszDesc, pPrev); 1998 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc cbRamRange=%zu\n", rc, cbRamRange), rc); 1999 2000 rc = pgmR3PhysInitAndLinkRamRange(pVM, pNew, GCPhys, GCPhysLast, NIL_RTRCPTR, MMHyperCCToR0(pVM, pNew), pszDesc, pPrev); 2001 AssertLogRelMsgRCReturn(rc, ("rc=%Rrc cbRamRange=%zu\n", rc, cbRamRange), rc); 1902 2002 } 1903 2003 pgmPhysInvalidatePageMapTLB(pVM); 1904 2004 1905 /*1906 * Notify NEM while holding the lock (experimental) and REM without (like always).1907 */1908 rc = NEMR3NotifyPhysRamRegister(pVM, GCPhys, cb);1909 2005 PGM_UNLOCK(pVM); 1910 2006 return rc; … … 1926 2022 Assert(pVM->pgm.s.fRamPreAlloc); 1927 2023 Log(("pgmR3PhysRamPreAllocate: enter\n")); 2024 #ifdef VBOX_WITH_PGM_NEM_MODE 2025 AssertLogRelReturn(!pVM->pgm.s.fNemMode, VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE); 2026 #endif 1928 2027 1929 2028 /* … … 2100 2199 2101 2200 if ( !pVM->pgm.s.fRamPreAlloc 2201 #ifdef VBOX_WITH_PGM_NEM_MODE 2202 && !pVM->pgm.s.fNemMode 2203 #endif 2102 2204 && pVM->pgm.s.fZeroRamPagesOnReset) 2103 2205 { … … 2135 2237 case PGMPAGETYPE_SPECIAL_ALIAS_MMIO: /** @todo perhaps leave the special page alone? I don't think VT-x copes with this code. */ 2136 2238 pgmHandlerPhysicalResetAliasedPage(pVM, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), 2137 true /*fDoAccounting*/);2239 pRam, true /*fDoAccounting*/); 2138 2240 break; 2139 2241 … … 2188 2290 case PGMPAGETYPE_SPECIAL_ALIAS_MMIO: /** @todo perhaps leave the special page alone? I don't think VT-x copes with this code. */ 2189 2291 pgmHandlerPhysicalResetAliasedPage(pVM, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), 2190 true /*fDoAccounting*/);2292 pRam, true /*fDoAccounting*/); 2191 2293 break; 2192 2294 … … 2396 2498 * for PCI memory, but we're doing the same thing for MMIO2 pages. 2397 2499 */ 2398 rc = pgmR3PhysFreePageRange(pVM, pRam, GCPhys, GCPhysLast, PGMPAGETYPE_MMIO);2500 rc = pgmR3PhysFreePageRange(pVM, pRam, GCPhys, GCPhysLast, NULL); 2399 2501 AssertRCReturnStmt(rc, PGM_UNLOCK(pVM), rc); 2400 2502 … … 2409 2511 else 2410 2512 { 2411 2412 2513 /* 2413 2514 * No RAM range, insert an ad hoc one. … … 2418 2519 Log(("PGMR3PhysMMIORegister: Adding ad hoc MMIO range for %RGp-%RGp %s\n", GCPhys, GCPhysLast, pszDesc)); 2419 2520 2521 /* Alloc. */ 2420 2522 const uint32_t cPages = cb >> PAGE_SHIFT; 2421 2523 const size_t cbRamRange = RT_UOFFSETOF_DYN(PGMRAMRANGE, aPages[cPages]); 2422 2524 rc = MMHyperAlloc(pVM, RT_UOFFSETOF_DYN(PGMRAMRANGE, aPages[cPages]), 16, MM_TAG_PGM_PHYS, (void **)&pNew); 2423 2525 AssertLogRelMsgRCReturnStmt(rc, ("cbRamRange=%zu\n", cbRamRange), PGM_UNLOCK(pVM), rc); 2526 2527 #ifdef VBOX_WITH_NATIVE_NEM 2528 /* Notify NEM. */ 2529 uint8_t u2State = 0; /* (must have valid state as there can't be anything to preserve) */ 2530 if (VM_IS_NEM_ENABLED(pVM)) 2531 { 2532 rc = NEMR3NotifyPhysMmioExMapEarly(pVM, GCPhys, cPages << PAGE_SHIFT, 0 /*fFlags*/, NULL, NULL, &u2State); 2533 AssertLogRelRCReturnStmt(rc, MMHyperFree(pVM, pNew), rc); 2534 } 2535 #endif 2424 2536 2425 2537 /* Initialize the range. */ … … 2435 2547 uint32_t iPage = cPages; 2436 2548 while (iPage-- > 0) 2549 { 2437 2550 PGM_PAGE_INIT_ZERO(&pNew->aPages[iPage], pVM, PGMPAGETYPE_MMIO); 2551 #ifdef VBOX_WITH_NATIVE_NEM 2552 PGM_PAGE_SET_NEM_STATE(&pNew->aPages[iPage], u2State); 2553 #endif 2554 } 2438 2555 Assert(PGM_PAGE_GET_TYPE(&pNew->aPages[0]) == PGMPAGETYPE_MMIO); 2439 2556 … … 2450 2567 */ 2451 2568 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, hType, pvUserR3, pvUserR0, pvUserRC, pszDesc); 2452 if ( RT_FAILURE(rc) 2453 && !fRamExists) 2569 if (RT_SUCCESS(rc)) 2570 { 2571 #ifdef VBOX_WITH_NATIVE_NEM 2572 /* Late NEM notification. */ 2573 if (VM_IS_NEM_ENABLED(pVM)) 2574 { 2575 uint32_t const fNemNotify = (fRamExists ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0); 2576 rc = NEMR3NotifyPhysMmioExMapLate(pVM, GCPhys, GCPhysLast - GCPhys + 1, fNemNotify, 2577 fRamExists ? (uint8_t *)pRam->pvR3 + (uintptr_t)(GCPhys - pRam->GCPhys) : NULL, 2578 NULL); 2579 AssertLogRelRCReturn(rc, rc); 2580 } 2581 #endif 2582 } 2583 /** @todo the phys handler failure handling isn't complete, esp. wrt NEM. */ 2584 else if (!fRamExists) 2454 2585 { 2455 2586 pVM->pgm.s.cPureMmioPages -= cb >> PAGE_SHIFT; … … 2532 2663 Log(("PGMR3PhysMMIODeregister: Freeing ad hoc MMIO range for %RGp-%RGp %s\n", 2533 2664 GCPhys, GCPhysLast, pRam->pszDesc)); 2665 /** @todo check the ad-hoc flags? */ 2666 2667 #ifdef VBOX_WITH_NATIVE_NEM 2668 if (VM_IS_NEM_ENABLED(pVM)) /* Notify REM before we unlink the range. */ 2669 { 2670 rc = NEMR3NotifyPhysMmioExUnmap(pVM, GCPhys, GCPhysLast - GCPhys + 1, 0 /*fFlags*/, NULL, NULL, NULL); 2671 AssertLogRelRCReturn(rc, rc); 2672 } 2673 #endif 2534 2674 2535 2675 pVM->pgm.s.cAllPages -= cPages; … … 2568 2708 iPage++; 2569 2709 } 2710 2711 #ifdef VBOX_WITH_NATIVE_NEM 2712 /* Notify REM (failure will probably leave things in a non-working state). */ 2713 if (VM_IS_NEM_ENABLED(pVM)) 2714 { 2715 uint8_t u2State = UINT8_MAX; 2716 rc = NEMR3NotifyPhysMmioExUnmap(pVM, GCPhys, GCPhysLast - GCPhys + 1, NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE, 2717 pRam->pvR3 ? (uint8_t *)pRam->pvR3 + GCPhys - pRam->GCPhys : NULL, 2718 NULL, &u2State); 2719 AssertLogRelRCReturn(rc, rc); 2720 if (u2State != UINT8_MAX) 2721 pgmPhysSetNemStateForPages(&pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT], 2722 cb >> PAGE_SHIFT, u2State); 2723 } 2724 #endif 2570 2725 break; 2571 2726 } … … 3384 3539 * for PCI memory, but we're doing the same thing for MMIO2 pages. 3385 3540 * 3386 * We replace th isMMIO/ZERO pages with real pages in the MMIO2 case.3541 * We replace these MMIO/ZERO pages with real pages in the MMIO2 case. 3387 3542 */ 3388 3543 Assert(pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_LAST_CHUNK); /* Only one chunk */ 3389 3390 int rc = pgmR3PhysFreePageRange(pVM, pRam, GCPhys, GCPhysLast, PGMPAGETYPE_MMIO); 3544 Assert(pFirstMmio->pvR3 == pFirstMmio->RamRange.pvR3); 3545 Assert(pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 3546 ? pFirstMmio->RamRange.pvR3 != NULL : pFirstMmio->RamRange.pvR3 == NULL); 3547 3548 #ifdef VBOX_WITH_PGM_NEM_MODE 3549 /* We cannot mix MMIO2 into a RAM range in simplified memory mode because pRam->pvR3 can't point 3550 both at the RAM and MMIO2, so we won't ever write & read from the actual MMIO2 memory if we try. */ 3551 AssertLogRelMsgReturn(!pVM->pgm.s.fNemMode || !(pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2), 3552 ("%s at %RGp-%RGp\n", pFirstMmio->RamRange.pszDesc, GCPhys, GCPhysLast), 3553 VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE); 3554 #endif 3555 3556 int rc = pgmR3PhysFreePageRange(pVM, pRam, GCPhys, GCPhysLast, pFirstMmio->RamRange.pvR3); 3391 3557 AssertRCReturnStmt(rc, PGM_UNLOCK(pVM), rc); 3392 3558 … … 3410 3576 PGM_PAGE_SET_PTE_INDEX(pVM, pPageDst, 0); 3411 3577 PGM_PAGE_SET_TRACKING(pVM, pPageDst, 0); 3412 /* (We tell NEM at the end of the function.)*/3578 /* NEM state is set by pgmR3PhysFreePageRange. */ 3413 3579 3414 3580 pVM->pgm.s.cZeroPages--; … … 3436 3602 for (PPGMREGMMIO2RANGE pCurMmio = pFirstMmio; ; pCurMmio = pCurMmio->pNextR3) 3437 3603 { 3604 #ifdef VBOX_WITH_NATIVE_NEM 3605 /* Tell NEM and get the new NEM state for the pages. */ 3606 uint8_t u2NemState = 0; 3607 if (VM_IS_NEM_ENABLED(pVM)) 3608 { 3609 int rc = NEMR3NotifyPhysMmioExMapEarly(pVM, pCurMmio->RamRange.GCPhys, 3610 pCurMmio->RamRange.GCPhysLast - pCurMmio->RamRange.GCPhys + 1, 3611 pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 3612 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0, 3613 NULL, pCurMmio->RamRange.pvR3, &u2NemState); 3614 AssertLogRelRCReturnStmt(rc, PGM_UNLOCK(pVM), rc); 3615 } 3616 #endif 3617 3438 3618 /* Clear the tracking data of pages we're going to reactivate. */ 3439 3619 PPGMPAGE pPageSrc = &pCurMmio->RamRange.aPages[0]; … … 3443 3623 PGM_PAGE_SET_TRACKING(pVM, pPageSrc, 0); 3444 3624 PGM_PAGE_SET_PTE_INDEX(pVM, pPageSrc, 0); 3625 #ifdef VBOX_WITH_NATIVE_NEM 3626 PGM_PAGE_SET_NEM_STATE(pPageSrc, u2NemState); 3627 #endif 3445 3628 pPageSrc++; 3446 3629 } … … 3487 3670 { 3488 3671 pCurMmio->fFlags &= ~PGMREGMMIO2RANGE_F_MAPPED; 3489 pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3 , fRamExists);3672 pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3); 3490 3673 } 3491 3674 … … 3511 3694 } 3512 3695 3696 /** @todo NEM notification cleanup */ 3513 3697 PGM_UNLOCK(pVM); 3514 3698 return rc; … … 3531 3715 pgmPhysInvalidatePageMapTLB(pVM); 3532 3716 3533 /* 3534 * Notify NEM while holding the lock (experimental) and REM without (like always). 3535 */ 3536 uint32_t const fNemNotify = (pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0) 3537 | (pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_OVERLAPPING ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0); 3538 int rc = NEMR3NotifyPhysMmioExMap(pVM, GCPhys, cbRange, fNemNotify, pFirstMmio->pvR3); 3717 #ifdef VBOX_WITH_NATIVE_NEM 3718 /* 3719 * Late NEM notification. 3720 */ 3721 if (VM_IS_NEM_ENABLED(pVM)) 3722 { 3723 int rc; 3724 uint32_t fNemFlags = pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0; 3725 if (fRamExists) 3726 rc = NEMR3NotifyPhysMmioExMapLate(pVM, GCPhys, GCPhysLast - GCPhys + 1, fNemFlags | NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE, 3727 pRam->pvR3 ? (uint8_t *)pRam->pvR3 + GCPhys - pRam->GCPhys : NULL, pFirstMmio->pvR3); 3728 else 3729 { 3730 rc = VINF_SUCCESS; 3731 for (PPGMREGMMIO2RANGE pCurMmio = pFirstMmio; ; pCurMmio = pCurMmio->pNextR3) 3732 { 3733 rc = NEMR3NotifyPhysMmioExMapLate(pVM, pCurMmio->RamRange.GCPhys, pCurMmio->RamRange.cb, fNemFlags, 3734 NULL, pCurMmio->RamRange.pvR3); 3735 if ((pCurMmio->fFlags & PGMREGMMIO2RANGE_F_LAST_CHUNK) || RT_FAILURE(rc)) 3736 break; 3737 } 3738 } 3739 AssertLogRelRCReturnStmt(rc, PGMR3PhysMmio2Unmap(pVM, pDevIns, hMmio2, GCPhys); PGM_UNLOCK(pVM), rc); 3740 } 3741 #endif 3539 3742 3540 3743 PGM_UNLOCK(pVM); 3541 3744 3542 return rc;3745 return VINF_SUCCESS; 3543 3746 } 3544 3747 … … 3601 3804 3602 3805 PPGMREGMMIO2RANGE pCurMmio = pFirstMmio; 3603 rc = pgmHandlerPhysicalExDeregister(pVM, pFirstMmio->pPhysHandlerR3 , RT_BOOL(fOldFlags & PGMREGMMIO2RANGE_F_OVERLAPPING));3806 rc = pgmHandlerPhysicalExDeregister(pVM, pFirstMmio->pPhysHandlerR3); 3604 3807 AssertRCReturnStmt(rc, PGM_UNLOCK(pVM), rc); 3605 3808 while (!(pCurMmio->fFlags & PGMREGMMIO2RANGE_F_LAST_CHUNK)) 3606 3809 { 3607 3810 pCurMmio = pCurMmio->pNextR3; 3608 rc = pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3 , RT_BOOL(fOldFlags & PGMREGMMIO2RANGE_F_OVERLAPPING));3811 rc = pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3); 3609 3812 AssertRCReturnStmt(rc, PGM_UNLOCK(pVM), VERR_PGM_PHYS_MMIO_EX_IPE); 3610 3813 } … … 3614 3817 * Unmap it. 3615 3818 */ 3616 RTGCPHYS const GCPhysRangeNotify = pFirstMmio->RamRange.GCPhys; 3819 int rcRet = VINF_SUCCESS; 3820 #ifdef VBOX_WITH_NATIVE_NEM 3821 uint32_t const fNemFlags = pFirstMmio->fFlags & PGMREGMMIO2RANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0; 3822 #endif 3617 3823 if (fOldFlags & PGMREGMMIO2RANGE_F_OVERLAPPING) 3618 3824 { … … 3632 3838 pRam = pRam->pNextR3; 3633 3839 3840 PPGMPAGE pPageDst = &pRam->aPages[(pFirstMmio->RamRange.GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; 3634 3841 uint32_t cPagesLeft = pFirstMmio->RamRange.cb >> PAGE_SHIFT; 3635 3842 if (fOldFlags & PGMREGMMIO2RANGE_F_MMIO2) 3636 3843 pVM->pgm.s.cZeroPages += cPagesLeft; 3637 3844 3638 PPGMPAGE pPageDst = &pRam->aPages[(pFirstMmio->RamRange.GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; 3845 #ifdef VBOX_WITH_NATIVE_NEM 3846 if (VM_IS_NEM_ENABLED(pVM)) /* Notify NEM. Note! we cannot be here in simple memory mode, see mapping function. */ 3847 { 3848 uint8_t u2State = UINT8_MAX; 3849 rc = NEMR3NotifyPhysMmioExUnmap(pVM, pFirstMmio->RamRange.GCPhys, pFirstMmio->RamRange.cb, 3850 fNemFlags | NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE, 3851 pRam->pvR3 3852 ? (uint8_t *)pRam->pvR3 + pFirstMmio->RamRange.GCPhys - pRam->GCPhys : NULL, 3853 pFirstMmio->pvR3, &u2State); 3854 AssertRCStmt(rc, rcRet = rc); 3855 if (u2State != UINT8_MAX) 3856 pgmPhysSetNemStateForPages(pPageDst, cPagesLeft, u2State); 3857 } 3858 #endif 3859 3639 3860 while (cPagesLeft-- > 0) 3640 3861 { … … 3658 3879 for (PPGMREGMMIO2RANGE pCurMmio = pFirstMmio; ; pCurMmio = pCurMmio->pNextR3) 3659 3880 { 3881 #ifdef VBOX_WITH_NATIVE_NEM 3882 if (VM_IS_NEM_ENABLED(pVM)) /* Notify NEM. */ 3883 { 3884 uint8_t u2State = UINT8_MAX; 3885 rc = NEMR3NotifyPhysMmioExUnmap(pVM, pCurMmio->RamRange.GCPhys, pCurMmio->RamRange.cb, fNemFlags, 3886 NULL, pCurMmio->pvR3, &u2State); 3887 AssertRCStmt(rc, rcRet = rc); 3888 if (u2State != UINT8_MAX) 3889 pgmPhysSetNemStateForPages(pCurMmio->RamRange.aPages, pCurMmio->RamRange.cb >> PAGE_SHIFT, u2State); 3890 } 3891 #endif 3660 3892 pgmR3PhysUnlinkRamRange(pVM, &pCurMmio->RamRange); 3661 3893 pCurMmio->RamRange.GCPhys = NIL_RTGCPHYS; … … 3677 3909 pgmPhysInvalidatePageMapTLB(pVM); 3678 3910 pgmPhysInvalidRamRangeTlbs(pVM); 3679 3680 /*3681 * Notify NEM while holding the lock (experimental) and REM without (like always).3682 */3683 uint32_t const fNemFlags = (fOldFlags & PGMREGMMIO2RANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0)3684 | (fOldFlags & PGMREGMMIO2RANGE_F_OVERLAPPING ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0);3685 rc = NEMR3NotifyPhysMmioExUnmap(pVM, GCPhysRangeNotify, cbRange, fNemFlags);3686 3911 3687 3912 PGM_UNLOCK(pVM); … … 3931 4156 */ 3932 4157 static int pgmR3PhysRomRegisterLocked(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb, 3933 const void *pvBinary, uint32_t cbBinary, uint 32_t fFlags, const char *pszDesc)4158 const void *pvBinary, uint32_t cbBinary, uint8_t fFlags, const char *pszDesc) 3934 4159 { 3935 4160 /* … … 3969 4194 * Find the RAM location and check for conflicts. 3970 4195 * 3971 * Conflict detection is a bit different than for RAM 3972 * registration since a ROM can be located within a RAM 3973 * range. So, what we have to check for is other memory 3974 * types (other than RAM that is) and that we don't span 3975 * more than one RAM range (layz). 4196 * Conflict detection is a bit different than for RAM registration since a 4197 * ROM can be located within a RAM range. So, what we have to check for is 4198 * other memory types (other than RAM that is) and that we don't span more 4199 * than one RAM range (lazy). 3976 4200 */ 3977 4201 bool fRamExists = false; … … 4008 4232 pRam->GCPhys + ((RTGCPHYS)(uintptr_t)(pPage - &pRam->aPages[0]) << PAGE_SHIFT), 4009 4233 pPage, GCPhys, GCPhysLast, pszDesc), VERR_PGM_RAM_CONFLICT); 4010 Assert(PGM_PAGE_IS_ZERO(pPage) );4234 Assert(PGM_PAGE_IS_ZERO(pPage) || PGM_IS_IN_NEM_MODE(pVM)); 4011 4235 pPage++; 4012 4236 } … … 4026 4250 } 4027 4251 4028 /* 4029 * Allocate memory for the virgin copy of the RAM. 4030 */ 4031 PGMMALLOCATEPAGESREQ pReq; 4032 int rc = GMMR3AllocatePagesPrepare(pVM, &pReq, cPages, GMMACCOUNT_BASE); 4033 AssertRCReturn(rc, rc); 4034 4035 for (uint32_t iPage = 0; iPage < cPages; iPage++) 4036 { 4037 pReq->aPages[iPage].HCPhysGCPhys = GCPhys + (iPage << PAGE_SHIFT); 4038 pReq->aPages[iPage].idPage = NIL_GMM_PAGEID; 4039 pReq->aPages[iPage].idSharedPage = NIL_GMM_PAGEID; 4040 } 4041 4042 rc = GMMR3AllocatePagesPerform(pVM, pReq); 4043 if (RT_FAILURE(rc)) 4044 { 4045 GMMR3AllocatePagesCleanup(pReq); 4046 return rc; 4252 #ifdef VBOX_WITH_NATIVE_NEM 4253 /* 4254 * Early NEM notification before we've made any changes or anything. 4255 */ 4256 uint32_t const fNemNotify = (fRamExists ? NEM_NOTIFY_PHYS_ROM_F_REPLACE : 0) 4257 | (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED ? NEM_NOTIFY_PHYS_ROM_F_SHADOW : 0); 4258 uint8_t u2NemState = UINT8_MAX; 4259 if (VM_IS_NEM_ENABLED(pVM)) 4260 { 4261 int rc = NEMR3NotifyPhysRomRegisterEarly(pVM, GCPhys, cPages << PAGE_SHIFT, 4262 fRamExists ? PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhys) : NULL, 4263 fNemNotify, &u2NemState); 4264 AssertLogRelRCReturn(rc, rc); 4265 } 4266 #endif 4267 4268 /* 4269 * Allocate memory for the virgin copy of the RAM. In simplified memory mode, 4270 * we allocate memory for any ad-hoc RAM range and for shadow pages. 4271 */ 4272 PGMMALLOCATEPAGESREQ pReq = NULL; 4273 #ifdef VBOX_WITH_PGM_NEM_MODE 4274 void *pvRam = NULL; 4275 void *pvAlt = NULL; 4276 if (pVM->pgm.s.fNemMode) 4277 { 4278 if (!fRamExists) 4279 { 4280 int rc = SUPR3PageAlloc(cPages, &pvRam); 4281 if (RT_FAILURE(rc)) 4282 return rc; 4283 } 4284 if (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED) 4285 { 4286 int rc = SUPR3PageAlloc(cPages, &pvAlt); 4287 if (RT_FAILURE(rc)) 4288 { 4289 if (pvRam) 4290 SUPR3PageFree(pvRam, cPages); 4291 return rc; 4292 } 4293 } 4294 } 4295 else 4296 #endif 4297 { 4298 int rc = GMMR3AllocatePagesPrepare(pVM, &pReq, cPages, GMMACCOUNT_BASE); 4299 AssertRCReturn(rc, rc); 4300 4301 for (uint32_t iPage = 0; iPage < cPages; iPage++) 4302 { 4303 pReq->aPages[iPage].HCPhysGCPhys = GCPhys + (iPage << PAGE_SHIFT); 4304 pReq->aPages[iPage].idPage = NIL_GMM_PAGEID; 4305 pReq->aPages[iPage].idSharedPage = NIL_GMM_PAGEID; 4306 } 4307 4308 rc = GMMR3AllocatePagesPerform(pVM, pReq); 4309 if (RT_FAILURE(rc)) 4310 { 4311 GMMR3AllocatePagesCleanup(pReq); 4312 return rc; 4313 } 4047 4314 } 4048 4315 … … 4051 4318 */ 4052 4319 PPGMROMRANGE pRomNew; 4053 rc = MMHyperAlloc(pVM, RT_UOFFSETOF_DYN(PGMROMRANGE, aPages[cPages]), 0, MM_TAG_PGM_PHYS, (void **)&pRomNew);4320 int rc = MMHyperAlloc(pVM, RT_UOFFSETOF_DYN(PGMROMRANGE, aPages[cPages]), 0, MM_TAG_PGM_PHYS, (void **)&pRomNew); 4054 4321 if (RT_SUCCESS(rc)) 4055 4322 { … … 4062 4329 * Initialize and insert the RAM range (if required). 4063 4330 */ 4331 uint32_t const idxFirstRamPage = fRamExists ? (GCPhys - pRam->GCPhys) >> PAGE_SHIFT : 0; 4064 4332 PPGMROMPAGE pRomPage = &pRomNew->aPages[0]; 4065 4333 if (!fRamExists) 4066 4334 { 4335 /* New RAM range. */ 4067 4336 pRamNew->pSelfR0 = MMHyperCCToR0(pVM, pRamNew); 4068 4337 pRamNew->GCPhys = GCPhys; … … 4074 4343 pRamNew->paLSPages = NULL; 4075 4344 4076 PPGMPAGE pPage = &pRamNew->aPages[0]; 4077 for (uint32_t iPage = 0; iPage < cPages; iPage++, pPage++, pRomPage++) 4345 PPGMPAGE pRamPage = &pRamNew->aPages[idxFirstRamPage]; 4346 #ifdef VBOX_WITH_PGM_NEM_MODE 4347 if (pVM->pgm.s.fNemMode) 4078 4348 { 4079 PGM_PAGE_INIT(pPage, 4080 pReq->aPages[iPage].HCPhysGCPhys, 4081 pReq->aPages[iPage].idPage, 4082 PGMPAGETYPE_ROM, 4083 PGM_PAGE_STATE_ALLOCATED); 4084 4085 pRomPage->Virgin = *pPage; 4349 AssertPtr(pvRam); Assert(pReq == NULL); 4350 pRamNew->pvR3 = pvRam; 4351 for (uint32_t iPage = 0; iPage < cPages; iPage++, pRamPage++, pRomPage++) 4352 { 4353 PGM_PAGE_INIT(pRamPage, UINT64_C(0x0000fffffffff000), NIL_GMM_PAGEID, 4354 PGMPAGETYPE_ROM, PGM_PAGE_STATE_ALLOCATED); 4355 pRomPage->Virgin = *pRamPage; 4356 } 4086 4357 } 4087 4088 pVM->pgm.s.cAllPages += cPages; 4358 else 4359 #endif 4360 for (uint32_t iPage = 0; iPage < cPages; iPage++, pRamPage++, pRomPage++) 4361 { 4362 PGM_PAGE_INIT(pRamPage, 4363 pReq->aPages[iPage].HCPhysGCPhys, 4364 pReq->aPages[iPage].idPage, 4365 PGMPAGETYPE_ROM, 4366 PGM_PAGE_STATE_ALLOCATED); 4367 4368 pRomPage->Virgin = *pRamPage; 4369 } 4370 4371 pVM->pgm.s.cAllPages += cPages; 4372 pVM->pgm.s.cPrivatePages += cPages; 4089 4373 pgmR3PhysLinkRamRange(pVM, pRamNew, pRamPrev); 4090 4374 } 4091 4375 else 4092 4376 { 4093 PPGMPAGE pPage = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT]; 4094 for (uint32_t iPage = 0; iPage < cPages; iPage++, pPage++, pRomPage++) 4377 /* Existing RAM range. */ 4378 PPGMPAGE pRamPage = &pRam->aPages[idxFirstRamPage]; 4379 #ifdef VBOX_WITH_PGM_NEM_MODE 4380 if (pVM->pgm.s.fNemMode) 4095 4381 { 4096 PGM_PAGE_SET_TYPE(pVM, pPage, PGMPAGETYPE_ROM); 4097 PGM_PAGE_SET_HCPHYS(pVM, pPage, pReq->aPages[iPage].HCPhysGCPhys); 4098 PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED); 4099 PGM_PAGE_SET_PAGEID(pVM, pPage, pReq->aPages[iPage].idPage); 4100 PGM_PAGE_SET_PDE_TYPE(pVM, pPage, PGM_PAGE_PDE_TYPE_DONTCARE); 4101 PGM_PAGE_SET_PTE_INDEX(pVM, pPage, 0); 4102 PGM_PAGE_SET_TRACKING(pVM, pPage, 0); 4103 4104 pRomPage->Virgin = *pPage; 4382 Assert(pvRam == NULL); Assert(pReq == NULL); 4383 for (uint32_t iPage = 0; iPage < cPages; iPage++, pRamPage++, pRomPage++) 4384 { 4385 Assert(PGM_PAGE_GET_HCPHYS(pRamPage) == UINT64_C(0x0000fffffffff000)); 4386 Assert(PGM_PAGE_GET_PAGEID(pRamPage) == NIL_GMM_PAGEID); 4387 Assert(PGM_PAGE_GET_STATE(pRamPage) == PGM_PAGE_STATE_ALLOCATED); 4388 PGM_PAGE_SET_TYPE(pVM, pRamPage, PGMPAGETYPE_ROM); 4389 PGM_PAGE_SET_STATE(pVM, pRamPage, PGM_PAGE_STATE_ALLOCATED); 4390 PGM_PAGE_SET_PDE_TYPE(pVM, pRamPage, PGM_PAGE_PDE_TYPE_DONTCARE); 4391 PGM_PAGE_SET_PTE_INDEX(pVM, pRamPage, 0); 4392 PGM_PAGE_SET_TRACKING(pVM, pRamPage, 0); 4393 4394 pRomPage->Virgin = *pRamPage; 4395 } 4105 4396 } 4106 4397 else 4398 #endif 4399 { 4400 for (uint32_t iPage = 0; iPage < cPages; iPage++, pRamPage++, pRomPage++) 4401 { 4402 PGM_PAGE_SET_TYPE(pVM, pRamPage, PGMPAGETYPE_ROM); 4403 PGM_PAGE_SET_HCPHYS(pVM, pRamPage, pReq->aPages[iPage].HCPhysGCPhys); 4404 PGM_PAGE_SET_STATE(pVM, pRamPage, PGM_PAGE_STATE_ALLOCATED); 4405 PGM_PAGE_SET_PAGEID(pVM, pRamPage, pReq->aPages[iPage].idPage); 4406 PGM_PAGE_SET_PDE_TYPE(pVM, pRamPage, PGM_PAGE_PDE_TYPE_DONTCARE); 4407 PGM_PAGE_SET_PTE_INDEX(pVM, pRamPage, 0); 4408 PGM_PAGE_SET_TRACKING(pVM, pRamPage, 0); 4409 4410 pRomPage->Virgin = *pRamPage; 4411 } 4412 pVM->pgm.s.cZeroPages -= cPages; 4413 pVM->pgm.s.cPrivatePages += cPages; 4414 } 4107 4415 pRamNew = pRam; 4108 4109 pVM->pgm.s.cZeroPages -= cPages;4110 4416 } 4111 pVM->pgm.s.cPrivatePages += cPages; 4417 4418 /* Set the NEM state of the pages if needed. */ 4419 if (u2NemState != UINT8_MAX) 4420 pgmPhysSetNemStateForPages(&pRamNew->aPages[idxFirstRamPage], cPages, u2NemState); 4112 4421 4113 4422 /* Flush physical page map TLB. */ 4114 4423 pgmPhysInvalidatePageMapTLB(pVM); 4115 4424 4116 4117 /* Notify NEM before we register handlers. */ 4118 uint32_t const fNemNotify = (fRamExists ? NEM_NOTIFY_PHYS_ROM_F_REPLACE : 0) 4119 | (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED ? NEM_NOTIFY_PHYS_ROM_F_SHADOW : 0); 4120 rc = NEMR3NotifyPhysRomRegisterEarly(pVM, GCPhys, cb, fNemNotify); 4121 4122 /* Register the ROM access handler. */ 4123 if (RT_SUCCESS(rc)) 4124 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType, 4125 pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew), 4126 pszDesc); 4425 /* 4426 * Register the ROM access handler. 4427 */ 4428 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType, 4429 pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew), pszDesc); 4127 4430 if (RT_SUCCESS(rc)) 4128 4431 { … … 4132 4435 */ 4133 4436 size_t cbBinaryLeft = cbBinary; 4134 PPGMPAGE pRamPage = &pRamNew->aPages[ (GCPhys - pRamNew->GCPhys) >> PAGE_SHIFT];4437 PPGMPAGE pRamPage = &pRamNew->aPages[idxFirstRamPage]; 4135 4438 for (uint32_t iPage = 0; iPage < cPages; iPage++, pRamPage++) 4136 4439 { … … 4170 4473 pRomNew->cbOriginal = cbBinary; 4171 4474 pRomNew->pszDesc = pszDesc; 4475 #ifdef VBOX_WITH_PGM_NEM_MODE 4476 pRomNew->pbR3Alternate = (uint8_t *)pvAlt; 4477 #endif 4172 4478 pRomNew->pvOriginal = fFlags & PGMPHYS_ROM_FLAGS_PERMANENT_BINARY 4173 4479 ? pvBinary : RTMemDup(pvBinary, cbBinary); … … 4178 4484 PPGMROMPAGE pPage = &pRomNew->aPages[iPage]; 4179 4485 pPage->enmProt = PGMROMPROT_READ_ROM_WRITE_IGNORE; 4180 PGM_PAGE_INIT_ZERO(&pPage->Shadow, pVM, PGMPAGETYPE_ROM_SHADOW); 4486 #ifdef VBOX_WITH_PGM_NEM_MODE 4487 if (pVM->pgm.s.fNemMode) 4488 PGM_PAGE_INIT(&pPage->Shadow, UINT64_C(0x0000fffffffff000), NIL_GMM_PAGEID, 4489 PGMPAGETYPE_ROM_SHADOW, PGM_PAGE_STATE_ALLOCATED); 4490 else 4491 #endif 4492 PGM_PAGE_INIT_ZERO(&pPage->Shadow, pVM, PGMPAGETYPE_ROM_SHADOW); 4181 4493 } 4182 4494 … … 4184 4496 if (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED) 4185 4497 { 4186 pVM->pgm.s.cZeroPages += cPages; 4187 pVM->pgm.s.cAllPages += cPages; 4498 #ifdef VBOX_WITH_PGM_NEM_MODE 4499 if (pVM->pgm.s.fNemMode) 4500 pVM->pgm.s.cPrivatePages += cPages; 4501 else 4502 #endif 4503 pVM->pgm.s.cZeroPages += cPages; 4504 pVM->pgm.s.cAllPages += cPages; 4188 4505 } 4189 4506 … … 4206 4523 4207 4524 pgmPhysInvalidatePageMapTLB(pVM); 4208 GMMR3AllocatePagesCleanup(pReq); 4209 4210 /* Notify NEM again. */ 4211 return NEMR3NotifyPhysRomRegisterLate(pVM, GCPhys, cb, fNemNotify); 4525 #ifdef VBOX_WITH_PGM_NEM_MODE 4526 if (!pVM->pgm.s.fNemMode) 4527 #endif 4528 GMMR3AllocatePagesCleanup(pReq); 4529 4530 /* 4531 * Notify NEM again. 4532 */ 4533 u2NemState = UINT8_MAX; 4534 rc = NEMR3NotifyPhysRomRegisterLate(pVM, GCPhys, cb, PGM_RAMRANGE_CALC_PAGE_R3PTR(pRamNew, GCPhys), 4535 fNemNotify, &u2NemState); 4536 if (u2NemState != UINT8_MAX) 4537 pgmPhysSetNemStateForPages(&pRamNew->aPages[idxFirstRamPage], cPages, u2NemState); 4538 if (RT_SUCCESS(rc)) 4539 return rc; 4540 4541 /* 4542 * bail out 4543 */ 4544 /* unlink */ 4545 if (pRomPrev) 4546 { 4547 pRomPrev->pNextR3 = pRom; 4548 pRomPrev->pNextR0 = pRom ? MMHyperCCToR0(pVM, pRom) : NIL_RTR0PTR; 4549 } 4550 else 4551 { 4552 pVM->pgm.s.pRomRangesR3 = pRom; 4553 pVM->pgm.s.pRomRangesR0 = pRom ? MMHyperCCToR0(pVM, pRom) : NIL_RTR0PTR; 4554 } 4555 4556 if (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED) 4557 { 4558 #ifdef VBOX_WITH_PGM_NEM_MODE 4559 if (pVM->pgm.s.fNemMode) 4560 pVM->pgm.s.cPrivatePages -= cPages; 4561 else 4562 #endif 4563 pVM->pgm.s.cZeroPages -= cPages; 4564 pVM->pgm.s.cAllPages -= cPages; 4565 } 4566 4212 4567 } 4213 4214 /* bail out */ 4215 rc = VERR_NO_MEMORY; 4568 else 4569 rc = VERR_NO_MEMORY; 4216 4570 } 4217 4571 … … 4225 4579 MMHyperFree(pVM, pRamNew); 4226 4580 } 4581 else 4582 { 4583 PPGMPAGE pRamPage = &pRam->aPages[idxFirstRamPage]; 4584 #ifdef VBOX_WITH_PGM_NEM_MODE 4585 if (pVM->pgm.s.fNemMode) 4586 { 4587 Assert(pvRam == NULL); Assert(pReq == NULL); 4588 for (uint32_t iPage = 0; iPage < cPages; iPage++, pRamPage++, pRomPage++) 4589 { 4590 Assert(PGM_PAGE_GET_HCPHYS(pRamPage) == UINT64_C(0x0000fffffffff000)); 4591 Assert(PGM_PAGE_GET_PAGEID(pRamPage) == NIL_GMM_PAGEID); 4592 Assert(PGM_PAGE_GET_STATE(pRamPage) == PGM_PAGE_STATE_ALLOCATED); 4593 PGM_PAGE_SET_TYPE(pVM, pRamPage, PGMPAGETYPE_RAM); 4594 PGM_PAGE_SET_STATE(pVM, pRamPage, PGM_PAGE_STATE_ALLOCATED); 4595 } 4596 } 4597 else 4598 #endif 4599 { 4600 for (uint32_t iPage = 0; iPage < cPages; iPage++, pRamPage++) 4601 PGM_PAGE_INIT_ZERO(pRamPage, pVM, PGMPAGETYPE_RAM); 4602 pVM->pgm.s.cZeroPages += cPages; 4603 pVM->pgm.s.cPrivatePages -= cPages; 4604 } 4605 } 4227 4606 } 4228 4607 MMHyperFree(pVM, pRomNew); … … 4230 4609 4231 4610 /** @todo Purge the mapping cache or something... */ 4232 GMMR3FreeAllocatedPages(pVM, pReq); 4233 GMMR3AllocatePagesCleanup(pReq); 4611 #ifdef VBOX_WITH_PGM_NEM_MODE 4612 if (pVM->pgm.s.fNemMode) 4613 { 4614 Assert(!pReq); 4615 if (pvRam) 4616 SUPR3PageFree(pvRam, cPages); 4617 if (pvAlt) 4618 SUPR3PageFree(pvAlt, cPages); 4619 } 4620 else 4621 #endif 4622 { 4623 GMMR3FreeAllocatedPages(pVM, pReq); 4624 GMMR3AllocatePagesCleanup(pReq); 4625 } 4234 4626 return rc; 4235 4627 } … … 4267 4659 */ 4268 4660 VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb, 4269 const void *pvBinary, uint32_t cbBinary, uint 32_t fFlags, const char *pszDesc)4661 const void *pvBinary, uint32_t cbBinary, uint8_t fFlags, const char *pszDesc) 4270 4662 { 4271 4663 Log(("PGMR3PhysRomRegister: pDevIns=%p GCPhys=%RGp(-%RGp) cb=%RGp pvBinary=%p cbBinary=%#x fFlags=%#x pszDesc=%s\n", … … 4308 4700 * out all the dirty pages and replace them by the zero page. 4309 4701 */ 4702 #ifdef VBOX_WITH_PGM_NEM_MODE 4703 if (pVM->pgm.s.fNemMode) 4704 { 4705 /* Clear all the shadow pages (currently using alternate backing). */ 4706 RT_BZERO(pRom->pbR3Alternate, pRom->cb); 4707 } 4708 else 4709 #endif 4310 4710 if (!pVM->pgm.s.fRamPreAlloc) 4311 4711 { … … 4467 4867 * Iterate the relevant pages and make necessary the changes. 4468 4868 */ 4869 #ifdef VBOX_WITH_NATIVE_NEM 4870 PPGMRAMRANGE const pRam = pgmPhysGetRange(pVM, GCPhys); 4871 AssertPtrReturn(pRam, VERR_INTERNAL_ERROR_3); 4872 #endif 4469 4873 bool fChanges = false; 4470 4874 uint32_t const cPages = pRom->GCPhysLast <= GCPhysLast … … 4481 4885 4482 4886 /* flush references to the page. */ 4483 PPGMPAGE pRamPage = pgmPhysGetPage(pVM, pRom->GCPhys + (iPage << PAGE_SHIFT));4484 int rc2 = pgmPoolTrackUpdateGCPhys(pVM, pRom->GCPhys + (iPage << PAGE_SHIFT), pRamPage,4485 4887 RTGCPHYS const GCPhysPage = pRom->GCPhys + (iPage << PAGE_SHIFT); 4888 PPGMPAGE pRamPage = pgmPhysGetPage(pVM, GCPhysPage); 4889 int rc2 = pgmPoolTrackUpdateGCPhys(pVM, GCPhysPage, pRamPage, true /*fFlushPTEs*/, &fFlushTLB); 4486 4890 if (rc2 != VINF_SUCCESS && (rc == VINF_SUCCESS || RT_FAILURE(rc2))) 4487 4891 rc = rc2; … … 4495 4899 /** @todo preserve the volatile flags (handlers) when these have been moved out of HCPhys! */ 4496 4900 4901 #ifdef VBOX_WITH_NATIVE_NEM 4902 # ifdef VBOX_WITH_PGM_NEM_MODE 4903 /* In simplified mode we have to switch the page data around too. */ 4904 if (pVM->pgm.s.fNemMode) 4905 { 4906 uint8_t abPage[PAGE_SIZE]; 4907 uint8_t * const pbRamPage = PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysPage); 4908 memcpy(abPage, &pRom->pbR3Alternate[(size_t)iPage << PAGE_SHIFT], sizeof(abPage)); 4909 memcpy(&pRom->pbR3Alternate[(size_t)iPage << PAGE_SHIFT], pbRamPage, sizeof(abPage)); 4910 memcpy(pbRamPage, abPage, sizeof(abPage)); 4911 } 4912 # endif 4497 4913 /* Tell NEM about the backing and protection change. */ 4498 4914 if (VM_IS_NEM_ENABLED(pVM)) … … 4500 4916 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pNew); 4501 4917 NEMHCNotifyPhysPageChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pOld), PGM_PAGE_GET_HCPHYS(pNew), 4918 PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysPage), 4502 4919 pgmPhysPageCalcNemProtection(pRamPage, enmType), enmType, &u2State); 4503 4920 PGM_PAGE_SET_NEM_STATE(pRamPage, u2State); 4504 4921 } 4922 #endif 4505 4923 } 4506 4924 pRomPage->enmProt = enmProt; … … 5216 5634 * 5217 5635 * @param pVM The cross context VM structure. 5218 * @param pReq Pointer to the request. 5636 * @param pReq Pointer to the request. This is NULL when doing a 5637 * bulk free in NEM memory mode. 5219 5638 * @param pcPendingPages Where the number of pages waiting to be freed are 5220 * kept. This will normally be incremented. 5639 * kept. This will normally be incremented. This is 5640 * NULL when doing a bulk free in NEM memory mode. 5221 5641 * @param pPage Pointer to the page structure. 5222 5642 * @param GCPhys The guest physical address of the page, if applicable. … … 5250 5670 const uint32_t idPage = PGM_PAGE_GET_PAGEID(pPage); 5251 5671 Log3(("pgmPhysFreePage: idPage=%#x GCPhys=%RGp pPage=%R[pgmpage]\n", idPage, GCPhys, pPage)); 5252 if (RT_UNLIKELY( idPage == NIL_GMM_PAGEID 5253 || idPage > GMM_PAGEID_LAST 5254 || PGM_PAGE_GET_CHUNKID(pPage) == NIL_GMM_CHUNKID)) 5672 if (RT_UNLIKELY(!PGM_IS_IN_NEM_MODE(pVM) 5673 ? idPage == NIL_GMM_PAGEID 5674 || idPage > GMM_PAGEID_LAST 5675 || PGM_PAGE_GET_CHUNKID(pPage) == NIL_GMM_CHUNKID 5676 : idPage != NIL_GMM_PAGEID)) 5255 5677 { 5256 5678 AssertMsgFailed(("GCPhys=%RGp pPage=%R[pgmpage]\n", GCPhys, pPage)); … … 5286 5708 pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhys); 5287 5709 5710 #ifdef VBOX_WITH_PGM_NEM_MODE 5711 /* 5712 * Skip the rest if we're doing a bulk free in NEM memory mode. 5713 */ 5714 if (!pReq) 5715 return VINF_SUCCESS; 5716 AssertLogRelReturn(!pVM->pgm.s.fNemMode, VERR_PGM_NOT_SUPPORTED_FOR_NEM_MODE); 5717 #endif 5718 5719 #ifdef VBOX_WITH_NATIVE_NEM 5288 5720 /* Notify NEM. */ 5289 /** @todo consider doing batch NEM notifications.*/5721 /** @todo Remove this one? */ 5290 5722 if (VM_IS_NEM_ENABLED(pVM)) 5291 5723 { 5292 5724 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 5293 NEMHCNotifyPhysPageChanged(pVM, GCPhys, HCPhysPrev, pVM->pgm.s.HCPhysZeroPg, 5725 NEMHCNotifyPhysPageChanged(pVM, GCPhys, HCPhysPrev, pVM->pgm.s.HCPhysZeroPg, pVM->pgm.s.pvZeroPgR3, 5294 5726 pgmPhysPageCalcNemProtection(pPage, enmNewType), enmNewType, &u2State); 5295 5727 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 5296 5728 } 5729 #endif 5297 5730 5298 5731 /* -
trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp
r90439 r91848 2700 2700 if ( PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_ROM 2701 2701 || PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_ROM_SHADOW 2702 #ifdef VBOX_WITH_PGM_NEM_MODE 2703 || pVM->pgm.s.fNemMode 2704 #endif 2702 2705 || pVM->pgm.s.fRamPreAlloc) 2703 2706 { -
trunk/src/VBox/VMM/include/NEMInternal.h
r91702 r91848 42 42 */ 43 43 44 #if defined(VBOX_WITH_PGM_NEM_MODE) && !defined(VBOX_WITH_NATIVE_NEM) 45 # error "VBOX_WITH_PGM_NEM_MODE requires VBOX_WITH_NATIVE_NEM to be defined" 46 #endif 47 44 48 45 49 #ifdef RT_OS_WINDOWS … … 60 64 # if defined(NEM_WIN_WITH_RING0_RUNLOOP) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) 61 65 # error "NEM_WIN_WITH_RING0_RUNLOOP requires NEM_WIN_USE_HYPERCALLS_FOR_PAGES" 66 # endif 67 # if defined(VBOX_WITH_PGM_NEM_MODE) && defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) 68 # error "VBOX_WITH_PGM_NEM_MODE cannot be used together with NEM_WIN_USE_HYPERCALLS_FOR_PAGES" 62 69 # endif 63 70 … … 451 458 void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags); 452 459 453 int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);454 int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2);455 int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);456 int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);457 int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);458 460 void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled); 459 461 #endif 460 462 461 463 void nemHCNativeNotifyHandlerPhysicalRegister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb); 462 void nemHCNativeNotifyHandlerPhysicalDeregister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb,463 int fRestoreAsRAM, bool fRestoreAsRAM2);464 464 void nemHCNativeNotifyHandlerPhysicalModify(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld, 465 465 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM); 466 466 int nemHCNativeNotifyPhysPageAllocated(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt, 467 467 PGMPAGETYPE enmType, uint8_t *pu2State); 468 void nemHCNativeNotifyPhysPageProtChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,469 PGMPAGETYPE enmType, uint8_t *pu2State);470 void nemHCNativeNotifyPhysPageChanged(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, uint32_t fPageProt,471 PGMPAGETYPE enmType, uint8_t *pu2State);472 468 473 469 -
trunk/src/VBox/VMM/include/PGMInline.h
r91247 r91848 346 346 } 347 347 348 #ifdef VBOX_WITH_NATIVE_NEM 348 349 /* Tell NEM. */ 349 350 if (VM_IS_NEM_ENABLED(pVM)) 350 351 { 351 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 352 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 352 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 353 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 354 PPGMRAMRANGE pRam = pgmPhysGetRange(pVM, GCPhysPage); 353 355 NEMHCNotifyPhysPageProtChanged(pVM, GCPhysPage, PGM_PAGE_GET_HCPHYS(pPage), 356 pRam ? PGM_RAMRANGE_CALC_PAGE_R3PTR(pRam, GCPhysPage) : NULL, 354 357 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 355 358 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 356 359 } 360 #endif 357 361 } 358 362 -
trunk/src/VBox/VMM/include/PGMInternal.h
r91712 r91848 159 159 * only making them writable when getting a write access \#PF. */ 160 160 #define VBOX_WITH_REAL_WRITE_MONITORED_PAGES 161 162 /** @def VBOX_WITH_PGM_NEM_MODE 163 * Enabled the NEM memory management mode in PGM. See PGM::fNemMode for 164 * details. */ 165 #ifdef DOXYGEN_RUNNING 166 # define VBOX_WITH_PGM_NEM_MODE 167 #endif 161 168 162 169 /** @} */ … … 1276 1283 /** Last address in the range (inclusive). Page aligned (-1). */ 1277 1284 RTGCPHYS GCPhysLast; 1278 /** Start of the HC mapping of the range. This is only used for MMIO2 . */1285 /** Start of the HC mapping of the range. This is only used for MMIO2 and in NEM mode. */ 1279 1286 R3PTRTYPE(void *) pvR3; 1280 1287 /** Live save per page tracking data. */ … … 1335 1342 #define PGM_RAMRANGE_TLB_IDX(a_GCPhys) ( ((a_GCPhys) >> 20) & (PGM_RAMRANGE_TLB_ENTRIES - 1) ) 1336 1343 1344 /** 1345 * Calculates the ring-3 address for a_GCPhysPage if the RAM range has a 1346 * mapping address. 1347 */ 1348 #define PGM_RAMRANGE_CALC_PAGE_R3PTR(a_pRam, a_GCPhysPage) \ 1349 ( (a_pRam)->pvR3 ? (R3PTRTYPE(uint8_t *))(a_pRam)->pvR3 + (a_GCPhysPage) - (a_pRam)->GCPhys : NULL ) 1337 1350 1338 1351 … … 1395 1408 RTGCPHYS cb; 1396 1409 /** The flags (PGMPHYS_ROM_FLAGS_*). */ 1397 uint 32_tfFlags;1410 uint8_t fFlags; 1398 1411 /** The saved state range ID. */ 1399 1412 uint8_t idSavedState; 1400 1413 /** Alignment padding. */ 1401 uint8_t au8Alignment[3]; 1402 /** Alignment padding ensuring that aPages is sizeof(PGMROMPAGE) aligned. */ 1403 uint32_t au32Alignemnt[HC_ARCH_BITS == 32 ? 5 : 1]; 1414 uint8_t au8Alignment[2]; 1404 1415 /** The size bits pvOriginal points to. */ 1405 1416 uint32_t cbOriginal; … … 1409 1420 /** The ROM description. */ 1410 1421 R3PTRTYPE(const char *) pszDesc; 1422 #ifdef VBOX_WITH_PGM_NEM_MODE 1423 /** In simplified memory mode this provides alternate backing for shadowed ROMs. 1424 * - PGMROMPROT_READ_ROM_WRITE_IGNORE: Shadow 1425 * - PGMROMPROT_READ_ROM_WRITE_RAM: Shadow 1426 * - PGMROMPROT_READ_RAM_WRITE_IGNORE: ROM 1427 * - PGMROMPROT_READ_RAM_WRITE_RAM: ROM */ 1428 R3PTRTYPE(uint8_t *) pbR3Alternate; 1429 RTR3PTR pvAlignment2; 1430 #endif 1411 1431 /** The per page tracking structures. */ 1412 1432 PGMROMPAGE aPages[1]; … … 2919 2939 */ 2920 2940 bool fRamPreAlloc; 2941 #ifdef VBOX_WITH_PGM_NEM_MODE 2942 /** Set if we're operating in NEM memory mode. 2943 * 2944 * NEM mode implies that memory is allocated in big chunks for each RAM range 2945 * rather than on demand page by page. Memory is also not locked and PGM has 2946 * therefore no physical addresses for them. Page sharing is out of the 2947 * question. Ballooning depends on the native execution engine, but probably 2948 * pointless as well. */ 2949 bool fNemMode; 2950 # define PGM_IS_IN_NEM_MODE(a_pVM) ((a_pVM)->pgm.s.fNemMode) 2951 #else 2952 # define PGM_IS_IN_NEM_MODE(a_pVM) (false) 2953 #endif 2921 2954 /** Indicates whether write monitoring is currently in use. 2922 2955 * This is used to prevent conflicts between live saving and page sharing … … 2932 2965 * change this later on. */ 2933 2966 bool fNestedPaging; 2934 /** The host paging mode. (This is what SUPLib reports.) */2935 SUPPAGINGMODE enmHostMode;2936 2967 /** We're not in a state which permits writes to guest memory. 2937 2968 * (Only used in strict builds.) */ … … 2955 2986 bool fUseLargePages; 2956 2987 /** Alignment padding. */ 2957 bool afAlignment3[6]; 2988 #ifndef VBOX_WITH_PGM_NEM_MODE 2989 bool afAlignment3[1]; 2990 #endif 2991 /** The host paging mode. (This is what SUPLib reports.) */ 2992 SUPPAGINGMODE enmHostMode; 2993 bool fAlignment3b; 2958 2994 2959 2995 /** Indicates that PGMR3FinalizeMappings has been called and that further … … 2975 3011 * This is valid if either fMappingsFixed or fMappingsFixedRestored is set. */ 2976 3012 RTGCPTR GCPtrMappingFixed; 3013 #ifndef PGM_WITHOUT_MAPPINGS 2977 3014 /** The address of the previous RAM range mapping. */ 2978 3015 RTGCPTR GCPtrPrevRamRangeMapping; 3016 #else 3017 RTGCPTR Unused0; 3018 #endif 2979 3019 2980 3020 /** Physical access handler type for ROM protection. */ … … 3722 3762 int pgmHandlerPhysicalExDup(PVMCC pVM, PPGMPHYSHANDLER pPhysHandlerSrc, PPGMPHYSHANDLER *ppPhysHandler); 3723 3763 int pgmHandlerPhysicalExRegister(PVMCC pVM, PPGMPHYSHANDLER pPhysHandler, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast); 3724 int pgmHandlerPhysicalExDeregister(PVMCC pVM, PPGMPHYSHANDLER pPhysHandler , int fRestoreAsRAM);3764 int pgmHandlerPhysicalExDeregister(PVMCC pVM, PPGMPHYSHANDLER pPhysHandler); 3725 3765 int pgmHandlerPhysicalExDestroy(PVMCC pVM, PPGMPHYSHANDLER pHandler); 3726 3766 void pgmR3HandlerPhysicalUpdateAll(PVM pVM); 3727 3767 bool pgmHandlerPhysicalIsAll(PVMCC pVM, RTGCPHYS GCPhys); 3728 void pgmHandlerPhysicalResetAliasedPage(PVMCC pVM, PPGMPAGE pPage, RTGCPHYS GCPhysPage, bool fDoAccounting);3768 void pgmHandlerPhysicalResetAliasedPage(PVMCC pVM, PPGMPAGE pPage, RTGCPHYS GCPhysPage, PPGMRAMRANGE pRam, bool fDoAccounting); 3729 3769 DECLCALLBACK(void) pgmR3InfoHandlers(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 3730 3770 int pgmR3InitSavedState(PVM pVM, uint64_t cbRam); … … 3763 3803 int pgmPhysGetPageExSlow(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage); 3764 3804 int pgmPhysGetPageAndRangeExSlow(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam); 3805 #ifdef VBOX_WITH_NATIVE_NEM 3806 void pgmPhysSetNemStateForPages(PPGMPAGE paPages, RTGCPHYS cPages, uint8_t u2State); 3807 #endif 3765 3808 3766 3809 #ifdef IN_RING3
Note:
See TracChangeset
for help on using the changeset viewer.