Changeset 6927 in vbox for trunk/src/VBox
- Timestamp:
- Feb 12, 2008 8:44:35 PM (17 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGM.cpp
r6925 r6927 2150 2150 uint16_t u16 = 0; 2151 2151 SSMR3GetU16(pSSM, &u16); 2152 u16 &= PAGE_OFFSET_MASK & ~( MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_WRITE | MM_RAM_FLAGS_VIRTUAL_ALL2152 u16 &= PAGE_OFFSET_MASK & ~( RT_BIT(4) | RT_BIT(5) | RT_BIT(6) 2153 2153 | RT_BIT(7) | RT_BIT(8) | RT_BIT(9) | RT_BIT(10) ); 2154 2154 // &= MM_RAM_FLAGS_DYNAMIC_ALLOC | MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2 -
trunk/src/VBox/VMM/PGMInternal.h
r6914 r6927 405 405 AVLROGCPHYSNODECORE Core; 406 406 /** Offset from this struct to the PGMVIRTHANDLER structure. */ 407 RTGCINTPTRoffVirtHandler;408 /** Offset of the next alias relative rto this one.407 int32_t offVirtHandler; 408 /** Offset of the next alias relative to this one. 409 409 * Bit 0 is used for indicating whether we're in the tree. 410 410 * Bit 1 is used for indicating that we're the head node. … … 530 530 /** The physical handler state (PGM_PAGE_HNDL_PHYS_STATE*) */ 531 531 uint32_t u2HandlerPhysStateX : 2; 532 uint32_t u29B : 27; 532 /** The virtual handler state (PGM_PAGE_HNDL_VIRT_STATE*) */ 533 uint32_t u2HandlerVirtStateX : 2; 534 uint32_t u29B : 25; 533 535 } PGMPAGE; 534 536 AssertCompileSize(PGMPAGE, 16); … … 791 793 792 794 /** 793 * Checks if the page has any access handlers, including temporarily disabled ones.794 * @returns true/false795 * @param pPage Pointer to the physical guest page tracking structure.796 */797 #define PGM_PAGE_HAVE_ANY_HANDLERS(pPage) \798 ( (pPage)->u2HandlerPhysStateX != PGM_PAGE_HNDL_PHYS_STATE_NONE \799 || ((pPage)->HCPhys & MM_RAM_FLAGS_VIRTUAL_HANDLER) )800 801 /**802 * Checks if the page has any active access handlers.803 * @returns true/false804 * @param pPage Pointer to the physical guest page tracking structure.805 */806 #define PGM_PAGE_HAVE_ACTIVE_HANDLERS(pPage) \807 ( (pPage)->u2HandlerPhysStateX >= PGM_PAGE_HNDL_PHYS_STATE_WRITE \808 || ((pPage)->HCPhys & MM_RAM_FLAGS_VIRTUAL_HANDLER) )809 810 /**811 * Checks if the page has any active access handlers catching all accesses.812 * @returns true/false813 * @param pPage Pointer to the physical guest page tracking structure.814 */815 #define PGM_PAGE_HAVE_ACTIVE_ALL_HANDLERS(pPage) \816 ( (pPage)->u2HandlerPhysStateX == PGM_PAGE_HNDL_PHYS_STATE_ALL \817 || ((pPage)->HCPhys & MM_RAM_FLAGS_VIRTUAL_ALL) )818 819 /**820 795 * Checks if the page has any physical access handlers, including temporariliy disabled ones. 821 796 * @returns true/false … … 831 806 #define PGM_PAGE_HAVE_ACTIVE_PHYSICAL_HANDLERS(pPage) ( (pPage)->u2HandlerPhysStateX >= PGM_PAGE_HNDL_PHYS_STATE_WRITE ) 832 807 808 809 /** @name Virtual Access Handler State values (PGMPAGE::u2HandlerVirtStateX). 810 * 811 * @remarks The values are assigned in order of priority, so we can calculate 812 * the correct state for a page with different handlers installed. 813 * @{ */ 814 /** No handler installed. */ 815 #define PGM_PAGE_HNDL_VIRT_STATE_NONE 0 816 /* 1 is reserved so the lineup is identical with the physical ones. */ 817 /** Write access is monitored. */ 818 #define PGM_PAGE_HNDL_VIRT_STATE_WRITE 2 819 /** All access is monitored. */ 820 #define PGM_PAGE_HNDL_VIRT_STATE_ALL 3 821 /** @} */ 822 823 /** 824 * Gets the virtual access handler state of a page. 825 * @returns PGM_PAGE_HNDL_VIRT_STATE_* value. 826 * @param pPage Pointer to the physical guest page tracking structure. 827 */ 828 #define PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) ( (pPage)->u2HandlerVirtStateX ) 829 830 /** 831 * Sets the virtual access handler state of a page. 832 * @param pPage Pointer to the physical guest page tracking structure. 833 * @param _uState The new state value. 834 */ 835 #define PGM_PAGE_SET_HNDL_VIRT_STATE(pPage, _uState) \ 836 do { (pPage)->u2HandlerVirtStateX = (_uState); } while (0) 837 833 838 /** 834 839 * Checks if the page has any virtual access handlers. … … 836 841 * @param pPage Pointer to the physical guest page tracking structure. 837 842 */ 838 #define PGM_PAGE_HAVE_ANY_VIRTUAL_HANDLERS(pPage) ( (pPage)-> HCPhys & MM_RAM_FLAGS_VIRTUAL_HANDLER)843 #define PGM_PAGE_HAVE_ANY_VIRTUAL_HANDLERS(pPage) ( (pPage)->u2HandlerVirtStateX != PGM_PAGE_HNDL_VIRT_STATE_NONE ) 839 844 840 845 /** … … 845 850 */ 846 851 #define PGM_PAGE_HAVE_ACTIVE_VIRTUAL_HANDLERS(pPage) PGM_PAGE_HAVE_ANY_VIRTUAL_HANDLERS(pPage) 852 853 854 855 /** 856 * Checks if the page has any access handlers, including temporarily disabled ones. 857 * @returns true/false 858 * @param pPage Pointer to the physical guest page tracking structure. 859 */ 860 #define PGM_PAGE_HAVE_ANY_HANDLERS(pPage) \ 861 ( (pPage)->u2HandlerPhysStateX != PGM_PAGE_HNDL_PHYS_STATE_NONE \ 862 || (pPage)->u2HandlerVirtStateX != PGM_PAGE_HNDL_VIRT_STATE_NONE ) 863 864 /** 865 * Checks if the page has any active access handlers. 866 * @returns true/false 867 * @param pPage Pointer to the physical guest page tracking structure. 868 */ 869 #define PGM_PAGE_HAVE_ACTIVE_HANDLERS(pPage) \ 870 ( (pPage)->u2HandlerPhysStateX >= PGM_PAGE_HNDL_PHYS_STATE_WRITE \ 871 || (pPage)->u2HandlerVirtStateX >= PGM_PAGE_HNDL_VIRT_STATE_WRITE ) 872 873 /** 874 * Checks if the page has any active access handlers catching all accesses. 875 * @returns true/false 876 * @param pPage Pointer to the physical guest page tracking structure. 877 */ 878 #define PGM_PAGE_HAVE_ACTIVE_ALL_HANDLERS(pPage) \ 879 ( (pPage)->u2HandlerPhysStateX == PGM_PAGE_HNDL_PHYS_STATE_ALL \ 880 || (pPage)->u2HandlerVirtStateX == PGM_PAGE_HNDL_VIRT_STATE_ALL ) 847 881 848 882 … … 2455 2489 * @{ 2456 2490 */ 2457 /** Updates the MM_RAM_FLAGS_VIRTUAL_HANDLER page bit. */2491 /** Updates the virtual access handler state bit in PGMPAGE. */ 2458 2492 #define PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL RT_BIT(0) 2459 2493 /** Always sync CR3. */ … … 3250 3284 3251 3285 /** 3286 * Gets the page state for a virtual handler. 3287 * 3288 * @returns The virtual handler page state. 3289 * @param pCur The virtual handler in question. 3290 * @remarks This should never be used on a hypervisor access handler. 3291 */ 3292 DECLINLINE(unsigned) pgmHandlerVirtualCalcState(PPGMVIRTHANDLER pCur) 3293 { 3294 switch (pCur->enmType) 3295 { 3296 case PGMVIRTHANDLERTYPE_WRITE: 3297 return PGM_PAGE_HNDL_VIRT_STATE_WRITE; 3298 case PGMVIRTHANDLERTYPE_ALL: 3299 return PGM_PAGE_HNDL_VIRT_STATE_ALL; 3300 default: 3301 AssertFatalMsgFailed(("Invalid type %d\n", pCur->enmType)); 3302 } 3303 } 3304 3305 3306 /** 3252 3307 * Clears one physical page of a virtual handler 3253 3308 * … … 3255 3310 * @param pCur Virtual handler structure 3256 3311 * @param iPage Physical page index 3312 * 3313 * @remark Only used when PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL is being set, so no 3314 * need to care about other handlers in the same page. 3257 3315 */ 3258 3316 DECLINLINE(void) pgmHandlerVirtualClearPage(PPGM pPGM, PPGMVIRTHANDLER pCur, unsigned iPage) … … 3345 3403 * Clear the ram flags for this page. 3346 3404 */ 3347 int rc = pgmRamFlagsClearByGCPhys(pPGM, pPhys2Virt->Core.Key,3348 MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_VIRTUAL_WRITE);3349 AssertRC(rc);3405 PPGMPAGE pPage = pgmPhysGetPage(pPGM, pPhys2Virt->Core.Key); 3406 AssertReturnVoid(pPage); 3407 PGM_PAGE_SET_HNDL_VIRT_STATE(pPage, PGM_PAGE_HNDL_VIRT_STATE_NONE); 3350 3408 } 3351 3409 -
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r6913 r6927 93 93 94 94 # if PGM_WITH_PAGING(PGM_GST_TYPE) 95 /* Determine current privilege level */96 uint32_t cpl = CPUMGetGuestCPL(pVM, pRegFrame);97 98 95 # ifdef PGM_SYNC_DIRTY_BIT 99 96 /* … … 345 342 * In case of write access continue to the GC write handler. 346 343 */ 347 if ( (pPage->HCPhys & (MM_RAM_FLAGS_VIRTUAL_WRITE | MM_RAM_FLAGS_VIRTUAL_ALL)) == MM_RAM_FLAGS_VIRTUAL_WRITE /** @todo PAGE FLAGS */344 if ( PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) < PGM_PAGE_HNDL_PHYS_STATE_ALL 348 345 && !(uErr & X86_TRAP_PF_P)) 349 346 { … … 439 436 STAM_COUNTER_INC(&pVM->pgm.s.StatHandlersUnhandled); 440 437 441 if ( !(pPage->HCPhys & (MM_RAM_FLAGS_VIRTUAL_ALL)) /** @todo PAGE FLAGS */ 442 && PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) < PGM_PAGE_HNDL_PHYS_STATE_ALL 438 if ( !PGM_PAGE_HAVE_ACTIVE_ALL_HANDLERS(pPage) 443 439 && !(uErr & X86_TRAP_PF_P)) 444 440 { … … 539 535 540 536 # if PGM_WITH_PAGING(PGM_GST_TYPE) && !defined(IN_RING0) 541 if ( cpl== 0)537 if (CPUMGetGuestCPL(pVM, pRegFrame) == 0) 542 538 { 543 539 uint64_t fPageGst; … … 1128 1124 const RTHCPHYS HCPhys = pPage->HCPhys; /** @todo FLAGS */ 1129 1125 SHWPTE PteDst; 1130 if ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) >= PGM_PAGE_HNDL_PHYS_STATE_WRITE 1131 || (HCPhys & (MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_VIRTUAL_WRITE))) 1126 if (PGM_PAGE_HAVE_ACTIVE_HANDLERS(pPage)) 1132 1127 { 1133 1128 /** @todo r=bird: Are we actually handling dirty and access bits for pages with access handlers correctly? No. */ 1134 if ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) <= PGM_PAGE_HNDL_PHYS_STATE_WRITE 1135 && !(HCPhys & MM_RAM_FLAGS_VIRTUAL_ALL)) 1129 if (!PGM_PAGE_HAVE_ACTIVE_ALL_HANDLERS(pPage)) 1136 1130 PteDst.u = (PteSrc.u & ~(X86_PTE_PAE_PG_MASK | X86_PTE_AVL_MASK | X86_PTE_PAT | X86_PTE_PCD | X86_PTE_PWT | X86_PTE_RW)) 1137 1131 | (HCPhys & X86_PTE_PAE_PG_MASK); -
trunk/src/VBox/VMM/VMMAll/PGMAllGst.h
r6913 r6927 657 657 #endif 658 658 659 unsigned fFlags;660 switch (pCur->enmType)661 {662 case PGMVIRTHANDLERTYPE_WRITE: fFlags = MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_WRITE; break;663 case PGMVIRTHANDLERTYPE_ALL: fFlags = MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_ALL; break;664 /* hypervisor handlers need no flags and wouldn't have nowhere to put them in any case. */665 case PGMVIRTHANDLERTYPE_HYPERVISOR:666 return 0;667 }668 669 659 unsigned offPage = GCPtr & PAGE_OFFSET_MASK; 670 660 unsigned iPage = 0; -
trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
r6913 r6927 1026 1026 *piPage = pCur - &(*ppVirt)->aPhysToVirt[0]; 1027 1027 1028 LogFlow(("PHYS2VIRT: found match for %VGp -> %VGv *piPage=%#x\n", 1029 GCPhys, (*ppVirt)->GCPtr, *piPage)); 1028 LogFlow(("PHYS2VIRT: found match for %VGp -> %VGv *piPage=%#x\n", GCPhys, (*ppVirt)->GCPtr, *piPage)); 1030 1029 STAM_PROFILE_STOP(CTXSUFF(&pVM->pgm.s.StatVirtHandleSearchByPhys), a); 1031 1030 return VINF_SUCCESS; … … 1041 1040 * Deal with aliases in phys2virt. 1042 1041 * 1042 * As pointed out by the various todos, this currently only deals with 1043 * aliases where the two ranges match 100%. 1044 * 1043 1045 * @param pVM The VM handle. 1044 1046 * @param pPhys2Virt The node we failed insert. … … 1050 1052 */ 1051 1053 /** @todo Deal with partial overlapping. (Unlikly situation, so I'm too lazy to do anything about it now.) */ 1054 /** @todo check if the current head node covers the ground we do. This is highly unlikely 1055 * and I'm too lazy to implement this now as it will require sorting the list and stuff like that. */ 1052 1056 PPGMPHYS2VIRTHANDLER pHead = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTXSUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key); 1053 if (!pHead)1054 {1055 /** @todo do something clever here... */1056 #ifdef IN_RING31057 LogRel(("pgmHandlerVirtualInsertAliased: %VGp-%VGp\n", pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast));1058 #endif1059 pPhys2Virt->offNextAlias = 0;1060 return;1061 }1062 1057 #ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL 1063 1058 AssertReleaseMsg(pHead != pPhys2Virt, ("%VGp-%VGp offVirtHandler=%#RX32\n", 1064 1059 pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offVirtHandler)); 1065 1060 #endif 1066 1067 /** @todo check if the current head node covers the ground we do. This is highly unlikely 1068 * and I'm too lazy to implement this now as it will require sorting the list and stuff like that. */ 1061 if (RT_UNLIKELY(!pHead || pHead->Core.KeyLast != pPhys2Virt->Core.KeyLast)) 1062 { 1063 /** @todo do something clever here... */ 1064 LogRel(("pgmHandlerVirtualInsertAliased: %VGp-%VGp\n", pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast)); 1065 pPhys2Virt->offNextAlias = 0; 1066 return; 1067 } 1069 1068 1070 1069 /* … … 1088 1087 * Resets one virtual handler range. 1089 1088 * 1089 * This is called by HandlerVirtualUpdate when it has detected some kind of 1090 * problem and have started clearing the virtual handler page states (or 1091 * when there have been registration/deregistrations). For this reason this 1092 * function will only update the page status if it's lower than desired. 1093 * 1090 1094 * @returns 0 1091 1095 * @param pNode Pointer to a PGMVIRTHANDLER. … … 1098 1102 1099 1103 /* 1100 * Calc flags. 1101 */ 1102 Assert(pCur->enmType != PGMVIRTHANDLERTYPE_HYPERVISOR); 1103 unsigned fFlags; 1104 switch (pCur->enmType) 1105 { 1106 case PGMVIRTHANDLERTYPE_WRITE: fFlags = MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_WRITE; break; 1107 case PGMVIRTHANDLERTYPE_ALL: fFlags = MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_ALL; break; 1108 /* hypervisor handlers need no flags and wouldn't have nowhere to put them in any case. */ 1109 case PGMVIRTHANDLERTYPE_HYPERVISOR: 1110 return 0; 1111 default: 1112 AssertMsgFailed(("Invalid type %d\n", pCur->enmType)); 1113 return 0; 1114 } 1115 1116 /* 1117 * Iterate the pages and apply the flags. 1118 */ 1104 * Iterate the pages and apply the new state. 1105 */ 1106 unsigned uState = pgmHandlerVirtualCalcState(pCur); 1119 1107 PPGMRAMRANGE pRamHint = NULL; 1120 1108 RTGCUINTPTR offPage = ((RTGCUINTPTR)pCur->GCPtr & PAGE_OFFSET_MASK); … … 1125 1113 if (pPhys2Virt->Core.Key != NIL_RTGCPHYS) 1126 1114 { 1127 /* Update the flags. */ 1128 int rc = pgmRamFlagsSetByGCPhysWithHint(&pVM->pgm.s, pPhys2Virt->Core.Key, fFlags, &pRamHint); 1129 AssertRC(rc); 1130 1131 /* Need to insert the page in the Phys2Virt lookup tree? */ 1115 /* 1116 * Update the page state wrt virtual handlers. 1117 */ 1118 PPGMPAGE pPage; 1119 int rc = pgmPhysGetPageWithHintEx(&pVM->pgm.s, pPhys2Virt->Core.Key, &pPage, &pRamHint); 1120 if ( RT_SUCCESS(rc) 1121 && PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) < uState) 1122 PGM_PAGE_SET_HNDL_VIRT_STATE(pPage, uState); 1123 else 1124 AssertRC(rc); 1125 1126 /* 1127 * Need to insert the page in the Phys2Virt lookup tree? 1128 */ 1132 1129 if (pPhys2Virt->Core.KeyLast == NIL_RTGCPHYS) 1133 1130 { … … 1200 1197 typedef struct PGMAHAFIS 1201 1198 { 1199 /** The current physical address. */ 1200 RTGCPHYS GCPhys; 1201 /** The state we've calculated. */ 1202 unsigned uVirtStateFound; 1203 /** The state we're matching up to. */ 1204 unsigned uVirtState; 1205 /** Number of errors. */ 1206 unsigned cErrors; 1202 1207 /** The VM handle. */ 1203 1208 PVM pVM; 1204 /** Number of errors. */1205 unsigned cErrors;1206 /** The flags we've found. */1207 unsigned fFlagsFound;1208 /** The flags we're matching up to.1209 * This is also on the stack as a const, thus only valid during enumeration. */1210 unsigned fFlags;1211 /** The current physical address. */1212 RTGCPHYS GCPhys;1213 1209 } PGMAHAFIS, *PPGMAHAFIS; 1214 1210 1211 1212 #if 0 /* unused */ 1215 1213 /** 1216 1214 * Verify virtual handler by matching physical address. … … 1220 1218 * @param pvUser Pointer to user parameter. 1221 1219 */ 1222 static DECLCALLBACK(int) pgm VirtHandlerVerifyOneByPhysAddr(PAVLROGCPTRNODECORE pNode, void *pvUser)1220 static DECLCALLBACK(int) pgmHandlerVirtualVerifyOneByPhysAddr(PAVLROGCPTRNODECORE pNode, void *pvUser) 1223 1221 { 1224 1222 PPGMVIRTHANDLER pCur = (PPGMVIRTHANDLER)pNode; … … 1229 1227 if ((pCur->aPhysToVirt[iPage].Core.Key & X86_PTE_PAE_PG_MASK) == pState->GCPhys) 1230 1228 { 1231 switch (pCur->enmType) 1229 unsigned uState = pgmHandlerVirtualCalcState(pCur); 1230 if (pState->uVirtState < uState) 1232 1231 { 1233 case PGMVIRTHANDLERTYPE_WRITE: pState->fFlagsFound |= MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_WRITE; break; 1234 case PGMVIRTHANDLERTYPE_ALL: pState->fFlagsFound |= MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_ALL; break; 1235 /* hypervisor handlers need no flags and wouldn't have nowhere to put them in any case. */ 1236 case PGMVIRTHANDLERTYPE_HYPERVISOR: 1237 return 0; 1232 error 1238 1233 } 1239 if ( (pState->fFlags & (MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_WRITE | MM_RAM_FLAGS_VIRTUAL_ALL)) 1240 == pState->fFlagsFound)1241 break; 1234 1235 if (pState->uVirtState == uState) 1236 break; //?? 1242 1237 } 1243 1238 } 1244 1239 return 0; 1245 1240 } 1246 1247 1248 /** 1249 * Verify a virtual handler. 1241 #endif /* unused */ 1242 1243 1244 /** 1245 * Verify a virtual handler (enumeration callback). 1246 * 1247 * Called by PGMAssertHandlerAndFlagsInSync to check the sanity of all 1248 * the virtual handlers, esp. that the physical addresses matches up. 1250 1249 * 1251 1250 * @returns 0 1252 1251 * @param pNode Pointer to a PGMVIRTHANDLER. 1253 * @param pvUser Pointer to user parameter.1254 */ 1255 static DECLCALLBACK(int) pgm VirtHandlerVerifyOne(PAVLROGCPTRNODECORE pNode, void *pvUser)1252 * @param pvUser Pointer to a PPGMAHAFIS structure. 1253 */ 1254 static DECLCALLBACK(int) pgmHandlerVirtualVerifyOne(PAVLROGCPTRNODECORE pNode, void *pvUser) 1256 1255 { 1257 1256 PPGMVIRTHANDLER pVirt = (PPGMVIRTHANDLER)pNode; 1258 PPGMAHAFIS pState = (PPGMAHAFIS)pvUser;1257 PPGMAHAFIS pState = (PPGMAHAFIS)pvUser; 1259 1258 PVM pVM = pState->pVM; 1260 1259 1261 if ( pVirt->aPhysToVirt[0].Core.Key != NIL_RTGCPHYS 1262 && (pVirt->aPhysToVirt[0].Core.Key & PAGE_OFFSET_MASK) != ((RTGCUINTPTR)pVirt->GCPtr & PAGE_OFFSET_MASK)) 1263 { 1264 AssertMsgFailed(("virt handler phys out has incorrect key! %VGp %VGv %s\n", 1260 /* 1261 * Validate the type and calc state. 1262 */ 1263 switch (pVirt->enmType) 1264 { 1265 case PGMVIRTHANDLERTYPE_WRITE: 1266 case PGMVIRTHANDLERTYPE_ALL: 1267 break; 1268 default: 1269 AssertMsgFailed(("unknown/wrong enmType=%d\n", pVirt->enmType)); 1270 pState->cErrors++; 1271 return 0; 1272 } 1273 const unsigned uState = pgmHandlerVirtualCalcState(pVirt); 1274 1275 /* 1276 * Check key alignment. 1277 */ 1278 if ( (pVirt->aPhysToVirt[0].Core.Key & PAGE_OFFSET_MASK) != ((RTGCUINTPTR)pVirt->GCPtr & PAGE_OFFSET_MASK) 1279 && pVirt->aPhysToVirt[0].Core.Key != NIL_RTGCPHYS) 1280 { 1281 AssertMsgFailed(("virt handler phys has incorrect key! %VGp %VGv %s\n", 1265 1282 pVirt->aPhysToVirt[0].Core.Key, pVirt->GCPtr, HCSTRING(pVirt->pszDesc))); 1266 1283 pState->cErrors++; 1267 1284 } 1268 1285 1269 /* 1270 * Calc flags. 1271 */ 1272 unsigned fFlags; 1273 switch (pVirt->enmType) 1274 { 1275 case PGMVIRTHANDLERTYPE_WRITE: fFlags = MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_WRITE; break; 1276 case PGMVIRTHANDLERTYPE_ALL: fFlags = MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_ALL; break; 1277 /* hypervisor handlers need no flags and wouldn't have nowhere to put them in any case. */ 1278 case PGMVIRTHANDLERTYPE_HYPERVISOR: 1279 return 0; 1280 default: 1281 AssertMsgFailed(("unknown enmType=%d\n", pVirt->enmType)); 1282 return 0; 1283 } 1284 1285 /* 1286 * Check pages against flags. 1286 if ( (pVirt->aPhysToVirt[pVirt->cPages - 1].Core.KeyLast & PAGE_OFFSET_MASK) != ((RTGCUINTPTR)pVirt->GCPtrLast & PAGE_OFFSET_MASK) 1287 && pVirt->aPhysToVirt[pVirt->cPages - 1].Core.Key != NIL_RTGCPHYS) 1288 { 1289 AssertMsgFailed(("virt handler phys has incorrect key! %VGp %VGv %s\n", 1290 pVirt->aPhysToVirt[pVirt->cPages - 1].Core.KeyLast, pVirt->GCPtrLast, HCSTRING(pVirt->pszDesc))); 1291 pState->cErrors++; 1292 } 1293 1294 /* 1295 * Check pages for sanity and state. 1287 1296 */ 1288 1297 RTGCUINTPTR GCPtr = (RTGCUINTPTR)pVirt->GCPtr; … … 1322 1331 } 1323 1332 1324 if ( (pPage->HCPhys & fFlags) != fFlags) /** @todo PAGE FLAGS */1325 { 1326 AssertMsgFailed(("virt handler flags mismatch. HCPhys=%VHp fFlags=%#x GCPhysGst=%VGp iPage=%#x %VGv%s\n",1327 pPage->HCPhys, fFlags, GCPhysGst, iPage, GCPtr, HCSTRING(pVirt->pszDesc)));1333 if (PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) < uState) 1334 { 1335 AssertMsgFailed(("virt handler state mismatch. HCPhys=%VHp GCPhysGst=%VGp iPage=%#x %VGv state=%d expected>=%d %s\n", 1336 pPage->HCPhys, GCPhysGst, iPage, GCPtr, PGM_PAGE_GET_HNDL_VIRT_STATE(pPage), uState, HCSTRING(pVirt->pszDesc))); 1328 1337 pState->cErrors++; 1329 1338 continue; … … 1346 1355 PPGM pPGM = &pVM->pgm.s; 1347 1356 PGMAHAFIS State; 1357 State.GCPhys = 0; 1358 State.uVirtState = 0; 1359 State.uVirtStateFound = 0; 1348 1360 State.cErrors = 0; 1349 State.pVM 1361 State.pVM = pVM; 1350 1362 1351 1363 /* … … 1361 1373 { 1362 1374 State.GCPhys = pRam->GCPhys + (iPage << PAGE_SHIFT); 1363 State.fFlagsFound = 0; /* build flags and compare. */1364 1375 1365 1376 /* … … 1424 1435 } 1425 1436 1426 /* virtual flags. */ 1437 /* 1438 * Virtual handlers. 1439 */ 1427 1440 if (PGM_PAGE_HAVE_ACTIVE_VIRTUAL_HANDLERS(pPage)) 1428 1441 { 1429 State.fFlags = pPage->HCPhys & (MM_RAM_FLAGS_VIRTUAL_HANDLER | MM_RAM_FLAGS_VIRTUAL_WRITE | MM_RAM_FLAGS_VIRTUAL_ALL); /// @todo PAGE FLAGS 1430 RTAvlroGCPtrDoWithAll(CTXSUFF(&pVM->pgm.s.pTrees)->VirtHandlers, true, pgmVirtHandlerVerifyOneByPhysAddr, &State); 1431 if (State.fFlags != State.fFlagsFound) 1442 State.uVirtState = PGM_PAGE_GET_HNDL_VIRT_STATE(pPage); 1443 #if 1 1444 /* locate all the matching physical ranges. */ 1445 State.uVirtStateFound = PGM_PAGE_HNDL_VIRT_STATE_NONE; 1446 RTGCPHYS GCPhysKey = State.GCPhys; 1447 for (;;) 1432 1448 { 1433 AssertMsgFailed(("ram range vs virt handler flags mismatch. GCPhys=%RGp fFlags=%#x fFlagsFound=%#x\n", 1434 State.GCPhys, State.fFlags, State.fFlagsFound)); 1449 PPGMPHYS2VIRTHANDLER pPhys2Virt = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysGetBestFit(&CTXSUFF(pVM->pgm.s.pTrees)->PhysToVirtHandlers, 1450 GCPhysKey, true /* above-or-equal */); 1451 if ( !pPhys2Virt 1452 || (pPhys2Virt->Core.Key & X86_PTE_PAE_PG_MASK) != State.GCPhys) 1453 break; 1454 1455 /* the head */ 1456 GCPhysKey = pPhys2Virt->Core.KeyLast; 1457 PPGMVIRTHANDLER pCur = (PPGMVIRTHANDLER)((uintptr_t)pPhys2Virt + pPhys2Virt->offVirtHandler); 1458 unsigned uState = pgmHandlerVirtualCalcState(pCur); 1459 State.uVirtStateFound = RT_MAX(State.uVirtStateFound, uState); 1460 1461 /* any aliases */ 1462 while (pPhys2Virt->offNextAlias & PGMPHYS2VIRTHANDLER_OFF_MASK) 1463 { 1464 pPhys2Virt = (PPGMPHYS2VIRTHANDLER)((uintptr_t)pPhys2Virt + (pPhys2Virt->offNextAlias & PGMPHYS2VIRTHANDLER_OFF_MASK)); 1465 pCur = (PPGMVIRTHANDLER)((uintptr_t)pPhys2Virt + pPhys2Virt->offVirtHandler); 1466 uState = pgmHandlerVirtualCalcState(pCur); 1467 State.uVirtStateFound = RT_MAX(State.uVirtStateFound, uState); 1468 } 1469 1470 /* done? */ 1471 if ((GCPhysKey & X86_PTE_PAE_PG_MASK) != State.GCPhys) 1472 break; 1473 } 1474 #else 1475 /* very slow */ 1476 RTAvlroGCPtrDoWithAll(CTXSUFF(&pVM->pgm.s.pTrees)->VirtHandlers, true, pgmHandlerVirtualVerifyOneByPhysAddr, &State); 1477 #endif 1478 if (State.uVirtState != State.uVirtStateFound) 1479 { 1480 AssertMsgFailed(("ram range vs virt handler flags mismatch. GCPhys=%RGp uVirtState=%#x uVirtStateFound=%#x\n", 1481 State.GCPhys, State.uVirtState, State.uVirtStateFound)); 1435 1482 State.cErrors++; 1436 1483 } 1437 1438 1484 } 1439 1485 } … … 1442 1488 1443 1489 /* 1444 * Check that the physical addresses of the virtual handlers matches up. 1445 */ 1446 RTAvlroGCPtrDoWithAll(CTXSUFF(&pVM->pgm.s.pTrees)->VirtHandlers, true, pgmVirtHandlerVerifyOne, &State); 1490 * Check that the physical addresses of the virtual handlers matches up 1491 * and that they are otherwise sane. 1492 */ 1493 RTAvlroGCPtrDoWithAll(CTXSUFF(&pVM->pgm.s.pTrees)->VirtHandlers, true, pgmHandlerVirtualVerifyOne, &State); 1447 1494 1448 1495 /* -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r6902 r6927 1179 1179 { 1180 1180 memcpy(pvBuf, pvSrc, cbRead); 1181 break;1181 goto end; 1182 1182 } 1183 1183 memcpy(pvBuf, pvSrc, cb); 1184 1184 } 1185 1185 else if (cb >= cbRead) 1186 break; 1186 goto end; 1187 } 1188 /* 1189 * Virtual handlers. 1190 */ 1191 else if ( RT_UNLIKELY(PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) >= PGM_PAGE_HNDL_VIRT_STATE_ALL) 1192 && !(pPage->HCPhys & MM_RAM_FLAGS_MMIO)) /// @todo PAGE FLAGS 1193 { 1194 int rc = VINF_PGM_HANDLER_DO_DEFAULT; 1195 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 1196 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */ 1197 /* Search the whole tree for matching physical addresses (rather expensive!) */ 1198 PPGMVIRTHANDLER pNode; 1199 unsigned iPage; 1200 int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pNode, &iPage); 1201 if (VBOX_SUCCESS(rc2) && pNode->pfnHandlerHC) 1202 { 1203 size_t cbRange = pNode->Core.KeyLast - GCPhys + 1; 1204 if (cbRange < cb) 1205 cb = cbRange; 1206 if (cb > cbRead) 1207 cb = cbRead; 1208 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pNode->GCPtr & PAGE_BASE_GC_MASK) 1209 + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK); 1210 1211 void *pvSrc = PGMRAMRANGE_GETHCPTR(pRam, off) 1212 1213 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 1214 rc = pNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, 0); 1215 } 1216 #endif /* IN_RING3 */ 1217 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 1218 { 1219 #ifdef IN_GC 1220 void *pvSrc = NULL; 1221 PGMGCDynMapHCPage(pVM, PGM_PAGE_GET_HCPHYS(pPage), &pvSrc); 1222 pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK); 1223 #else 1224 void *pvSrc = PGMRAMRANGE_GETHCPTR(pRam, off) 1225 #endif 1226 if (cb >= cbRead) 1227 { 1228 memcpy(pvBuf, pvSrc, cbRead); 1229 goto end; 1230 } 1231 memcpy(pvBuf, pvSrc, cb); 1232 } 1233 else if (cb >= cbRead) 1234 goto end; 1187 1235 } 1188 1236 else 1189 1237 { 1190 switch (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ VIRTUAL_ALL | MM_RAM_FLAGS_ROM)) /** @todo PAGE FLAGS */1238 switch (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ROM)) /** @todo PAGE FLAGS */ 1191 1239 { 1192 1240 /* … … 1198 1246 //case MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_MMIO2: /* = shadow */ - //MMIO2 isn't in the mask. 1199 1247 case MM_RAM_FLAGS_MMIO2: // MMIO2 isn't in the mask. 1200 case MM_RAM_FLAGS_VIRTUAL_WRITE:1201 1248 { 1202 1249 #ifdef IN_GC … … 1234 1281 break; 1235 1282 1236 case MM_RAM_FLAGS_VIRTUAL_ALL:1237 {1238 int rc = VINF_PGM_HANDLER_DO_DEFAULT;1239 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);1240 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */1241 /* Search the whole tree for matching physical addresses (rather expensive!) */1242 PPGMVIRTHANDLER pNode;1243 unsigned iPage;1244 int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pNode, &iPage);1245 if (VBOX_SUCCESS(rc2) && pNode->pfnHandlerHC)1246 {1247 size_t cbRange = pNode->Core.KeyLast - GCPhys + 1;1248 if (cbRange < cb)1249 cb = cbRange;1250 if (cb > cbRead)1251 cb = cbRead;1252 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pNode->GCPtr & PAGE_BASE_GC_MASK)1253 + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK);1254 1255 void *pvSrc = PGMRAMRANGE_GETHCPTR(pRam, off)1256 1257 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */1258 rc = pNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, 0);1259 }1260 #endif /* IN_RING3 */1261 if (rc == VINF_PGM_HANDLER_DO_DEFAULT)1262 {1263 #ifdef IN_GC1264 void *pvSrc = NULL;1265 PGMGCDynMapHCPage(pVM, PGM_PAGE_GET_HCPHYS(pPage), &pvSrc);1266 pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK);1267 #else1268 void *pvSrc = PGMRAMRANGE_GETHCPTR(pRam, off)1269 #endif1270 if (cb >= cbRead)1271 {1272 memcpy(pvBuf, pvSrc, cbRead);1273 goto end;1274 }1275 memcpy(pvBuf, pvSrc, cb);1276 }1277 else if (cb >= cbRead)1278 goto end;1279 break;1280 }1281 1282 1283 /* 1283 1284 * The rest needs to be taken more carefully. … … 1293 1294 AssertReleaseMsgFailed(("Unknown read at %VGp size %d implement the complex physical reading case %x\n", 1294 1295 GCPhys, cbRead, 1295 pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ VIRTUAL_ALL | MM_RAM_FLAGS_ROM))); /** @todo PAGE FLAGS */1296 pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ROM))); /** @todo PAGE FLAGS */ 1296 1297 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 1297 1298 break; … … 1410 1411 /* temporary hack, will reogranize is later. */ 1411 1412 /* 1413 * Virtual handlers 1414 */ 1415 if ( PGM_PAGE_HAVE_ACTIVE_VIRTUAL_HANDLERS(pPage) 1416 && !(pPage->HCPhys & MM_RAM_FLAGS_MMIO)) /// @todo PAGE FLAGS 1417 { 1418 if (PGM_PAGE_HAVE_ACTIVE_PHYSICAL_HANDLERS(pPage)) 1419 { 1420 /* 1421 * Physical write handler + virtual write handler. 1422 * Consider this a quick workaround for the CSAM + shadow caching problem. 1423 * 1424 * We hand it to the shadow caching first since it requires the unchanged 1425 * data. CSAM will have to put up with it already being changed. 1426 */ 1427 int rc = VINF_PGM_HANDLER_DO_DEFAULT; 1428 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 1429 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */ 1430 /* 1. The physical handler */ 1431 PPGMPHYSHANDLER pPhysNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys); 1432 if (pPhysNode && pPhysNode->pfnHandlerR3) 1433 { 1434 size_t cbRange = pPhysNode->Core.KeyLast - GCPhys + 1; 1435 if (cbRange < cb) 1436 cb = cbRange; 1437 if (cb > cbWrite) 1438 cb = cbWrite; 1439 1440 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off) 1441 1442 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 1443 rc = pPhysNode->pfnHandlerR3(pVM, GCPhys, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, pPhysNode->pvUserR3); 1444 } 1445 1446 /* 2. The virtual handler (will see incorrect data) */ 1447 PPGMVIRTHANDLER pVirtNode; 1448 unsigned iPage; 1449 int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pVirtNode, &iPage); 1450 if (VBOX_SUCCESS(rc2) && pVirtNode->pfnHandlerHC) 1451 { 1452 size_t cbRange = pVirtNode->Core.KeyLast - GCPhys + 1; 1453 if (cbRange < cb) 1454 cb = cbRange; 1455 if (cb > cbWrite) 1456 cb = cbWrite; 1457 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pVirtNode->GCPtr & PAGE_BASE_GC_MASK) 1458 + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK); 1459 1460 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off) 1461 1462 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 1463 rc2 = pVirtNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, 0); 1464 if ( ( rc2 != VINF_PGM_HANDLER_DO_DEFAULT 1465 && rc == VINF_PGM_HANDLER_DO_DEFAULT) 1466 || ( VBOX_FAILURE(rc2) 1467 && VBOX_SUCCESS(rc))) 1468 rc = rc2; 1469 } 1470 #endif /* IN_RING3 */ 1471 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 1472 { 1473 #ifdef IN_GC 1474 void *pvDst = NULL; 1475 PGMGCDynMapHCPage(pVM, PGM_PAGE_GET_HCPHYS(pPage), &pvDst); 1476 pvDst = (char *)pvDst + (off & PAGE_OFFSET_MASK); 1477 #else 1478 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off) 1479 #endif 1480 if (cb >= cbWrite) 1481 { 1482 memcpy(pvDst, pvBuf, cbWrite); 1483 goto end; 1484 } 1485 memcpy(pvDst, pvBuf, cb); 1486 } 1487 else if (cb >= cbWrite) 1488 goto end; 1489 } 1490 else 1491 { 1492 int rc = VINF_PGM_HANDLER_DO_DEFAULT; 1493 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 1494 #ifdef IN_RING3 1495 /** @todo deal with this in GC and R0! */ 1496 /* Search the whole tree for matching physical addresses (rather expensive!) */ 1497 PPGMVIRTHANDLER pNode; 1498 unsigned iPage; 1499 int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pNode, &iPage); 1500 if (VBOX_SUCCESS(rc2) && pNode->pfnHandlerHC) 1501 { 1502 size_t cbRange = pNode->Core.KeyLast - GCPhys + 1; 1503 if (cbRange < cb) 1504 cb = cbRange; 1505 if (cb > cbWrite) 1506 cb = cbWrite; 1507 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pNode->GCPtr & PAGE_BASE_GC_MASK) 1508 + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK); 1509 1510 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off) 1511 1512 /** @tode Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 1513 rc = pNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, 0); 1514 } 1515 #endif /* IN_RING3 */ 1516 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 1517 { 1518 #ifdef IN_GC 1519 void *pvDst = NULL; 1520 PGMGCDynMapHCPage(pVM, PGM_PAGE_GET_HCPHYS(pPage), &pvDst); 1521 pvDst = (char *)pvDst + (off & PAGE_OFFSET_MASK); 1522 #else 1523 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off) 1524 #endif 1525 if (cb >= cbWrite) 1526 { 1527 memcpy(pvDst, pvBuf, cbWrite); 1528 goto end; 1529 } 1530 memcpy(pvDst, pvBuf, cb); 1531 } 1532 else if (cb >= cbWrite) 1533 goto end; 1534 } 1535 } 1536 /* 1412 1537 * Physical handler. 1413 1538 */ 1414 if ( RT_UNLIKELY(PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) >= PGM_PAGE_HNDL_PHYS_STATE_ALL)1415 && !(pPage->HCPhys & MM_RAM_FLAGS_MMIO)) /// @todo PAGE FLAGS1539 else if ( RT_UNLIKELY(PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) >= PGM_PAGE_HNDL_PHYS_STATE_WRITE) 1540 && !(pPage->HCPhys & MM_RAM_FLAGS_MMIO)) /// @todo PAGE FLAGS 1416 1541 { 1417 1542 int rc = VINF_PGM_HANDLER_DO_DEFAULT; … … 1430 1555 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off) 1431 1556 1432 /** @ noteDangerous assumption that HC handlers don't do anything that really requires an EMT lock! */1557 /** @todo Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 1433 1558 rc = pNode->pfnHandlerR3(pVM, GCPhys, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, pNode->pvUserR3); 1434 1559 } … … 1456 1581 { 1457 1582 /** @todo r=bird: missing MM_RAM_FLAGS_ROM here, we shall not allow anyone to overwrite the ROM! */ 1458 switch (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_VIRTUAL_WRITE)) /** @todo PAGE FLAGS */1583 switch (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2)) /** @todo PAGE FLAGS */ 1459 1584 { 1460 1585 /* … … 1496 1621 break; 1497 1622 1498 case MM_RAM_FLAGS_VIRTUAL_WRITE:1499 if (PGM_PAGE_HAVE_ACTIVE_PHYSICAL_HANDLERS(pPage)) /* temporary mess */1500 {1501 /*1502 * Physical write handler + virtual write handler.1503 * Consider this a quick workaround for the CSAM + shadow caching problem.1504 *1505 * We hand it to the shadow caching first since it requires the unchanged1506 * data. CSAM will have to put up with it already being changed.1507 */1508 int rc = VINF_PGM_HANDLER_DO_DEFAULT;1509 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);1510 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */1511 /* 1. The physical handler */1512 PPGMPHYSHANDLER pPhysNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);1513 if (pPhysNode && pPhysNode->pfnHandlerR3)1514 {1515 size_t cbRange = pPhysNode->Core.KeyLast - GCPhys + 1;1516 if (cbRange < cb)1517 cb = cbRange;1518 if (cb > cbWrite)1519 cb = cbWrite;1520 1521 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off)1522 1523 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */1524 rc = pPhysNode->pfnHandlerR3(pVM, GCPhys, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, pPhysNode->pvUserR3);1525 }1526 1527 /* 2. The virtual handler (will see incorrect data) */1528 PPGMVIRTHANDLER pVirtNode;1529 unsigned iPage;1530 int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pVirtNode, &iPage);1531 if (VBOX_SUCCESS(rc2) && pVirtNode->pfnHandlerHC)1532 {1533 size_t cbRange = pVirtNode->Core.KeyLast - GCPhys + 1;1534 if (cbRange < cb)1535 cb = cbRange;1536 if (cb > cbWrite)1537 cb = cbWrite;1538 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pVirtNode->GCPtr & PAGE_BASE_GC_MASK)1539 + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK);1540 1541 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off)1542 1543 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */1544 rc2 = pVirtNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, 0);1545 if ( ( rc2 != VINF_PGM_HANDLER_DO_DEFAULT1546 && rc == VINF_PGM_HANDLER_DO_DEFAULT)1547 || ( VBOX_FAILURE(rc2)1548 && VBOX_SUCCESS(rc)))1549 rc = rc2;1550 }1551 #endif /* IN_RING3 */1552 if (rc == VINF_PGM_HANDLER_DO_DEFAULT)1553 {1554 #ifdef IN_GC1555 void *pvDst = NULL;1556 PGMGCDynMapHCPage(pVM, PGM_PAGE_GET_HCPHYS(pPage), &pvDst);1557 pvDst = (char *)pvDst + (off & PAGE_OFFSET_MASK);1558 #else1559 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off)1560 #endif1561 if (cb >= cbWrite)1562 {1563 memcpy(pvDst, pvBuf, cbWrite);1564 goto end;1565 }1566 memcpy(pvDst, pvBuf, cb);1567 }1568 else if (cb >= cbWrite)1569 goto end;1570 break;1571 }1572 /* fall thru */1573 case MM_RAM_FLAGS_VIRTUAL_ALL:1574 {1575 int rc = VINF_PGM_HANDLER_DO_DEFAULT;1576 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);1577 #ifdef IN_RING31578 /** @todo deal with this in GC and R0! */1579 /* Search the whole tree for matching physical addresses (rather expensive!) */1580 PPGMVIRTHANDLER pNode;1581 unsigned iPage;1582 int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pNode, &iPage);1583 if (VBOX_SUCCESS(rc2) && pNode->pfnHandlerHC)1584 {1585 size_t cbRange = pNode->Core.KeyLast - GCPhys + 1;1586 if (cbRange < cb)1587 cb = cbRange;1588 if (cb > cbWrite)1589 cb = cbWrite;1590 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pNode->GCPtr & PAGE_BASE_GC_MASK)1591 + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK);1592 1593 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off)1594 1595 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */1596 rc = pNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, 0);1597 }1598 #endif /* IN_RING3 */1599 if (rc == VINF_PGM_HANDLER_DO_DEFAULT)1600 {1601 #ifdef IN_GC1602 void *pvDst = NULL;1603 PGMGCDynMapHCPage(pVM, PGM_PAGE_GET_HCPHYS(pPage), &pvDst);1604 pvDst = (char *)pvDst + (off & PAGE_OFFSET_MASK);1605 #else1606 void *pvDst = PGMRAMRANGE_GETHCPTR(pRam, off)1607 #endif1608 if (cb >= cbWrite)1609 {1610 memcpy(pvDst, pvBuf, cbWrite);1611 goto end;1612 }1613 memcpy(pvDst, pvBuf, cb);1614 }1615 else if (cb >= cbWrite)1616 goto end;1617 break;1618 }1619 1623 1620 1624 /* … … 1631 1635 AssertReleaseMsgFailed(("Unknown write at %VGp size %d implement the complex physical writing case %x\n", 1632 1636 GCPhys, cbWrite, 1633 (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_VIRTUAL_WRITE)))); /** @todo PAGE FLAGS */1637 (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2)))); /** @todo PAGE FLAGS */ 1634 1638 /* skip the write */ 1635 1639 cb = cbWrite;
Note:
See TracChangeset
for help on using the changeset viewer.