- Timestamp:
- Mar 7, 2009 3:54:02 AM (16 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PDMDevHlp.cpp
r17371 r17510 47 47 * Defined Constants And Macros * 48 48 *******************************************************************************/ 49 /** Allow physical read and writes from any thread.50 * (pdmR3DevHlp_PhysRead and pdmR3DevHlp_PhysWrite.)51 */52 #define PDM_PHYS_READWRITE_FROM_ANY_THREAD53 54 55 49 /** @name R3 DevHlp 56 50 * @{ … … 2033 2027 { 2034 2028 PDMDEV_ASSERT_DEVINS(pDevIns); 2029 PVM pVM = pDevIns->Internal.s.pVMR3; 2035 2030 LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n", 2036 2031 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbRead)); 2037 2032 2038 /* 2039 * For the convenience of the device we put no thread restriction on this interface. 2040 * That means we'll have to check which thread we're in and choose our path. 2041 */ 2042 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD 2043 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 2044 #else 2045 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3)) 2046 PGMPhysRead(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead); 2033 int rc = VINF_SUCCESS; 2034 #ifdef VBOX_WITH_NEW_PHYS_CODE 2035 if (!VM_IS_EMT(pVM)) 2036 rc = PGMR3PhysReadExternal(pVM, GCPhys, pvBuf, cbRead); 2047 2037 else 2048 {2049 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));2050 PVMREQ pReq;2051 AssertCompileSize(RTGCPHYS, 4);2052 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT,2053 (PFNRT)PGMPhysRead, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbRead);2054 while (rc == VERR_TIMEOUT)2055 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);2056 AssertReleaseRC(rc);2057 VMR3ReqFree(pReq);2058 }2059 2038 #endif 2060 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2039 PGMPhysRead(pVM, GCPhys, pvBuf, cbRead); 2040 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2041 /** @todo return rc; */ NOREF(rc); 2061 2042 } 2062 2043 … … 2066 2047 { 2067 2048 PDMDEV_ASSERT_DEVINS(pDevIns); 2049 PVM pVM = pDevIns->Internal.s.pVMR3; 2068 2050 LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n", 2069 2051 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite)); 2070 2052 2071 /* 2072 * For the convenience of the device we put no thread restriction on this interface. 2073 * That means we'll have to check which thread we're in and choose our path. 2074 */ 2075 #ifdef PDM_PHYS_READWRITE_FROM_ANY_THREAD 2076 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 2077 #else 2078 if (VM_IS_EMT(pDevIns->Internal.s.pVMR3) || VMMR3LockIsOwner(pDevIns->Internal.s.pVMR3)) 2079 PGMPhysWrite(pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite); 2053 int rc = VINF_SUCCESS; 2054 #ifdef VBOX_WITH_NEW_PHYS_CODE 2055 if (!VM_IS_EMT(pVM)) 2056 rc = PGMR3PhysWriteExternal(pVM, GCPhys, pvBuf, cbWrite); 2080 2057 else 2081 {2082 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: Requesting call in EMT...\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));2083 PVMREQ pReq;2084 AssertCompileSize(RTGCPHYS, 4);2085 int rc = VMR3ReqCallVoid(pDevIns->Internal.s.pVMR3, &pReq, RT_INDEFINITE_WAIT,2086 (PFNRT)PGMPhysWrite, 4, pDevIns->Internal.s.pVMR3, GCPhys, pvBuf, cbWrite);2087 while (rc == VERR_TIMEOUT)2088 rc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);2089 AssertReleaseRC(rc);2090 VMR3ReqFree(pReq);2091 }2092 2058 #endif 2093 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns void\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2059 PGMPhysWrite(pVM, GCPhys, pvBuf, cbWrite); 2060 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc)); 2061 /** @todo return rc; */ NOREF(rc); 2094 2062 } 2095 2063 -
trunk/src/VBox/VMM/PGMPhys.cpp
r17509 r17510 87 87 #define PGMPHYS_DATATYPE uint64_t 88 88 #include "PGMPhysRWTmpl.h" 89 90 91 /** 92 * EMT worker for PGMR3PhysReadExternal. 93 */ 94 static DECLCALLBACK(int) pgmR3PhysReadExternalEMT(PVM pVM, PRTGCPHYS pGCPhys, void *pvBuf, size_t cbRead) 95 { 96 PGMPhysRead(pVM, *pGCPhys, pvBuf, cbRead); 97 return VINF_SUCCESS; 98 } 99 100 101 /** 102 * Write to physical memory, external users. 103 * 104 * @returns VBox status code. 105 * @retval VINF_SUCCESS. 106 * 107 * @param pVM VM Handle. 108 * @param GCPhys Physical address to write to. 109 * @param pvBuf What to write. 110 * @param cbWrite How many bytes to write. 111 * 112 * @thread Any but EMTs. 113 */ 114 VMMR3DECL(int) PGMR3PhysReadExternal(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) 115 { 116 VM_ASSERT_OTHER_THREAD(pVM); 117 118 AssertMsgReturn(cbRead > 0, ("don't even think about reading zero bytes!\n"), VINF_SUCCESS); 119 LogFlow(("PGMR3PhysReadExternal: %RGp %d\n", GCPhys, cbRead)); 120 121 pgmLock(pVM); 122 123 /* 124 * Copy loop on ram ranges. 125 */ 126 PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges); 127 for (;;) 128 { 129 /* Find range. */ 130 while (pRam && GCPhys > pRam->GCPhysLast) 131 pRam = pRam->CTX_SUFF(pNext); 132 /* Inside range or not? */ 133 if (pRam && GCPhys >= pRam->GCPhys) 134 { 135 /* 136 * Must work our way thru this page by page. 137 */ 138 RTGCPHYS off = GCPhys - pRam->GCPhys; 139 while (off < pRam->cb) 140 { 141 unsigned iPage = off >> PAGE_SHIFT; 142 PPGMPAGE pPage = &pRam->aPages[iPage]; 143 144 /* 145 * If the page has an ALL access handler, we'll have to 146 * delegate the job to EMT. 147 */ 148 if (PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage)) 149 { 150 pgmUnlock(pVM); 151 152 PVMREQ pReq = NULL; 153 int rc = VMR3ReqCall(pVM, VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT, 154 (PFNRT)pgmR3PhysReadExternalEMT, 4, pVM, &GCPhys, pvBuf, cbRead); 155 if (RT_SUCCESS(rc)) 156 { 157 rc = pReq->iStatus; 158 VMR3ReqFree(pReq); 159 } 160 return rc; 161 } 162 Assert(!PGM_PAGE_IS_MMIO(pPage)); 163 164 /* 165 * Simple stuff, go ahead. 166 */ 167 size_t cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 168 if (cb > cbRead) 169 cb = cbRead; 170 const void *pvSrc; 171 int rc = pgmPhysGCPhys2CCPtrInternalReadOnly(pVM, pPage, pRam->GCPhys + off, &pvSrc); 172 if (RT_SUCCESS(rc)) 173 memcpy(pvBuf, pvSrc, cb); 174 else 175 { 176 AssertLogRelMsgFailed(("pgmPhysGCPhys2CCPtrInternalReadOnly failed on %RGp / %R[pgmpage] -> %Rrc\n", 177 pRam->GCPhys + off, pPage, rc)); 178 memset(pvBuf, 0xff, cb); 179 } 180 181 /* next page */ 182 if (cb >= cbRead) 183 { 184 pgmUnlock(pVM); 185 return VINF_SUCCESS; 186 } 187 cbRead -= cb; 188 off += cb; 189 GCPhys += cb; 190 pvBuf = (char *)pvBuf + cb; 191 } /* walk pages in ram range. */ 192 } 193 else 194 { 195 LogFlow(("PGMPhysRead: Unassigned %RGp size=%u\n", GCPhys, cbRead)); 196 197 /* 198 * Unassigned address space. 199 */ 200 if (!pRam) 201 break; 202 size_t cb = pRam->GCPhys - GCPhys; 203 if (cb >= cbRead) 204 { 205 memset(pvBuf, 0xff, cbRead); 206 break; 207 } 208 memset(pvBuf, 0xff, cb); 209 210 cbRead -= cb; 211 pvBuf = (char *)pvBuf + cb; 212 GCPhys += cb; 213 } 214 } /* Ram range walk */ 215 216 pgmUnlock(pVM); 217 218 return VINF_SUCCESS; 219 } 220 221 222 /** 223 * EMT worker for PGMR3PhysWriteExternal. 224 */ 225 static DECLCALLBACK(int) pgmR3PhysWriteExternalEMT(PVM pVM, PRTGCPHYS pGCPhys, const void *pvBuf, size_t cbWrite) 226 { 227 /** @todo VERR_EM_NO_MEMORY */ 228 PGMPhysWrite(pVM, *pGCPhys, pvBuf, cbWrite); 229 return VINF_SUCCESS; 230 } 231 232 233 /** 234 * Write to physical memory, external users. 235 * 236 * @returns VBox status code. 237 * @retval VINF_SUCCESS. 238 * @retval VERR_EM_NO_MEMORY. 239 * 240 * @param pVM VM Handle. 241 * @param GCPhys Physical address to write to. 242 * @param pvBuf What to write. 243 * @param cbWrite How many bytes to write. 244 * 245 * @thread Any but EMTs. 246 */ 247 VMMDECL(int) PGMR3PhysWriteExternal(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) 248 { 249 VM_ASSERT_OTHER_THREAD(pVM); 250 251 AssertMsg(!pVM->pgm.s.fNoMorePhysWrites, ("Calling PGMR3PhysWriteExternal after pgmR3Save()!\n")); 252 AssertMsgReturn(cbWrite > 0, ("don't even think about writing zero bytes!\n"), VINF_SUCCESS); 253 LogFlow(("PGMR3PhysWriteExternal: %RGp %d\n", GCPhys, cbWrite)); 254 255 pgmLock(pVM); 256 257 /* 258 * Copy loop on ram ranges, stop when we hit something difficult. 259 */ 260 PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges); 261 for (;;) 262 { 263 /* Find range. */ 264 while (pRam && GCPhys > pRam->GCPhysLast) 265 pRam = pRam->CTX_SUFF(pNext); 266 /* Inside range or not? */ 267 if (pRam && GCPhys >= pRam->GCPhys) 268 { 269 /* 270 * Must work our way thru this page by page. 271 */ 272 RTGCPTR off = GCPhys - pRam->GCPhys; 273 while (off < pRam->cb) 274 { 275 RTGCPTR iPage = off >> PAGE_SHIFT; 276 PPGMPAGE pPage = &pRam->aPages[iPage]; 277 278 /* 279 * It the page is in any way problematic, we have to 280 * do the work on the EMT. Anything that needs to be made 281 * writable or involves access handlers is problematic. 282 */ 283 if ( PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage) 284 || PGM_PAGE_GET_STATE(pPage) != PGM_PAGE_STATE_ALLOCATED) 285 { 286 pgmUnlock(pVM); 287 288 PVMREQ pReq = NULL; 289 int rc = VMR3ReqCall(pVM, VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT, 290 (PFNRT)pgmR3PhysWriteExternalEMT, 4, pVM, &GCPhys, pvBuf, cbWrite); 291 if (RT_SUCCESS(rc)) 292 { 293 rc = pReq->iStatus; 294 VMR3ReqFree(pReq); 295 } 296 return rc; 297 } 298 Assert(!PGM_PAGE_IS_MMIO(pPage)); 299 300 /* 301 * Simple stuff, go ahead. 302 */ 303 size_t cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 304 if (cb > cbWrite) 305 cb = cbWrite; 306 void *pvDst; 307 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, pRam->GCPhys + off, &pvDst); 308 if (RT_SUCCESS(rc)) 309 memcpy(pvDst, pvBuf, cb); 310 else 311 AssertLogRelMsgFailed(("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", 312 pRam->GCPhys + off, pPage, rc)); 313 314 /* next page */ 315 if (cb >= cbWrite) 316 { 317 pgmUnlock(pVM); 318 return VINF_SUCCESS; 319 } 320 321 cbWrite -= cb; 322 off += cb; 323 GCPhys += cb; 324 pvBuf = (const char *)pvBuf + cb; 325 } /* walk pages in ram range */ 326 } 327 else 328 { 329 /* 330 * Unassigned address space, skip it. 331 */ 332 if (!pRam) 333 break; 334 size_t cb = pRam->GCPhys - GCPhys; 335 if (cb >= cbWrite) 336 break; 337 cbWrite -= cb; 338 pvBuf = (const char *)pvBuf + cb; 339 GCPhys += cb; 340 } 341 } /* Ram range walk */ 342 343 pgmUnlock(pVM); 344 return VINF_SUCCESS; 345 } 89 346 90 347 -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r17505 r17510 299 299 300 300 301 DECLINLINE(int) emRamRead(PVM pVM, void *pDest, RTGCPTR GCSrc, uint32_t cb)302 { 303 #ifdef IN_RC 304 int rc = MMGCRamRead(pVM, p Dest, (void *)GCSrc, cb);301 DECLINLINE(int) emRamRead(PVM pVM, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, uint32_t cb) 302 { 303 #ifdef IN_RC 304 int rc = MMGCRamRead(pVM, pvDst, (void *)GCPtrSrc, cb); 305 305 if (RT_LIKELY(rc != VERR_ACCESS_DENIED)) 306 306 return rc; … … 310 310 * instruction and it either flushed the TLB or the CPU reused it. 311 311 */ 312 #endif 313 #ifdef VBOX_WITH_NEW_PHYS_CODE 314 return PGMPhysInterpretedReadNoHandlers(pVM, pCtxCore, pvDst, GCPtrSrc, cb, /*fMayTrap*/ false); 315 #else 316 NOREF(pCtxCore); 317 # ifdef IN_RC 312 318 RTGCPHYS GCPhys; 313 rc = PGMPhysGCPtr2GCPhys(pVM, GC Src, &GCPhys);319 rc = PGMPhysGCPtr2GCPhys(pVM, GCPtrSrc, &GCPhys); 314 320 AssertRCReturn(rc, rc); 315 PGMPhysRead(pVM, GCPhys, p Dest, cb);321 PGMPhysRead(pVM, GCPhys, pvDst, cb); 316 322 return VINF_SUCCESS; 317 #else 318 return PGMPhysReadGCPtr(pVM, pDest, GCSrc, cb); 319 #endif 320 } 321 322 323 DECLINLINE(int) emRamWrite(PVM pVM, RTGCPTR GCDest, void *pSrc, uint32_t cb) 324 { 325 #ifdef IN_RC 326 int rc = MMGCRamWrite(pVM, (void *)GCDest, pSrc, cb); 323 # else 324 return PGMPhysReadGCPtr(pVM, pvDst, GCPtrSrc, cb); 325 # endif 326 #endif 327 } 328 329 330 DECLINLINE(int) emRamWrite(PVM pVM, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, const void *pvSrc, uint32_t cb) 331 { 332 #ifdef IN_RC 333 int rc = MMGCRamWrite(pVM, (void *)(uintptr_t)GCPtrDst, (void *)pvSrc, cb); 327 334 if (RT_LIKELY(rc != VERR_ACCESS_DENIED)) 328 335 return rc; … … 334 341 * access doesn't cost us much (see PGMPhysGCPtr2GCPhys()). 335 342 */ 343 #endif 344 #ifdef VBOX_WITH_NEW_PHYS_CODE 345 return PGMPhysInterpretedWriteNoHandlers(pVM, pCtxCore, GCPtrDst, pvSrc, cb, /*fMayTrap*/ false); 346 #else 347 NOREF(pCtxCore); 348 # ifdef IN_RC 336 349 uint64_t fFlags; 337 350 RTGCPHYS GCPhys; 338 rc = PGMGstGetPage(pVM, GC Dest, &fFlags, &GCPhys);351 rc = PGMGstGetPage(pVM, GCPtrDst, &fFlags, &GCPhys); 339 352 if (RT_FAILURE(rc)) 340 353 return rc; … … 345 358 PGMPhysWrite(pVM, GCPhys + ((RTGCUINTPTR)GCDest & PAGE_OFFSET_MASK), pSrc, cb); 346 359 return VINF_SUCCESS; 347 348 #else 349 return PGMPhysWriteGCPtr(pVM, GCDest, pSrc, cb); 360 # else 361 return PGMPhysWriteGCPtr(pVM, GCPtrDst, pvSrc, cb); 362 # endif 350 363 #endif 351 364 } … … 455 468 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 456 469 EM_ASSERT_FAULT_RETURN(pParam1 == pvFault, VERR_EM_INTERPRETER); 457 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);470 rc = emRamRead(pVM, pRegFrame, &valpar1, pParam1, param1.size); 458 471 if (RT_FAILURE(rc)) 459 472 { … … 474 487 pParam2 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param2, pParam2); 475 488 EM_ASSERT_FAULT_RETURN(pParam2 == pvFault, VERR_EM_INTERPRETER); 476 rc = emRamRead(pVM, &valpar2, pParam2, param2.size);489 rc = emRamRead(pVM, pRegFrame, &valpar2, pParam2, param2.size); 477 490 if (RT_FAILURE(rc)) 478 491 { … … 508 521 else 509 522 { 510 rc = emRamWrite(pVM, p Param1, &valpar2, param1.size);523 rc = emRamWrite(pVM, pRegFrame, pParam1, &valpar2, param1.size); 511 524 if (RT_FAILURE(rc)) 512 525 { … … 534 547 else 535 548 { 536 rc = emRamWrite(pVM, p Param2, &valpar1, param2.size);549 rc = emRamWrite(pVM, pRegFrame, pParam2, &valpar1, param2.size); 537 550 if (RT_FAILURE(rc)) 538 551 { … … 581 594 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 582 595 #endif 583 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);596 rc = emRamRead(pVM, pRegFrame, &valpar1, pParam1, param1.size); 584 597 if (RT_FAILURE(rc)) 585 598 { … … 599 612 600 613 /* Write result back */ 601 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);614 rc = emRamWrite(pVM, pRegFrame, pParam1, &valpar1, param1.size); 602 615 if (RT_FAILURE(rc)) 603 616 { … … 651 664 return VERR_EM_INTERPRETER; 652 665 653 rc = emRamRead(pVM, &valpar1, pStackVal, param1.size);666 rc = emRamRead(pVM, pRegFrame, &valpar1, pStackVal, param1.size); 654 667 if (RT_FAILURE(rc)) 655 668 { … … 672 685 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 673 686 EM_ASSERT_FAULT_RETURN(pParam1 == pvFault || (RTGCPTR)pRegFrame->esp == pvFault, VERR_EM_INTERPRETER); 674 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);687 rc = emRamWrite(pVM, pRegFrame, pParam1, &valpar1, param1.size); 675 688 if (RT_FAILURE(rc)) 676 689 { … … 744 757 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 745 758 EM_ASSERT_FAULT_RETURN(pParam1 == pvFault, VERR_EM_INTERPRETER); 746 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);759 rc = emRamRead(pVM, pRegFrame, &valpar1, pParam1, param1.size); 747 760 if (RT_FAILURE(rc)) 748 761 { … … 781 794 782 795 /* And write it back */ 783 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);796 rc = emRamWrite(pVM, pRegFrame, pParam1, &valpar1, param1.size); 784 797 if (RT_SUCCESS(rc)) 785 798 { … … 922 935 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 923 936 EM_ASSERT_FAULT_RETURN(pParam1 == pvFault, VERR_EM_INTERPRETER); 924 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);937 rc = emRamRead(pVM, pRegFrame, &valpar1, pParam1, param1.size); 925 938 if (RT_FAILURE(rc)) 926 939 { … … 957 970 958 971 /* And write it back */ 959 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);972 rc = emRamWrite(pVM, pRegFrame, pParam1, &valpar1, param1.size); 960 973 if (RT_SUCCESS(rc)) 961 974 { … … 1031 1044 pParam1 = (RTGCPTR)((RTGCUINTPTR)pParam1 + valpar2/8); 1032 1045 EM_ASSERT_FAULT_RETURN((RTGCPTR)((RTGCUINTPTR)pParam1 & ~3) == pvFault, VERR_EM_INTERPRETER); 1033 rc = emRamRead(pVM, &valpar1, pParam1, 1);1046 rc = emRamRead(pVM, pRegFrame, &valpar1, pParam1, 1); 1034 1047 if (RT_FAILURE(rc)) 1035 1048 { … … 1049 1062 1050 1063 /* And write it back */ 1051 rc = emRamWrite(pVM, p Param1, &valpar1, 1);1064 rc = emRamWrite(pVM, pRegFrame, pParam1, &valpar1, 1); 1052 1065 if (RT_SUCCESS(rc)) 1053 1066 { … … 1202 1215 Assert(param2.size <= 8 && param2.size > 0); 1203 1216 EM_ASSERT_FAULT_RETURN(pDest == pvFault, VERR_EM_INTERPRETER); 1204 rc = emRamWrite(pVM, p Dest, &val64, param2.size);1217 rc = emRamWrite(pVM, pRegFrame, pDest, &val64, param2.size); 1205 1218 if (RT_FAILURE(rc)) 1206 1219 return VERR_EM_INTERPRETER; … … 1232 1245 Assert(param1.size <= 8 && param1.size > 0); 1233 1246 EM_ASSERT_FAULT_RETURN(pSrc == pvFault, VERR_EM_INTERPRETER); 1234 rc = emRamRead(pVM, &val64, pSrc, param1.size);1247 rc = emRamRead(pVM, pRegFrame, &val64, pSrc, param1.size); 1235 1248 if (RT_FAILURE(rc)) 1236 1249 return VERR_EM_INTERPRETER; … … 1773 1786 Assert(!CPUMIsGuestIn64BitCode(pVM, pRegFrame)); 1774 1787 1775 rc = emRamRead(pVM, &eip, (RTGCPTR)pIretStack , 4);1776 rc |= emRamRead(pVM, &cs, (RTGCPTR)(pIretStack + 4), 4);1777 rc |= emRamRead(pVM, &eflags, (RTGCPTR)(pIretStack + 8), 4);1788 rc = emRamRead(pVM, pRegFrame, &eip, (RTGCPTR)pIretStack , 4); 1789 rc |= emRamRead(pVM, pRegFrame, &cs, (RTGCPTR)(pIretStack + 4), 4); 1790 rc |= emRamRead(pVM, pRegFrame, &eflags, (RTGCPTR)(pIretStack + 8), 4); 1778 1791 AssertRCReturn(rc, VERR_EM_INTERPRETER); 1779 1792 AssertReturn(eflags & X86_EFL_VM, VERR_EM_INTERPRETER); 1780 1793 1781 rc |= emRamRead(pVM, &esp, (RTGCPTR)(pIretStack + 12), 4);1782 rc |= emRamRead(pVM, &ss, (RTGCPTR)(pIretStack + 16), 4);1783 rc |= emRamRead(pVM, &es, (RTGCPTR)(pIretStack + 20), 4);1784 rc |= emRamRead(pVM, &ds, (RTGCPTR)(pIretStack + 24), 4);1785 rc |= emRamRead(pVM, &fs, (RTGCPTR)(pIretStack + 28), 4);1786 rc |= emRamRead(pVM, &gs, (RTGCPTR)(pIretStack + 32), 4);1794 rc |= emRamRead(pVM, pRegFrame, &esp, (RTGCPTR)(pIretStack + 12), 4); 1795 rc |= emRamRead(pVM, pRegFrame, &ss, (RTGCPTR)(pIretStack + 16), 4); 1796 rc |= emRamRead(pVM, pRegFrame, &es, (RTGCPTR)(pIretStack + 20), 4); 1797 rc |= emRamRead(pVM, pRegFrame, &ds, (RTGCPTR)(pIretStack + 24), 4); 1798 rc |= emRamRead(pVM, pRegFrame, &fs, (RTGCPTR)(pIretStack + 28), 4); 1799 rc |= emRamRead(pVM, pRegFrame, &gs, (RTGCPTR)(pIretStack + 32), 4); 1787 1800 AssertRCReturn(rc, VERR_EM_INTERPRETER); 1788 1801 … … 2257 2270 LogFlow(("emInterpretSmsw %VGv <- cr0 (%x)\n", pParam1, cr0)); 2258 2271 2259 rc = emRamWrite(pVM, p Param1, &cr0, sizeof(uint16_t));2272 rc = emRamWrite(pVM, pRegFrame, pParam1, &cr0, sizeof(uint16_t)); 2260 2273 if (RT_FAILURE(rc)) 2261 2274 { … … 2451 2464 } 2452 2465 2453 rc = emRamRead(pVM, &dtr32, pParam1, sizeof(dtr32));2466 rc = emRamRead(pVM, pRegFrame, &dtr32, pParam1, sizeof(dtr32)); 2454 2467 AssertRCReturn(rc, VERR_EM_INTERPRETER); 2455 2468 -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r17509 r17510 1538 1538 if (cb >= cbRead) 1539 1539 { 1540 #if 0 /** @todo enable this later. */1541 1540 memset(pvBuf, 0xff, cbRead); 1542 #else1543 memset(pvBuf, 0, cbRead);1544 #endif1545 1541 break; 1546 1542 } 1547 1543 1548 #if 0 /** @todo enable this later. */1549 1544 memset(pvBuf, 0xff, cb); 1550 #else1551 memset(pvBuf, 0, cb);1552 #endif1553 1545 cbRead -= cb; 1554 1546 pvBuf = (char *)pvBuf + cb; … … 2583 2575 #endif /* Old PGMPhysWrite */ 2584 2576 2577 2585 2578 /** 2586 2579 * Read from guest physical memory by GC physical address, bypassing … … 3257 3250 } 3258 3251 3259 /// @todo VMMDECL(int) PGMPhysInterpretedWrite(PVM pVM, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb) 3260 3261 3252 3253 /** 3254 * Performs a read of guest virtual memory for instruction emulation. 3255 * 3256 * This will check permissions, raise exceptions and update the access bits. 3257 * 3258 * The current implementation will bypass all access handlers. It may later be 3259 * changed to at least respect MMIO. 3260 * 3261 * 3262 * @returns VBox status code suitable to scheduling. 3263 * @retval VINF_SUCCESS if the read was performed successfully. 3264 * @retval VINF_EM_RAW_GUEST_TRAP if an exception was raised but not dispatched yet. 3265 * @retval VINF_TRPM_XCPT_DISPATCHED if an exception was raised and dispatched. 3266 * 3267 * @param pVM The VM handle. 3268 * @param pCtxCore The context core. 3269 * @param pvDst Where to put the bytes we've read. 3270 * @param GCPtrSrc The source address. 3271 * @param cb The number of bytes to read. Not more than a page. 3272 * @param fRaiseTrap If set the trap will be raised on as per spec, if clear 3273 * an appropriate error status will be returned (no 3274 * informational at all). 3275 * 3276 * 3277 * @remarks Takes the PGM lock. 3278 * @remarks A page fault on the 2nd page of the access will be raised without 3279 * writing the bits on the first page since we're ASSUMING that the 3280 * caller is emulating an instruction access. 3281 * @remarks This function will dynamically map physical pages in GC. This may 3282 * unmap mappings done by the caller. Be careful! 3283 */ 3284 VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVM pVM, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb, bool fRaiseTrap) 3285 { 3286 Assert(cb <= PAGE_SIZE); 3287 3288 /* 3289 * 1. Translate virtual to physical. This may fault. 3290 * 2. Map the physical address. 3291 * 3. Do the read operation. 3292 * 4. Set access bits if required. 3293 */ 3294 int rc; 3295 unsigned cb1 = PAGE_SIZE - (GCPtrSrc & PAGE_OFFSET_MASK); 3296 if (cb <= cb1) 3297 { 3298 /* 3299 * Not crossing pages. 3300 */ 3301 RTGCPHYS GCPhys; 3302 uint64_t fFlags; 3303 rc = PGM_GST_PFN(GetPage,pVM)(pVM, GCPtrSrc, &fFlags, &GCPhys); 3304 if (RT_SUCCESS(rc)) 3305 { 3306 if (1) /** @todo we should check reserved bits ... */ 3307 { 3308 const void *pvSrc; 3309 PGMPAGEMAPLOCK Lock; 3310 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys, &pvSrc, &Lock); 3311 switch (rc) 3312 { 3313 case VINF_SUCCESS: 3314 Log(("PGMPhysInterpretedReadNoHandlers: pvDst=%p pvSrc=%p (%RGv) cb=%d\n", 3315 pvDst, (const uint8_t *)pvSrc + (GCPtrSrc & PAGE_OFFSET_MASK), GCPtrSrc, cb)); 3316 memcpy(pvDst, (const uint8_t *)pvSrc + (GCPtrSrc & PAGE_OFFSET_MASK), cb); 3317 break; 3318 case VERR_PGM_PHYS_PAGE_RESERVED: 3319 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3320 memset(pvDst, 0xff, cb); 3321 break; 3322 default: 3323 AssertMsgFailed(("%Rrc\n", rc)); 3324 AssertReturn(RT_FAILURE(rc), VERR_INTERNAL_ERROR); 3325 return rc; 3326 } 3327 PGMPhysReleasePageMappingLock(pVM, &Lock); 3328 3329 if (!(fFlags & X86_PTE_A)) 3330 { 3331 /** @todo access bit emulation isn't 100% correct. */ 3332 rc = PGM_GST_PFN(ModifyPage,pVM)(pVM, GCPtrSrc, 1, X86_PTE_A, ~(uint64_t)X86_PTE_A); 3333 AssertRC(rc); 3334 } 3335 return VINF_SUCCESS; 3336 } 3337 } 3338 } 3339 else 3340 { 3341 /* 3342 * Crosses pages. 3343 */ 3344 size_t cb2 = cb - cb1; 3345 uint64_t fFlags1; 3346 RTGCPHYS GCPhys1; 3347 uint64_t fFlags2; 3348 RTGCPHYS GCPhys2; 3349 rc = PGM_GST_PFN(GetPage,pVM)(pVM, GCPtrSrc, &fFlags1, &GCPhys1); 3350 if (RT_SUCCESS(rc)) 3351 { 3352 rc = PGM_GST_PFN(GetPage,pVM)(pVM, GCPtrSrc + cb1, &fFlags2, &GCPhys2); 3353 if (RT_SUCCESS(rc)) 3354 { 3355 if (1) /** @todo we should check reserved bits ... */ 3356 { 3357 const void *pvSrc; 3358 PGMPAGEMAPLOCK Lock; 3359 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys1, &pvSrc, &Lock); 3360 switch (rc) 3361 { 3362 case VINF_SUCCESS: 3363 Log(("PGMPhysInterpretedReadNoHandlers: pvDst=%p pvSrc=%p (%RGv) cb=%d [2]\n", 3364 pvDst, (const uint8_t *)pvSrc + (GCPtrSrc & PAGE_OFFSET_MASK), GCPtrSrc, cb1)); 3365 memcpy(pvDst, (const uint8_t *)pvSrc + (GCPtrSrc & PAGE_OFFSET_MASK), cb1); 3366 PGMPhysReleasePageMappingLock(pVM, &Lock); 3367 break; 3368 case VERR_PGM_PHYS_PAGE_RESERVED: 3369 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3370 memset(pvDst, 0xff, cb1); 3371 break; 3372 default: 3373 AssertMsgFailed(("%Rrc\n", rc)); 3374 AssertReturn(RT_FAILURE(rc), VERR_INTERNAL_ERROR); 3375 return rc; 3376 } 3377 3378 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys2, &pvSrc, &Lock); 3379 switch (rc) 3380 { 3381 case VINF_SUCCESS: 3382 memcpy((uint8_t *)pvDst + cb1, pvSrc, cb2); 3383 PGMPhysReleasePageMappingLock(pVM, &Lock); 3384 break; 3385 case VERR_PGM_PHYS_PAGE_RESERVED: 3386 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3387 memset((uint8_t *)pvDst + cb1, 0xff, cb2); 3388 break; 3389 default: 3390 AssertMsgFailed(("%Rrc\n", rc)); 3391 AssertReturn(RT_FAILURE(rc), VERR_INTERNAL_ERROR); 3392 return rc; 3393 } 3394 3395 if (!(fFlags1 & X86_PTE_A)) 3396 { 3397 rc = PGM_GST_PFN(ModifyPage,pVM)(pVM, GCPtrSrc, 1, X86_PTE_A, ~(uint64_t)X86_PTE_A); 3398 AssertRC(rc); 3399 } 3400 if (!(fFlags2 & X86_PTE_A)) 3401 { 3402 rc = PGM_GST_PFN(ModifyPage,pVM)(pVM, GCPtrSrc + cb1, 1, X86_PTE_A, ~(uint64_t)X86_PTE_A); 3403 AssertRC(rc); 3404 } 3405 return VINF_SUCCESS; 3406 } 3407 /* sort out which page */ 3408 } 3409 else 3410 GCPtrSrc += cb1; /* fault on 2nd page */ 3411 } 3412 } 3413 3414 /* 3415 * Raise a #PF if we're allowed to do that. 3416 */ 3417 /* Calc the error bits. */ 3418 uint32_t cpl = CPUMGetGuestCPL(pVM, pCtxCore); 3419 uint32_t uErr; 3420 switch (rc) 3421 { 3422 case VINF_SUCCESS: 3423 uErr = (cpl >= 2) ? X86_TRAP_PF_RSVD | X86_TRAP_PF_US : X86_TRAP_PF_RSVD; 3424 rc = VERR_ACCESS_DENIED; 3425 break; 3426 3427 case VERR_PAGE_NOT_PRESENT: 3428 case VERR_PAGE_TABLE_NOT_PRESENT: 3429 uErr = (cpl >= 2) ? X86_TRAP_PF_US : 0; 3430 break; 3431 3432 default: 3433 AssertMsgFailed(("rc=%Rrc GCPtrSrc=%RGv cb=%#x\n", rc, GCPtrSrc, cb)); 3434 AssertReturn(RT_FAILURE(rc), VERR_INTERNAL_ERROR); 3435 return rc; 3436 } 3437 if (fRaiseTrap) 3438 { 3439 Log(("PGMPhysInterpretedReadNoHandlers: GCPtrSrc=%RGv cb=%#x -> Raised #PF(%#x)\n", GCPtrSrc, cb, uErr)); 3440 return TRPMRaiseXcptErrCR2(pVM, pCtxCore, X86_XCPT_PF, uErr, GCPtrSrc); 3441 } 3442 Log(("PGMPhysInterpretedReadNoHandlers: GCPtrSrc=%RGv cb=%#x -> #PF(%#x) [!raised]\n", GCPtrSrc, cb, uErr)); 3443 return rc; 3444 } 3445 3446 3447 /** 3448 * Performs a write to guest virtual memory for instruction emulation. 3449 * 3450 * This will check permissions, raise exceptions and update the dirty and access 3451 * bits. 3452 * 3453 * @returns VBox status code suitable to scheduling. 3454 * @retval VINF_SUCCESS if the read was performed successfully. 3455 * @retval VINF_EM_RAW_GUEST_TRAP if an exception was raised but not dispatched yet. 3456 * @retval VINF_TRPM_XCPT_DISPATCHED if an exception was raised and dispatched. 3457 * 3458 * @param pVM The VM handle. 3459 * @param pCtxCore The context core. 3460 * @param GCPtrDst The destination address. 3461 * @param pvSrc What to write. 3462 * @param cb The number of bytes to write. Not more than a page. 3463 * @param fRaiseTrap If set the trap will be raised on as per spec, if clear 3464 * an appropriate error status will be returned (no 3465 * informational at all). 3466 * 3467 * @remarks Takes the PGM lock. 3468 * @remarks A page fault on the 2nd page of the access will be raised without 3469 * writing the bits on the first page since we're ASSUMING that the 3470 * caller is emulating an instruction access. 3471 * @remarks This function will dynamically map physical pages in GC. This may 3472 * unmap mappings done by the caller. Be careful! 3473 */ 3474 VMMDECL(int) PGMPhysInterpretedWriteNoHandlers(PVM pVM, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb, bool fRaiseTrap) 3475 { 3476 Assert(cb <= PAGE_SIZE); 3477 3478 /* 3479 * 1. Translate virtual to physical. This may fault. 3480 * 2. Map the physical address. 3481 * 3. Do the write operation. 3482 * 4. Set access bits if required. 3483 */ 3484 int rc; 3485 unsigned cb1 = PAGE_SIZE - (GCPtrDst & PAGE_OFFSET_MASK); 3486 if (cb <= cb1) 3487 { 3488 /* 3489 * Not crossing pages. 3490 */ 3491 RTGCPHYS GCPhys; 3492 uint64_t fFlags; 3493 rc = PGM_GST_PFN(GetPage,pVM)(pVM, GCPtrDst, &fFlags, &GCPhys); 3494 if (RT_SUCCESS(rc)) 3495 { 3496 if ( (fFlags & X86_PTE_RW) /** @todo Also check reserved bits. */ 3497 || ( !(CPUMGetGuestCR0(pVM) & X86_CR0_WP) 3498 && CPUMGetGuestCPL(pVM, pCtxCore) <= 2) ) /** @todo it's 2, right? Check cpl check below as well. */ 3499 { 3500 void *pvDst; 3501 PGMPAGEMAPLOCK Lock; 3502 rc = PGMPhysGCPhys2CCPtr(pVM, GCPhys, &pvDst, &Lock); 3503 switch (rc) 3504 { 3505 case VINF_SUCCESS: 3506 Log(("PGMPhysInterpretedWriteNoHandlers: pvDst=%p (%RGv) pvSrc=%p cb=%d\n", 3507 (uint8_t *)pvDst + (GCPtrDst & PAGE_OFFSET_MASK), GCPtrDst, pvSrc, cb)); 3508 memcpy((uint8_t *)pvDst + (GCPtrDst & PAGE_OFFSET_MASK), pvSrc, cb); 3509 PGMPhysReleasePageMappingLock(pVM, &Lock); 3510 break; 3511 case VERR_PGM_PHYS_PAGE_RESERVED: 3512 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3513 /* bit bucket */ 3514 break; 3515 default: 3516 AssertMsgFailed(("%Rrc\n", rc)); 3517 AssertReturn(RT_FAILURE(rc), VERR_INTERNAL_ERROR); 3518 return rc; 3519 } 3520 3521 if (!(fFlags & (X86_PTE_A | X86_PTE_D))) 3522 { 3523 /** @todo dirty & access bit emulation isn't 100% correct. */ 3524 rc = PGM_GST_PFN(ModifyPage,pVM)(pVM, GCPtrDst, 1, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D)); 3525 AssertRC(rc); 3526 } 3527 return VINF_SUCCESS; 3528 } 3529 rc = VERR_ACCESS_DENIED; 3530 } 3531 } 3532 else 3533 { 3534 /* 3535 * Crosses pages. 3536 */ 3537 size_t cb2 = cb - cb1; 3538 uint64_t fFlags1; 3539 RTGCPHYS GCPhys1; 3540 uint64_t fFlags2; 3541 RTGCPHYS GCPhys2; 3542 rc = PGM_GST_PFN(GetPage,pVM)(pVM, GCPtrDst, &fFlags1, &GCPhys1); 3543 if (RT_SUCCESS(rc)) 3544 { 3545 rc = PGM_GST_PFN(GetPage,pVM)(pVM, GCPtrDst + cb1, &fFlags2, &GCPhys2); 3546 if (RT_SUCCESS(rc)) 3547 { 3548 if ( ( (fFlags1 & X86_PTE_RW) /** @todo Also check reserved bits. */ 3549 && (fFlags2 & X86_PTE_RW)) 3550 || ( !(CPUMGetGuestCR0(pVM) & X86_CR0_WP) 3551 && CPUMGetGuestCPL(pVM, pCtxCore) <= 2) ) 3552 { 3553 void *pvDst; 3554 PGMPAGEMAPLOCK Lock; 3555 rc = PGMPhysGCPhys2CCPtr(pVM, GCPhys1, &pvDst, &Lock); 3556 switch (rc) 3557 { 3558 case VINF_SUCCESS: 3559 Log(("PGMPhysInterpretedWriteNoHandlers: pvDst=%p (%RGv) pvSrc=%p cb=%d\n", 3560 (uint8_t *)pvDst + (GCPtrDst & PAGE_OFFSET_MASK), GCPtrDst, pvSrc, cb1)); 3561 memcpy((uint8_t *)pvDst + (GCPtrDst & PAGE_OFFSET_MASK), pvSrc, cb1); 3562 PGMPhysReleasePageMappingLock(pVM, &Lock); 3563 break; 3564 case VERR_PGM_PHYS_PAGE_RESERVED: 3565 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3566 /* bit bucket */ 3567 break; 3568 default: 3569 AssertMsgFailed(("%Rrc\n", rc)); 3570 AssertReturn(RT_FAILURE(rc), VERR_INTERNAL_ERROR); 3571 return rc; 3572 } 3573 3574 rc = PGMPhysGCPhys2CCPtr(pVM, GCPhys2, &pvDst, &Lock); 3575 switch (rc) 3576 { 3577 case VINF_SUCCESS: 3578 memcpy(pvDst, (const uint8_t *)pvSrc + cb1, cb2); 3579 PGMPhysReleasePageMappingLock(pVM, &Lock); 3580 break; 3581 case VERR_PGM_PHYS_PAGE_RESERVED: 3582 case VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS: 3583 /* bit bucket */ 3584 break; 3585 default: 3586 AssertMsgFailed(("%Rrc\n", rc)); 3587 AssertReturn(RT_FAILURE(rc), VERR_INTERNAL_ERROR); 3588 return rc; 3589 } 3590 3591 if (!(fFlags1 & (X86_PTE_A | X86_PTE_RW))) 3592 { 3593 rc = PGM_GST_PFN(ModifyPage,pVM)(pVM, GCPtrDst, 1, (X86_PTE_A | X86_PTE_RW), ~(uint64_t)(X86_PTE_A | X86_PTE_RW)); 3594 AssertRC(rc); 3595 } 3596 if (!(fFlags2 & (X86_PTE_A | X86_PTE_RW))) 3597 { 3598 rc = PGM_GST_PFN(ModifyPage,pVM)(pVM, GCPtrDst + cb1, 1, (X86_PTE_A | X86_PTE_RW), ~(uint64_t)(X86_PTE_A | X86_PTE_RW)); 3599 AssertRC(rc); 3600 } 3601 return VINF_SUCCESS; 3602 } 3603 if ((fFlags1 & (X86_PTE_RW)) == X86_PTE_RW) 3604 GCPtrDst += cb1; /* fault on the 2nd page. */ 3605 rc = VERR_ACCESS_DENIED; 3606 } 3607 else 3608 GCPtrDst += cb1; /* fault on the 2nd page. */ 3609 } 3610 } 3611 3612 /* 3613 * Raise a #PF if we're allowed to do that. 3614 */ 3615 /* Calc the error bits. */ 3616 uint32_t uErr; 3617 uint32_t cpl = CPUMGetGuestCPL(pVM, pCtxCore); 3618 switch (rc) 3619 { 3620 case VINF_SUCCESS: 3621 uErr = (cpl >= 2) ? X86_TRAP_PF_RSVD | X86_TRAP_PF_US : X86_TRAP_PF_RSVD; 3622 rc = VERR_ACCESS_DENIED; 3623 break; 3624 3625 case VERR_ACCESS_DENIED: 3626 uErr = (cpl >= 2) ? X86_TRAP_PF_RW | X86_TRAP_PF_US : X86_TRAP_PF_RW; 3627 break; 3628 3629 case VERR_PAGE_NOT_PRESENT: 3630 case VERR_PAGE_TABLE_NOT_PRESENT: 3631 uErr = (cpl >= 2) ? X86_TRAP_PF_US : 0; 3632 break; 3633 3634 default: 3635 AssertMsgFailed(("rc=%Rrc GCPtrDst=%RGv cb=%#x\n", rc, GCPtrDst, cb)); 3636 AssertReturn(RT_FAILURE(rc), VERR_INTERNAL_ERROR); 3637 return rc; 3638 } 3639 if (fRaiseTrap) 3640 { 3641 Log(("PGMPhysInterpretedWriteNoHandlers: GCPtrDst=%RGv cb=%#x -> Raised #PF(%#x)\n", GCPtrDst, cb, uErr)); 3642 return TRPMRaiseXcptErrCR2(pVM, pCtxCore, X86_XCPT_PF, uErr, GCPtrDst); 3643 } 3644 Log(("PGMPhysInterpretedWriteNoHandlers: GCPtrDst=%RGv cb=%#x -> #PF(%#x) [!raised]\n", GCPtrDst, cb, uErr)); 3645 return rc; 3646 } 3647 3648
Note:
See TracChangeset
for help on using the changeset viewer.