VirtualBox

Changeset 37039 in vbox


Ignore:
Timestamp:
May 11, 2011 3:04:25 PM (13 years ago)
Author:
vboxsync
Message:

IEM: Hacking in progress...

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r37034 r37039  
    537537*   Internal Functions                                                         *
    538538*******************************************************************************/
     539static VBOXSTRICTRC     iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu);
     540static VBOXSTRICTRC     iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr);
     541static VBOXSTRICTRC     iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr);
    539542static VBOXSTRICTRC     iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu);
    540543static VBOXSTRICTRC     iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
     
    542545static VBOXSTRICTRC     iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
    543546static VBOXSTRICTRC     iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc);
     547static VBOXSTRICTRC     iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
     548static VBOXSTRICTRC     iemMemFetchDataU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
     549static VBOXSTRICTRC     iemMemFetchSelDesc(PIEMCPU pIemCpu, PIEMSELDESC pDesc, uint16_t uSel);
     550static VBOXSTRICTRC     iemMemStackPushCommitSpecial(PIEMCPU pIemCpu, void *pvMem, uint64_t uNewRsp);
     551static VBOXSTRICTRC     iemMemStackPushBeginSpecial(PIEMCPU pIemCpu, size_t cbMem, void **ppvMem, uint64_t *puNewRsp);
     552
    544553#ifdef IEM_VERIFICATION_MODE
    545554static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu);
     
    11961205 */
    11971206
     1207/** @name IEM_XCPT_FLAGS_XXX - flags for iemRaiseXcptOrInt.
     1208 * @{ */
     1209/** CPU exception. */
     1210#define IEM_XCPT_FLAGS_T_CPU_XCPT       RT_BIT_32(0)
     1211/** External interrupt (from PIC, APIC, whatever). */
     1212#define IEM_XCPT_FLAGS_T_EXT_INT        RT_BIT_32(1)
     1213/** Software interrupt (int, into or bound). */
     1214#define IEM_XCPT_FLAGS_T_SOFT_INT       RT_BIT_32(2)
     1215/** Takes an error code. */
     1216#define IEM_XCPT_FLAGS_ERR              RT_BIT_32(3)
     1217/** Takes a CR2. */
     1218#define IEM_XCPT_FLAGS_CR2              RT_BIT_32(4)
     1219/** Generated by the breakpoint instruction. */
     1220#define IEM_XCPT_FLAGS_BP_INSTR         RT_BIT_32(5)
     1221/** Mask out the nesting level. */
     1222#define IEM_XCPT_FLAGS_NESTING_MASK     UINT32_C(0xff000000)
     1223/** Shift count for the nesting level. */
     1224#define IEM_XCPT_FLAGS_NESTING_SHIFT    24
     1225/** Mask out the nesting level after shifting. */
     1226#define IEM_XCPT_FLAGS_NESTING_SMASK    UINT32_C(0x000000ff)
     1227/** @}  */
     1228
     1229/**
     1230 * Loads the specified stack far pointer from the TSS.
     1231 *
     1232 * @returns VBox strict status code.
     1233 * @param   pIemCpu         The IEM per CPU instance data.
     1234 * @param   pCtx            The CPU context.
     1235 * @param   uCpl            The CPL to load the stack for.
     1236 * @param   pSelSS          Where to return the new stack segment.
     1237 * @param   puEsp           Where to return the new stack pointer.
     1238 */
     1239static VBOXSTRICTRC iemRaiseLoadStackFromTss32Or16(PIEMCPU pIemCpu, PCCPUMCTX pCtx, uint8_t uCpl,
     1240                                                   PRTSEL pSelSS, uint32_t *puEsp)
     1241{
     1242    VBOXSTRICTRC rcStrict;
     1243    Assert(uCpl < 4);
     1244
     1245    switch (pCtx->trHid.Attr.n.u4Type)
     1246    {
     1247        /*
     1248         * 16-bit TSS (X86TSS16).
     1249         */
     1250        case X86_SEL_TYPE_SYS_286_TSS_AVAIL: AssertFailed();
     1251        case X86_SEL_TYPE_SYS_286_TSS_BUSY:
     1252        {
     1253            uint32_t off = uCpl * 4 + 2;
     1254            if (off + 4 > pCtx->trHid.u32Limit)
     1255            {
     1256                Log(("LoadStackFromTss32Or16: out of bounds! uCpl=%d, u32Limit=%#x TSS16\n", uCpl, pCtx->trHid.u32Limit));
     1257                return iemRaiseTaskSwitchFaultCurrentTSS(pIemCpu);
     1258            }
     1259
     1260            uint32_t u32Tmp;
     1261            rcStrict = iemMemFetchDataU32(pIemCpu, &u32Tmp, UINT8_MAX, pCtx->trHid.u64Base + off);
     1262            if (rcStrict == VINF_SUCCESS)
     1263            {
     1264                *puEsp  = RT_LOWORD(u32Tmp);
     1265                *pSelSS = RT_HIWORD(u32Tmp);
     1266                return VINF_SUCCESS;
     1267            }
     1268            break;
     1269        }
     1270
     1271        /*
     1272         * 32-bit TSS (X86TSS32).
     1273         */
     1274        case X86_SEL_TYPE_SYS_386_TSS_AVAIL: AssertFailed();
     1275        case X86_SEL_TYPE_SYS_386_TSS_BUSY:
     1276        {
     1277            uint32_t off = uCpl * 8 + 4;
     1278            if (off + 7 > pCtx->trHid.u32Limit)
     1279            {
     1280                Log(("LoadStackFromTss32Or16: out of bounds! uCpl=%d, u32Limit=%#x TSS16\n", uCpl, pCtx->trHid.u32Limit));
     1281                return iemRaiseTaskSwitchFaultCurrentTSS(pIemCpu);
     1282            }
     1283
     1284            uint64_t u64Tmp;
     1285            rcStrict = iemMemFetchDataU64(pIemCpu, &u64Tmp, UINT8_MAX, pCtx->trHid.u64Base + off);
     1286            if (rcStrict == VINF_SUCCESS)
     1287            {
     1288                *puEsp  = u64Tmp & UINT32_MAX;
     1289                *pSelSS = (RTSEL)(u64Tmp >> 32);
     1290                return VINF_SUCCESS;
     1291            }
     1292            break;
     1293        }
     1294
     1295        default:
     1296            AssertFailedReturn(VERR_INTERNAL_ERROR_2);
     1297    }
     1298    return rcStrict;
     1299}
     1300
     1301
     1302/**
     1303 * Adjust the CPU state according to the exception being raised.
     1304 *
     1305 * @param   pCtx                The CPU context.
     1306 * @param   u8Vector            The exception that has been raised.
     1307 */
     1308DECLINLINE(void) iemRaiseXcptAdjustState(PCPUMCTX pCtx, uint8_t u8Vector)
     1309{
     1310    switch (u8Vector)
     1311    {
     1312        case X86_XCPT_DB:
     1313            pCtx->dr[7] &= ~X86_DR7_GD;
     1314            break;
     1315        /** @todo Read the AMD and Intel exception reference... */
     1316    }
     1317}
     1318
     1319
     1320/**
     1321 * Implements exceptions and interrupts for real mode.
     1322 *
     1323 * @returns VBox strict status code.
     1324 * @param   pIemCpu         The IEM per CPU instance data.
     1325 * @param   pCtx            The CPU context.
     1326 * @param   cbInstr         The number of bytes to offset rIP by in the return
     1327 *                          address.
     1328 * @param   u8Vector        The interrupt / exception vector number.
     1329 * @param   fFlags          The flags.
     1330 * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
     1331 * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
     1332 */
     1333static VBOXSTRICTRC
     1334iemRaiseXcptOrIntInRealMode(PIEMCPU     pIemCpu,
     1335                             PCPUMCTX    pCtx,
     1336                             uint8_t     cbInstr,
     1337                             uint8_t     u8Vector,
     1338                             uint32_t    fFlags,
     1339                             uint16_t    uErr,
     1340                             uint64_t    uCr2)
     1341{
     1342    AssertReturn(pIemCpu->enmCpuMode == IEMMODE_16BIT, VERR_INTERNAL_ERROR_3);
     1343
     1344    /*
     1345     * Read the IDT entry.
     1346     */
     1347    if (pCtx->idtr.cbIdt < UINT32_C(4) * u8Vector + 3)
     1348    {
     1349        Log(("RaiseXcptOrIntInRealMode: %#x is out of bounds (%#x)\n", u8Vector, pCtx->idtr.cbIdt));
     1350        return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
     1351    }
     1352    RTFAR16 Idte;
     1353    VBOXSTRICTRC rcStrict = iemMemFetchDataU32(pIemCpu, (uint32_t *)&Idte, UINT8_MAX,
     1354                                               pCtx->idtr.pIdt + UINT32_C(4) * u8Vector);
     1355    if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
     1356        return rcStrict;
     1357
     1358    /*
     1359     * Push the stack frame.
     1360     */
     1361    uint16_t *pu16Frame;
     1362    uint64_t  uNewRsp;
     1363    rcStrict = iemMemStackPushBeginSpecial(pIemCpu, 6, (void **)&pu16Frame, &uNewRsp);
     1364    if (rcStrict != VINF_SUCCESS)
     1365        return rcStrict;
     1366
     1367    pu16Frame[2] = (uint16_t)pCtx->eflags.u;
     1368    pu16Frame[1] = (uint16_t)pCtx->cs;
     1369    pu16Frame[0] = pCtx->ip + cbInstr;
     1370    rcStrict = iemMemStackPushCommitSpecial(pIemCpu, pu16Frame, uNewRsp);
     1371    if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
     1372        return rcStrict;
     1373
     1374    /*
     1375     * Load the vector address into cs:ip and make exception specific state
     1376     * adjustments.
     1377     */
     1378    pCtx->cs               = Idte.sel;
     1379    pCtx->csHid.u64Base    = (uint32_t)Idte.sel << 4;
     1380    /** @todo do we load attribs and limit as well? Should we check against limit like far jump? */
     1381    pCtx->rip              = Idte.off;
     1382    pCtx->eflags.Bits.u1IF = 0;
     1383
     1384    /** @todo do we actually do this in real mode? */
     1385    if (fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT)
     1386        iemRaiseXcptAdjustState(pCtx, u8Vector);
     1387
     1388    return VINF_SUCCESS;
     1389}
     1390
     1391
     1392/**
     1393 * Implements exceptions and interrupts for protected mode.
     1394 *
     1395 * @returns VBox strict status code.
     1396 * @param   pIemCpu         The IEM per CPU instance data.
     1397 * @param   pCtx            The CPU context.
     1398 * @param   cbInstr         The number of bytes to offset rIP by in the return
     1399 *                          address.
     1400 * @param   u8Vector        The interrupt / exception vector number.
     1401 * @param   fFlags          The flags.
     1402 * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
     1403 * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
     1404 */
     1405static VBOXSTRICTRC
     1406iemRaiseXcptOrIntInProtMode(PIEMCPU     pIemCpu,
     1407                            PCPUMCTX    pCtx,
     1408                            uint8_t     cbInstr,
     1409                            uint8_t     u8Vector,
     1410                            uint32_t    fFlags,
     1411                            uint16_t    uErr,
     1412                            uint64_t    uCr2)
     1413{
     1414    /*
     1415     * Read the IDT entry.
     1416     */
     1417    if (pCtx->idtr.cbIdt < UINT32_C(8) * u8Vector + 7)
     1418    {
     1419        Log(("RaiseXcptOrIntInProtMode: %#x is out of bounds (%#x)\n", u8Vector, pCtx->idtr.cbIdt));
     1420        return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
     1421    }
     1422    X86DESC Idte;
     1423    VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pIemCpu, &Idte.u, UINT8_MAX,
     1424                                               pCtx->idtr.pIdt + UINT32_C(8) * u8Vector);
     1425    if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
     1426        return rcStrict;
     1427
     1428    /*
     1429     * Check the descriptor type, DPL and such.
     1430     * ASSUMES this is done in the same order as described for call-gate calls.
     1431     */
     1432    if (Idte.Gate.u1DescType)
     1433    {
     1434        Log(("RaiseXcptOrIntInProtMode %#x - not system selector (%#x) -> #GP\n", u8Vector, Idte.Gate.u4Type));
     1435        return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
     1436    }
     1437    uint32_t fEflToClear = X86_EFL_TF | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM;
     1438    switch (Idte.Gate.u4Type)
     1439    {
     1440        case X86_SEL_TYPE_SYS_UNDEFINED:
     1441        case X86_SEL_TYPE_SYS_286_TSS_AVAIL:
     1442        case X86_SEL_TYPE_SYS_LDT:
     1443        case X86_SEL_TYPE_SYS_286_TSS_BUSY:
     1444        case X86_SEL_TYPE_SYS_286_CALL_GATE:
     1445        case X86_SEL_TYPE_SYS_UNDEFINED2:
     1446        case X86_SEL_TYPE_SYS_386_TSS_AVAIL:
     1447        case X86_SEL_TYPE_SYS_UNDEFINED3:
     1448        case X86_SEL_TYPE_SYS_386_TSS_BUSY:
     1449        case X86_SEL_TYPE_SYS_386_CALL_GATE:
     1450        case X86_SEL_TYPE_SYS_UNDEFINED4:
     1451        {
     1452            /** @todo check what actually happens when the type is wrong...
     1453             *        esp. call gates. */
     1454            Log(("RaiseXcptOrIntInProtMode %#x - invalid type (%#x) -> #GP\n", u8Vector, Idte.Gate.u4Type));
     1455            return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
     1456        }
     1457
     1458        case X86_SEL_TYPE_SYS_286_INT_GATE:
     1459        case X86_SEL_TYPE_SYS_386_INT_GATE:
     1460            fEflToClear |= X86_EFL_IF;
     1461            break;
     1462
     1463        case X86_SEL_TYPE_SYS_TASK_GATE:
     1464            /** @todo task gates. */
     1465            AssertFailedReturn(VERR_NOT_SUPPORTED);
     1466
     1467        case X86_SEL_TYPE_SYS_286_TRAP_GATE:
     1468        case X86_SEL_TYPE_SYS_386_TRAP_GATE:
     1469            break;
     1470
     1471        IEM_NOT_REACHED_DEFAULT_CASE_RET();
     1472    }
     1473
     1474    /* Check DPL against CPL if applicable. */
     1475    if (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT)
     1476    {
     1477        if (pIemCpu->uCpl > Idte.Gate.u2Dpl)
     1478        {
     1479            Log(("RaiseXcptOrIntInProtMode %#x - CPL (%d) > DPL (%d) -> #GP\n", u8Vector, pIemCpu->uCpl, Idte.Gate.u2Dpl));
     1480            return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
     1481        }
     1482    }
     1483
     1484    /* Is it there? */
     1485    if (!Idte.Gate.u1Present)
     1486    {
     1487        Log(("RaiseXcptOrIntInProtMode %#x - not present -> #NP\n", u8Vector));
     1488        return iemRaiseSelectorNotPresentWithErr(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
     1489    }
     1490
     1491    /* A null CS is bad. */
     1492    RTSEL NewCS = Idte.Gate.u16Sel;
     1493    if (!(NewCS & (X86_SEL_MASK | X86_SEL_LDT)))
     1494    {
     1495        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x -> #GP\n", u8Vector, NewCS));
     1496        return iemRaiseGeneralProtectionFault0(pIemCpu);
     1497    }
     1498
     1499    /* Fetch the descriptor for the new CS. */
     1500    IEMSELDESC DescCS;
     1501    rcStrict = iemMemFetchSelDesc(pIemCpu, &DescCS, NewCS);
     1502    if (rcStrict != VINF_SUCCESS)
     1503        return rcStrict;
     1504
     1505    /* Must be a code segment. */
     1506    if (!DescCS.Legacy.Gen.u1DescType)
     1507    {
     1508        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - system selector (%#x) -> #GP\n", u8Vector, NewCS, DescCS.Legacy.Gen.u4Type));
     1509        return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
     1510    }
     1511    if (!(DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE))
     1512    {
     1513        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - data selector (%#x) -> #GP\n", u8Vector, NewCS, DescCS.Legacy.Gen.u4Type));
     1514        return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
     1515    }
     1516
     1517    /* Don't allow lowering the privilege level. */
     1518    /** @todo Does the lowering of privileges apply to software interrupts
     1519     *        only?  This has bearings on the more-privileged or
     1520     *        same-privilege stack behavior further down.  A testcase would
     1521     *        be nice. */
     1522    if (DescCS.Legacy.Gen.u2Dpl > pIemCpu->uCpl)
     1523    {
     1524        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - DPL (%d) > CPL (%d) -> #GP\n",
     1525             u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
     1526        return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
     1527    }
     1528    /** @todo is the RPL of the interrupt/trap gate descriptor checked? */
     1529
     1530    /*
     1531     * If the privilege level changes, we need to get a new stack from the TSS.
     1532     */
     1533    uint8_t const uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF
     1534                          ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;
     1535    if (uNewCpl != pIemCpu->uCpl)
     1536    {
     1537        uint32_t uNewEsp;
     1538        RTSEL    uNewSs;
     1539        rcStrict = iemRaiseLoadStackFromTss32Or16(pIemCpu, pCtx, uNewCpl, &uNewSs, &uNewEsp);
     1540        if (rcStrict != VINF_SUCCESS)
     1541            return rcStrict;
     1542
     1543    }
     1544
     1545    return VERR_NOT_IMPLEMENTED;
     1546}
     1547
     1548
     1549/**
     1550 * Implements exceptions and interrupts for V8086 mode.
     1551 *
     1552 * @returns VBox strict status code.
     1553 * @param   pIemCpu         The IEM per CPU instance data.
     1554 * @param   pCtx            The CPU context.
     1555 * @param   cbInstr         The number of bytes to offset rIP by in the return
     1556 *                          address.
     1557 * @param   u8Vector        The interrupt / exception vector number.
     1558 * @param   fFlags          The flags.
     1559 * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
     1560 * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
     1561 */
     1562static VBOXSTRICTRC
     1563iemRaiseXcptOrIntInV8086Mode(PIEMCPU     pIemCpu,
     1564                             PCPUMCTX    pCtx,
     1565                             uint8_t     cbInstr,
     1566                             uint8_t     u8Vector,
     1567                             uint32_t    fFlags,
     1568                             uint16_t    uErr,
     1569                             uint64_t    uCr2)
     1570{
     1571    AssertMsgFailed(("V8086 exception / interrupt dispatching\n"));
     1572    return VERR_NOT_IMPLEMENTED;
     1573}
     1574
     1575
     1576/**
     1577 * Implements exceptions and interrupts for long mode.
     1578 *
     1579 * @returns VBox strict status code.
     1580 * @param   pIemCpu         The IEM per CPU instance data.
     1581 * @param   pCtx            The CPU context.
     1582 * @param   cbInstr         The number of bytes to offset rIP by in the return
     1583 *                          address.
     1584 * @param   u8Vector        The interrupt / exception vector number.
     1585 * @param   fFlags          The flags.
     1586 * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
     1587 * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
     1588 */
     1589static VBOXSTRICTRC
     1590iemRaiseXcptOrIntInLongMode(PIEMCPU     pIemCpu,
     1591                            PCPUMCTX    pCtx,
     1592                            uint8_t     cbInstr,
     1593                            uint8_t     u8Vector,
     1594                            uint32_t    fFlags,
     1595                            uint16_t    uErr,
     1596                            uint64_t    uCr2)
     1597{
     1598    AssertMsgFailed(("long mode exception / interrupt dispatching\n"));
     1599    return VERR_NOT_IMPLEMENTED;
     1600}
     1601
     1602
     1603/**
     1604 * Implements exceptions and interrupts.
     1605 *
     1606 * All exceptions and interrupts goes thru this function!
     1607 *
     1608 * @returns VBox strict status code.
     1609 * @param   pIemCpu         The IEM per CPU instance data.
     1610 * @param   cbInstr         The number of bytes to offset rIP by in the return
     1611 *                          address.
     1612 * @param   u8Vector        The interrupt / exception vector number.
     1613 * @param   fFlags          The flags.
     1614 * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
     1615 * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
     1616 */
     1617static VBOXSTRICTRC
     1618iemRaiseXcptOrInt(PIEMCPU     pIemCpu,
     1619                  uint8_t     cbInstr,
     1620                  uint8_t     u8Vector,
     1621                  uint32_t    fFlags,
     1622                  uint16_t    uErr,
     1623                  uint64_t    uCr2)
     1624{
     1625    /*
     1626     * Do recursion accounting.
     1627     */
     1628    uint8_t uPrevXcpt = pIemCpu->uCurXcpt;
     1629    if (pIemCpu->cXcptRecursions > 0)
     1630    {
     1631        /** @todo double and tripple faults. */
     1632        AssertReturn(pIemCpu->cXcptRecursions < 3, VERR_NOT_IMPLEMENTED);
     1633    }
     1634    pIemCpu->cXcptRecursions++;
     1635    pIemCpu->uCurXcpt = u8Vector;
     1636
     1637    /*
     1638     * Call mode specific worker function.
     1639     */
     1640    VBOXSTRICTRC    rcStrict;
     1641    PCPUMCTX        pCtx = pIemCpu->CTX_SUFF(pCtx);
     1642    if (!(pCtx->cr0 & X86_CR0_PE))
     1643        rcStrict = iemRaiseXcptOrIntInRealMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
     1644    else if (pCtx->msrEFER & MSR_K6_EFER_LMA)
     1645        rcStrict = iemRaiseXcptOrIntInLongMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
     1646    else if (!pCtx->eflags.Bits.u1VM)
     1647        rcStrict = iemRaiseXcptOrIntInProtMode( pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
     1648    else
     1649        rcStrict = iemRaiseXcptOrIntInV8086Mode(pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
     1650
     1651    /*
     1652     * Unwind.
     1653     */
     1654    pIemCpu->cXcptRecursions--;
     1655    pIemCpu->uCurXcpt = uPrevXcpt;
     1656    return rcStrict;
     1657}
     1658
     1659
     1660/** \#DE - 00.  */
    11981661static VBOXSTRICTRC iemRaiseDivideError(PIEMCPU pIemCpu)
    11991662{
     
    12021665}
    12031666
     1667
     1668/** \#DB - 01.  */
    12041669static VBOXSTRICTRC iemRaiseDebugException(PIEMCPU pIemCpu)
    12051670{
     
    12081673}
    12091674
     1675
     1676/** \#UD - 06.  */
    12101677static VBOXSTRICTRC iemRaiseUndefinedOpcode(PIEMCPU pIemCpu)
     1678{
     1679    AssertFailed(/** @todo implement X86_XCPT_UD */);
     1680    return VERR_NOT_IMPLEMENTED;
     1681}
     1682
     1683
     1684/** \#NM - 07.  */
     1685static VBOXSTRICTRC iemRaiseDeviceNotAvailable(PIEMCPU pIemCpu)
    12111686{
    12121687    AssertFailed(/** @todo implement this */);
     
    12151690
    12161691
    1217 static VBOXSTRICTRC iemRaiseDeviceNotAvailable(PIEMCPU pIemCpu)
     1692/** \#TS(err) - 0a.  */
     1693static VBOXSTRICTRC iemRaiseTaskSwitchFaultWithErr(PIEMCPU pIemCpu, uint16_t uErr)
    12181694{
    12191695    AssertFailed(/** @todo implement this */);
     
    12221698
    12231699
    1224 static VBOXSTRICTRC iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr)
     1700/** \#TS(tr) - 0a.  */
     1701static VBOXSTRICTRC iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu)
     1702{
     1703    return iemRaiseTaskSwitchFaultWithErr(pIemCpu, pIemCpu->CTX_SUFF(pCtx)->tr);
     1704}
     1705
     1706
     1707/** \#NP(err) - 0b.  */
     1708static VBOXSTRICTRC iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr)
    12251709{
    12261710    AssertFailed(/** @todo implement this */);
     
    12291713
    12301714
    1231 static VBOXSTRICTRC iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu)
     1715/** \#NP(seg) - 0b.  */
     1716static VBOXSTRICTRC iemRaiseSelectorNotPresentBySegReg(PIEMCPU pIemCpu, uint32_t iSegReg)
    12321717{
    12331718    AssertFailed(/** @todo implement this */);
     
    12361721
    12371722
    1238 static VBOXSTRICTRC iemRaiseNotCanonical(PIEMCPU pIemCpu)
     1723/** \#NP(sel) - 0b.  */
     1724static VBOXSTRICTRC iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel)
    12391725{
    12401726    AssertFailed(/** @todo implement this */);
     
    12431729
    12441730
    1245 static VBOXSTRICTRC iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
     1731/** \#GP(n) - 0d.  */
     1732static VBOXSTRICTRC iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr)
    12461733{
    12471734    AssertFailed(/** @todo implement this */);
     
    12501737
    12511738
    1252 static VBOXSTRICTRC iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
     1739/** \#GP(0) - 0d.  */
     1740static VBOXSTRICTRC iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu)
     1741{
     1742    return iemRaiseGeneralProtectionFault(pIemCpu, 0);
     1743}
     1744
     1745
     1746/** \#GP(0) - 0d.  */
     1747static VBOXSTRICTRC iemRaiseNotCanonical(PIEMCPU pIemCpu)
    12531748{
    12541749    AssertFailed(/** @todo implement this */);
     
    12571752
    12581753
    1259 static VBOXSTRICTRC iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr)
     1754/** \#GP(sel) - 0d.  */
     1755static VBOXSTRICTRC iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
    12601756{
    12611757    AssertFailed(/** @todo implement this */);
     
    12641760
    12651761
    1266 static VBOXSTRICTRC iemRaiseSelectorNotPresentBySegReg(PIEMCPU pIemCpu, uint32_t iSegReg)
     1762/** \#GP(sel) - 0d.  */
     1763static VBOXSTRICTRC iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
    12671764{
    12681765    AssertFailed(/** @todo implement this */);
     
    12711768
    12721769
    1273 static VBOXSTRICTRC iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel)
     1770/** \#PF(n) - 0e.  */
     1771static VBOXSTRICTRC iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc)
    12741772{
    12751773    AssertFailed(/** @todo implement this */);
     
    12781776
    12791777
    1280 static VBOXSTRICTRC iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc)
    1281 {
    1282     AssertFailed(/** @todo implement this */);
    1283     return VERR_NOT_IMPLEMENTED;
    1284 }
    1285 
    1286 
     1778/** \#MF(n) - 10.  */
    12871779static VBOXSTRICTRC iemRaiseMathFault(PIEMCPU pIemCpu)
    12881780{
     
    53655857    }
    53665858
    5367     return iemCImpl_RaiseXcptOrInt(&pVCpu->iem.s, 0, u8TrapNo, fFlags, uErrCode, uCr2);
    5368 }
    5369 
     5859    return iemRaiseXcptOrInt(&pVCpu->iem.s, 0, u8TrapNo, fFlags, uErrCode, uCr2);
     5860}
     5861
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r37034 r37039  
    11151115
    11161116
    1117 /** @name IEM_XCPT_FLAGS_XXX - flags for iemCImpl_RaiseXcptOrInt.
    1118  * @{ */
    1119 /** CPU exception. */
    1120 #define IEM_XCPT_FLAGS_T_CPU_XCPT       RT_BIT_32(0)
    1121 /** External interrupt (from PIC, APIC, whatever). */
    1122 #define IEM_XCPT_FLAGS_T_EXT_INT        RT_BIT_32(1)
    1123 /** Software interrupt (int, into or bound). */
    1124 #define IEM_XCPT_FLAGS_T_SOFT_INT       RT_BIT_32(2)
    1125 /** Takes an error code. */
    1126 #define IEM_XCPT_FLAGS_ERR              RT_BIT_32(3)
    1127 /** Takes a CR2. */
    1128 #define IEM_XCPT_FLAGS_CR2              RT_BIT_32(4)
    1129 /** Generated by the breakpoint instruction. */
    1130 #define IEM_XCPT_FLAGS_BP_INSTR         RT_BIT_32(5)
    1131 /** Mask out the nesting level. */
    1132 #define IEM_XCPT_FLAGS_NESTING_MASK     UINT32_C(0xff000000)
    1133 /** Shift count for the nesting level. */
    1134 #define IEM_XCPT_FLAGS_NESTING_SHIFT    24
    1135 /** Mask out the nesting level after shifting. */
    1136 #define IEM_XCPT_FLAGS_NESTING_SMASK    UINT32_C(0x000000ff)
    1137 /** @}  */
    1138 
    1139 
    1140 /**
    1141  * Adjust the CPU state according to the exception being raised.
    1142  *
    1143  * @param   pCtx                The CPU context.
    1144  * @param   u8Vector            The exception that has been raised.
    1145  */
    1146 DECLINLINE(void) iemCImpl_RaiseXcptAdjustState(PCPUMCTX pCtx, uint8_t u8Vector)
    1147 {
    1148     switch (u8Vector)
    1149     {
    1150         case X86_XCPT_DB:
    1151             pCtx->dr[7] &= ~X86_DR7_GD;
    1152             break;
    1153         /** @todo Read the AMD and Intel exception reference... */
    1154     }
    1155 }
    1156 
    1157 
    1158 /**
    1159  * Implements exceptions and interrupts for real mode.
    1160  *
    1161  * @returns VBox strict status code.
    1162  * @param   pIemCpu         The IEM per CPU instance data.
    1163  * @param   pCtx            The CPU context.
    1164  * @param   cbInstr         The number of bytes to offset rIP by in the return
    1165  *                          address.
    1166  * @param   u8Vector        The interrupt / exception vector number.
    1167  * @param   fFlags          The flags.
    1168  * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
    1169  * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
    1170  */
    1171 static VBOXSTRICTRC
    1172 iemCImpl_RaiseXcptOrIntInRealMode(PIEMCPU     pIemCpu,
    1173                                   PCPUMCTX    pCtx,
    1174                                   uint8_t     cbInstr,
    1175                                   uint8_t     u8Vector,
    1176                                   uint32_t    fFlags,
    1177                                   uint16_t    uErr,
    1178                                   uint64_t    uCr2)
    1179 {
    1180     AssertReturn(pIemCpu->enmCpuMode == IEMMODE_16BIT, VERR_INTERNAL_ERROR_3);
    1181 
    1182     /*
    1183      * Read the IDT entry.
    1184      */
    1185     if (pCtx->idtr.cbIdt < UINT32_C(4) * u8Vector + 3)
    1186     {
    1187         Log(("RaiseXcptOrIntInRealMode: %#x is out of bounds (%#x)\n", u8Vector, pCtx->idtr.cbIdt));
    1188         return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
    1189     }
    1190     RTFAR16 Idte;
    1191     VBOXSTRICTRC rcStrict = iemMemFetchDataU32(pIemCpu, (uint32_t *)&Idte, UINT8_MAX,
    1192                                                pCtx->idtr.pIdt + UINT32_C(4) * u8Vector);
    1193     if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
    1194         return rcStrict;
    1195 
    1196     /*
    1197      * Push the stack frame.
    1198      */
    1199     uint16_t *pu16Frame;
    1200     uint64_t  uNewRsp;
    1201     rcStrict = iemMemStackPushBeginSpecial(pIemCpu, 6, (void **)&pu16Frame, &uNewRsp);
    1202     if (rcStrict != VINF_SUCCESS)
    1203         return rcStrict;
    1204 
    1205     pu16Frame[2] = (uint16_t)pCtx->eflags.u;
    1206     pu16Frame[1] = (uint16_t)pCtx->cs;
    1207     pu16Frame[0] = pCtx->ip + cbInstr;
    1208     rcStrict = iemMemStackPushCommitSpecial(pIemCpu, pu16Frame, uNewRsp);
    1209     if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
    1210         return rcStrict;
    1211 
    1212     /*
    1213      * Load the vector address into cs:ip and make exception specific state
    1214      * adjustments.
    1215      */
    1216     pCtx->cs               = Idte.sel;
    1217     pCtx->csHid.u64Base    = (uint32_t)Idte.sel << 4;
    1218     /** @todo do we load attribs and limit as well? Should we check against limit like far jump? */
    1219     pCtx->rip              = Idte.off;
    1220     pCtx->eflags.Bits.u1IF = 0;
    1221 
    1222     /** @todo do we actually do this in real mode? */
    1223     if (fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT)
    1224         iemCImpl_RaiseXcptAdjustState(pCtx, u8Vector);
    1225 
    1226     return VINF_SUCCESS;
    1227 }
    1228 
    1229 
    1230 /**
    1231  * Implements exceptions and interrupts for protected mode.
    1232  *
    1233  * @returns VBox strict status code.
    1234  * @param   pIemCpu         The IEM per CPU instance data.
    1235  * @param   pCtx            The CPU context.
    1236  * @param   cbInstr         The number of bytes to offset rIP by in the return
    1237  *                          address.
    1238  * @param   u8Vector        The interrupt / exception vector number.
    1239  * @param   fFlags          The flags.
    1240  * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
    1241  * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
    1242  */
    1243 static VBOXSTRICTRC
    1244 iemCImpl_RaiseXcptOrIntInProtMode(PIEMCPU     pIemCpu,
    1245                                   PCPUMCTX    pCtx,
    1246                                   uint8_t     cbInstr,
    1247                                   uint8_t     u8Vector,
    1248                                   uint32_t    fFlags,
    1249                                   uint16_t    uErr,
    1250                                   uint64_t    uCr2)
    1251 {
    1252     /*
    1253      * Read the IDT entry.
    1254      */
    1255     if (pCtx->idtr.cbIdt < UINT32_C(8) * u8Vector + 7)
    1256     {
    1257         Log(("RaiseXcptOrIntInProtMode: %#x is out of bounds (%#x)\n", u8Vector, pCtx->idtr.cbIdt));
    1258         return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
    1259     }
    1260     X86DESC Idte;
    1261     VBOXSTRICTRC rcStrict = iemMemFetchDataU64(pIemCpu, &Idte.u, UINT8_MAX,
    1262                                                pCtx->idtr.pIdt + UINT32_C(8) * u8Vector);
    1263     if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
    1264         return rcStrict;
    1265 
    1266     /*
    1267      * Check the descriptor type, DPL and such.
    1268      * ASSUMES this is done in the same order as described for selectors.
    1269      */
    1270     if (Idte.Gate.u1DescType)
    1271     {
    1272         Log(("RaiseXcptOrIntInProtMode %#x - not system selector (%#x) -> #GP\n", u8Vector, Idte.Gate.u4Type));
    1273         return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
    1274     }
    1275     uint32_t fEflToClear = X86_EFL_TF | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM;
    1276     switch (Idte.Gate.u4Type)
    1277     {
    1278         case X86_SEL_TYPE_SYS_UNDEFINED:
    1279         case X86_SEL_TYPE_SYS_286_TSS_AVAIL:
    1280         case X86_SEL_TYPE_SYS_LDT:
    1281         case X86_SEL_TYPE_SYS_286_TSS_BUSY:
    1282         case X86_SEL_TYPE_SYS_286_CALL_GATE:
    1283         case X86_SEL_TYPE_SYS_UNDEFINED2:
    1284         case X86_SEL_TYPE_SYS_386_TSS_AVAIL:
    1285         case X86_SEL_TYPE_SYS_UNDEFINED3:
    1286         case X86_SEL_TYPE_SYS_386_TSS_BUSY:
    1287         case X86_SEL_TYPE_SYS_386_CALL_GATE:
    1288         case X86_SEL_TYPE_SYS_UNDEFINED4:
    1289         {
    1290             /** @todo check what actually happens when the type is wrong...
    1291              *        esp. call gates. */
    1292             Log(("RaiseXcptOrIntInProtMode %#x - invalid type (%#x) -> #GP\n", u8Vector, Idte.Gate.u4Type));
    1293             return iemRaiseGeneralProtectionFault(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
    1294         }
    1295 
    1296         case X86_SEL_TYPE_SYS_286_INT_GATE:
    1297         case X86_SEL_TYPE_SYS_386_INT_GATE:
    1298             fEflToClear |= X86_EFL_IF;
    1299             break;
    1300 
    1301         case X86_SEL_TYPE_SYS_TASK_GATE:
    1302         case X86_SEL_TYPE_SYS_286_TRAP_GATE:
    1303         case X86_SEL_TYPE_SYS_386_TRAP_GATE:
    1304             break;
    1305 
    1306         IEM_NOT_REACHED_DEFAULT_CASE_RET();
    1307     }
    1308 
    1309     /* Check DPL against CPL if applicable. */
    1310     if (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT)
    1311     {
    1312 #if 0 /** @todo continue here */
    1313         if (pIemCpu->uCpl > Desc.Legacy.Gen.u2Dpl)
    1314         {
    1315             Log(("load sreg%u, %#x - CPL (%d) is greater than DPL (%d) -> #GP\n",
    1316                  iSegReg, uSel, pIemCpu->uCpl, Desc.Legacy.Gen.u2Dpl));
    1317             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
    1318         }
    1319 #endif
    1320     }
    1321 
    1322     /* Is it there? */
    1323     if (!Idte.Gate.u1Present)
    1324     {
    1325         Log(("RaiseXcptOrIntInProtMode %#x - not present -> #NP\n", u8Vector));
    1326         return iemRaiseSelectorNotPresentWithErr(pIemCpu, X86_TRAP_ERR_IDT | ((uint16_t)u8Vector << X86_TRAP_ERR_SEL_SHIFT));
    1327     }
    1328 
    1329     return VERR_NOT_IMPLEMENTED;
    1330 }
    1331 
    1332 
    1333 /**
    1334  * Implements exceptions and interrupts for long mode.
    1335  *
    1336  * @returns VBox strict status code.
    1337  * @param   pIemCpu         The IEM per CPU instance data.
    1338  * @param   pCtx            The CPU context.
    1339  * @param   cbInstr         The number of bytes to offset rIP by in the return
    1340  *                          address.
    1341  * @param   u8Vector        The interrupt / exception vector number.
    1342  * @param   fFlags          The flags.
    1343  * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
    1344  * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
    1345  */
    1346 static VBOXSTRICTRC
    1347 iemCImpl_RaiseXcptOrIntInLongMode(PIEMCPU     pIemCpu,
    1348                                   PCPUMCTX    pCtx,
    1349                                   uint8_t     cbInstr,
    1350                                   uint8_t     u8Vector,
    1351                                   uint32_t    fFlags,
    1352                                   uint16_t    uErr,
    1353                                   uint64_t    uCr2)
    1354 {
    1355     AssertMsgFailed(("long mode exception / interrupt dispatching\n"));
    1356     return VERR_NOT_IMPLEMENTED;
    1357 }
    1358 
    1359 
    1360 /**
    1361  * Implements exceptions and interrupts.
    1362  *
    1363  * All exceptions and interrupts goes thru this function!
    1364  *
    1365  * @returns VBox strict status code.
    1366  * @param   pIemCpu         The IEM per CPU instance data.
    1367  * @param   cbInstr         The number of bytes to offset rIP by in the return
    1368  *                          address.
    1369  * @param   u8Vector        The interrupt / exception vector number.
    1370  * @param   fFlags          The flags.
    1371  * @param   uErr            The error value if IEM_XCPT_FLAGS_ERR is set.
    1372  * @param   uCr2            The CR2 value if IEM_XCPT_FLAGS_CR2 is set.
    1373  */
    1374 static VBOXSTRICTRC
    1375 iemCImpl_RaiseXcptOrInt(PIEMCPU     pIemCpu,
    1376                         uint8_t     cbInstr,
    1377                         uint8_t     u8Vector,
    1378                         uint32_t    fFlags,
    1379                         uint16_t    uErr,
    1380                         uint64_t    uCr2)
    1381 {
    1382     /*
    1383      * Do recursion accounting.
    1384      */
    1385     uint8_t uPrevXcpt = pIemCpu->uCurXcpt;
    1386     if (pIemCpu->cXcptRecursions > 0)
    1387     {
    1388         /** @todo double and tripple faults. */
    1389         AssertReturn(pIemCpu->cXcptRecursions < 3, VERR_NOT_IMPLEMENTED);
    1390     }
    1391     pIemCpu->cXcptRecursions++;
    1392     pIemCpu->uCurXcpt = u8Vector;
    1393 
    1394     /*
    1395      * Call mode specific worker function.
    1396      */
    1397     VBOXSTRICTRC    rcStrict;
    1398     PCPUMCTX        pCtx = pIemCpu->CTX_SUFF(pCtx);
    1399     if (!(pCtx->cr0 & X86_CR0_PE))
    1400         rcStrict = iemCImpl_RaiseXcptOrIntInRealMode(pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
    1401     else if (pCtx->msrEFER & MSR_K6_EFER_LMA)
    1402         rcStrict = iemCImpl_RaiseXcptOrIntInLongMode(pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
    1403     else
    1404         rcStrict = iemCImpl_RaiseXcptOrIntInProtMode(pIemCpu, pCtx, cbInstr, u8Vector, fFlags, uErr, uCr2);
    1405 
    1406     /*
    1407      * Unwind.
    1408      */
    1409     pIemCpu->cXcptRecursions--;
    1410     pIemCpu->uCurXcpt = uPrevXcpt;
    1411     return rcStrict;
    1412 }
    1413 
    1414 
    14151117/**
    14161118 * Implements int3 and int XX.
     
    14221124{
    14231125    Assert(pIemCpu->cXcptRecursions == 0);
    1424     return iemCImpl_RaiseXcptOrInt(pIemCpu,
    1425                                    cbInstr,
    1426                                    u8Int,
    1427                                    (fIsBpInstr ? IEM_XCPT_FLAGS_BP_INSTR : 0) | IEM_XCPT_FLAGS_T_SOFT_INT,
    1428                                    0,
    1429                                    0);
     1126    return iemRaiseXcptOrInt(pIemCpu,
     1127                             cbInstr,
     1128                             u8Int,
     1129                             (fIsBpInstr ? IEM_XCPT_FLAGS_BP_INSTR : 0) | IEM_XCPT_FLAGS_T_SOFT_INT,
     1130                             0,
     1131                             0);
    14301132}
    14311133
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