Changeset 302 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jan 25, 2007 2:48:55 PM (18 years ago)
- Location:
- trunk/src/VBox/VMM/PATM
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PATM/PATM.cpp
r208 r302 427 427 pVM->patm.s.pfnHelperCallGC += delta; 428 428 pVM->patm.s.pfnHelperRetGC += delta; 429 pVM->patm.s.pfnHelperIretGC += delta; 429 430 pVM->patm.s.pfnHelperJumpGC += delta; 430 431 -
trunk/src/VBox/VMM/PATM/PATMA.asm
r277 r302 1094 1094 1095 1095 test dword [esp+12], X86_EFL_IF 1096 jz iret_ fault1096 jz iret_clearIF 1097 1097 1098 1098 ; if interrupts are pending, then we must go back to the host context to handle them! … … 1151 1151 mov dword [ss:PATM_INTERRUPTFLAG], 1 1152 1152 PATM_INT3 1153 1154 iret_clearIF: 1155 push dword [esp+4] ; eip to return to 1156 pushfd 1157 push eax 1158 push PATM_FIXUP 1159 DB 0E8h ; call 1160 DD PATM_IRET_FUNCTION 1161 add esp, 4 ; pushed address of jump table 1162 1163 cmp eax, 0 1164 je near iret_fault3 1165 1166 mov dword [esp+12+4], eax ; stored eip in iret frame 1167 pop eax 1168 popfd 1169 add esp, 4 ; pushed eip 1170 1171 ; always ring 0 return -> change to ring 1 (CS in iret frame) 1172 or dword [esp+8], 1 1173 1174 ; This section must *always* be executed (!!) 1175 ; Extract the IOPL from the return flags, save them to our virtual flags and 1176 ; put them back to zero 1177 push eax 1178 mov eax, dword [esp+16] 1179 and eax, X86_EFL_IOPL 1180 and dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL 1181 or dword [ss:PATM_VMFLAGS], eax 1182 pop eax 1183 and dword [esp+12], ~X86_EFL_IOPL 1184 1185 ; Clear IF 1186 and dword [ss:PATM_VMFLAGS], ~X86_EFL_IF 1187 popfd 1188 1189 ; the patched destination code will set PATM_INTERRUPTFLAG after the return! 1190 iretd 1191 1192 iret_fault3: 1193 pop eax 1194 popfd 1195 add esp, 4 ; pushed eip 1196 jmp iret_fault 1197 1198 align 4 1199 PATMIretTable: 1200 DW PATM_MAX_JUMPTABLE_ENTRIES ; nrSlots 1201 DW 0 ; ulInsertPos 1202 DD 0 ; cAddresses 1203 RESB PATCHJUMPTABLE_SIZE ; lookup slots 1204 1153 1205 PATMIretEnd: 1154 1206 ENDPROC PATMIretReplacement … … 1162 1214 DD PATMIretEnd- PATMIretStart 1163 1215 %ifdef PATM_LOG_IF_CHANGES 1164 DD 171216 DD 22 1165 1217 %else 1166 DD 161218 DD 21 1167 1219 %endif 1168 1220 DD PATM_INTERRUPTFLAG … … 1201 1253 DD 0 1202 1254 DD PATM_INTERRUPTFLAG 1255 DD 0 1256 DD PATM_FIXUP 1257 DD PATMIretTable - PATMIretStart 1258 DD PATM_IRET_FUNCTION 1259 DD 0 1260 DD PATM_VMFLAGS 1261 DD 0 1262 DD PATM_VMFLAGS 1263 DD 0 1264 DD PATM_VMFLAGS 1265 DD 0 1266 DD 0ffffffffh 1267 1268 1269 ; 1270 ; global function for implementing 'iret' to code with IF cleared 1271 ; 1272 ; Caller is responsible for right stack layout 1273 ; + 16 original return address 1274 ; + 12 eflags 1275 ; + 8 eax 1276 ; + 4 Jump table address 1277 ;( + 0 return address ) 1278 ; 1279 ; @note assumes PATM_INTERRUPTFLAG is zero 1280 ; @note assumes it can trash eax and eflags 1281 ; 1282 ; @returns eax=0 on failure 1283 ; otherwise return address in eax 1284 ; 1285 ; @note NEVER change this without bumping the SSM version 1286 align 16 1287 BEGINPROC PATMIretFunction 1288 PATMIretFunction_Start: 1289 push ecx 1290 push edx 1291 push edi 1292 1293 ; Event order: 1294 ; 1) Check if the return patch address can be found in the lookup table 1295 ; 2) Query return patch address from the hypervisor 1296 1297 ; 1) Check if the return patch address can be found in the lookup table 1298 mov edx, dword [esp+12+16] ; pushed target address 1299 1300 xor eax, eax ; default result -> nothing found 1301 mov edi, dword [esp+12+4] ; jump table 1302 mov ecx, [ss:edi + PATCHJUMPTABLE.cAddresses] 1303 cmp ecx, 0 1304 je near PATMIretFunction_AskHypervisor 1305 1306 PATMIretFunction_SearchStart: 1307 cmp [ss:edi + PATCHJUMPTABLE.Slot_pInstrGC + eax*8], edx ; edx = GC address to search for 1308 je near PATMIretFunction_SearchHit 1309 inc eax 1310 cmp eax, ecx 1311 jl near PATMIretFunction_SearchStart 1312 1313 PATMIretFunction_AskHypervisor: 1314 ; 2) Query return patch address from the hypervisor 1315 ; @todo private ugly interface, since we have nothing generic at the moment 1316 lock or dword [ss:PATM_PENDINGACTION], PATM_ACTION_LOOKUP_ADDRESS 1317 mov eax, PATM_ACTION_LOOKUP_ADDRESS 1318 mov ecx, PATM_ACTION_MAGIC 1319 mov edi, dword [esp+12+4] ; jump table address 1320 mov edx, dword [esp+12+16] ; original return address 1321 db 0fh, 0bh ; illegal instr (hardcoded assumption in PATMHandleIllegalInstrTrap) 1322 jmp near PATMIretFunction_SearchEnd 1323 1324 PATMIretFunction_SearchHit: 1325 mov eax, [ss:edi + PATCHJUMPTABLE.Slot_pRelPatchGC + eax*8] ; found a match! 1326 ;@note can be zero, so the next check is required!! 1327 1328 PATMIretFunction_SearchEnd: 1329 cmp eax, 0 1330 jz PATMIretFunction_Failure 1331 1332 add eax, PATM_PATCHBASE 1333 1334 pop edi 1335 pop edx 1336 pop ecx 1337 ret 1338 1339 PATMIretFunction_Failure: 1340 ;signal error 1341 xor eax, eax 1342 pop edi 1343 pop edx 1344 pop ecx 1345 ret 1346 1347 PATMIretFunction_End: 1348 ENDPROC PATMIretFunction 1349 1350 GLOBALNAME PATMIretFunctionRecord 1351 RTCCPTR_DEF PATMIretFunction_Start 1352 DD 0 1353 DD 0 1354 DD 0 1355 DD PATMIretFunction_End - PATMIretFunction_Start 1356 DD 2 1357 DD PATM_PENDINGACTION 1358 DD 0 1359 DD PATM_PATCHBASE 1203 1360 DD 0 1204 1361 DD 0ffffffffh -
trunk/src/VBox/VMM/PATM/PATMA.h
r267 r302 65 65 #define PATM_RETURN_FUNCTION 0xF1ABCE08 /** Relative address of global PATM return function. */ 66 66 #define PATM_LOOKUP_AND_JUMP_FUNCTION 0xF1ABCE09 /** Relative address of global PATM lookup and jump function. */ 67 #define PATM_IRET_FUNCTION 0xF1ABCE0A /** Relative address of global PATM iret function. */ 67 68 68 69 // everything except IOPL, NT, IF, VM, VIF, VIP and RF … … 167 168 extern PATCHASMRECORD PATMRetFunctionRecord; 168 169 extern PATCHASMRECORD PATMLookupAndJumpRecord; 170 extern PATCHASMRECORD PATMIretFunctionRecord; 169 171 170 172 extern PATCHASMRECORD PATMStatsRecord; -
trunk/src/VBox/VMM/PATM/PATMA.mac
r267 r302 64 64 %define PATM_RETURN_FUNCTION 0xF1ABCE08 ; /** Relative address of global PATM return function. */ 65 65 %define PATM_LOOKUP_AND_JUMP_FUNCTION 0xF1ABCE09 ; /** Relative address of global PATM lookup and jump function. */ 66 %define PATM_IRET_FUNCTION 0xF1ABCE0A ; /** Relative address of global PATM iret function. */ 66 67 67 68 -
trunk/src/VBox/VMM/PATM/PATMInternal.h
r266 r302 37 37 38 38 39 #define PATM_SSM_VERSION 4939 #define PATM_SSM_VERSION 50 40 40 41 41 /* Enable for call patching. */ … … 402 402 /** Global PATM jump function (used by indirect jmp patches). */ 403 403 RTGCPTR pfnHelperJumpGC; 404 /** Global PATM return function (used by iret patches). */ 405 RTGCPTR pfnHelperIretGC; 404 406 405 407 /** Fake patch record for global functions. */ -
trunk/src/VBox/VMM/PATM/PATMPatch.cpp
r23 r302 124 124 125 125 #define PATCHGEN_EPILOG(pPatch, size) \ 126 Assert(size <= 400); \126 Assert(size <= 512); \ 127 127 pPatch->uCurPatchOffset += size; 128 128 … … 309 309 /* Relative value is target minus address of instruction after the actual call instruction. */ 310 310 dest = pVM->patm.s.pfnHelperRetGC - pInstrAfterCall; 311 break; 312 } 313 314 case PATM_IRET_FUNCTION: 315 { 316 RTGCPTR pInstrAfterCall = pVM->patm.s.pPatchMemGC + (RTGCUINTPTR)(&pPB[j] + sizeof(RTGCPTR) - pVM->patm.s.pPatchMemHC); 317 Assert(pVM->patm.s.pfnHelperIretGC); 318 Assert(sizeof(uint32_t) == sizeof(RTGCPTR)); 319 320 /* Relative value is target minus address of instruction after the actual call instruction. */ 321 dest = pVM->patm.s.pfnHelperIretGC - pInstrAfterCall; 311 322 break; 312 323 } … … 895 906 PATCHGEN_EPILOG(pPatch, size); 896 907 908 /* Round to next 8 byte boundary. */ 909 pPatch->uCurPatchOffset = RT_ALIGN_32(pPatch->uCurPatchOffset, 8); 910 911 pVM->patm.s.pfnHelperIretGC = PATCHCODE_PTR_GC(pPatch) + pPatch->uCurPatchOffset; 912 PATCHGEN_PROLOG_NODEF(pVM, pPatch); 913 size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretFunctionRecord, 0, false); 914 PATCHGEN_EPILOG(pPatch, size); 915 897 916 Log(("pfnHelperCallGC %VGv\n", pVM->patm.s.pfnHelperCallGC)); 898 917 Log(("pfnHelperRetGC %VGv\n", pVM->patm.s.pfnHelperRetGC)); 899 918 Log(("pfnHelperJumpGC %VGv\n", pVM->patm.s.pfnHelperJumpGC)); 919 Log(("pfnHelperIretGC %VGv\n", pVM->patm.s.pfnHelperIretGC)); 900 920 901 921 return VINF_SUCCESS; -
trunk/src/VBox/VMM/PATM/PATMSSM.cpp
r101 r302 302 302 } 303 303 304 /* Relative calls are made to the helper functions. Therefor their location must not change! */ 305 if ( pVM->patm.s.pfnHelperCallGC != patmInfo.pfnHelperCallGC 306 || pVM->patm.s.pfnHelperRetGC != patmInfo.pfnHelperRetGC 307 || pVM->patm.s.pfnHelperJumpGC != patmInfo.pfnHelperJumpGC 308 || pVM->patm.s.pfnHelperIretGC != patmInfo.pfnHelperIretGC) 309 { 310 AssertMsgFailed(("Helper function ptrs don't match!!!\n")); 311 return VERR_SSM_INVALID_STATE; 312 } 313 304 314 if ( pVM->patm.s.pPatchMemGC != patmInfo.pPatchMemGC 305 315 || pVM->patm.s.cbPatchMem != patmInfo.cbPatchMem)
Note:
See TracChangeset
for help on using the changeset viewer.