VirtualBox

Changeset 5384

Show
Ignore:
Timestamp:
10/19/07 16:13:42 (1 year ago)
Author:
vboxsync
Message:

LOCK BTR and LOCK OR (for Solaris guests).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/em.h

    r5342 r5384  
    307307EMDECL(uint32_t) EMEmulateDec(uint32_t *pu32Param1, size_t cb); 
    308308EMDECL(uint32_t) EMEmulateOr(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb); 
     309EMDECL(int)      EMEmulateLockOr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, size_t cbSize, uint32_t *pf); 
    309310EMDECL(uint32_t) EMEmulateXor(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb); 
    310311EMDECL(uint32_t) EMEmulateAdd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb); 
     
    312313EMDECL(uint32_t) EMEmulateAdcWithCarrySet(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb); 
    313314EMDECL(uint32_t) EMEmulateBtr(uint32_t *pu32Param1, uint32_t u32Param2); 
     315EMDECL(int)      EMEmulateLockBtr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, uint32_t *pf); 
    314316EMDECL(uint32_t) EMEmulateBts(uint32_t *pu32Param1, uint32_t u32Param2); 
    315317EMDECL(uint32_t) EMEmulateBtc(uint32_t *pu32Param1, uint32_t u32Param2); 
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r5343 r5384  
    5050typedef DECLCALLBACK(uint32_t) PFN_EMULATE_PARAM2(uint32_t *pu32Param1, size_t val2); 
    5151typedef DECLCALLBACK(uint32_t) PFN_EMULATE_PARAM3(uint32_t *pu32Param1, uint32_t val2, size_t val3); 
     52typedef DECLCALLBACK(int)      FNEMULATELOCKPARAM2(RTGCPTR GCPtrParam1, RTGCUINTREG Val2, uint32_t *pf); 
     53typedef FNEMULATELOCKPARAM2 *PFNEMULATELOCKPARAM2; 
     54typedef DECLCALLBACK(int)      FNEMULATELOCKPARAM3(RTGCPTR GCPtrParam1, RTGCUINTREG Val2, size_t cb, uint32_t *pf); 
     55typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; 
    5256 
    5357 
     
    345349} 
    346350 
     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 */  
     358static 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 
    347374/** 
    348375 * XCHG instruction emulation. 
     
    738765} 
    739766 
     767#ifdef IN_GC 
     768/** 
     769 * LOCK XOR/OR/AND Emulation. 
     770 */ 
     771static 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, &param1, PARAM_DEST); 
     776    if(VBOX_FAILURE(rc)) 
     777        return VERR_EM_INTERPRETER; 
     778 
     779    rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, &param2, 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 
    740832 
    741833/** 
     
    9521044    return VERR_EM_INTERPRETER; 
    9531045} 
     1046 
     1047#ifdef IN_GC 
     1048/** 
     1049 * LOCK BTR/C/S Emulation. 
     1050 */ 
     1051static 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, &param1, PARAM_DEST); 
     1056    if(VBOX_FAILURE(rc)) 
     1057        return VERR_EM_INTERPRETER; 
     1058 
     1059    rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, &param2, 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 */ 
    9541109 
    9551110/** 
     
    11011256            uint32_t valpar, eflags; 
    11021257#ifdef VBOX_STRICT 
    1103             uint32_t valpar1; 
     1258            uint32_t valpar1 = 0; /// @todo used uninitialized... 
    11041259#endif 
    11051260 
     
    17661921    if (    (pCpu->prefix & (PREFIX_REPNE | PREFIX_REP)) 
    17671922        ||  (   (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 
    17691926            ) 
    17701927       ) 
     
    17811938    switch (pCpu->pCurInstr->opcode) 
    17821939    { 
    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) \ 
    17841957        case opcode:\ 
    17851958            rc = emInterpret##InstrFn(pVM, pCpu, pRegFrame, pvFault, pcbSize, pfnEmulate); \ 
     
    17891962                STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 
    17901963            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) \ 
    18001971        case opcode:\ 
    18011972            rc = emInterpret##Instr(pVM, pCpu, pRegFrame, pvFault, pcbSize); \ 
     
    18051976                STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 
    18061977            return rc 
    1807 #define INTERPRET_STAT_CASE(opcode,Instr) \ 
     1978#define INTERPRET_STAT_CASE(opcode, Instr) \ 
    18081979        case opcode: STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); return VERR_EM_INTERPRETER; 
    18091980 
    18101981        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); 
    18131984        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); 
    18151986        INTERPRET_CASE_EX_PARAM3(OP_XOR,Xor, OrXorAnd, EMEmulateXor); 
    18161987        INTERPRET_CASE_EX_PARAM3(OP_AND,And, OrXorAnd, EMEmulateAnd); 
     
    18271998        INTERPRET_CASE_EX_PARAM3(OP_SUB,Sub, AddSub, EMEmulateSub); 
    18281999        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); 
    18302001        INTERPRET_CASE_EX_PARAM2(OP_BTS,Bts, BitTest, EMEmulateBts); 
    18312002        INTERPRET_CASE_EX_PARAM2(OP_BTC,Btc, BitTest, EMEmulateBtc); 
  • trunk/src/VBox/VMM/VMMAll/EMAllA.asm

    r4284 r5384  
    235235 
    236236;; 
     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. 
     246align 16 
     247BEGINPROC   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.  
     312GLOBALNAME EMEmulateLockOr_Error 
     313    mov     eax, VERR_ACCESS_DENIED 
     314    ret 
     315%endif 
     316 
     317ENDPROC     EMEmulateLockOr 
     318 
     319;; 
    237320; Emulate XOR instruction, CDECL calling conv. 
    238321; EMDECL(uint32_t) EMEmulateXor(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb); 
     
    651734 
    652735;; 
     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; 
     744align 16 
     745BEGINPROC   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.  
     771GLOBALNAME EMEmulateLockBtr_Error 
     772    mov     eax, VERR_ACCESS_DENIED 
     773    ret 
     774%endif 
     775 
     776ENDPROC     EMEmulateLockBtr 
     777 
     778;; 
    653779; Emulate BTC instruction, CDECL calling conv. 
    654780; EMDECL(uint32_t) EMEmulateBtc(uint32_t *pu32Param1, uint32_t u32Param2); 
  • trunk/src/VBox/VMM/VMMGC/MMRamGC.cpp

    r5342 r5384  
    3737*   Internal Functions                                                         * 
    3838*******************************************************************************/ 
    39 static DECLCALLBACK(int) mmgcramTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame); 
     39static DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame); 
    4040 
    4141DECLASM(void) MMGCRamReadNoTrapHandler_EndProc(void); 
    4242DECLASM(void) MMGCRamWriteNoTrapHandler_EndProc(void); 
     43DECLASM(void) EMGCEmulateLockCmpXchg_EndProc(void); 
     44DECLASM(void) EMGCEmulateLockCmpXchg_Error(void); 
    4345DECLASM(void) EMGCEmulateCmpXchg_EndProc(void); 
    44 DECLASM(void) EMGCEmulateLockCmpXchg_EndProc(void); 
    4546DECLASM(void) EMGCEmulateCmpXchg_Error(void); 
    46 DECLASM(void) EMGCEmulateLockCmpXchg_Error(void); 
     47DECLASM(void) EMEmulateLockOr_EndProc(void); 
     48DECLASM(void) EMEmulateLockOr_Error(void); 
     49DECLASM(void) EMEmulateLockBtr_EndProc(void); 
     50DECLASM(void) EMEmulateLockBtr_Error(void); 
    4751DECLASM(void) MMGCRamRead_Error(void); 
    4852DECLASM(void) MMGCRamWrite_Error(void); 
     
    5963MMGCDECL(void) MMGCRamRegisterTrapHandler(PVM pVM) 
    6064{ 
    61     TRPMGCSetTempHandler(pVM, 0xe, mmgcramTrap0eHandler); 
     65    TRPMGCSetTempHandler(pVM, 0xe, mmGCRamTrap0eHandler); 
    6266} 
    6367 
     
    133137 * @internal 
    134138 */ 
    135 DECLCALLBACK(int) mmgcramTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame) 
    136 { 
    137     /* 
    138      * Check where the trap was occurred
     139DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame) 
     140{ 
     141    /* 
     142     * Page fault inside MMGCRamRead()? Resume at *_Error
    139143     */ 
    140144    if (    (uintptr_t)&MMGCRamReadNoTrapHandler < (uintptr_t)pRegFrame->eip 
    141145        &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamReadNoTrapHandler_EndProc) 
    142146    { 
    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);  
    153149        pRegFrame->eip = (uintptr_t)&MMGCRamRead_Error; 
    154150        return VINF_SUCCESS; 
    155151    } 
    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);  
    169161        pRegFrame->eip = (uintptr_t)&MMGCRamWrite_Error; 
    170162        return VINF_SUCCESS; 
    171163    } 
    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    { 
    180171        pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg_Error; 
    181172        return VINF_SUCCESS; 
    182173    } 
    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    { 
    191181        pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg_Error; 
    192182        return VINF_SUCCESS; 
    193183    } 
    194184 
    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     */ 
    196208    return VERR_INTERNAL_ERROR; 
    197209} 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy