VirtualBox

Changeset 2036 in vbox


Ignore:
Timestamp:
Apr 11, 2007 4:27:39 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
20332
Message:

Emulate (lock) cmpxchg in the guest context.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r2026 r2036  
    6060DECLINLINE(int) emInterpretInstructionCPU(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize);
    6161
    62 /* Enable to allow segment prefix support */
    63 #define EM_ALLOW_SEG_PREFIX
    64 
    6562/**
    6663 * Get the current execution manager status.
     
    328325static RTGCPTR emConvertToFlatAddr(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu, POP_PARAMETER pParam, RTGCPTR pvAddr)
    329326{
    330 #ifdef EM_ALLOW_SEG_PREFIX
    331327    int   prefix_seg, rc;
    332328    RTSEL sel;
     
    339335
    340336    return SELMToFlat(pVM, pRegFrame->eflags, sel, pSelHidReg, pvAddr);
    341 #else
    342     return pvAddr;
    343 #endif
    344337}
    345338
     
    479472    return VERR_EM_INTERPRETER;
    480473}
    481 
    482474
    483475/**
     
    10801072}
    10811073
     1074#ifdef IN_GC
     1075static int emInterpretCmpXchg(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
     1076{
     1077    OP_PARAMVAL param1, param2;
     1078
     1079    /* Source to make DISQueryParamVal read the register value - ugly hack */
     1080    int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, &param1, PARAM_SOURCE);
     1081    if(VBOX_FAILURE(rc))
     1082        return VERR_EM_INTERPRETER;
     1083
     1084    rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, &param2, PARAM_SOURCE);
     1085    if(VBOX_FAILURE(rc))
     1086        return VERR_EM_INTERPRETER;
     1087
     1088    if (TRPMHasTrap(pVM))
     1089    {
     1090        if (TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW)
     1091        {
     1092            RTGCPTR pParam1;
     1093            uint32_t valpar, eflags;
     1094#ifdef VBOX_STRICT
     1095            uint32_t valpar1;
     1096#endif
     1097
     1098            AssertReturn(pCpu->param1.size == pCpu->param2.size, VERR_EM_INTERPRETER);
     1099            switch(param1.type)
     1100            {
     1101            case PARMTYPE_ADDRESS:
     1102                pParam1 = (RTGCPTR)param1.val.val32;
     1103                pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1);
     1104
     1105                /* Safety check (in theory it could cross a page boundary and fault there though) */
     1106                AssertMsgReturn(pParam1 == pvFault, ("eip=%VGv pParam1=%VGv pvFault=%VGv\n", pRegFrame->eip, pParam1, pvFault), VERR_EM_INTERPRETER);
     1107
     1108#ifdef VBOX_STRICT
     1109                rc = emRamRead(pVM, &valpar1, pParam1, param1.size);
     1110                if (VBOX_FAILURE(rc))
     1111                    return VERR_EM_INTERPRETER;
     1112#endif
     1113                break;
     1114
     1115            default:
     1116                return VERR_EM_INTERPRETER;
     1117            }
     1118
     1119            switch(param2.type)
     1120            {
     1121            case PARMTYPE_IMMEDIATE: /* register actually */
     1122                valpar = param2.val.val32;
     1123                break;
     1124
     1125            default:
     1126                return VERR_EM_INTERPRETER;
     1127            }
     1128
     1129#ifdef VBOX_STRICT
     1130            Log(("CmpXchg %VGv=%08x eax=%08x %08x\n", pParam1, valpar1, pRegFrame->eax, valpar));
     1131#endif
     1132            if (pCpu->prefix & PREFIX_LOCK)
     1133                eflags = EMGCEmulateLockCmpXchg(pParam1, &pRegFrame->eax, valpar, pCpu->param2.size);
     1134            else
     1135                eflags = EMGCEmulateCmpXchg(pParam1, &pRegFrame->eax, valpar, pCpu->param2.size);
     1136
     1137#ifdef VBOX_STRICT
     1138            rc = emRamRead(pVM, &valpar1, pParam1, param1.size);
     1139            Log(("CmpXchg %VGv=%08x eax=%08x %08x ZF=%d\n", pParam1, valpar1, pRegFrame->eax, valpar, !!(eflags & X86_EFL_ZF)));
     1140#endif
     1141            /* Update guest's eflags and finish. */
     1142            pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF))
     1143                                  | (eflags                &  (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF));
     1144
     1145            *pcbSize = param2.size;
     1146            return VINF_SUCCESS;
     1147        }
     1148    }
     1149    return VERR_EM_INTERPRETER;
     1150}
     1151#endif
    10821152
    10831153/**
     
    16671737    }
    16681738
    1669 #ifdef EM_ALLOW_SEG_PREFIX
     1739#ifdef IN_GC
     1740    if (    (pCpu->prefix & (PREFIX_REPNE | PREFIX_REP))
     1741        ||  (   (pCpu->prefix & PREFIX_LOCK)
     1742             && (pCpu->pCurInstr->opcode != OP_CMPXCHG)
     1743            )
     1744       )
     1745#else
    16701746    if (pCpu->prefix & (PREFIX_REPNE | PREFIX_REP | PREFIX_LOCK))
    1671 #else
    1672     /* Out emulation above can't cope with 16 bits code yet. */
    1673     if (!SELMIsSelector32Bit(pVM, pRegFrame->eflags, pRegFrame->cs, &pRegFrame->csHid))
    1674         return VERR_EM_INTERPRETER;
    1675 
    1676     if (pCpu->prefix & (PREFIX_REPNE | PREFIX_REP | PREFIX_SEG | PREFIX_LOCK))
    16771747#endif
    16781748    {
     
    17361806        INTERPRET_CASE(OP_RDTSC,Rdtsc);
    17371807        INTERPRET_CASE(OP_STI,Sti);
     1808        INTERPRET_CASE(OP_CMPXCHG, CmpXchg);
    17381809#endif
    17391810        INTERPRET_CASE(OP_HLT,Hlt);
    17401811        INTERPRET_CASE(OP_IRET,Iret);
    17411812#ifdef VBOX_WITH_STATISTICS
     1813#ifndef IN_GC
    17421814        INTERPRET_STAT_CASE(OP_CMPXCHG,CmpXchg);
     1815#endif
    17431816        INTERPRET_STAT_CASE(OP_MOVNTPS,MovNTPS);
    17441817        INTERPRET_STAT_CASE(OP_STOSWD,StosWD);
Note: See TracChangeset for help on using the changeset viewer.

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