VirtualBox

Changeset 5384 in vbox for trunk/src


Ignore:
Timestamp:
Oct 19, 2007 2:13:42 PM (17 years ago)
Author:
vboxsync
Message:

LOCK BTR and LOCK OR (for Solaris guests).

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette