- Timestamp:
- May 19, 2015 2:27:00 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/patm.h
r55001 r55937 165 165 */ 166 166 167 VMMRC_INT_DECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame);168 VMMRC_INT_DECL( int)PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite);169 VMMRC_INT_DECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame);167 VMMRC_INT_DECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame); 168 VMMRC_INT_DECL(VBOXSTRICTRC) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite); 169 VMMRC_INT_DECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame); 170 170 171 171 /** @} */ -
trunk/src/VBox/VMM/VMMAll/CSAMAll.cpp
r45620 r55937 29 29 #include <VBox/vmm/hm.h> 30 30 #include <VBox/vmm/mm.h> 31 #ifdef VBOX_WITH_REM 32 # include <VBox/vmm/rem.h> 33 #endif 31 34 #include <VBox/sup.h> 32 35 #include <VBox/vmm/mm.h> … … 45 48 #include <iprt/string.h> 46 49 50 #ifdef IN_RING0 51 # error "IN_RING3 & IN_RC only!" 52 #endif 53 54 55 /** 56 * Access handler callback for virtual access handler ranges. 57 * 58 * Important to realize that a physical page in a range can have aliases, and 59 * for ALL and WRITE handlers these will also trigger. 60 * 61 * @returns VINF_SUCCESS if the handler have carried out the operation. 62 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation. 63 * @param pVM Pointer to the VM. 64 * @param pVCpu Pointer to the cross context CPU context for the 65 * calling EMT. 66 * @param GCPtr The virtual address the guest is writing to. (not correct if it's an alias!) 67 * @param pvPtr The HC mapping of that address. 68 * @param pvBuf What the guest is reading/writing. 69 * @param cbBuf How much it's reading/writing. 70 * @param enmAccessType The access type. 71 * @param enmOrigin Who is making this write. 72 * @param pvUser User argument. 73 */ 74 PGM_ALL_CB2_DECL(int) csamCodePageWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, 75 PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser) 76 { 77 RTGCPTR const GCPtrMonitored = (uintptr_t)pvUser | (GCPtr & PAGE_OFFSET_MASK); 78 Log(("csamCodePageWriteHandler: write to %RGv LB %zu\n", GCPtr, cbBuf)); 79 80 Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType); 81 Assert(VMCPU_IS_EMT(pVCpu)); 82 83 /* 84 * Check if it's a dummy write that doesn't change anything. 85 */ 86 if ( PAGE_ADDRESS(pvPtr) == PAGE_ADDRESS((uintptr_t)pvPtr + cbBuf - 1) 87 && !memcmp(pvPtr, pvBuf, cbBuf)) 88 { 89 Log(("csamCodePageWriteHandler: dummy write -> ignore\n")); 90 return VINF_PGM_HANDLER_DO_DEFAULT; 91 } 92 93 #ifdef IN_RING3 94 /* 95 * Ring-3: Do proper handling. 96 */ 97 int rc = PATMR3PatchWrite(pVM, GCPtrMonitored, (uint32_t)cbBuf); 98 AssertRC(rc); 99 return VINF_PGM_HANDLER_DO_DEFAULT; 100 101 #else 102 /* 103 * Raw-mode: Try avoid needing to go to ring-3 (same as csamRCCodePageWritePfHandler). 104 */ 105 uint32_t const cpl = CPUMGetGuestCPL(pVCpu); 106 bool const fPatchCode = PATMIsPatchGCAddr(pVM, CPUMGetGuestRIP(pVCpu)); 107 PPATMGCSTATE pPATMGCState = PATMGetGCState(pVM); 108 109 Assert(pVM->csam.s.cDirtyPages < CSAM_MAX_DIRTY_PAGES); 110 Assert(pPATMGCState); 111 Assert(pPATMGCState->fPIF || fPatchCode); 112 113 # ifdef VBOX_WITH_REM 114 /* Flush the recompilers translation block cache as the guest seems to be modifying instructions. */ 115 /** @todo a bit overkill?? */ 116 REMFlushTBs(pVM); 117 # endif 118 119 /* 120 * When patch code is executing instructions that must complete, then we 121 * must *never* interrupt it. 122 */ 123 if (!pPATMGCState->fPIF && fPatchCode) 124 { 125 Log(("csamRCCodePageWriteHandler: fPIF=0 -> stack fault in patch generated code at %08RX32!\n", CPUMGetGuestRIP(pVCpu))); 126 return VINF_PGM_HANDLER_DO_DEFAULT; 127 } 128 129 Log(("csamRCCodePageWriteHandler: code page write at %RGv original address %RGv (cpl=%d)\n", GCPtr, GCPtrMonitored, cpl)); 130 131 /* 132 * If user code is modifying one of our monitored pages, then we can safely 133 * write to it as it's no longer being used for supervisor code. 134 */ 135 if (cpl != 3) 136 { 137 VBOXSTRICTRC rcStrict = PATMRCHandleWriteToPatchPage(pVM, NULL /* pRegFrame = no interpret */, 138 (RTRCPTR)GCPtrMonitored, cbBuf); 139 if ( rcStrict == VINF_PGM_HANDLER_DO_DEFAULT 140 || rcStrict == VINF_SUCCESS) 141 return VBOXSTRICTRC_TODO(rcStrict); 142 if (rcStrict == VINF_EM_RAW_EMULATE_INSTR) 143 { 144 STAM_COUNTER_INC(&pVM->csam.s.StatDangerousWrite); 145 return VINF_EM_RAW_EMULATE_INSTR; 146 } 147 Assert(rcStrict == VERR_PATCH_NOT_FOUND); 148 } 149 150 /* 151 * Schedule ring-3 activity. 152 * Note that GCPtr might be a different address in case of aliases. So, 153 * take down both alternatives. 154 */ 155 VMCPU_FF_SET(pVCpu, VMCPU_FF_CSAM_PENDING_ACTION); 156 pVM->csam.s.pvDirtyBasePage[pVM->csam.s.cDirtyPages] = (RTRCPTR)GCPtrMonitored; 157 pVM->csam.s.pvDirtyFaultPage[pVM->csam.s.cDirtyPages] = (RTRCPTR)GCPtr; 158 if (++pVM->csam.s.cDirtyPages == CSAM_MAX_DIRTY_PAGES) 159 return VINF_CSAM_PENDING_ACTION; 160 161 /* 162 * Continue with the write. The VM_FF_CSAM_FLUSH_DIRTY_PAGE handler will reset it to readonly again. 163 */ 164 Log(("csamRCCodePageWriteHandler: enabled r/w for page %RGv (%RGv)\n", GCPtr, GCPtrMonitored)); 165 STAM_COUNTER_INC(&pVM->csam.s.StatCodePageModified); 166 return VINF_PGM_HANDLER_DO_DEFAULT; 167 #endif 168 } 169 170 47 171 /** 48 172 * Check if this page needs to be analysed by CSAM -
trunk/src/VBox/VMM/VMMAll/PATMAll.cpp
r55001 r55937 5 5 6 6 /* 7 * Copyright (C) 2006-201 3Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 37 37 #include <iprt/assert.h> 38 38 #include <iprt/string.h> 39 40 41 /** 42 * Access handler callback for virtual access handler ranges. 43 * 44 * Important to realize that a physical page in a range can have aliases, and 45 * for ALL and WRITE handlers these will also trigger. 46 * 47 * @returns VINF_SUCCESS if the handler have carried out the operation. 48 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation. 49 * @param pVM Pointer to the VM. 50 * @param pVCpu Pointer to the cross context CPU context for the 51 * calling EMT. 52 * @param GCPtr The virtual address the guest is writing to. (not correct if it's an alias!) 53 * @param pvPtr The HC mapping of that address. 54 * @param pvBuf What the guest is reading/writing. 55 * @param cbBuf How much it's reading/writing. 56 * @param enmAccessType The access type. 57 * @param enmOrigin Who is making this write. 58 * @param pvUser The address of the guest page we're monitoring. 59 */ 60 PGM_ALL_CB2_DECL(int) patmVirtPageHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, 61 PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser) 62 { 63 Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType); 64 NOREF(pvPtr); NOREF(pvBuf); NOREF(cbBuf); NOREF(enmOrigin); NOREF(pvUser); 65 Assert(pvUser); Assert(!((uintptr_t)pvUser & PAGE_OFFSET_MASK)); 66 67 pVM->patm.s.pvFaultMonitor = (RTRCPTR)((uintptr_t)pvUser + (GCPtr & PAGE_OFFSET_MASK)); 68 #ifdef IN_RING3 69 PATMR3HandleMonitoredPage(pVM); 70 return VINF_PGM_HANDLER_DO_DEFAULT; 71 #else 72 /* RC: Go handle this in ring-3. */ 73 return VINF_PATM_CHECK_PATCH_PAGE; 74 #endif 75 } 39 76 40 77 -
trunk/src/VBox/VMM/VMMR3/CSAM.cpp
r55900 r55937 72 72 static DECLCALLBACK(int) csamR3Save(PVM pVM, PSSMHANDLE pSSM); 73 73 static DECLCALLBACK(int) csamR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass); 74 static FNPGMR3VIRTHANDLER csamR3CodePageWriteHandler;75 74 static FNPGMR3VIRTINVALIDATE csamR3CodePageInvalidate; 76 75 … … 255 254 rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_WRITE, false /*fRelocUserRC*/, 256 255 NULL /*pfnInvalidateR3 */, 257 csam R3CodePageWriteHandler,256 csamCodePageWriteHandler, 258 257 "csamRCCodePageWritePfHandler", 259 258 "CSAM code page write handler", … … 262 261 rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_WRITE, false /*fRelocUserRC*/, 263 262 csamR3CodePageInvalidate, 264 csam R3CodePageWriteHandler,263 csamCodePageWriteHandler, 265 264 "csamRCCodePageWritePfHandler", 266 265 "CSAM code page write and invlpg handler", … … 2164 2163 2165 2164 /** 2166 * \#PF Handler callback for virtual access handler ranges.2167 *2168 * Important to realize that a physical page in a range can have aliases, and2169 * for ALL and WRITE handlers these will also trigger.2170 *2171 * @returns VINF_SUCCESS if the handler have carried out the operation.2172 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.2173 * @param pVM Pointer to the VM.2174 * @param pVCpu Pointer to the cross context CPU context for the2175 * calling EMT.2176 * @param GCPtr The virtual address the guest is writing to. (not correct if it's an alias!)2177 * @param pvPtr The HC mapping of that address.2178 * @param pvBuf What the guest is reading/writing.2179 * @param cbBuf How much it's reading/writing.2180 * @param enmAccessType The access type.2181 * @param enmOrigin Who is making this write.2182 * @param pvUser User argument.2183 */2184 static DECLCALLBACK(int) csamR3CodePageWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,2185 PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)2186 {2187 int rc;2188 2189 Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType);2190 Log(("csamR3CodePageWriteHandler: write to %RGv size=%zu\n", GCPtr, cbBuf));2191 NOREF(pvUser);2192 2193 if ( PAGE_ADDRESS(pvPtr) == PAGE_ADDRESS((uintptr_t)pvPtr + cbBuf - 1)2194 && !memcmp(pvPtr, pvBuf, cbBuf))2195 {2196 Log(("csamR3CodePageWriteHandler: dummy write -> ignore\n"));2197 return VINF_PGM_HANDLER_DO_DEFAULT;2198 }2199 2200 if (VM_IS_EMT(pVM))2201 rc = PATMR3PatchWrite(pVM, GCPtr, (uint32_t)cbBuf);2202 else2203 {2204 AssertFailed(); /* PGM should make sure this does not happen anymore! */2205 /* Queue the write instead otherwise we'll get concurrency issues. */2206 /** @note in theory not correct to let it write the data first before disabling a patch!2207 * (if it writes the same data as the patch jump and we replace it with obsolete opcodes)2208 */2209 Log(("csamR3CodePageWriteHandler: delayed write!\n"));2210 AssertCompileSize(RTRCPTR, 4);2211 rc = VMR3ReqCallVoidNoWait(pVM, VMCPUID_ANY, (PFNRT)CSAMDelayedWriteHandler, 3, pVM, (RTRCPTR)GCPtr, cbBuf);2212 }2213 AssertRC(rc);2214 2215 return VINF_PGM_HANDLER_DO_DEFAULT;2216 }2217 2218 /**2219 2165 * \#PF Handler callback for invalidation of virtual access handler ranges. 2220 2166 * … … 2435 2381 STAM_PROFILE_START(&pVM->csam.s.StatFlushDirtyPages, a); 2436 2382 2437 for (uint32_t i =0;i<pVM->csam.s.cDirtyPages;i++)2383 for (uint32_t i = 0; i < pVM->csam.s.cDirtyPages; i++) 2438 2384 { 2439 2385 int rc; 2440 2386 PCSAMPAGEREC pPageRec; 2441 RTRCPTR GCPtr = pVM->csam.s.pvDirtyBasePage[i]; 2442 2443 GCPtr = GCPtr & PAGE_BASE_GC_MASK; 2387 RTRCPTR GCPtr = pVM->csam.s.pvDirtyBasePage[i] & PAGE_BASE_GC_MASK; 2444 2388 2445 2389 #ifdef VBOX_WITH_REM 2446 2390 /* Notify the recompiler that this page has been changed. */ 2447 2391 REMR3NotifyCodePageChanged(pVM, pVCpu, GCPtr); 2392 if (pVM->csam.s.pvDirtyFaultPage[i] != pVM->csam.s.pvDirtyBasePage[i]) 2393 REMR3NotifyCodePageChanged(pVM, pVCpu, pVM->csam.s.pvDirtyFaultPage[i] & PAGE_BASE_GC_MASK); 2448 2394 #endif 2449 2395 -
trunk/src/VBox/VMM/VMMR3/PATM.cpp
r55900 r55937 92 92 * Internal Functions * 93 93 *******************************************************************************/ 94 static FNPGMR3VIRTHANDLER patmR3VirtPageHandler;95 96 94 static int patmDisableUnusablePatch(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictAddr, PPATCHINFO pPatch); 97 95 static int patmActivateInt3Patch(PVM pVM, PPATCHINFO pPatch); … … 224 222 rc = PGMR3HandlerVirtualTypeRegister(pVM, PGMVIRTHANDLERKIND_ALL, false /*fRelocUserRC*/, 225 223 NULL /*pfnInvalidateR3*/, 226 patm R3VirtPageHandler,224 patmVirtPageHandler, 227 225 "patmRCVirtPagePfHandler", 228 226 "PATMMonitorPatchJump", &pVM->patm.s.hMonitorPageType); … … 975 973 } 976 974 977 /**978 * \#PF Handler callback for virtual access handler ranges.979 *980 * Important to realize that a physical page in a range can have aliases, and981 * for ALL and WRITE handlers these will also trigger.982 *983 * @returns VINF_SUCCESS if the handler have carried out the operation.984 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.985 * @param pVM Pointer to the VM.986 * @param pVCpu Pointer to the cross context CPU context for the987 * calling EMT.988 * @param GCPtr The virtual address the guest is writing to. (not correct if it's an alias!)989 * @param pvPtr The HC mapping of that address.990 * @param pvBuf What the guest is reading/writing.991 * @param cbBuf How much it's reading/writing.992 * @param enmAccessType The access type.993 * @param enmOrigin Who is making this write.994 * @param pvUser The address of the guest page we're monitoring.995 */996 static DECLCALLBACK(int) patmR3VirtPageHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,997 PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)998 {999 Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType);1000 NOREF(pVCpu); NOREF(pvPtr); NOREF(pvBuf); NOREF(cbBuf); NOREF(enmOrigin); NOREF(pvUser);1001 1002 /** @todo could be the wrong virtual address (alias) */1003 pVM->patm.s.pvFaultMonitor = GCPtr;1004 PATMR3HandleMonitoredPage(pVM);1005 return VINF_PGM_HANDLER_DO_DEFAULT;1006 }1007 1008 975 #ifdef VBOX_WITH_DEBUGGER 1009 976 -
trunk/src/VBox/VMM/VMMRC/CSAMRC.cpp
r55900 r55937 72 72 PPATMGCSTATE pPATMGCState; 73 73 bool fPatchCode = PATMIsPatchGCAddr(pVM, pRegFrame->eip); 74 int rc;75 74 NOREF(uErrorCode); 76 75 … … 96 95 * Make this particular page R/W. 97 96 */ 98 rc = PGMShwMakePageWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT);97 int rc = PGMShwMakePageWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT); 99 98 AssertMsgRC(rc, ("PGMShwModifyPage -> rc=%Rrc\n", rc)); 100 99 ASMInvalidatePage((void *)(uintptr_t)pvFault); … … 114 113 if (cpl != 3) 115 114 { 116 rc = PATMRCHandleWriteToPatchPage(pVM, pRegFrame, (RTRCPTR)((RTRCUINTPTR)pvRange + offRange), 4 /** @todo */); 117 if (rc == VINF_SUCCESS) 118 return rc; 119 if (rc == VINF_EM_RAW_EMULATE_INSTR) 115 VBOXSTRICTRC rcStrict = PATMRCHandleWriteToPatchPage(pVM, pRegFrame, (RTRCPTR)((RTRCUINTPTR)pvRange + offRange), 116 4 /** @todo */); 117 if (rcStrict == VINF_SUCCESS) 118 return rcStrict; 119 if (rcStrict == VINF_EM_RAW_EMULATE_INSTR) 120 120 { 121 121 STAM_COUNTER_INC(&pVM->csam.s.StatDangerousWrite); 122 122 return VINF_EM_RAW_EMULATE_INSTR; 123 123 } 124 Assert(rc == VERR_PATCH_NOT_FOUND);124 Assert(rcStrict == VERR_PATCH_NOT_FOUND); 125 125 } 126 126 … … 129 129 /* Note that pvFault might be a different address in case of aliases. So use pvRange + offset instead!. */ 130 130 pVM->csam.s.pvDirtyBasePage[pVM->csam.s.cDirtyPages] = (RTRCPTR)((RTRCUINTPTR)pvRange + offRange); 131 pVM->csam.s.pvDirtyFaultPage[pVM->csam.s.cDirtyPages] = (RTRCPTR) ((RTRCUINTPTR)pvRange + offRange);131 pVM->csam.s.pvDirtyFaultPage[pVM->csam.s.cDirtyPages] = (RTRCPTR)pvFault; 132 132 if (++pVM->csam.s.cDirtyPages == CSAM_MAX_DIRTY_PAGES) 133 133 return VINF_CSAM_PENDING_ACTION; … … 137 137 */ 138 138 Log(("csamRCCodePageWriteHandler: enabled r/w for page %RGv\n", pvFault)); 139 rc = PGMShwMakePageWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT);139 int rc = PGMShwMakePageWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT); 140 140 AssertMsgRC(rc, ("PGMShwModifyPage -> rc=%Rrc\n", rc)); 141 141 ASMInvalidatePage((void *)(uintptr_t)pvFault); -
trunk/src/VBox/VMM/VMMRC/PATMRC.cpp
r55900 r55937 63 63 RTGCPTR pvRange, uintptr_t offRange, void *pvUser) 64 64 { 65 NOREF(pVCpu); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser); 66 pVM->patm.s.pvFaultMonitor = (RTRCPTR)(RTRCUINTPTR)pvFault; 65 NOREF(pVCpu); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); 66 Assert(pvUser); Assert(!((uintptr_t)pvUser & PAGE_OFFSET_MASK)); 67 pVM->patm.s.pvFaultMonitor = (RTRCPTR)((uintptr_t)pvUser + (pvFault & PAGE_OFFSET_MASK)); 67 68 return VINF_PATM_CHECK_PATCH_PAGE; 68 69 } … … 73 74 * (if so, then we are not allowed to turn on r/w) 74 75 * 75 * @returns VBox status 76 * @returns Strict VBox status code. 77 * @retval VINF_SUCCESS if access interpreted (@a pRegFrame != NULL). 78 * @retval VINF_PGM_HANDLER_DO_DEFAULT (@a pRegFrame == NULL). 79 * @retval VINF_EM_RAW_EMULATE_INSTR on needing to go to ring-3 to do this. 80 * @retval VERR_PATCH_NOT_FOUND if no patch was found. 81 * 76 82 * @param pVM Pointer to the VM. 77 * @param pRegFrame CPU context 78 * @param GCPtr GC pointer to write address 79 * @param cbWrite N r of bytes to write83 * @param pRegFrame CPU context if \#PF, NULL if other write.. 84 * @param GCPtr GC pointer to write address. 85 * @param cbWrite Number of bytes to write. 80 86 * 81 87 */ 82 VMMRC_INT_DECL( int) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite)88 VMMRC_INT_DECL(VBOXSTRICTRC) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite) 83 89 { 84 RTGCUINTPTR pWritePageStart, pWritePageEnd; 85 PPATMPATCHPAGE pPatchPage; 90 Assert(cbWrite > 0); 86 91 87 92 /* Quick boundary check */ 88 if ( PAGE_ADDRESS(GCPtr) < PAGE_ADDRESS(pVM->patm.s.pPatchedInstrGCLowest) 89 || PAGE_ADDRESS(GCPtr) > PAGE_ADDRESS(pVM->patm.s.pPatchedInstrGCHighest) 90 ) 91 return VERR_PATCH_NOT_FOUND; 93 if ( PAGE_ADDRESS(GCPtr) < PAGE_ADDRESS(pVM->patm.s.pPatchedInstrGCLowest) 94 || PAGE_ADDRESS(GCPtr) > PAGE_ADDRESS(pVM->patm.s.pPatchedInstrGCHighest)) 95 return VERR_PATCH_NOT_FOUND; 92 96 93 97 STAM_PROFILE_ADV_START(&pVM->patm.s.StatPatchWriteDetect, a); 94 98 95 pWritePageStart = (RTRCUINTPTR)GCPtr & PAGE_BASE_GC_MASK; 96 pWritePageEnd = ((RTRCUINTPTR)GCPtr + cbWrite - 1) & PAGE_BASE_GC_MASK; 97 98 pPatchPage = (PPATMPATCHPAGE)RTAvloU32Get(CTXSUFF(&pVM->patm.s.PatchLookupTree)->PatchTreeByPage, (AVLOU32KEY)pWritePageStart); 99 /* 100 * Lookup the patch page record for the write. 101 */ 102 RTRCUINTPTR pWritePageStart = (RTRCUINTPTR)GCPtr & PAGE_BASE_GC_MASK; 103 RTRCUINTPTR pWritePageEnd = ((RTRCUINTPTR)GCPtr + cbWrite - 1) & PAGE_BASE_GC_MASK; 104 105 PPATMPATCHPAGE pPatchPage; 106 pPatchPage = (PPATMPATCHPAGE)RTAvloU32Get(&pVM->patm.s.CTXSUFF(PatchLookupTree)->PatchTreeByPage, pWritePageStart); 99 107 if ( !pPatchPage 100 && pWritePageStart != pWritePageEnd 101 ) 102 { 103 pPatchPage = (PPATMPATCHPAGE)RTAvloU32Get(CTXSUFF(&pVM->patm.s.PatchLookupTree)->PatchTreeByPage, (AVLOU32KEY)pWritePageEnd); 104 } 105 106 #ifdef LOG_ENABLED 107 if (pPatchPage) 108 Log(("PATMGCHandleWriteToPatchPage: Found page %RRv for write to %RRv %d bytes (page low:high %RRv:%RRv\n", pPatchPage->Core.Key, GCPtr, cbWrite, pPatchPage->pLowestAddrGC, pPatchPage->pHighestAddrGC)); 109 #endif 110 108 && pWritePageStart != pWritePageEnd) 109 pPatchPage = (PPATMPATCHPAGE)RTAvloU32Get(&pVM->patm.s.CTXSUFF(PatchLookupTree)->PatchTreeByPage, pWritePageEnd); 111 110 if (pPatchPage) 112 111 { 113 if ( pPatchPage->pLowestAddrGC > (RTRCPTR)((RTRCUINTPTR)GCPtr + cbWrite - 1) 114 || pPatchPage->pHighestAddrGC < (RTRCPTR)GCPtr) 112 Log(("PATMGCHandleWriteToPatchPage: Found page %RRv for write to %RRv %d bytes (page low:high %RRv:%RRv\n", 113 pPatchPage->Core.Key, GCPtr, cbWrite, pPatchPage->pLowestAddrGC, pPatchPage->pHighestAddrGC)); 114 if ( (RTRCUINTPTR)pPatchPage->pLowestAddrGC > (RTRCUINTPTR)GCPtr + cbWrite - 1U 115 || (RTRCUINTPTR)pPatchPage->pHighestAddrGC < (RTRCUINTPTR)GCPtr) 115 116 { 116 /* This part of the page was not patched; try to emulate the instruction. */ 117 /* This part of the page was not patched; try to emulate the instruction / tell the caller to do so. */ 118 if (!pRegFrame) 119 { 120 LogFlow(("PATMHandleWriteToPatchPage: Allow writing %RRv LB %#x\n", pRegFrame->eip, GCPtr, cbWrite)); 121 STAM_COUNTER_INC(&pVM->patm.s.StatPatchWriteInterpreted); 122 STAM_PROFILE_ADV_STOP(&pVM->patm.s.StatPatchWriteDetect, a); 123 return VINF_PGM_HANDLER_DO_DEFAULT; 124 } 117 125 LogFlow(("PATMHandleWriteToPatchPage: Interpret %x accessing %RRv\n", pRegFrame->eip, GCPtr)); 118 126 int rc = EMInterpretInstruction(VMMGetCpu0(pVM), pRegFrame, (RTGCPTR)(RTRCUINTPTR)GCPtr); -
trunk/src/VBox/VMM/include/CSAMInternal.h
r55895 r55937 283 283 284 284 RT_C_DECLS_BEGIN 285 DECLEXPORT(FNPGMRCVIRTPFHANDLER) csamRCCodePageWritePfHandler;285 DECLEXPORT(FNPGMRCVIRTPFHANDLER) csamRCCodePageWritePfHandler; 286 286 RT_C_DECLS_END 287 288 #endif 287 PGM_ALL_CB2_DECL(FNPGMR3VIRTHANDLER) csamCodePageWriteHandler; 288 289 #endif -
trunk/src/VBox/VMM/include/PATMInternal.h
r55895 r55937 687 687 void patmR3DbgAddPatch(PVM pVM, PPATMPATCHREC pPatchRec); 688 688 689 #endif 689 PGM_ALL_CB2_DECL(FNPGMPHYSHANDLER) patmVirtPageHandler; 690 691 #endif
Note:
See TracChangeset
for help on using the changeset viewer.