Changeset 7286 in vbox for trunk/src/VBox
- Timestamp:
- Mar 5, 2008 8:06:41 AM (17 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/EM.cpp
r6796 r7286 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->StatGCXAdd, STAMTYPE_COUNTER, "/EM/GC/Interpret/Success/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was successfully interpreted."); 204 STAM_REG_USED(pVM, &pStats->StatHCXAdd, STAMTYPE_COUNTER, "/EM/HC/Interpret/Success/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was successfully interpreted."); 203 205 204 206 STAM_REG(pVM, &pStats->StatGCInterpretFailed, STAMTYPE_COUNTER, "/EM/GC/Interpret/Failed", STAMUNIT_OCCURENCES, "The number of times an instruction was not interpreted."); … … 260 262 STAM_REG_USED(pVM, &pStats->StatGCFailedCmpXchg, STAMTYPE_COUNTER, "/EM/GC/Interpret/Failed/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was not interpreted."); 261 263 STAM_REG_USED(pVM, &pStats->StatHCFailedCmpXchg, STAMTYPE_COUNTER, "/EM/HC/Interpret/Failed/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was not interpreted."); 264 STAM_REG_USED(pVM, &pStats->StatGCFailedXAdd, STAMTYPE_COUNTER, "/EM/GC/Interpret/Failed/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was not interpreted."); 265 STAM_REG_USED(pVM, &pStats->StatHCFailedXAdd, STAMTYPE_COUNTER, "/EM/HC/Interpret/Failed/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was not interpreted."); 262 266 STAM_REG_USED(pVM, &pStats->StatGCFailedMovNTPS, STAMTYPE_COUNTER, "/EM/GC/Interpret/Failed/MovNTPS", STAMUNIT_OCCURENCES, "The number of times MOVNTPS was not interpreted."); 263 267 STAM_REG_USED(pVM, &pStats->StatHCFailedMovNTPS, STAMTYPE_COUNTER, "/EM/HC/Interpret/Failed/MovNTPS", STAMUNIT_OCCURENCES, "The number of times MOVNTPS was not interpreted."); -
trunk/src/VBox/VMM/EMInternal.h
r5999 r7286 131 131 STAMCOUNTER StatGCCmpXchg; 132 132 STAMCOUNTER StatHCCmpXchg; 133 STAMCOUNTER StatGCXAdd; 134 STAMCOUNTER StatHCXAdd; 133 135 STAMCOUNTER StatGCClts; 134 136 STAMCOUNTER StatHCClts; … … 190 192 STAMCOUNTER StatGCFailedCmpXchg; 191 193 STAMCOUNTER StatHCFailedCmpXchg; 194 STAMCOUNTER StatGCFailedXAdd; 195 STAMCOUNTER StatHCFailedXAdd; 192 196 STAMCOUNTER StatHCFailedMovNTPS; 193 197 STAMCOUNTER StatGCFailedMovNTPS; -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r6297 r7286 1237 1237 } 1238 1238 1239 /* 1240 * [LOCK] CMPXCHG emulation. 1241 */ 1239 1242 #ifdef IN_GC 1240 1243 static int emInterpretCmpXchg(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) … … 1308 1311 1309 1312 *pcbSize = param2.size; 1313 return VINF_SUCCESS; 1314 } 1315 } 1316 return VERR_EM_INTERPRETER; 1317 } 1318 #endif 1319 1320 /* 1321 * [LOCK] XADD emulation. 1322 */ 1323 #ifdef IN_GC 1324 static int emInterpretXAdd(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 1325 { 1326 OP_PARAMVAL param1; 1327 uint32_t *pParamReg2; 1328 size_t cbSizeParamReg2; 1329 1330 /* Source to make DISQueryParamVal read the register value - ugly hack */ 1331 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_SOURCE); 1332 if(VBOX_FAILURE(rc)) 1333 return VERR_EM_INTERPRETER; 1334 1335 rc = DISQueryParamRegPtr(pRegFrame, pCpu, &pCpu->param2, &pParamReg2, &cbSizeParamReg2); 1336 if(VBOX_FAILURE(rc)) 1337 return VERR_EM_INTERPRETER; 1338 1339 if (TRPMHasTrap(pVM)) 1340 { 1341 if (TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW) 1342 { 1343 RTGCPTR pParam1; 1344 uint32_t eflags; 1345 #ifdef VBOX_STRICT 1346 uint32_t valpar1 = 0; /// @todo used uninitialized... 1347 #endif 1348 1349 AssertReturn(pCpu->param1.size == pCpu->param2.size, VERR_EM_INTERPRETER); 1350 switch(param1.type) 1351 { 1352 case PARMTYPE_ADDRESS: 1353 pParam1 = (RTGCPTR)param1.val.val32; 1354 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 1355 1356 /* Safety check (in theory it could cross a page boundary and fault there though) */ 1357 AssertMsgReturn(pParam1 == pvFault, ("eip=%VGv pParam1=%VGv pvFault=%VGv\n", pRegFrame->eip, pParam1, pvFault), VERR_EM_INTERPRETER); 1358 break; 1359 1360 default: 1361 return VERR_EM_INTERPRETER; 1362 } 1363 1364 LogFlow(("XAdd %VGv=%08x reg=%08x\n", pParam1, *pParamReg2)); 1365 1366 MMGCRamRegisterTrapHandler(pVM); 1367 if (pCpu->prefix & PREFIX_LOCK) 1368 rc = EMGCEmulateLockXAdd(pParam1, pParamReg2, cbSizeParamReg2, &eflags); 1369 else 1370 rc = EMGCEmulateXAdd(pParam1, pParamReg2, cbSizeParamReg2, &eflags); 1371 MMGCRamDeregisterTrapHandler(pVM); 1372 1373 if (VBOX_FAILURE(rc)) 1374 { 1375 Log(("XAdd %VGv=%08x reg=%08x -> emulation failed due to page fault!\n", pParam1, valpar1, pRegFrame->eax)); 1376 return VERR_EM_INTERPRETER; 1377 } 1378 1379 LogFlow(("XAdd %VGv=%08x reg=%08x ZF=%d\n", pParam1, valpar1, pRegFrame->eax, !!(eflags & X86_EFL_ZF))); 1380 1381 /* Update guest's eflags and finish. */ 1382 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 1383 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 1384 1385 *pcbSize = cbSizeParamReg2; 1310 1386 return VINF_SUCCESS; 1311 1387 } … … 1910 1986 || ( (pCpu->prefix & PREFIX_LOCK) 1911 1987 && pCpu->pCurInstr->opcode != OP_CMPXCHG 1988 && pCpu->pCurInstr->opcode != OP_XADD 1912 1989 && pCpu->pCurInstr->opcode != OP_OR 1913 1990 && pCpu->pCurInstr->opcode != OP_BTR … … 1993 2070 INTERPRET_CASE(OP_STI,Sti); 1994 2071 INTERPRET_CASE(OP_CMPXCHG, CmpXchg); 2072 INTERPRET_CASE(OP_XADD, XAdd); 1995 2073 #endif 1996 2074 INTERPRET_CASE(OP_HLT,Hlt); … … 1999 2077 #ifndef IN_GC 2000 2078 INTERPRET_STAT_CASE(OP_CMPXCHG,CmpXchg); 2079 INTERPRET_STAT_CASE(OP_XADD, XAdd); 2001 2080 #endif 2002 2081 INTERPRET_STAT_CASE(OP_MOVNTPS,MovNTPS); -
trunk/src/VBox/VMM/VMMGC/EMGCA.asm
-
Property svn:eol-style
set to
native
r5999 r7286 26 26 27 27 ;; 28 ; Emulate lockCMPXCHG instruction, CDECL calling conv.28 ; Emulate LOCK CMPXCHG instruction, CDECL calling conv. 29 29 ; EMGCDECL(uint32_t) EMGCEmulateLockCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags); 30 30 ; … … 165 165 ret 166 166 ENDPROC EMGCEmulateCmpXchg 167 168 ;; 169 ; Emulate LOCK XADD instruction, CDECL calling conv. 170 ; EMGCDECL(uint32_t) EMGCEmulateLockXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags); 171 ; 172 ; @returns eax=0 if data exchanged, 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 - Second parameter - pointer to second parameter (general register) 175 ; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid. 176 ; @param [esp + 10h] Param 4 - Pointer to eflags (out) 177 ; @uses eax, ecx, edx 178 ; 179 align 16 180 BEGINPROC EMGCEmulateLockXAdd 181 push ebx 182 mov ecx, [esp + 04h + 4] ; ecx = first parameter 183 mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter 184 mov eax, [esp + 0ch + 4] ; eax = size of parameters 185 186 cmp al, 4 187 je short .do_dword ; 4 bytes variant 188 cmp al, 2 189 je short .do_word ; 2 byte variant 190 cmp al, 1 191 je short .do_byte ; 1 bytes variant 192 int3 193 194 .do_dword: 195 ; load 2nd parameter's value 196 mov eax, dword [ebx] 197 lock xadd dword [ecx], eax ; do 4 bytes XADD 198 mov dword [ebx], eax 199 jmp short .done 200 201 .do_word: 202 ; load 2nd parameter's value 203 mov eax, dword [ebx] 204 lock xadd word [ecx], ax ; do 2 bytes XADD 205 mov word [ebx], ax 206 jmp short .done 207 208 .do_byte: 209 ; load 2nd parameter's value 210 mov eax, dword [ebx] 211 lock xadd byte [ecx], al ; do 1 bytes XADD 212 mov byte [ebx], al 213 214 .done: 215 ; collect flags and return. 216 pushf 217 pop eax 218 219 mov edx, [esp + 10h + 4] ; eflags pointer 220 mov dword [edx], eax 221 222 pop ebx 223 mov eax, VINF_SUCCESS 224 retn 225 226 ; Read error - we will be here after our page fault handler. 227 GLOBALNAME EMGCEmulateLockXAdd_Error 228 pop ebx 229 mov eax, VERR_ACCESS_DENIED 230 ret 231 232 ENDPROC EMGCEmulateLockXAdd 233 234 ;; 235 ; Emulate XADD instruction, CDECL calling conv. 236 ; EMGCDECL(uint32_t) EMGCEmulateXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags); 237 ; 238 ; @returns eax=0 if data written, other code - invalid access, #PF was generated. 239 ; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter 240 ; @param [esp + 08h] Param 2 - Second parameter - pointer to second parameter (general register) 241 ; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid. 242 ; @param [esp + 10h] Param 4 - Pointer to eflags (out) 243 ; @uses eax, ecx, edx 244 ; 245 align 16 246 BEGINPROC EMGCEmulateXAdd 247 push ebx 248 mov ecx, [esp + 04h + 4] ; ecx = first parameter 249 mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax) 250 mov eax, [esp + 0ch + 4] ; eax = size of parameters 251 252 cmp al, 4 253 je short .do_dword ; 4 bytes variant 254 cmp al, 2 255 je short .do_word ; 2 byte variant 256 cmp al, 1 257 je short .do_byte ; 1 bytes variant 258 int3 259 260 .do_dword: 261 ; load 2nd parameter's value 262 mov eax, dword [ebx] 263 xadd dword [ecx], eax ; do 4 bytes XADD 264 mov dword [ebx], eax 265 jmp short .done 266 267 .do_word: 268 ; load 2nd parameter's value 269 mov eax, dword [ebx] 270 xadd word [ecx], ax ; do 2 bytes XADD 271 mov word [ebx], ax 272 jmp short .done 273 274 .do_byte: 275 ; load 2nd parameter's value 276 mov eax, dword [ebx] 277 xadd byte [ecx], al ; do 1 bytes XADD 278 mov byte [ebx], al 279 280 .done: 281 ; collect flags and return. 282 pushf 283 pop eax 284 285 mov edx, [esp + 10h + 4] ; eflags pointer 286 mov dword [edx], eax 287 288 pop ebx 289 mov eax, VINF_SUCCESS 290 retn 291 292 ; Read error - we will be here after our page fault handler. 293 GLOBALNAME EMGCEmulateXAdd_Error 294 pop ebx 295 mov eax, VERR_ACCESS_DENIED 296 ret 297 ENDPROC EMGCEmulateXAdd -
Property svn:eol-style
set to
-
trunk/src/VBox/VMM/VMMGC/MMRamGC.cpp
r5999 r7286 45 45 DECLASM(void) EMGCEmulateCmpXchg_EndProc(void); 46 46 DECLASM(void) EMGCEmulateCmpXchg_Error(void); 47 DECLASM(void) EMGCEmulateLockXAdd_EndProc(void); 48 DECLASM(void) EMGCEmulateLockXAdd_Error(void); 49 DECLASM(void) EMGCEmulateXAdd_EndProc(void); 50 DECLASM(void) EMGCEmulateXAdd_Error(void); 47 51 DECLASM(void) EMEmulateLockOr_EndProc(void); 48 52 DECLASM(void) EMEmulateLockOr_Error(void); … … 184 188 185 189 /* 190 * Page fault inside EMGCEmulateLockXAdd()? Resume at _Error. 191 */ 192 if ( (uintptr_t)&EMGCEmulateLockXAdd < (uintptr_t)pRegFrame->eip 193 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockXAdd_EndProc) 194 { 195 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockXAdd_Error; 196 return VINF_SUCCESS; 197 } 198 199 /* 200 * Page fault inside EMGCEmulateXAdd()? Resume at _Error. 201 */ 202 if ( (uintptr_t)&EMGCEmulateXAdd < (uintptr_t)pRegFrame->eip 203 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateXAdd_EndProc) 204 { 205 pRegFrame->eip = (uintptr_t)&EMGCEmulateXAdd_Error; 206 return VINF_SUCCESS; 207 } 208 209 /* 186 210 * Page fault inside EMEmulateLockOr()? Resume at *_Error. 187 211 */
Note:
See TracChangeset
for help on using the changeset viewer.