- Timestamp:
- Oct 19, 2007 2:13:42 PM (17 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r5343 r5384 50 50 typedef DECLCALLBACK(uint32_t) PFN_EMULATE_PARAM2(uint32_t *pu32Param1, size_t val2); 51 51 typedef DECLCALLBACK(uint32_t) PFN_EMULATE_PARAM3(uint32_t *pu32Param1, uint32_t val2, size_t val3); 52 typedef DECLCALLBACK(int) FNEMULATELOCKPARAM2(RTGCPTR GCPtrParam1, RTGCUINTREG Val2, uint32_t *pf); 53 typedef FNEMULATELOCKPARAM2 *PFNEMULATELOCKPARAM2; 54 typedef DECLCALLBACK(int) FNEMULATELOCKPARAM3(RTGCPTR GCPtrParam1, RTGCUINTREG Val2, size_t cb, uint32_t *pf); 55 typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; 52 56 53 57 … … 345 349 } 346 350 351 #if defined(VBOX_STRICT) || defined(LOG_ENABLED) 352 /** 353 * Get the mnemonic for the disassembled instruction. 354 * 355 * GC/R0 doesn't include the strings in the DIS tables because 356 * of limited space. 357 */ 358 static const char *emGetMnemonic(PDISCPUSTATE pCpu) 359 { 360 switch (pCpu->pCurInstr->opcode) 361 { 362 case OP_XOR: return "Xor"; 363 case OP_OR: return "Or"; 364 case OP_AND: return "And"; 365 case OP_BTR: return "Btr"; 366 case OP_BTS: return "Bts"; 367 default: 368 AssertMsgFailed(("%d\n", pCpu->pCurInstr->opcode)); 369 return "???"; 370 } 371 } 372 #endif 373 347 374 /** 348 375 * XCHG instruction emulation. … … 738 765 } 739 766 767 #ifdef IN_GC 768 /** 769 * LOCK XOR/OR/AND Emulation. 770 */ 771 static int emInterpretLockOrXorAnd(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, 772 uint32_t *pcbSize, PFNEMULATELOCKPARAM3 pfnEmulate) 773 { 774 OP_PARAMVAL param1, param2; 775 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_DEST); 776 if(VBOX_FAILURE(rc)) 777 return VERR_EM_INTERPRETER; 778 779 rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, ¶m2, PARAM_SOURCE); 780 if(VBOX_FAILURE(rc)) 781 return VERR_EM_INTERPRETER; 782 783 if (pCpu->param1.size != pCpu->param2.size) 784 { 785 AssertMsgReturn(pCpu->param1.size >= pCpu->param2.size, /* should never happen! */ 786 ("%s at %VGv parameter mismatch %d vs %d!!\n", emGetMnemonic(pCpu), pRegFrame->eip, pCpu->param1.size, pCpu->param2.size), 787 VERR_EM_INTERPRETER); 788 789 /* Or %Ev, Ib -> just a hack to save some space; the data width of the 1st parameter determines the real width */ 790 pCpu->param2.size = pCpu->param1.size; 791 param2.size = param1.size; 792 } 793 794 /* The destination is always a virtual address */ 795 AssertReturn(param1.type == PARMTYPE_ADDRESS, VERR_EM_INTERPRETER); 796 RTGCPTR GCPtrPar1 = (RTGCPTR)param1.val.val32; 797 GCPtrPar1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, GCPtrPar1); 798 799 # ifdef IN_GC 800 /* Safety check (in theory it could cross a page boundary and fault there though) */ 801 Assert( TRPMHasTrap(pVM) 802 && (TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW)); 803 AssertMsgReturn(GCPtrPar1 == pvFault, ("eip=%VGv, GCPtrPar1=%VGv pvFault=%VGv\n", pRegFrame->eip, GCPtrPar1, pvFault), VERR_EM_INTERPRETER); 804 # endif 805 806 /* Register and immediate data == PARMTYPE_IMMEDIATE */ 807 AssertReturn(param2.type == PARMTYPE_IMMEDIATE, VERR_EM_INTERPRETER); 808 RTGCUINTREG ValPar2 = param2.val.val32; 809 810 /* Try emulate it with a one-shot #PF handler in place. */ 811 Log2(("%s %RGv imm%d=%RGr\n", emGetMnemonic(pCpu), GCPtrPar1, pCpu->param2.size*8, ValPar2)); 812 813 RTGCUINTREG eflags = 0; 814 MMGCRamRegisterTrapHandler(pVM); 815 rc = pfnEmulate(GCPtrPar1, ValPar2, pCpu->param2.size, &eflags); 816 MMGCRamDeregisterTrapHandler(pVM); 817 818 if (RT_FAILURE(rc)) 819 { 820 Log(("%s %RGv imm%d=%RGr -> emulation failed due to page fault!\n", emGetMnemonic(pCpu), GCPtrPar1, pCpu->param2.size*8, ValPar2)); 821 return VERR_EM_INTERPRETER; 822 } 823 824 /* Update guest's eflags and finish. */ 825 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 826 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 827 828 *pcbSize = param2.size; 829 return VINF_SUCCESS; 830 } 831 #endif 740 832 741 833 /** … … 952 1044 return VERR_EM_INTERPRETER; 953 1045 } 1046 1047 #ifdef IN_GC 1048 /** 1049 * LOCK BTR/C/S Emulation. 1050 */ 1051 static int emInterpretLockBitTest(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, 1052 uint32_t *pcbSize, PFNEMULATELOCKPARAM2 pfnEmulate) 1053 { 1054 OP_PARAMVAL param1, param2; 1055 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_DEST); 1056 if(VBOX_FAILURE(rc)) 1057 return VERR_EM_INTERPRETER; 1058 1059 rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, ¶m2, PARAM_SOURCE); 1060 if(VBOX_FAILURE(rc)) 1061 return VERR_EM_INTERPRETER; 1062 1063 /* The destination is always a virtual address */ 1064 if (param1.type != PARMTYPE_ADDRESS) 1065 return VERR_EM_INTERPRETER; 1066 1067 RTGCPTR GCPtrPar1 = (RTGCPTR)param1.val.val32; 1068 GCPtrPar1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, GCPtrPar1); 1069 1070 /* Register and immediate data == PARMTYPE_IMMEDIATE */ 1071 AssertReturn(param2.type == PARMTYPE_IMMEDIATE, VERR_EM_INTERPRETER); 1072 RTGCUINTREG ValPar2 = param2.val.val32; 1073 1074 Log2(("emInterpretLockBitTest %s: pvFault=%VGv GCPtrPar1=%RGv imm=%RGr\n", emGetMnemonic(pCpu), pvFault, GCPtrPar1, ValPar2)); 1075 1076 /* Adjust the parameters so what we're dealing with is a bit within the byte pointed to. */ 1077 GCPtrPar1 = (RTGCPTR)((RTGCUINTPTR)GCPtrPar1 + ValPar2 / 8); 1078 ValPar2 &= 7; 1079 # ifdef IN_GC 1080 Assert(TRPMHasTrap(pVM)); 1081 AssertMsgReturn((RTGCPTR)((RTGCUINTPTR)GCPtrPar1 & ~(RTGCUINTPTR)3) == pvFault, 1082 ("GCPtrPar1=%VGv pvFault=%VGv\n", GCPtrPar1, pvFault), 1083 VERR_EM_INTERPRETER); 1084 # endif 1085 1086 /* Try emulate it with a one-shot #PF handler in place. */ 1087 RTGCUINTREG eflags = 0; 1088 MMGCRamRegisterTrapHandler(pVM); 1089 rc = pfnEmulate(GCPtrPar1, ValPar2, &eflags); 1090 MMGCRamDeregisterTrapHandler(pVM); 1091 1092 if (RT_FAILURE(rc)) 1093 { 1094 Log(("emInterpretLockBitTest %s: %RGv imm%d=%RGr -> emulation failed due to page fault!\n", 1095 emGetMnemonic(pCpu), GCPtrPar1, pCpu->param2.size*8, ValPar2)); 1096 return VERR_EM_INTERPRETER; 1097 } 1098 1099 Log2(("emInterpretLockBitTest %s: GCPtrPar1=%RGv imm=%RGr CF=%d\n", emGetMnemonic(pCpu), GCPtrPar1, ValPar2, !!(eflags & X86_EFL_CF))); 1100 1101 /* Update guest's eflags and finish. */ 1102 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 1103 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 1104 1105 *pcbSize = 1; 1106 return VINF_SUCCESS; 1107 } 1108 #endif /* IN_GC */ 954 1109 955 1110 /** … … 1101 1256 uint32_t valpar, eflags; 1102 1257 #ifdef VBOX_STRICT 1103 uint32_t valpar1 ;1258 uint32_t valpar1 = 0; /// @todo used uninitialized... 1104 1259 #endif 1105 1260 … … 1766 1921 if ( (pCpu->prefix & (PREFIX_REPNE | PREFIX_REP)) 1767 1922 || ( (pCpu->prefix & PREFIX_LOCK) 1768 && (pCpu->pCurInstr->opcode != OP_CMPXCHG) 1923 && pCpu->pCurInstr->opcode != OP_CMPXCHG 1924 && pCpu->pCurInstr->opcode != OP_OR 1925 && pCpu->pCurInstr->opcode != OP_BTR 1769 1926 ) 1770 1927 ) … … 1781 1938 switch (pCpu->pCurInstr->opcode) 1782 1939 { 1783 #define INTERPRET_CASE_EX_PARAM3(opcode,Instr,InstrFn, pfnEmulate) \ 1940 #ifdef IN_GC 1941 # define INTERPRET_CASE_EX_LOCK_PARAM3(opcode, Instr, InstrFn, pfnEmulate, pfnEmulateLock) \ 1942 case opcode:\ 1943 if (pCpu->prefix & PREFIX_LOCK) \ 1944 rc = emInterpretLock##InstrFn(pVM, pCpu, pRegFrame, pvFault, pcbSize, pfnEmulateLock); \ 1945 else \ 1946 rc = emInterpret##InstrFn(pVM, pCpu, pRegFrame, pvFault, pcbSize, pfnEmulate); \ 1947 if (VBOX_SUCCESS(rc)) \ 1948 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Instr)); \ 1949 else \ 1950 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 1951 return rc 1952 #else 1953 # define INTERPRET_CASE_EX_LOCK_PARAM3(opcode, Instr, InstrFn, pfnEmulate, pfnEmulateLock) \ 1954 INTERPRET_CASE_EX_PARAM3(opcode, Instr, InstrFn, pfnEmulate) 1955 #endif 1956 #define INTERPRET_CASE_EX_PARAM3(opcode, Instr, InstrFn, pfnEmulate) \ 1784 1957 case opcode:\ 1785 1958 rc = emInterpret##InstrFn(pVM, pCpu, pRegFrame, pvFault, pcbSize, pfnEmulate); \ … … 1789 1962 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 1790 1963 return rc 1791 #define INTERPRET_CASE_EX_PARAM2(opcode,Instr,InstrFn, pfnEmulate) \ 1792 case opcode:\ 1793 rc = emInterpret##InstrFn(pVM, pCpu, pRegFrame, pvFault, pcbSize, pfnEmulate); \ 1794 if (VBOX_SUCCESS(rc)) \ 1795 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Instr)); \ 1796 else \ 1797 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 1798 return rc 1799 #define INTERPRET_CASE(opcode,Instr) \ 1964 1965 #define INTERPRET_CASE_EX_PARAM2(opcode, Instr, InstrFn, pfnEmulate) \ 1966 INTERPRET_CASE_EX_PARAM3(opcode, Instr, InstrFn, pfnEmulate) 1967 #define INTERPRET_CASE_EX_LOCK_PARAM2(opcode, Instr, InstrFn, pfnEmulate, pfnEmulateLock) \ 1968 INTERPRET_CASE_EX_LOCK_PARAM3(opcode, Instr, InstrFn, pfnEmulate, pfnEmulateLock) 1969 1970 #define INTERPRET_CASE(opcode, Instr) \ 1800 1971 case opcode:\ 1801 1972 rc = emInterpret##Instr(pVM, pCpu, pRegFrame, pvFault, pcbSize); \ … … 1805 1976 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 1806 1977 return rc 1807 #define INTERPRET_STAT_CASE(opcode, Instr) \1978 #define INTERPRET_STAT_CASE(opcode, Instr) \ 1808 1979 case opcode: STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); return VERR_EM_INTERPRETER; 1809 1980 1810 1981 INTERPRET_CASE(OP_XCHG,Xchg); 1811 INTERPRET_CASE_EX_PARAM2(OP_DEC,Dec, IncDec,EMEmulateDec);1812 INTERPRET_CASE_EX_PARAM2(OP_INC,Inc, IncDec,EMEmulateInc);1982 INTERPRET_CASE_EX_PARAM2(OP_DEC,Dec, IncDec, EMEmulateDec); 1983 INTERPRET_CASE_EX_PARAM2(OP_INC,Inc, IncDec, EMEmulateInc); 1813 1984 INTERPRET_CASE(OP_POP,Pop); 1814 INTERPRET_CASE_EX_ PARAM3(OP_OR, Or, OrXorAnd, EMEmulateOr);1985 INTERPRET_CASE_EX_LOCK_PARAM3(OP_OR, Or, OrXorAnd, EMEmulateOr, EMEmulateLockOr); 1815 1986 INTERPRET_CASE_EX_PARAM3(OP_XOR,Xor, OrXorAnd, EMEmulateXor); 1816 1987 INTERPRET_CASE_EX_PARAM3(OP_AND,And, OrXorAnd, EMEmulateAnd); … … 1827 1998 INTERPRET_CASE_EX_PARAM3(OP_SUB,Sub, AddSub, EMEmulateSub); 1828 1999 INTERPRET_CASE(OP_ADC,Adc); 1829 INTERPRET_CASE_EX_ PARAM2(OP_BTR,Btr, BitTest, EMEmulateBtr);2000 INTERPRET_CASE_EX_LOCK_PARAM2(OP_BTR,Btr, BitTest, EMEmulateBtr, EMEmulateLockBtr); 1830 2001 INTERPRET_CASE_EX_PARAM2(OP_BTS,Bts, BitTest, EMEmulateBts); 1831 2002 INTERPRET_CASE_EX_PARAM2(OP_BTC,Btc, BitTest, EMEmulateBtc); -
trunk/src/VBox/VMM/VMMAll/EMAllA.asm
r4284 r5384 235 235 236 236 ;; 237 ; Emulate LOCK OR instruction. 238 ; EMDECL(int) EMEmulateLockOr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, size_t cbSize, RTGCUINTREG *pf); 239 ; 240 ; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only). 241 ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff). 242 ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value. 243 ; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Size of the operation - 1, 2, 4 or 8 bytes. 244 ; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - Where to store the eflags on success. 245 ; only arithmetic flags are valid. 246 align 16 247 BEGINPROC EMEmulateLockOr 248 %ifdef RT_ARCH_AMD64 249 %ifdef RT_OS_WINDOWS 250 mov rax, r8 ; eax = size of parameters 251 %else ; !RT_OS_WINDOWS 252 mov rax, rdx ; rax = size of parameters 253 mov rcx, rdi ; rcx = first parameter 254 mov rdx, rsi ; rdx = second parameter 255 %endif ; !RT_OS_WINDOWS 256 %else ; !RT_ARCH_AMD64 257 mov eax, [esp + 0ch] ; eax = size of parameters 258 mov ecx, [esp + 04h] ; ecx = first parameter (MY_PTR_REG) 259 mov edx, [esp + 08h] ; edx = second parameter 260 %endif 261 262 ; switch on size 263 %ifdef RT_ARCH_AMD64 264 cmp al, 8 265 je short .do_qword ; 8 bytes variant 266 %endif 267 cmp al, 4 268 je short .do_dword ; 4 bytes variant 269 cmp al, 2 270 je short .do_word ; 2 byte variant 271 cmp al, 1 272 je short .do_byte ; 1 bytes variant 273 int3 274 275 ; workers 276 %ifdef RT_ARCH_AMD64 277 .do_qword: 278 lock or [MY_PTR_REG], rdx ; do 8 bytes OR 279 jmp short .done 280 %endif 281 282 .do_dword: 283 lock or [MY_PTR_REG], edx ; do 4 bytes OR 284 jmp short .done 285 286 .do_word: 287 lock or [MY_PTR_REG], dx ; do 2 bytes OR 288 jmp short .done 289 290 .do_byte: 291 lock or [MY_PTR_REG], dl ; do 1 byte OR 292 293 ; collect flags and return. 294 .done: 295 pushf 296 %ifdef RT_ARCH_AMD64 297 pop rax 298 %ifdef RT_OS_WINDOWS 299 mov [r9], eax 300 %else ; !RT_OS_WINDOWS 301 mov [rcx], eax 302 %endif ; !RT_OS_WINDOWS 303 %else ; !RT_ARCH_AMD64 304 mov eax, [esp + 10h + 4] 305 pop dword [eax] 306 %endif 307 mov eax, VINF_SUCCESS 308 retn 309 310 %ifdef IN_GC 311 ; #PF resume point. 312 GLOBALNAME EMEmulateLockOr_Error 313 mov eax, VERR_ACCESS_DENIED 314 ret 315 %endif 316 317 ENDPROC EMEmulateLockOr 318 319 ;; 237 320 ; Emulate XOR instruction, CDECL calling conv. 238 321 ; EMDECL(uint32_t) EMEmulateXor(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb); … … 651 734 652 735 ;; 736 ; Emulate LOCK BTR instruction. 737 ; EMDECL(int) EMEmulateLockBtr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, uint32_t *pf); 738 ; 739 ; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only). 740 ; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff). 741 ; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value. (really an 8 byte value) 742 ; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Where to store the eflags on success. 743 ; 744 align 16 745 BEGINPROC EMEmulateLockBtr 746 %ifdef RT_ARCH_AMD64 747 %ifdef RT_OS_WINDOWS 748 mov rax, r8 ; rax = third parameter 749 %else ; !RT_OS_WINDOWS 750 mov rcx, rdi ; rcx = first parameter 751 mov rax, rdx ; rax = third parameter 752 mov rdx, rsi ; rdx = second parameter 753 %endif ; !RT_OS_WINDOWS 754 %else ; !RT_ARCH_AMD64 755 mov ecx, [esp + 04h] ; ecx = first parameter 756 mov edx, [esp + 08h] ; edx = second parameter 757 mov eax, [esp + 0ch] ; eax = third parameter 758 %endif 759 760 lock btr [MY_PTR_REG], edx 761 762 ; collect flags and return. 763 pushf 764 pop xDX 765 mov [xAX], edx 766 mov eax, VINF_SUCCESS 767 retn 768 769 %ifdef IN_GC 770 ; #PF resume point. 771 GLOBALNAME EMEmulateLockBtr_Error 772 mov eax, VERR_ACCESS_DENIED 773 ret 774 %endif 775 776 ENDPROC EMEmulateLockBtr 777 778 ;; 653 779 ; Emulate BTC instruction, CDECL calling conv. 654 780 ; EMDECL(uint32_t) EMEmulateBtc(uint32_t *pu32Param1, uint32_t u32Param2); -
trunk/src/VBox/VMM/VMMGC/MMRamGC.cpp
r5342 r5384 37 37 * Internal Functions * 38 38 *******************************************************************************/ 39 static DECLCALLBACK(int) mm gcramTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame);39 static DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame); 40 40 41 41 DECLASM(void) MMGCRamReadNoTrapHandler_EndProc(void); 42 42 DECLASM(void) MMGCRamWriteNoTrapHandler_EndProc(void); 43 DECLASM(void) EMGCEmulateLockCmpXchg_EndProc(void); 44 DECLASM(void) EMGCEmulateLockCmpXchg_Error(void); 43 45 DECLASM(void) EMGCEmulateCmpXchg_EndProc(void); 44 DECLASM(void) EMGCEmulateLockCmpXchg_EndProc(void);45 46 DECLASM(void) EMGCEmulateCmpXchg_Error(void); 46 DECLASM(void) EMGCEmulateLockCmpXchg_Error(void); 47 DECLASM(void) EMEmulateLockOr_EndProc(void); 48 DECLASM(void) EMEmulateLockOr_Error(void); 49 DECLASM(void) EMEmulateLockBtr_EndProc(void); 50 DECLASM(void) EMEmulateLockBtr_Error(void); 47 51 DECLASM(void) MMGCRamRead_Error(void); 48 52 DECLASM(void) MMGCRamWrite_Error(void); … … 59 63 MMGCDECL(void) MMGCRamRegisterTrapHandler(PVM pVM) 60 64 { 61 TRPMGCSetTempHandler(pVM, 0xe, mm gcramTrap0eHandler);65 TRPMGCSetTempHandler(pVM, 0xe, mmGCRamTrap0eHandler); 62 66 } 63 67 … … 133 137 * @internal 134 138 */ 135 DECLCALLBACK(int) mm gcramTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame)136 { 137 /* 138 * Check where the trap was occurred.139 DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame) 140 { 141 /* 142 * Page fault inside MMGCRamRead()? Resume at *_Error. 139 143 */ 140 144 if ( (uintptr_t)&MMGCRamReadNoTrapHandler < (uintptr_t)pRegFrame->eip 141 145 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamReadNoTrapHandler_EndProc) 142 146 { 143 /* 144 * Page fault inside MMGCRamRead() func. 145 */ 146 RTGCUINT uErrorCode = TRPMGetErrorCode(pVM); 147 148 /* Must be read violation. */ 149 if (uErrorCode & X86_TRAP_PF_RW) 150 return VERR_INTERNAL_ERROR; 151 152 /* Return execution to func at error label. */ 147 /* Must be a read violation. */ 148 AssertReturn(!(TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW), VERR_INTERNAL_ERROR); 153 149 pRegFrame->eip = (uintptr_t)&MMGCRamRead_Error; 154 150 return VINF_SUCCESS; 155 151 } 156 else if ( (uintptr_t)&MMGCRamWriteNoTrapHandler < (uintptr_t)pRegFrame->eip 157 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamWriteNoTrapHandler_EndProc) 158 { 159 /* 160 * Page fault inside MMGCRamWrite() func. 161 */ 162 RTGCUINT uErrorCode = TRPMGetErrorCode(pVM); 163 164 /* Must be write violation. */ 165 if (!(uErrorCode & X86_TRAP_PF_RW)) 166 return VERR_INTERNAL_ERROR; 167 168 /* Return execution to func at error label. */ 152 153 /* 154 * Page fault inside MMGCRamWrite()? Resume at _Error. 155 */ 156 if ( (uintptr_t)&MMGCRamWriteNoTrapHandler < (uintptr_t)pRegFrame->eip 157 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamWriteNoTrapHandler_EndProc) 158 { 159 /* Must be a write violation. */ 160 AssertReturn(TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW, VERR_INTERNAL_ERROR); 169 161 pRegFrame->eip = (uintptr_t)&MMGCRamWrite_Error; 170 162 return VINF_SUCCESS; 171 163 } 172 else if ( (uintptr_t)&EMGCEmulateLockCmpXchg < (uintptr_t)pRegFrame->eip 173 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg_EndProc) 174 { 175 /* 176 * Page fault inside EMGCEmulateLockCmpXchg() func. 177 */ 178 179 /* Return execution to func at error label. */ 164 165 /* 166 * Page fault inside EMGCEmulateLockCmpXchg()? Resume at _Error. 167 */ 168 if ( (uintptr_t)&EMGCEmulateLockCmpXchg < (uintptr_t)pRegFrame->eip 169 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg_EndProc) 170 { 180 171 pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg_Error; 181 172 return VINF_SUCCESS; 182 173 } 183 else if ( (uintptr_t)&EMGCEmulateCmpXchg < (uintptr_t)pRegFrame->eip 184 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg_EndProc) 185 { 186 /* 187 * Page fault inside EMGCEmulateCmpXchg() func. 188 */ 189 190 /* Return execution to func at error label. */ 174 175 /* 176 * Page fault inside EMGCEmulateCmpXchg()? Resume at _Error. 177 */ 178 if ( (uintptr_t)&EMGCEmulateCmpXchg < (uintptr_t)pRegFrame->eip 179 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg_EndProc) 180 { 191 181 pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg_Error; 192 182 return VINF_SUCCESS; 193 183 } 194 184 195 /* #PF is not handled - kill the Hypervisor. */ 185 /* 186 * Page fault inside EMEmulateLockOr()? Resume at *_Error. 187 */ 188 if ( (uintptr_t)&EMEmulateLockOr < (uintptr_t)pRegFrame->eip 189 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockOr_EndProc) 190 { 191 pRegFrame->eip = (uintptr_t)&EMEmulateLockOr_Error; 192 return VINF_SUCCESS; 193 } 194 195 /* 196 * Page fault inside EMEmulateLockBtr()? Resume at *_Error. 197 */ 198 if ( (uintptr_t)&EMEmulateLockBtr < (uintptr_t)pRegFrame->eip 199 && (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockBtr_EndProc) 200 { 201 pRegFrame->eip = (uintptr_t)&EMEmulateLockBtr_Error; 202 return VINF_SUCCESS; 203 } 204 205 /* 206 * #PF is not handled - cause guru meditation. 207 */ 196 208 return VERR_INTERNAL_ERROR; 197 209 }
Note:
See TracChangeset
for help on using the changeset viewer.