VirtualBox

Changeset 40187 in vbox


Ignore:
Timestamp:
Feb 21, 2012 12:32:45 AM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
76351
Message:

callf fixes. fxsave bounce buffering fix. Don't try fxsave output as REM is incomplete.

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

Legend:

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

    r40185 r40187  
    4949 * for FPU exception delivery, because with CR0.NE=0 there is a window where we
    5050 * can trigger spurious FPU exceptions.
     51 *
     52 * The guest FPU state is not loaded into the host CPU and kept there till we
     53 * leave IEM because the calling conventions have declared an all year open
     54 * season on much of the FPU state.  For instance an innocent looking call to
     55 * memcpy might end up using a whole bunch of XMM or MM registers if the
     56 * particular implementation finds it worthwhile.
    5157 *
    5258 *
     
    42334239            pEvtRec->u.RamWrite.cb      = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
    42344240            memcpy(pEvtRec->u.RamWrite.ab, &pIemCpu->aBounceBuffers[iMemMap].ab[0], pIemCpu->aMemBbMappings[iMemMap].cbFirst);
     4241            AssertCompile(sizeof(pEvtRec->u.RamWrite.ab) == sizeof(pIemCpu->aBounceBuffers[0].ab));
    42354242            pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
    42364243            *pIemCpu->ppIemEvtRecNext = pEvtRec;
     
    42854292
    42864293    /*
    4287      * Read in the current memory content if it's a read of execute access.
     4294     * Read in the current memory content if it's a read, execute or partial
     4295     * write access.
    42884296     */
    42894297    uint8_t        *pbBuf        = &pIemCpu->aBounceBuffers[iMemMap].ab[0];
     
    42914299    uint32_t const  cbSecondPage = (uint32_t)(cbMem - cbFirstPage);
    42924300
    4293     if (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC))
     4301    if (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC | IEM_ACCESS_PARTIAL_WRITE))
    42944302    {
    42954303        int rc;
     
    43144322
    43154323#ifdef IEM_VERIFICATION_MODE
    4316         if (!pIemCpu->fNoRem)
     4324        if (   !pIemCpu->fNoRem
     4325            && (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC)) )
    43174326        {
    43184327            /*
     
    43854394
    43864395    /*
    4387      * Read in the current memory content if it's a read of execute access.
     4396     * Read in the current memory content if it's a read, execute or partial
     4397     * write access.
    43884398     */
    43894399    uint8_t *pbBuf = &pIemCpu->aBounceBuffers[iMemMap].ab[0];
    4390     if (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC))
     4400    if (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC | IEM_ACCESS_PARTIAL_WRITE))
    43914401    {
    43924402        if (rcMap == VERR_PGM_PHYS_TLB_UNASSIGNED)
     
    44044414
    44054415#ifdef IEM_VERIFICATION_MODE
    4406         if (!pIemCpu->fNoRem)
     4416        if (   !pIemCpu->fNoRem
     4417            && (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC)) )
    44074418        {
    44084419            /*
     
    68606871            break;
    68616872        case IEMVERIFYEVENT_RAM_WRITE:
    6862             RTAssertMsg2Add("RAM WRITE at %RGp, %#4zx bytes: %.*RHxs\n",
     6873            RTAssertMsg2Add("RAM WRITE at %RGp, %#4zx bytes: %.*Rhxs\n",
    68636874                            pEvtRec->u.RamWrite.GCPhys,
    68646875                            pEvtRec->u.RamWrite.cb,
     
    69186929{
    69196930    uint8_t abBuf[sizeof(pEvtRec->u.RamWrite.ab)]; RT_ZERO(abBuf);
     6931    Assert(sizeof(abBuf) >= pEvtRec->u.RamWrite.cb);
    69206932    int rc = PGMPhysSimpleReadGCPhys(IEMCPU_TO_VM(pIemCpu), abBuf, pEvtRec->u.RamWrite.GCPhys, pEvtRec->u.RamWrite.cb);
    69216933    if (   RT_FAILURE(rc)
     
    69346946                && pEvtRec->u.RamWrite.GCPhys - UINT32_C(0xfffc0000) > UINT32_C(0x40000) )
    69356947            {
    6936                 RTAssertMsg1(NULL, __LINE__, __FILE__, __PRETTY_FUNCTION__);
    6937                 RTAssertMsg2Weak("Memory at %RGv differs\n", pEvtRec->u.RamWrite.GCPhys);
    6938                 RTAssertMsg2Add("REM: %.*Rhxs\n"
    6939                                 "IEM: %.*Rhxs\n",
    6940                                 pEvtRec->u.RamWrite.cb, abBuf,
    6941                                 pEvtRec->u.RamWrite.cb, pEvtRec->u.RamWrite.ab);
    6942                 iemVerifyAssertAddRecordDump(pEvtRec);
    6943                 iemVerifyAssertMsg2(pIemCpu);
    6944                 RTAssertPanic();
     6948                /* fend off fxsave */
     6949                if (pEvtRec->u.RamWrite.cb != 512)
     6950                {
     6951                    RTAssertMsg1(NULL, __LINE__, __FILE__, __PRETTY_FUNCTION__);
     6952                    RTAssertMsg2Weak("Memory at %RGv differs\n", pEvtRec->u.RamWrite.GCPhys);
     6953                    RTAssertMsg2Add("REM: %.*Rhxs\n"
     6954                                    "IEM: %.*Rhxs\n",
     6955                                    pEvtRec->u.RamWrite.cb, abBuf,
     6956                                    pEvtRec->u.RamWrite.cb, pEvtRec->u.RamWrite.ab);
     6957                    iemVerifyAssertAddRecordDump(pEvtRec);
     6958                    iemVerifyAssertMsg2(pIemCpu);
     6959                    RTAssertPanic();
     6960                }
    69456961            }
    69466962        }
     
    73707386    iemExecVerificationModeCheck(pIemCpu);
    73717387#endif
    7372     LogFlow(("IEMExecOne: returns %Rrc - cs:rip=%04x:%08RX64 ss:rsp=%04x:%08RX64 EFL=%06x\n",
    7373              VBOXSTRICTRC_VAL(rcStrict), pCtx->cs, pCtx->rip, pCtx->ss, pCtx->rsp, pCtx->eflags.u));
     7388    if (rcStrict != VINF_SUCCESS)
     7389        LogFlow(("IEMExecOne: cs:rip=%04x:%08RX64 ss:rsp=%04x:%08RX64 EFL=%06x - rcStrict=%Rrc\n",
     7390                 pCtx->cs, pCtx->rip, pCtx->ss, pCtx->rsp, pCtx->eflags.u, VBOXSTRICTRC_VAL(rcStrict)));
    73747391    return rcStrict;
    73757392}
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r40184 r40187  
    10411041    VBOXSTRICTRC    rcStrict;
    10421042    uint64_t        uNewRsp;
    1043     void           *pvRet;
     1043    RTPTRUNION      uPtrRet;
    10441044
    10451045    /*
     
    10551055        /* Check stack first - may #SS(0). */
    10561056        rcStrict = iemMemStackPushBeginSpecial(pIemCpu, enmEffOpSize == IEMMODE_32BIT ? 6 : 4,
    1057                                                &pvRet, &uNewRsp);
     1057                                               &uPtrRet.pv, &uNewRsp);
    10581058        if (rcStrict != VINF_SUCCESS)
    10591059            return rcStrict;
     
    10661066        if (enmEffOpSize == IEMMODE_16BIT)
    10671067        {
    1068             ((uint16_t *)pvRet)[0] = pCtx->ip + cbInstr;
    1069             ((uint16_t *)pvRet)[1] = pCtx->cs;
     1068            uPtrRet.pu16[0] = pCtx->ip + cbInstr;
     1069            uPtrRet.pu16[1] = pCtx->cs;
    10701070        }
    10711071        else
    10721072        {
    1073             ((uint32_t *)pvRet)[0] = pCtx->eip + cbInstr;
    1074             ((uint16_t *)pvRet)[3] = pCtx->cs;
    1075         }
    1076         rcStrict = iemMemStackPushCommitSpecial(pIemCpu, pvRet, uNewRsp);
     1073            uPtrRet.pu32[0] = pCtx->eip + cbInstr;
     1074            uPtrRet.pu16[3] = pCtx->cs;
     1075        }
     1076        rcStrict = iemMemStackPushCommitSpecial(pIemCpu, uPtrRet.pv, uNewRsp);
    10771077        if (rcStrict != VINF_SUCCESS)
    10781078            return rcStrict;
     
    11601160
    11611161    /* Check stack first - may #SS(0). */
     1162    /** @todo check how operand prefix affects pushing of CS! Does callf 16:32 in
     1163     *        16-bit code cause a two or four byte CS to be pushed? */
    11621164    rcStrict = iemMemStackPushBeginSpecial(pIemCpu,
    1163                                            enmEffOpSize == IEMMODE_64BIT   ? 8+2
    1164                                            : enmEffOpSize == IEMMODE_32BIT ? 4+2 : 2+2,
    1165                                            &pvRet, &uNewRsp);
     1165                                           enmEffOpSize == IEMMODE_64BIT   ? 8+8
     1166                                           : enmEffOpSize == IEMMODE_32BIT ? 4+4 : 2+2,
     1167                                           &uPtrRet.pv, &uNewRsp);
    11661168    if (rcStrict != VINF_SUCCESS)
    11671169        return rcStrict;
     
    12151217    if (enmEffOpSize == IEMMODE_16BIT)
    12161218    {
    1217         ((uint16_t *)pvRet)[0] = pCtx->ip + cbInstr;
    1218         ((uint16_t *)pvRet)[1] = pCtx->cs;
     1219        uPtrRet.pu16[0] = pCtx->ip + cbInstr;
     1220        uPtrRet.pu16[1] = pCtx->cs;
    12191221    }
    12201222    else if (enmEffOpSize == IEMMODE_32BIT)
    12211223    {
    1222         ((uint32_t *)pvRet)[0] = pCtx->eip + cbInstr;
    1223         ((uint32_t *)pvRet)[1] = pCtx->cs;
     1224        uPtrRet.pu32[0] = pCtx->eip + cbInstr;
     1225        uPtrRet.pu32[1] = pCtx->cs; /** @todo Testcase: What is written to the high word when callf is pushing CS? */
    12241226    }
    12251227    else
    12261228    {
    1227         ((uint64_t *)pvRet)[0] = pCtx->rip + cbInstr;
    1228         ((uint64_t *)pvRet)[1] = pCtx->cs;
    1229     }
    1230     rcStrict = iemMemStackPushCommitSpecial(pIemCpu, pvRet, uNewRsp);
     1229        uPtrRet.pu64[0] = pCtx->rip + cbInstr;
     1230        uPtrRet.pu64[1] = pCtx->cs; /** @todo Testcase: What is written to the high words when callf is pushing CS? */
     1231    }
     1232    rcStrict = iemMemStackPushCommitSpecial(pIemCpu, uPtrRet.pv, uNewRsp);
    12311233    if (rcStrict != VINF_SUCCESS)
    12321234        return rcStrict;
     
    38843886     */
    38853887    void *pvMem512;
    3886     VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, &pvMem512, 512, iEffSeg, GCPtrEff, IEM_ACCESS_DATA_W);
     3888    VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, &pvMem512, 512, iEffSeg, GCPtrEff, IEM_ACCESS_DATA_W | IEM_ACCESS_PARTIAL_WRITE);
    38873889    if (rcStrict != VINF_SUCCESS)
    38883890        return rcStrict;
     
    39383940     * Commit the memory.
    39393941     */
    3940     rcStrict = iemMemCommitAndUnmap(pIemCpu, pvMem512, IEM_ACCESS_DATA_W);
     3942    rcStrict = iemMemCommitAndUnmap(pIemCpu, pvMem512, IEM_ACCESS_DATA_W | IEM_ACCESS_PARTIAL_WRITE);
    39413943    if (rcStrict != VINF_SUCCESS)
    39423944        return rcStrict;
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r40182 r40187  
    157157            RTGCPHYS    GCPhys;
    158158            uint32_t    cb;
    159             uint8_t     ab[32];
     159            uint8_t     ab[512];
    160160        } RamWrite;
    161161    } u;
     
    353353#define IEM_ACCESS_WHAT_SYS             UINT32_C(0x00000040)
    354354#define IEM_ACCESS_WHAT_MASK            UINT32_C(0x00000070)
     355/** The writes are partial, so if initialize the bounce buffer with the
     356 * orignal RAM content. */
     357#define IEM_ACCESS_PARTIAL_WRITE        UINT32_C(0x00000100)
    355358/** Used in aMemMappings to indicate that the entry is bounce buffered. */
    356 #define IEM_ACCESS_BOUNCE_BUFFERED      UINT32_C(0x00000100)
     359#define IEM_ACCESS_BOUNCE_BUFFERED      UINT32_C(0x00000200)
    357360/** Read+write data alias. */
    358361#define IEM_ACCESS_DATA_RW              (IEM_ACCESS_TYPE_READ  | IEM_ACCESS_TYPE_WRITE | IEM_ACCESS_WHAT_DATA)
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