Changeset 37058 in vbox
- Timestamp:
- May 13, 2011 9:06:40 AM (13 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
-
IEMAll.cpp (modified) (7 diffs)
-
IEMAllCImpl.cpp.h (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r37039 r37058 538 538 *******************************************************************************/ 539 539 static VBOXSTRICTRC iemRaiseTaskSwitchFaultCurrentTSS(PIEMCPU pIemCpu); 540 static VBOXSTRICTRC iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess); 541 static VBOXSTRICTRC iemRaiseSelectorNotPresentBySelector(PIEMCPU pIemCpu, uint16_t uSel); 540 542 static VBOXSTRICTRC iemRaiseSelectorNotPresentWithErr(PIEMCPU pIemCpu, uint16_t uErr); 541 543 static VBOXSTRICTRC iemRaiseGeneralProtectionFault(PIEMCPU pIemCpu, uint16_t uErr); 542 544 static VBOXSTRICTRC iemRaiseGeneralProtectionFault0(PIEMCPU pIemCpu); 545 static VBOXSTRICTRC iemRaiseGeneralProtectionFaultBySelector(PIEMCPU pIemCpu, RTSEL uSel); 543 546 static VBOXSTRICTRC iemRaiseSelectorBounds(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess); 544 547 static VBOXSTRICTRC iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess); 545 static VBOXSTRICTRC iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);546 548 static VBOXSTRICTRC iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc); 547 549 static VBOXSTRICTRC iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); … … 1199 1201 } while (0) 1200 1202 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 */ 1219 static 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 /** @} */ 1201 1282 1202 1283 /** @name Raising Exceptions. … … 1528 1609 /** @todo is the RPL of the interrupt/trap gate descriptor checked? */ 1529 1610 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 1530 1633 /* 1531 1634 * 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... 1532 1636 */ 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 1535 1645 if (uNewCpl != pIemCpu->uCpl) 1536 1646 { 1537 uint32_t uNewEsp; 1538 RTSEL uNewSs; 1539 rcStrict = iemRaiseLoadStackFromTss32Or16(pIemCpu, pCtx, uNewCpl, &uNewSs, &uNewEsp); 1647 rcStrict = iemRaiseLoadStackFromTss32Or16(pIemCpu, pCtx, uNewCpl, &NewSS, &uNewEsp); 1540 1648 if (rcStrict != VINF_SUCCESS) 1541 1649 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 1544 1681 1545 1682 return VERR_NOT_IMPLEMENTED; … … 1741 1878 { 1742 1879 return iemRaiseGeneralProtectionFault(pIemCpu, 0); 1880 } 1881 1882 1883 /** \#GP(sel) - 0d. */ 1884 static VBOXSTRICTRC iemRaiseGeneralProtectionFaultBySelector(PIEMCPU pIemCpu, RTSEL Sel) 1885 { 1886 return iemRaiseGeneralProtectionFault(pIemCpu, Sel & (X86_SEL_MASK | X86_SEL_LDT)); 1743 1887 } 1744 1888 … … 4065 4209 uSel, pCtx->ldtrHid.u32Limit, pCtx->ldtr)); 4066 4210 /** @todo is this the right exception? */ 4067 return iemRaiseGeneralProtectionFault (pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));4211 return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel); 4068 4212 } 4069 4213 … … 4077 4221 Log(("iemMemFetchSelDesc: GDT selector %#x is out of bounds (%3x)\n", uSel, pCtx->gdtr.cbGdt)); 4078 4222 /** @todo is this the right exception? */ 4079 return iemRaiseGeneralProtectionFault (pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));4223 return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel); 4080 4224 } 4081 4225 GCPtrBase = pCtx->gdtr.pGdt; … … 4098 4242 Log(("iemMemFetchSelDesc: system selector %#x is out of bounds\n", uSel)); 4099 4243 /** @todo is this the right exception? */ 4100 return iemRaiseGeneralProtectionFault (pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));4244 return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel); 4101 4245 } 4102 4246 } -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r37039 r37058 723 723 724 724 /* Is it there? */ 725 if (!Desc.Legacy.Gen.u1Present) 725 if (!Desc.Legacy.Gen.u1Present) /** @todo this is probably checked too early. Testcase! */ 726 726 { 727 727 Log(("jmpf %04x:%08x -> segment not present\n", uSel, offSeg)); … … 738 738 { 739 739 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); 741 741 } 742 742 … … 747 747 { 748 748 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); 750 750 } 751 751 … … 757 757 Log(("jmpf %04x:%08x -> DPL violation (conforming); DPL=%d CPL=%u\n", 758 758 uSel, offSeg, Desc.Legacy.Gen.u2Dpl, pIemCpu->uCpl)); 759 return iemRaiseGeneralProtectionFault (pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));759 return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel); 760 760 } 761 761 } … … 765 765 { 766 766 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); 768 768 } 769 769 if ((uSel & X86_SEL_RPL) > pIemCpu->uCpl) 770 770 { 771 771 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); 773 773 } 774 774 } … … 787 787 { 788 788 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); 790 790 } 791 791 u64Base = X86DESC_BASE(Desc.Legacy); … … 834 834 default: 835 835 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); 837 837 838 838 } … … 859 859 default: 860 860 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); 862 862 } 863 863 } … … 1346 1346 { 1347 1347 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); 1349 1349 } 1350 1350 if (iSegReg == X86_SREG_SS) /* SS gets different treatment */ … … 1354 1354 { 1355 1355 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); 1357 1357 } 1358 1358 if ( (Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE) … … 1360 1360 { 1361 1361 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); 1363 1363 } 1364 1364 if ((uSel & X86_SEL_RPL) != pIemCpu->uCpl) 1365 1365 { 1366 1366 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); 1368 1368 } 1369 1369 if (Desc.Legacy.Gen.u2Dpl != pIemCpu->uCpl) 1370 1370 { 1371 1371 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); 1373 1373 } 1374 1374 } … … 1378 1378 { 1379 1379 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); 1381 1381 } 1382 1382 if ( (Desc.Legacy.Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF)) … … 1389 1389 Log(("load sreg%u, %#x - both RPL (%d) and CPL (%d) are greater than DPL (%d) -> #GP\n", 1390 1390 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); 1392 1392 } 1393 1393 #else /* this is what makes more sense. */ … … 1396 1396 Log(("load sreg%u, %#x - RPL (%d) is greater than DPL (%d) -> #GP\n", 1397 1397 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); 1399 1399 } 1400 1400 if (pIemCpu->uCpl > Desc.Legacy.Gen.u2Dpl) … … 1402 1402 Log(("load sreg%u, %#x - CPL (%d) is greater than DPL (%d) -> #GP\n", 1403 1403 iSegReg, uSel, pIemCpu->uCpl, Desc.Legacy.Gen.u2Dpl)); 1404 return iemRaiseGeneralProtectionFault (pIemCpu, uSel & (X86_SEL_MASK | X86_SEL_LDT));1404 return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel); 1405 1405 } 1406 1406 #endif … … 1671 1671 { 1672 1672 Log(("lldt %04x - LDT selector -> #GP\n", uNewLdt)); 1673 return iemRaiseGeneralProtectionFault (pIemCpu, uNewLdt & (X86_SEL_MASK | X86_SEL_LDT));1673 return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewLdt); 1674 1674 } 1675 1675 … … 1780 1780 { 1781 1781 Log(("ltr %04x - LDT selector -> #GP\n", uNewTr)); 1782 return iemRaiseGeneralProtectionFault (pIemCpu, uNewTr & (X86_SEL_MASK | X86_SEL_LDT));1782 return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewTr); 1783 1783 } 1784 1784 if ((uNewTr & X86_SEL_MASK) == 0)
Note:
See TracChangeset
for help on using the changeset viewer.

