Changeset 8098 in vbox
- Timestamp:
- Apr 17, 2008 2:08:15 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 29799
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/em.h
r7286 r8098 469 469 EMGCDECL(uint32_t) EMGCEmulateLockCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags); 470 470 EMGCDECL(uint32_t) EMGCEmulateCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags); 471 EMGCDECL(uint32_t) EMGCEmulateLockCmpXchg8b(RTGCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags); 472 EMGCDECL(uint32_t) EMGCEmulateCmpXchg8b(RTGCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags); 471 473 EMGCDECL(uint32_t) EMGCEmulateLockXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, size_t cbSize, uint32_t *pEflags); 472 474 EMGCDECL(uint32_t) EMGCEmulateXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, size_t cbSize, uint32_t *pEflags); -
trunk/src/VBox/VMM/EM.cpp
r7996 r8098 201 201 STAM_REG_USED(pVM, &pStats->StatGCCmpXchg, STAMTYPE_COUNTER, "/EM/GC/Interpret/Success/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was successfully interpreted."); 202 202 STAM_REG_USED(pVM, &pStats->StatHCCmpXchg, STAMTYPE_COUNTER, "/EM/HC/Interpret/Success/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was successfully interpreted."); 203 STAM_REG_USED(pVM, &pStats->StatGCCmpXchg8b, STAMTYPE_COUNTER, "/EM/GC/Interpret/Success/CmpXchg8b", STAMUNIT_OCCURENCES, "The number of times CMPXCHG8B was successfully interpreted."); 204 STAM_REG_USED(pVM, &pStats->StatHCCmpXchg8b, STAMTYPE_COUNTER, "/EM/HC/Interpret/Success/CmpXchg8b", STAMUNIT_OCCURENCES, "The number of times CMPXCHG8B was successfully interpreted."); 203 205 STAM_REG_USED(pVM, &pStats->StatGCXAdd, STAMTYPE_COUNTER, "/EM/GC/Interpret/Success/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was successfully interpreted."); 204 206 STAM_REG_USED(pVM, &pStats->StatHCXAdd, STAMTYPE_COUNTER, "/EM/HC/Interpret/Success/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was successfully interpreted."); … … 262 264 STAM_REG_USED(pVM, &pStats->StatGCFailedCmpXchg, STAMTYPE_COUNTER, "/EM/GC/Interpret/Failed/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was not interpreted."); 263 265 STAM_REG_USED(pVM, &pStats->StatHCFailedCmpXchg, STAMTYPE_COUNTER, "/EM/HC/Interpret/Failed/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was not interpreted."); 266 STAM_REG_USED(pVM, &pStats->StatGCFailedCmpXchg8b, STAMTYPE_COUNTER, "/EM/GC/Interpret/Failed/CmpXchg8b", STAMUNIT_OCCURENCES, "The number of times CMPXCHG8B was not interpreted."); 267 STAM_REG_USED(pVM, &pStats->StatHCFailedCmpXchg8b, STAMTYPE_COUNTER, "/EM/HC/Interpret/Failed/CmpXchg8b", STAMUNIT_OCCURENCES, "The number of times CMPXCHG8B was not interpreted."); 264 268 STAM_REG_USED(pVM, &pStats->StatGCFailedXAdd, STAMTYPE_COUNTER, "/EM/GC/Interpret/Failed/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was not interpreted."); 265 269 STAM_REG_USED(pVM, &pStats->StatHCFailedXAdd, STAMTYPE_COUNTER, "/EM/HC/Interpret/Failed/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was not interpreted."); -
trunk/src/VBox/VMM/EMInternal.h
r7286 r8098 131 131 STAMCOUNTER StatGCCmpXchg; 132 132 STAMCOUNTER StatHCCmpXchg; 133 STAMCOUNTER StatGCCmpXchg8b; 134 STAMCOUNTER StatHCCmpXchg8b; 133 135 STAMCOUNTER StatGCXAdd; 134 136 STAMCOUNTER StatHCXAdd; … … 192 194 STAMCOUNTER StatGCFailedCmpXchg; 193 195 STAMCOUNTER StatHCFailedCmpXchg; 196 STAMCOUNTER StatGCFailedCmpXchg8b; 197 STAMCOUNTER StatHCFailedCmpXchg8b; 194 198 STAMCOUNTER StatGCFailedXAdd; 195 199 STAMCOUNTER StatHCFailedXAdd; -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r7905 r8098 1245 1245 OP_PARAMVAL param1, param2; 1246 1246 1247 #ifdef LOG_ENABLED 1248 char *pszInstr; 1249 1250 if (pCpu->prefix & PREFIX_LOCK) 1251 pszInstr = "Lock CmpXchg"; 1252 else 1253 pszInstr = "CmpXchg"; 1254 #endif 1255 1247 1256 /* Source to make DISQueryParamVal read the register value - ugly hack */ 1248 1257 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_SOURCE); … … 1289 1298 } 1290 1299 1291 LogFlow((" CmpXchg %VGv=%08x eax=%08x %08x\n", pParam1, valpar1, pRegFrame->eax, valpar));1300 LogFlow(("%s %VGv=%08x eax=%08x %08x\n", pszInstr, pParam1, valpar1, pRegFrame->eax, valpar)); 1292 1301 1293 1302 MMGCRamRegisterTrapHandler(pVM); … … 1300 1309 if (VBOX_FAILURE(rc)) 1301 1310 { 1302 Log((" CmpXchg %VGv=%08x eax=%08x %08x -> emulation failed due to page fault!\n", pParam1, valpar1, pRegFrame->eax, valpar));1303 return VERR_EM_INTERPRETER; 1304 } 1305 1306 LogFlow((" CmpXchg %VGv=%08x eax=%08x %08x ZF=%d\n", pParam1, valpar1, pRegFrame->eax, valpar, !!(eflags & X86_EFL_ZF)));1311 Log(("%s %VGv=%08x eax=%08x %08x -> emulation failed due to page fault!\n", pszInstr, pParam1, valpar1, pRegFrame->eax, valpar)); 1312 return VERR_EM_INTERPRETER; 1313 } 1314 1315 LogFlow(("%s %VGv=%08x eax=%08x %08x ZF=%d\n", pszInstr, pParam1, valpar1, pRegFrame->eax, valpar, !!(eflags & X86_EFL_ZF))); 1307 1316 1308 1317 /* Update guest's eflags and finish. */ … … 1311 1320 1312 1321 *pcbSize = param2.size; 1322 return VINF_SUCCESS; 1323 } 1324 } 1325 return VERR_EM_INTERPRETER; 1326 } 1327 1328 /* 1329 * [LOCK] CMPXCHG8B emulation. 1330 */ 1331 static int emInterpretCmpXchg8b(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 1332 { 1333 OP_PARAMVAL param1; 1334 1335 #ifdef LOG_ENABLED 1336 char *pszInstr; 1337 1338 if (pCpu->prefix & PREFIX_LOCK) 1339 pszInstr = "Lock CmpXchg8b"; 1340 else 1341 pszInstr = "CmpXchg8b"; 1342 #endif 1343 1344 /* Source to make DISQueryParamVal read the register value - ugly hack */ 1345 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_SOURCE); 1346 if(VBOX_FAILURE(rc)) 1347 return VERR_EM_INTERPRETER; 1348 1349 if (TRPMHasTrap(pVM)) 1350 { 1351 if (TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW) 1352 { 1353 RTGCPTR pParam1; 1354 uint32_t eflags; 1355 1356 AssertReturn(pCpu->param1.size == pCpu->param2.size, VERR_EM_INTERPRETER); 1357 switch(param1.type) 1358 { 1359 case PARMTYPE_ADDRESS: 1360 pParam1 = (RTGCPTR)param1.val.val32; 1361 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 1362 1363 /* Safety check (in theory it could cross a page boundary and fault there though) */ 1364 AssertMsgReturn(pParam1 == pvFault, ("eip=%VGv pParam1=%VGv pvFault=%VGv\n", pRegFrame->eip, pParam1, pvFault), VERR_EM_INTERPRETER); 1365 break; 1366 1367 default: 1368 return VERR_EM_INTERPRETER; 1369 } 1370 1371 LogFlow(("%s %VGv=%08x eax=%08x\n", pszInstr, pParam1, pRegFrame->eax)); 1372 1373 MMGCRamRegisterTrapHandler(pVM); 1374 if (pCpu->prefix & PREFIX_LOCK) 1375 rc = EMGCEmulateLockCmpXchg8b(pParam1, &pRegFrame->eax, &pRegFrame->edx, pRegFrame->ebx, pRegFrame->ecx, &eflags); 1376 else 1377 rc = EMGCEmulateCmpXchg8b(pParam1, &pRegFrame->eax, &pRegFrame->edx, pRegFrame->ebx, pRegFrame->ecx, &eflags); 1378 MMGCRamDeregisterTrapHandler(pVM); 1379 1380 if (VBOX_FAILURE(rc)) 1381 { 1382 Log(("%s %VGv=%08x eax=%08x -> emulation failed due to page fault!\n", pszInstr, pParam1, pRegFrame->eax)); 1383 return VERR_EM_INTERPRETER; 1384 } 1385 1386 LogFlow(("%s %VGv=%08x eax=%08x ZF=%d\n", pszInstr, pParam1, pRegFrame->eax, !!(eflags & X86_EFL_ZF))); 1387 1388 /* Update guest's eflags and finish. */ 1389 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 1390 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 1391 1392 *pcbSize = 8; 1313 1393 return VINF_SUCCESS; 1314 1394 } … … 2068 2148 INTERPRET_CASE(OP_STI,Sti); 2069 2149 INTERPRET_CASE(OP_CMPXCHG, CmpXchg); 2150 INTERPRET_CASE(OP_CMPXCHG8B, CmpXchg8b); 2070 2151 INTERPRET_CASE(OP_XADD, XAdd); 2071 2152 #endif … … 2075 2156 #ifndef IN_GC 2076 2157 INTERPRET_STAT_CASE(OP_CMPXCHG,CmpXchg); 2158 INTERPRET_STAT_CASE(OP_CMPXCHG8B, CmpXchg8b); 2077 2159 INTERPRET_STAT_CASE(OP_XADD, XAdd); 2078 2160 #endif -
trunk/src/VBox/VMM/VMMGC/EMGCA.asm
r7294 r8098 167 167 168 168 ;; 169 ; Emulate LOCK CMPXCHG8B instruction, CDECL calling conv. 170 ; EMGCDECL(uint32_t) EMGCEmulateLockCmpXchg8b(RTGCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags); 171 ; 172 ; @returns eax=0 if data written, other code - invalid access, #PF was generated. 173 ; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter 174 ; @param [esp + 08h] Param 2 - Address of the eax register 175 ; @param [esp + 0ch] Param 3 - Address of the edx register 176 ; @param [esp + 10h] Param 4 - EBX 177 ; @param [esp + 14h] Param 5 - ECX 178 ; @param [esp + 18h] Param 6 - Pointer to eflags (out) 179 ; @uses eax, ecx, edx 180 ; 181 align 16 182 BEGINPROC EMGCEmulateLockCmpXchg8b 183 push ebp 184 push ebx 185 mov ebp, [esp + 04h + 8] ; ebp = first parameter 186 mov eax, [esp + 08h + 8] ; &EAX 187 mov eax, dword [eax] 188 mov edx, [esp + 0ch + 8] ; &EDX 189 mov edx, dword [edx] 190 mov ebx, [esp + 10h + 8] ; EBX 191 mov ecx, [esp + 14h + 8] ; ECX 192 193 lock cmpxchg8b qword [ebp] ; do CMPXCHG8B 194 mov dword [esp + 08h + 8], eax 195 mov dword [esp + 0ch + 8], edx 196 197 ; collect flags and return. 198 pushf 199 pop eax 200 201 mov edx, [esp + 18h + 8] ; eflags pointer 202 mov dword [edx], eax 203 204 pop ebx 205 pop ebp 206 mov eax, VINF_SUCCESS 207 retn 208 209 ; Read error - we will be here after our page fault handler. 210 GLOBALNAME EMGCEmulateLockCmpXchg8b_Error 211 pop ebx 212 pop ebp 213 mov eax, VERR_ACCESS_DENIED 214 ret 215 216 ENDPROC EMGCEmulateLockCmpXchg8b 217 218 ;; 219 ; Emulate CMPXCHG8B instruction, CDECL calling conv. 220 ; EMGCDECL(uint32_t) EMGCEmulateCmpXchg8b(RTGCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags); 221 ; 222 ; @returns eax=0 if data written, other code - invalid access, #PF was generated. 223 ; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter 224 ; @param [esp + 08h] Param 2 - Address of the eax register 225 ; @param [esp + 0ch] Param 3 - Address of the edx register 226 ; @param [esp + 10h] Param 4 - EBX 227 ; @param [esp + 14h] Param 5 - ECX 228 ; @param [esp + 18h] Param 6 - Pointer to eflags (out) 229 ; @uses eax, ecx, edx 230 ; 231 align 16 232 BEGINPROC EMGCEmulateCmpXchg8b 233 push ebp 234 push ebx 235 mov ebp, [esp + 04h + 8] ; ebp = first parameter 236 mov eax, [esp + 08h + 8] ; &EAX 237 mov eax, dword [eax] 238 mov edx, [esp + 0ch + 8] ; &EDX 239 mov edx, dword [edx] 240 mov ebx, [esp + 10h + 8] ; EBX 241 mov ecx, [esp + 14h + 8] ; ECX 242 243 cmpxchg8b qword [ebp] ; do CMPXCHG8B 244 mov dword [esp + 08h + 8], eax 245 mov dword [esp + 0ch + 8], edx 246 247 ; collect flags and return. 248 pushf 249 pop eax 250 251 mov edx, [esp + 18h + 8] ; eflags pointer 252 mov dword [edx], eax 253 254 pop ebx 255 pop ebp 256 mov eax, VINF_SUCCESS 257 retn 258 259 ; Read error - we will be here after our page fault handler. 260 GLOBALNAME EMGCEmulateCmpXchg8b_Error 261 pop ebx 262 pop ebp 263 mov eax, VERR_ACCESS_DENIED 264 ret 265 ENDPROC EMGCEmulateCmpXchg8b 266 267 ;; 169 268 ; Emulate LOCK XADD instruction, CDECL calling conv. 170 269 ; EMGCDECL(uint32_t) EMGCEmulateLockXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags); -
trunk/src/VBox/VMM/VMMGC/MMRamGC.cpp
r7286 r8098 45 45 DECLASM(void) EMGCEmulateCmpXchg_EndProc(void); 46 46 DECLASM(void) EMGCEmulateCmpXchg_Error(void); 47 DECLASM(void) EMGCEmulateLockCmpXchg8b_EndProc(void); 48 DECLASM(void) EMGCEmulateLockCmpXchg8b_Error(void); 49 DECLASM(void) EMGCEmulateCmpXchg8b_EndProc(void); 50 DECLASM(void) EMGCEmulateCmpXchg8b_Error(void); 47 51 DECLASM(void) EMGCEmulateLockXAdd_EndProc(void); 48 52 DECLASM(void) EMGCEmulateLockXAdd_Error(void); … … 188 192 189 193 /* 194 * Page fault inside EMGCEmulateLockCmpXchg8b()? Resume at _Error. 195 */ 196 if ( (uintptr_t)&EMGCEmulateLockCmpXchg8b < (uintptr_t)pRegFrame->eip 197 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg8b_EndProc) 198 { 199 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg8b_Error; 200 return VINF_SUCCESS; 201 } 202 203 /* 204 * Page fault inside EMGCEmulateCmpXchg8b()? Resume at _Error. 205 */ 206 if ( (uintptr_t)&EMGCEmulateCmpXchg8b < (uintptr_t)pRegFrame->eip 207 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg8b_EndProc) 208 { 209 pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg8b_Error; 210 return VINF_SUCCESS; 211 } 212 213 /* 190 214 * Page fault inside EMGCEmulateLockXAdd()? Resume at _Error. 191 215 */
Note:
See TracChangeset
for help on using the changeset viewer.