VirtualBox

Changeset 37058 in vbox


Ignore:
Timestamp:
May 13, 2011 9:06:40 AM (13 years ago)
Author:
vboxsync
Message:

-> office

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

Legend:

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

    r37039 r37058  
    538538*******************************************************************************/
    539539static VBOXSTRICTRC     iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu);
     540static VBOXSTRICTRC     iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
     541static VBOXSTRICTRC     iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel);
    540542static VBOXSTRICTRC     iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr);
    541543static VBOXSTRICTRC     iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr);
    542544static VBOXSTRICTRC     iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu);
     545static VBOXSTRICTRC     iemRaiseGeneralProtectionFaultBySelector(PIEMCPU pIemCpu, RTSEL uSel);
    543546static VBOXSTRICTRC     iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
    544547static VBOXSTRICTRC     iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
    545 static VBOXSTRICTRC     iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
    546548static VBOXSTRICTRC     iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc);
    547549static VBOXSTRICTRC     iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem);
     
    11991201    } while (0)
    12001202
     1203
     1204/** @name  Misc Worker Functions.
     1205 * @{
     1206 */
     1207
     1208
     1209/**
     1210 * Validates a new SS segment.
     1211 *
     1212 * @returns VBox strict status code.
     1213 * @param   pIemCpu         The IEM per CPU instance data.
     1214 * @param   pCtx            The CPU context.
     1215 * @param   NewSS           The new SS selctor.
     1216 * @param   uCpl            The CPL to load the stack for.
     1217 * @param   pDesc           Where to return the descriptor.
     1218 */
     1219static VBOXSTRICTRC iemMiscValidateNewSS(PIEMCPU pIemCpu, PCCPUMCTX pCtx, RTSEL NewSS, uint8_t uCpl, PIEMSELDESC pDesc)
     1220{
     1221    /* Null selectors are not allowed (we're not called for dispatching
     1222       interrupts with SS=0 in long mode). */
     1223    if (!(NewSS & (X86_SEL_MASK | X86_SEL_LDT)))
     1224    {
     1225        Log(("iemMiscValidateNewSSandRsp: #x - null selector -> #GP(0)\n", NewSS));
     1226        return iemRaiseGeneralProtectionFault0(pIemCpu);
     1227    }
     1228
     1229    /*
     1230     * Read the descriptor.
     1231     */
     1232    VBOXSTRICTRC rcStrict = iemMemFetchSelDesc(pIemCpu, pDesc, NewSS);
     1233    if (rcStrict != VINF_SUCCESS)
     1234        return rcStrict;
     1235
     1236    /*
     1237     * Perform the descriptor validation documented for LSS, POP SS and MOV SS.
     1238     */
     1239    if (!pDesc->Legacy.Gen.u1DescType)
     1240    {
     1241        Log(("iemMiscValidateNewSSandRsp: %#x - system selector -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
     1242        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
     1243    }
     1244
     1245    if (   (pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
     1246        || !(pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
     1247    {
     1248        Log(("iemMiscValidateNewSSandRsp: %#x - code or read only (%#x) -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
     1249        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
     1250    }
     1251    if (    (pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
     1252        || !(pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
     1253    {
     1254        Log(("iemMiscValidateNewSSandRsp: %#x - code or read only (%#x) -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
     1255        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
     1256    }
     1257    /** @todo testcase: check if the TSS.ssX RPL is checked. */
     1258    if ((NewSS & X86_SEL_RPL) != uCpl)
     1259    {
     1260        Log(("iemMiscValidateNewSSandRsp: %#x - RPL and CPL (%d) differs -> #GP\n", NewSS, uCpl));
     1261        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
     1262    }
     1263    if (pDesc->Legacy.Gen.u2Dpl != uCpl)
     1264    {
     1265        Log(("iemMiscValidateNewSSandRsp: %#x - DPL (%d) and CPL (%d) differs -> #GP\n", NewSS, pDesc->Legacy.Gen.u2Dpl, uCpl));
     1266        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
     1267    }
     1268
     1269    /* Is it there? */
     1270    /** @todo testcase: Is this checked before the canonical / limit check below? */
     1271    if (!pDesc->Legacy.Gen.u1Present)
     1272    {
     1273        Log(("iemMiscValidateNewSSandRsp: %#x - segment not present -> #NP\n", NewSS));
     1274        return iemRaiseSelectorNotPresentBySelector(pIemCpu, NewSS);
     1275    }
     1276
     1277    return VINF_SUCCESS;
     1278}
     1279
     1280
     1281/** @}  */
    12011282
    12021283/** @name  Raising Exceptions.
     
    15281609    /** @todo is the RPL of the interrupt/trap gate descriptor checked? */
    15291610
     1611    /* Check the new EIP against the new CS limit. */
     1612    uint32_t const uNewEip =    Idte.Gate.u4Type == X86_SEL_TYPE_SYS_286_INT_GATE
     1613                             || Idte.Gate.u4Type == X86_SEL_TYPE_SYS_286_TRAP_GATE
     1614                           ? Idte.Gate.u16OffsetLow
     1615                           : Idte.Gate.u16OffsetLow | ((uint32_t)Idte.Gate.u16OffsetHigh << 16);
     1616    uint32_t cbLimit = X86DESC_LIMIT(DescCS.Legacy);
     1617    if (DescCS.Legacy.Gen.u1Granularity)
     1618        cbLimit = (cbLimit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     1619    if (uNewEip > X86DESC_LIMIT(DescCS.Legacy))
     1620    {
     1621        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - DPL (%d) > CPL (%d) -> #GP\n",
     1622             u8Vector, NewCS, DescCS.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
     1623        return iemRaiseGeneralProtectionFault(pIemCpu, NewCS & (X86_SEL_MASK | X86_SEL_LDT));
     1624    }
     1625
     1626    /* Make sure the selector is present. */
     1627    if (!DescCS.Legacy.Gen.u1Present)
     1628    {
     1629        Log(("RaiseXcptOrIntInProtMode %#x - CS=%#x - segment not present -> #NP\n", u8Vector, NewCS));
     1630        return iemRaiseSelectorNotPresentBySelector(pIemCpu, NewCS);
     1631    }
     1632
    15301633    /*
    15311634     * If the privilege level changes, we need to get a new stack from the TSS.
     1635     * This in turns means validating the new SS and ESP...
    15321636     */
    1533     uint8_t const uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF
    1534                           ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;
     1637    uint8_t const   uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF
     1638                            ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl;
     1639    uint32_t        uNewEsp;
     1640    RTSEL           NewSS;
     1641    uint32_t        fNewSSAttr;
     1642    uint32_t        cbNewSSLimit;
     1643    uint64_t        uNewSSBase;
     1644
    15351645    if (uNewCpl != pIemCpu->uCpl)
    15361646    {
    1537         uint32_t uNewEsp;
    1538         RTSEL    uNewSs;
    1539         rcStrict = iemRaiseLoadStackFromTss32Or16(pIemCpu, pCtx, uNewCpl, &uNewSs, &uNewEsp);
     1647        rcStrict = iemRaiseLoadStackFromTss32Or16(pIemCpu, pCtx, uNewCpl, &NewSS, &uNewEsp);
    15401648        if (rcStrict != VINF_SUCCESS)
    15411649            return rcStrict;
    1542 
    1543     }
     1650        IEMSELDESC DescSS;
     1651        rcStrict = iemMiscValidateNewSS(pIemCpu, pCtx, NewSS, uNewCpl, &DescSS);
     1652        if (rcStrict != VINF_SUCCESS)
     1653            return rcStrict;
     1654        fNewSSAttr   = X86DESC_GET_HID_ATTR(DescSS.Legacy);
     1655        cbNewSSLimit = X86DESC_LIMIT(DescSS.Legacy);
     1656        if (DescSS.Legacy.Gen.u1Granularity)
     1657            cbNewSSLimit = (cbNewSSLimit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     1658        uNewSSBase   = X86DESC_BASE(DescSS.Legacy);
     1659    }
     1660    else
     1661    {
     1662        uNewEsp      = pCtx->esp;
     1663        NewSS        = pCtx->ss;
     1664        fNewSSAttr   = pCtx->ssHid.Attr.u;
     1665        cbNewSSLimit = pCtx->ssHid.u32Limit;
     1666        uNewSSBase   = pCtx->ssHid.u64Base;
     1667    }
     1668
     1669    /*
     1670     * Check if we have the space for the stack frame.
     1671     */
     1672
     1673
     1674    /*
     1675     * Set the CS and maybe SS accessed bits.
     1676     */
     1677    /** @todo testcase: excatly when is the accessed bit set, before or after
     1678     *        pushing the stack frame. (write protect the gdt + stack to find
     1679     *        out). */
     1680
    15441681
    15451682    return VERR_NOT_IMPLEMENTED;
     
    17411878{
    17421879    return iemRaiseGeneralProtectionFault(pIemCpu, 0);
     1880}
     1881
     1882
     1883/** \#GP(sel) - 0d.  */
     1884static VBOXSTRICTRC iemRaiseGeneralProtectionFaultBySelector(PIEMCPU pIemCpu, RTSEL Sel)
     1885{
     1886    return iemRaiseGeneralProtectionFault(pIemCpu, Sel & (X86_SEL_MASK | X86_SEL_LDT));
    17431887}
    17441888
     
    40654209                 uSel, pCtx->ldtrHid.u32Limit, pCtx->ldtr));
    40664210            /** @todo is this the right exception? */
    4067             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     4211            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    40684212        }
    40694213
     
    40774221            Log(("iemMemFetchSelDesc: GDT selector %#x is out of bounds (%3x)\n", uSel, pCtx->gdtr.cbGdt));
    40784222            /** @todo is this the right exception? */
    4079             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     4223            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    40804224        }
    40814225        GCPtrBase = pCtx->gdtr.pGdt;
     
    40984242            Log(("iemMemFetchSelDesc: system selector %#x is out of bounds\n", uSel));
    40994243            /** @todo is this the right exception? */
    4100             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     4244            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    41014245        }
    41024246    }
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r37039 r37058  
    723723
    724724    /* Is it there? */
    725     if (!Desc.Legacy.Gen.u1Present)
     725    if (!Desc.Legacy.Gen.u1Present) /** @todo this is probably checked too early. Testcase! */
    726726    {
    727727        Log(("jmpf %04x:%08x -> segment not present\n", uSel, offSeg));
     
    738738        {
    739739            Log(("jmpf %04x:%08x -> not a code selector (u4Type=%#x).\n", uSel, offSeg, Desc.Legacy.Gen.u4Type));
    740             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     740            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    741741        }
    742742
     
    747747        {
    748748            Log(("jmpf %04x:%08x -> both L and D are set.\n", uSel, offSeg));
    749             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     749            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    750750        }
    751751
     
    757757                Log(("jmpf %04x:%08x -> DPL violation (conforming); DPL=%d CPL=%u\n",
    758758                     uSel, offSeg, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
    759                 return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     759                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    760760            }
    761761        }
     
    765765            {
    766766                Log(("jmpf %04x:%08x -> CPL != DPL; DPL=%d CPL=%u\n", uSel, offSeg, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
    767                 return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     767                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    768768            }
    769769            if ((uSel & X86_SEL_RPL) > pIemCpu->uCpl)
    770770            {
    771771                Log(("jmpf %04x:%08x -> RPL > DPL; RPL=%d CPL=%u\n", uSel, offSeg, (uSel & X86_SEL_RPL), pIemCpu->uCpl));
    772                 return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     772                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    773773            }
    774774        }
     
    787787            {
    788788                Log(("jmpf %04x:%08x -> out of bounds (%#x)\n", uSel, offSeg, cbLimit));
    789                 return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     789                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    790790            }
    791791            u64Base = X86DESC_BASE(Desc.Legacy);
     
    834834            default:
    835835                Log(("jmpf %04x:%08x -> wrong sys selector (64-bit): %d\n", uSel, offSeg, Desc.Legacy.Gen.u4Type));
    836                 return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     836                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    837837
    838838        }
     
    859859        default:
    860860            Log(("jmpf %04x:%08x -> wrong sys selector (32-bit): %d\n", uSel, offSeg, Desc.Legacy.Gen.u4Type));
    861             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     861            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    862862    }
    863863}
     
    13461346    {
    13471347        Log(("load sreg %d - system selector (%#x) -> #GP\n", iSegReg, uSel, Desc.Legacy.Gen.u4Type));
    1348         return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1348        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    13491349    }
    13501350    if (iSegReg == X86_SREG_SS) /* SS gets different treatment */
     
    13541354        {
    13551355            Log(("load sreg SS, %#x - code or read only (%#x) -> #GP\n", uSel, Desc.Legacy.Gen.u4Type));
    1356             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1356            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    13571357        }
    13581358        if (    (Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
     
    13601360        {
    13611361            Log(("load sreg SS, %#x - code or read only (%#x) -> #GP\n", uSel, Desc.Legacy.Gen.u4Type));
    1362             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1362            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    13631363        }
    13641364        if ((uSel & X86_SEL_RPL) != pIemCpu->uCpl)
    13651365        {
    13661366            Log(("load sreg SS, %#x - RPL and CPL (%d) differs -> #GP\n", uSel, pIemCpu->uCpl));
    1367             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1367            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    13681368        }
    13691369        if (Desc.Legacy.Gen.u2Dpl != pIemCpu->uCpl)
    13701370        {
    13711371            Log(("load sreg SS, %#x - DPL (%d) and CPL (%d) differs -> #GP\n", uSel, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl));
    1372             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1372            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    13731373        }
    13741374    }
     
    13781378        {
    13791379            Log(("load sreg%u, %#x - execute only segment -> #GP\n", iSegReg, uSel));
    1380             return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1380            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    13811381        }
    13821382        if (   (Desc.Legacy.Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
     
    13891389                Log(("load sreg%u, %#x - both RPL (%d) and CPL (%d) are greater than DPL (%d) -> #GP\n",
    13901390                     iSegReg, uSel, (uSel & X86_SEL_RPL), pIemCpu->uCpl, Desc.Legacy.Gen.u2Dpl));
    1391                 return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1391                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    13921392            }
    13931393#else /* this is what makes more sense. */
     
    13961396                Log(("load sreg%u, %#x - RPL (%d) is greater than DPL (%d) -> #GP\n",
    13971397                     iSegReg, uSel, (uSel & X86_SEL_RPL), Desc.Legacy.Gen.u2Dpl));
    1398                 return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1398                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    13991399            }
    14001400            if (pIemCpu->uCpl > Desc.Legacy.Gen.u2Dpl)
     
    14021402                Log(("load sreg%u, %#x - CPL (%d) is greater than DPL (%d) -> #GP\n",
    14031403                     iSegReg, uSel, pIemCpu->uCpl, Desc.Legacy.Gen.u2Dpl));
    1404                 return iemRaiseGeneralProtectionFault(pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));
     1404                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    14051405            }
    14061406#endif
     
    16711671    {
    16721672        Log(("lldt %04x - LDT selector -> #GP\n", uNewLdt));
    1673         return iemRaiseGeneralProtectionFault(pIemCpu, uNewLdt & (X86_SEL_MASK | X86_SEL_LDT));
     1673        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewLdt);
    16741674    }
    16751675
     
    17801780    {
    17811781        Log(("ltr %04x - LDT selector -> #GP\n", uNewTr));
    1782         return iemRaiseGeneralProtectionFault(pIemCpu, uNewTr & (X86_SEL_MASK | X86_SEL_LDT));
     1782        return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewTr);
    17831783    }
    17841784    if ((uNewTr & X86_SEL_MASK) == 0)
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