Changeset 20421 in vbox
- Timestamp:
- Jun 9, 2009 9:34:53 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vm.h
r20399 r20421 946 946 /** @def VM_REM_SIZE 947 947 * Must be multiple of 32 and coherent with REM_ENV_SIZE from REMInternal.h. */ 948 #if GC_ARCH_BITS == 32 949 # define VM_REM_SIZE (HC_ARCH_BITS == 32 ? 0x10800 : 0x10800) 950 #else 951 # define VM_REM_SIZE (HC_ARCH_BITS == 32 ? 0x10900 : 0x10900) 952 #endif 948 # define VM_REM_SIZE 0x10A00 953 949 char padding[VM_REM_SIZE]; /* multiple of 32 */ 954 950 } rem; -
trunk/src/VBox/VMM/REMInternal.h
r19660 r20421 107 107 uint64_t padding[5]; 108 108 } u; 109 uint32_t idxSelf; 110 uint32_t idxNext; 109 111 } REMHANDLERNOTIFICATION, *PREMHANDLERNOTIFICATION; 110 112 … … 166 168 * These instructions are replayed when entering REM. */ 167 169 RTGCPTR aGCPtrInvalidatedPages[48]; 168 /** The number of recorded handler notifications. */ 169 RTUINT volatile cHandlerNotifications; 170 RTUINT padding0; /**< Padding. */ 170 171 171 /** Array of recorded handler noticications. 172 172 * These are replayed when entering REM. */ 173 173 REMHANDLERNOTIFICATION aHandlerNotifications[32]; 174 volatile uint32_t idxPendingList; 175 volatile uint32_t idxFreeList; 174 176 175 177 /** MMIO memory type. … … 211 213 uint32_t abPadding[HC_ARCH_BITS == 32 ? 6 : 4]; 212 214 213 #if GC_ARCH_BITS == 32 214 # define REM_ENV_SIZE (HC_ARCH_BITS == 32 ? 0xff00 : 0xff00) 215 #else 216 # define REM_ENV_SIZE (HC_ARCH_BITS == 32 ? 0xff00 : 0xff00) 217 #endif 215 # define REM_ENV_SIZE 0xff00 218 216 219 217 /** Recompiler CPU state. */ -
trunk/src/VBox/VMM/VMMAll/REMAll.cpp
r20410 r20421 82 82 AssertReleaseMsgFailed(("Ring 3 call????.\n")); 83 83 #endif 84 Assert(pVM->rem.s.cHandlerNotifications == 0); 85 } 86 84 } 85 86 87 /** 88 * Insert pending notification 89 * 90 * @param pVM VM Handle. 91 * @param pRec Notification record to insert 92 */ 93 static void remNotifyHandlerInsert(PVM pVM, PREMHANDLERNOTIFICATION pRec) 94 { 95 uint32_t idxFree; 96 uint32_t idxNext; 97 PREMHANDLERNOTIFICATION pFree; 98 99 /* Fetch a free record. */ 100 do 101 { 102 idxFree = pVM->rem.s.idxFreeList; 103 if (idxFree == -1) 104 { 105 pFree = NULL; 106 break; 107 } 108 pFree = &pVM->rem.s.aHandlerNotifications[idxFree]; 109 } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxFreeList, pFree->idxNext, idxFree)); 110 111 if (!pFree) 112 { 113 remFlushHandlerNotifications(pVM); 114 return; 115 } 116 117 /* Copy the record. */ 118 *pFree = *pRec; 119 pFree->idxSelf = idxFree; /* was trashed */ 120 121 /* Insert it into the pending list. */ 122 do 123 { 124 idxNext = pVM->rem.s.idxPendingList; 125 pFree->idxNext = idxNext; 126 } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxPendingList, idxFree, idxNext)); 127 128 VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY); 129 } 87 130 88 131 /** … … 97 140 VMMDECL(void) REMNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler) 98 141 { 99 if (pVM->rem.s.cHandlerNotifications >= RT_ELEMENTS(pVM->rem.s.aHandlerNotifications)) 100 remFlushHandlerNotifications(pVM); 101 PREMHANDLERNOTIFICATION pRec = &pVM->rem.s.aHandlerNotifications[pVM->rem.s.cHandlerNotifications++]; 102 pRec->enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_REGISTER; 103 pRec->u.PhysicalRegister.enmType = enmType; 104 pRec->u.PhysicalRegister.GCPhys = GCPhys; 105 pRec->u.PhysicalRegister.cb = cb; 106 pRec->u.PhysicalRegister.fHasHCHandler = fHasHCHandler; 107 VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY); 142 REMHANDLERNOTIFICATION Rec; 143 Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_REGISTER; 144 Rec.u.PhysicalRegister.enmType = enmType; 145 Rec.u.PhysicalRegister.GCPhys = GCPhys; 146 Rec.u.PhysicalRegister.cb = cb; 147 Rec.u.PhysicalRegister.fHasHCHandler = fHasHCHandler; 148 remNotifyHandlerInsert(pVM, &Rec); 108 149 } 109 150 … … 121 162 VMMDECL(void) REMNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM) 122 163 { 123 if (pVM->rem.s.cHandlerNotifications >= RT_ELEMENTS(pVM->rem.s.aHandlerNotifications)) 124 remFlushHandlerNotifications(pVM); 125 PREMHANDLERNOTIFICATION pRec = &pVM->rem.s.aHandlerNotifications[pVM->rem.s.cHandlerNotifications++]; 126 pRec->enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_DEREGISTER; 127 pRec->u.PhysicalDeregister.enmType = enmType; 128 pRec->u.PhysicalDeregister.GCPhys = GCPhys; 129 pRec->u.PhysicalDeregister.cb = cb; 130 pRec->u.PhysicalDeregister.fHasHCHandler = fHasHCHandler; 131 pRec->u.PhysicalDeregister.fRestoreAsRAM = fRestoreAsRAM; 132 VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY); 164 REMHANDLERNOTIFICATION Rec; 165 Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_DEREGISTER; 166 Rec.u.PhysicalDeregister.enmType = enmType; 167 Rec.u.PhysicalDeregister.GCPhys = GCPhys; 168 Rec.u.PhysicalDeregister.cb = cb; 169 Rec.u.PhysicalDeregister.fHasHCHandler = fHasHCHandler; 170 Rec.u.PhysicalDeregister.fRestoreAsRAM = fRestoreAsRAM; 171 remNotifyHandlerInsert(pVM, &Rec); 133 172 } 134 173 … … 147 186 VMMDECL(void) REMNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM) 148 187 { 149 if (pVM->rem.s.cHandlerNotifications >= RT_ELEMENTS(pVM->rem.s.aHandlerNotifications)) 150 remFlushHandlerNotifications(pVM); 151 PREMHANDLERNOTIFICATION pRec = &pVM->rem.s.aHandlerNotifications[pVM->rem.s.cHandlerNotifications++]; 152 pRec->enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_MODIFY; 153 pRec->u.PhysicalModify.enmType = enmType; 154 pRec->u.PhysicalModify.GCPhysOld = GCPhysOld; 155 pRec->u.PhysicalModify.GCPhysNew = GCPhysNew; 156 pRec->u.PhysicalModify.cb = cb; 157 pRec->u.PhysicalModify.fHasHCHandler = fHasHCHandler; 158 pRec->u.PhysicalModify.fRestoreAsRAM = fRestoreAsRAM; 159 VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY); 188 REMHANDLERNOTIFICATION Rec; 189 Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_MODIFY; 190 Rec.u.PhysicalModify.enmType = enmType; 191 Rec.u.PhysicalModify.GCPhysOld = GCPhysOld; 192 Rec.u.PhysicalModify.GCPhysNew = GCPhysNew; 193 Rec.u.PhysicalModify.cb = cb; 194 Rec.u.PhysicalModify.fHasHCHandler = fHasHCHandler; 195 Rec.u.PhysicalModify.fRestoreAsRAM = fRestoreAsRAM; 196 remNotifyHandlerInsert(pVM, &Rec); 160 197 } 161 198 -
trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp
r20151 r20421 725 725 GEN_CHECK_OFF(REM, cCanExecuteRaw); 726 726 GEN_CHECK_OFF(REM, aGCPtrInvalidatedPages); 727 GEN_CHECK_OFF(REM, cHandlerNotifications);727 GEN_CHECK_OFF(REM, idxPendingList); 728 728 GEN_CHECK_OFF(REM, aHandlerNotifications); 729 GEN_CHECK_OFF(REM, idxFreeList); 729 730 GEN_CHECK_OFF(REM, rc); 730 731 GEN_CHECK_OFF(REM, StatsInQEMU); -
trunk/src/recompiler/VBoxRecompiler.c
r20408 r20421 106 106 static void remR3HandlerWriteU32(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32); 107 107 108 static void remR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM); 109 static void remR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler); 110 static void remR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM); 108 111 109 112 /******************************************************************************* … … 406 409 # endif 407 410 #endif 411 412 PREMHANDLERNOTIFICATION pCur; 413 unsigned i; 414 415 pVM->rem.s.idxPendingList = -1; 416 pVM->rem.s.idxFreeList = 0; 417 418 for (i = 0 ; i < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1; i++) 419 { 420 pCur = &pVM->rem.s.aHandlerNotifications[i]; 421 pCur->idxNext = i + 1; 422 pCur->idxSelf = i; 423 } 424 425 pCur = &pVM->rem.s.aHandlerNotifications[RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1]; 426 pCur->idxNext = -1; 427 pCur->idxSelf = RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1; 408 428 409 429 return rc; … … 1873 1893 } 1874 1894 1875 /* Replay notification changes? */ 1876 if (pVM->rem.s.cHandlerNotifications) 1877 REMR3ReplayHandlerNotifications(pVM); 1895 /* Replay notification changes. */ 1896 REMR3ReplayHandlerNotifications(pVM); 1878 1897 1879 1898 /* Update MSRs; before CRx registers! */ … … 2693 2712 REMR3DECL(void) REMR3ReplayHandlerNotifications(PVM pVM) 2694 2713 { 2695 Assert(EMRemIsLockOwner(pVM));2696 2697 2714 /* 2698 2715 * Replay the flushes. … … 2703 2720 if (VM_FF_TESTANDCLEAR(pVM, VM_FF_REM_HANDLER_NOTIFY_BIT)) 2704 2721 { 2705 RTUINT i; 2706 const RTUINT c = pVM->rem.s.cHandlerNotifications; 2707 2708 pVM->rem.s.cHandlerNotifications = 0; 2709 for (i = 0; i < c; i++) 2722 /* Lockless purging of pending notifications. */ 2723 uint32_t idxReqs = ASMAtomicXchgU32(&pVM->rem.s.idxPendingList, -1); 2724 if (idxReqs == -1) 2725 return; 2726 2727 Assert(idxReqs < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications)); 2728 PREMHANDLERNOTIFICATION pReqs = &pVM->rem.s.aHandlerNotifications[idxReqs]; 2729 2730 /* 2731 * Reverse the list to process it in FIFO order. 2732 */ 2733 PREMHANDLERNOTIFICATION pReq = pReqs; 2734 pReqs = NULL; 2735 while (pReq) 2710 2736 { 2711 PREMHANDLERNOTIFICATION pRec = &pVM->rem.s.aHandlerNotifications[i]; 2737 PREMHANDLERNOTIFICATION pCur = pReq; 2738 2739 if (pReq->idxNext != -1) 2740 { 2741 Assert(pReq->idxNext < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications)); 2742 pReq = &pVM->rem.s.aHandlerNotifications[pReq->idxNext]; 2743 } 2744 else 2745 pReq = NULL; 2746 2747 pCur->idxNext = (pReqs) ? pReqs->idxSelf : -1; 2748 pReqs = pCur; 2749 } 2750 2751 while (pReqs) 2752 { 2753 PREMHANDLERNOTIFICATION pRec = pReqs; 2754 2712 2755 switch (pRec->enmKind) 2713 2756 { 2714 2757 case REMHANDLERNOTIFICATIONKIND_PHYSICAL_REGISTER: 2715 REMR3NotifyHandlerPhysicalRegister(pVM,2758 remR3NotifyHandlerPhysicalRegister(pVM, 2716 2759 pRec->u.PhysicalRegister.enmType, 2717 2760 pRec->u.PhysicalRegister.GCPhys, … … 2721 2764 2722 2765 case REMHANDLERNOTIFICATIONKIND_PHYSICAL_DEREGISTER: 2723 REMR3NotifyHandlerPhysicalDeregister(pVM,2766 remR3NotifyHandlerPhysicalDeregister(pVM, 2724 2767 pRec->u.PhysicalDeregister.enmType, 2725 2768 pRec->u.PhysicalDeregister.GCPhys, … … 2730 2773 2731 2774 case REMHANDLERNOTIFICATIONKIND_PHYSICAL_MODIFY: 2732 REMR3NotifyHandlerPhysicalModify(pVM,2775 remR3NotifyHandlerPhysicalModify(pVM, 2733 2776 pRec->u.PhysicalModify.enmType, 2734 2777 pRec->u.PhysicalModify.GCPhysOld, … … 2743 2786 break; 2744 2787 } 2788 if (pReqs->idxNext != -1) 2789 { 2790 AssertMsg(pReqs->idxNext < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications), ("pReqs->idxNext=%d\n", pReqs->idxNext)); 2791 pReqs = &pVM->rem.s.aHandlerNotifications[pReqs->idxNext]; 2792 } 2793 else 2794 pReqs = NULL; 2795 2796 /* Put the record back into the free list */ 2797 uint32_t idxNext; 2798 2799 do 2800 { 2801 idxNext = pVM->rem.s.idxFreeList; 2802 pRec->idxNext = idxNext; 2803 } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxFreeList, pRec->idxSelf, idxNext)); 2745 2804 } 2746 2805 } … … 2931 2990 * Handler memory type to memory which has no HC handler. 2932 2991 */ 2933 REMR3DECL(void) REMR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler)2992 static void remR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler) 2934 2993 { 2935 2994 Log(("REMR3NotifyHandlerPhysicalRegister: enmType=%d GCPhys=%RGp cb=%RGp fHasHCHandler=%d\n", 2936 2995 enmType, GCPhys, cb, fHasHCHandler)); 2996 2937 2997 VM_ASSERT_EMT(pVM); 2938 2998 Assert(RT_ALIGN_T(GCPhys, PAGE_SIZE, RTGCPHYS) == GCPhys); … … 2942 3002 EMRemLock(pVM); 2943 3003 #endif 2944 if (pVM->rem.s.cHandlerNotifications)2945 REMR3ReplayHandlerNotifications(pVM);2946 3004 2947 3005 Assert(!pVM->rem.s.fIgnoreAll); … … 2960 3018 } 2961 3019 3020 /** 3021 * Notification about a successful PGMR3HandlerPhysicalRegister() call. 3022 * 3023 * @param pVM VM Handle. 3024 * @param enmType Handler type. 3025 * @param GCPhys Handler range address. 3026 * @param cb Size of the handler range. 3027 * @param fHasHCHandler Set if the handler has a HC callback function. 3028 * 3029 * @remark MMR3PhysRomRegister assumes that this function will not apply the 3030 * Handler memory type to memory which has no HC handler. 3031 */ 3032 REMR3DECL(void) REMR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler) 3033 { 3034 REMR3ReplayHandlerNotifications(pVM); 3035 3036 remR3NotifyHandlerPhysicalRegister(pVM, enmType, GCPhys, cb, fHasHCHandler); 3037 } 2962 3038 2963 3039 /** … … 2971 3047 * @param fRestoreAsRAM Whether the to restore it as normal RAM or as unassigned memory. 2972 3048 */ 2973 REMR3DECL(void) REMR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)3049 static void remR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM) 2974 3050 { 2975 3051 Log(("REMR3NotifyHandlerPhysicalDeregister: enmType=%d GCPhys=%RGp cb=%RGp fHasHCHandler=%RTbool fRestoreAsRAM=%RTbool RAM=%08x\n", … … 2980 3056 EMRemLock(pVM); 2981 3057 #endif 2982 if (pVM->rem.s.cHandlerNotifications)2983 REMR3ReplayHandlerNotifications(pVM);2984 3058 2985 3059 Assert(!pVM->rem.s.fIgnoreAll); … … 3011 3085 } 3012 3086 3087 /** 3088 * Notification about a successful PGMR3HandlerPhysicalDeregister() operation. 3089 * 3090 * @param pVM VM Handle. 3091 * @param enmType Handler type. 3092 * @param GCPhys Handler range address. 3093 * @param cb Size of the handler range. 3094 * @param fHasHCHandler Set if the handler has a HC callback function. 3095 * @param fRestoreAsRAM Whether the to restore it as normal RAM or as unassigned memory. 3096 */ 3097 REMR3DECL(void) REMR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM) 3098 { 3099 REMR3ReplayHandlerNotifications(pVM); 3100 remR3NotifyHandlerPhysicalDeregister(pVM, enmType, GCPhys, cb, fHasHCHandler, fRestoreAsRAM); 3101 } 3102 3013 3103 3014 3104 /** … … 3023 3113 * @param fRestoreAsRAM Whether the to restore it as normal RAM or as unassigned memory. 3024 3114 */ 3025 REMR3DECL(void) REMR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)3115 static void remR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM) 3026 3116 { 3027 3117 Log(("REMR3NotifyHandlerPhysicalModify: enmType=%d GCPhysOld=%RGp GCPhysNew=%RGp cb=%RGp fHasHCHandler=%RTbool fRestoreAsRAM=%RTbool\n", … … 3033 3123 EMRemLock(pVM); 3034 3124 #endif 3035 if (pVM->rem.s.cHandlerNotifications)3036 REMR3ReplayHandlerNotifications(pVM);3037 3125 3038 3126 if (fHasHCHandler) … … 3069 3157 } 3070 3158 3159 /** 3160 * Notification about a successful PGMR3HandlerPhysicalModify() call. 3161 * 3162 * @param pVM VM Handle. 3163 * @param enmType Handler type. 3164 * @param GCPhysOld Old handler range address. 3165 * @param GCPhysNew New handler range address. 3166 * @param cb Size of the handler range. 3167 * @param fHasHCHandler Set if the handler has a HC callback function. 3168 * @param fRestoreAsRAM Whether the to restore it as normal RAM or as unassigned memory. 3169 */ 3170 REMR3DECL(void) REMR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM) 3171 { 3172 REMR3ReplayHandlerNotifications(pVM); 3173 3174 remR3NotifyHandlerPhysicalModify(pVM, enmType, GCPhysOld, GCPhysNew, cb, fHasHCHandler, fRestoreAsRAM); 3175 } 3071 3176 3072 3177 /** … … 3084 3189 #ifdef VBOX_STRICT 3085 3190 unsigned long off; 3086 if (pVM->rem.s.cHandlerNotifications) 3087 REMR3ReplayHandlerNotifications(pVM); 3191 REMR3ReplayHandlerNotifications(pVM); 3088 3192 3089 3193 off = get_phys_page_offset(GCPhys);
Note:
See TracChangeset
for help on using the changeset viewer.