VirtualBox

Changeset 17032 in vbox


Ignore:
Timestamp:
Feb 23, 2009 6:47:03 PM (16 years ago)
Author:
vboxsync
Message:

SELM: Corrected CheckTSS and updated comments+logging.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/SELM.cpp

    r16506 r17032  
    14211421{
    14221422    Assert(enmAccessType == PGMACCESSTYPE_WRITE);
    1423     Log(("selmR3GuestTSSWriteHandler: write to %RGv size %d\n", GCPtr, cbBuf));
     1423    Log(("selmR3GuestTSSWriteHandler: write %.*Rhxs to %RGv size %d\n", RT_MIN(8, cbBuf), pvBuf, GCPtr, cbBuf));
     1424
    14241425    VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
     1426
    14251427    return VINF_PGM_HANDLER_DO_DEFAULT;
    14261428}
     
    14771479                                  || pDesc->Gen.u4Type == X86_SEL_TYPE_SYS_386_TSS_BUSY;
    14781480
    1479         /* Note: We should monitor the whole TSS to catch accesses to the virtual interrupt redirection bitmap, but
    1480          *       that causes some problems and with Windows guests some overhead as the entire TSS is rather big (3 pages).
    1481          *       We'll assume for now that the bitmap is static.
    1482          */
    1483 #if 1
    1484         /* Don't bother with anything but the core structure. (Actually all we care for is the r0 ss.) */
     1481        /*
     1482         * Presently we monitor the TSS and the interrupt redirection bitmap if it's present.
     1483         * We're assuming the guest is playing nice and that the bits we're monitoring won't
     1484         * cross page boundraries. (The TSS core must be on a single page, while the bitmap
     1485         * probably doesn't need to be.)
     1486        */
    14851487        if (cbTss > sizeof(VBOXTSS))
    14861488            cbTss = sizeof(VBOXTSS);
    1487 #endif
    1488         /* The guest's TSS can span multiple pages now. We will monitor the whole thing. */
    1489 #ifndef DEBUG_michael
    1490         AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + RT_MIN(sizeof(VBOXTSS), cbTss) - 1) >> PAGE_SHIFT),
     1489        AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + cbTss - 1) >> PAGE_SHIFT),
    14911490                  ("GCPtrTss=%RGv cbTss=%#x - We assume everything is inside one page!\n", GCPtrTss, cbTss));
    1492 #endif
    14931491
    14941492        // All system GDTs are marked not present above. That explains why this check fails.
     
    15441542            }
    15451543
    1546             /* Update the ring 0 stack selector and base address */
    1547             /* feeling very lazy; reading too much */
    1548             VBOXTSS tss;
    1549             rc = PGMPhysSimpleReadGCPtr(pVM, &tss, GCPtrTss, RT_OFFSETOF(VBOXTSS, offIoBitmap) + sizeof(tss.offIoBitmap));
     1544            /*
     1545             * Update the ring 0 stack selector and base address.
     1546             * (Reading up to and including offIoBitmap to save effort in the VME case.)
     1547             */
     1548            VBOXTSS Tss;
     1549            rc = PGMPhysSimpleReadGCPtr(pVM, &Tss, GCPtrTss, RT_OFFSETOF(VBOXTSS, offIoBitmap) + sizeof(Tss.offIoBitmap));
    15501550            if (RT_SUCCESS(rc))
    15511551            {
    15521552#ifdef LOG_ENABLED
    1553                 uint32_t ssr0, espr0;
    1554 
    1555                 SELMGetRing1Stack(pVM, &ssr0, &espr0);
    1556                 ssr0 &= ~1;
    1557 
    1558                 if (ssr0 != tss.ss0 || espr0 != tss.esp0)
    1559                     Log(("SELMR3SyncTSS: Updating TSS ring 0 stack to %04X:%08X\n", tss.ss0, tss.esp0));
    1560                 Log(("offIoBitmap=%#x\n", tss.offIoBitmap));
     1553                if (LogIsEnabled())
     1554                {
     1555                    uint32_t ssr0, espr0;
     1556                    SELMGetRing1Stack(pVM, &ssr0, &espr0);
     1557                    if ((ssr0 & ~1) != Tss.ss0 || espr0 != Tss.esp0)
     1558                    {
     1559                        RTGCPHYS GCPhys = NIL_RTGCPHYS;
     1560                        rc = PGMGstGetPage(pVM, GCPtrTss, NULL, &GCPhys); AssertRC(rc);
     1561                        Log(("SELMR3SyncTSS: Updating TSS ring 0 stack to %04X:%08X from %04X:%08X; TSS Phys=%VGp)\n",
     1562                             Tss.ss0, Tss.esp0, (ssr0 & ~1), espr0,  GCPhys));
     1563                        AssertMsg(ssr0 != Tss.ss0,
     1564                                  ("ring-1 leak into TSS.SS0! %04X:%08X from %04X:%08X; TSS Phys=%VGp)\n",
     1565                                   Tss.ss0, Tss.esp0, (ssr0 & ~1), espr0,  GCPhys));
     1566                    }
     1567                    Log(("offIoBitmap=%#x\n", Tss.offIoBitmap));
     1568                }
    15611569#endif /* LOG_ENABLED */
     1570                AssertMsg(!(Tss.ss0 & 3), ("ring-1 leak into TSS.SS0? %04X:%08X\n", Tss.ss0, Tss.esp0));
     1571
     1572
    15621573                /* Update our TSS structure for the guest's ring 1 stack */
    1563                 SELMSetRing1Stack(pVM, tss.ss0 | 1, tss.esp0);
    1564 
    1565                 /* Should we sync the virtual interrupt redirection bitmap as well? */
     1574                SELMSetRing1Stack(pVM, Tss.ss0 | 1, Tss.esp0);
     1575
     1576                /*
     1577                 * Should we sync the virtual interrupt redirection bitmap as well?
     1578                 */
    15661579                if (CPUMGetGuestCR4(pVM) & X86_CR4_VME)
    15671580                {
    1568                     uint32_t offRedirBitmap;
    1569 
    15701581                    /* Make sure the io bitmap offset is valid; anything less than sizeof(VBOXTSS) means there's none. */
    1571                     if (tss.offIoBitmap < RT_OFFSETOF(VBOXTSS, IntRedirBitmap) + sizeof(tss.IntRedirBitmap))
     1582                    if (Tss.offIoBitmap < RT_OFFSETOF(VBOXTSS, IntRedirBitmap) + sizeof(Tss.IntRedirBitmap))
    15721583                    {
    1573                         Log(("Invalid io bitmap offset detected (%x)!\n", tss.offIoBitmap));
    1574                         tss.offIoBitmap = RT_OFFSETOF(VBOXTSS, IntRedirBitmap) + sizeof(tss.IntRedirBitmap);
     1584                        Log(("Invalid io bitmap offset detected (%x)!\n", Tss.offIoBitmap));
     1585                        Tss.offIoBitmap = RT_OFFSETOF(VBOXTSS, IntRedirBitmap) + sizeof(Tss.IntRedirBitmap);
    15751586                    }
    15761587
    1577                     offRedirBitmap = tss.offIoBitmap - sizeof(tss.IntRedirBitmap);
     1588                    uint32_t offRedirBitmap = Tss.offIoBitmap - sizeof(Tss.IntRedirBitmap);
    15781589
    15791590                    /** @todo not sure how the partial case is handled; probably not allowed */
    1580                     if (offRedirBitmap + sizeof(tss.IntRedirBitmap) <= pVM->selm.s.cbGuestTss)
     1591                    if (offRedirBitmap + sizeof(Tss.IntRedirBitmap) <= pVM->selm.s.cbGuestTss)
    15811592                    {
    1582                         rc = PGMPhysSimpleReadGCPtr(pVM, &pVM->selm.s.Tss.IntRedirBitmap, GCPtrTss + offRedirBitmap, sizeof(tss.IntRedirBitmap));
     1593                        rc = PGMPhysSimpleReadGCPtr(pVM, &pVM->selm.s.Tss.IntRedirBitmap, GCPtrTss + offRedirBitmap, sizeof(Tss.IntRedirBitmap));
    15831594                        AssertRC(rc);
    15841595                        Log2(("Redirection bitmap:\n"));
    1585                         Log2(("%.*Rhxd\n", sizeof(tss.IntRedirBitmap), &pVM->selm.s.Tss.IntRedirBitmap));
     1596                        Log2(("%.*Rhxd\n", sizeof(Tss.IntRedirBitmap), &pVM->selm.s.Tss.IntRedirBitmap));
    15861597                    }
    15871598                }
     
    17531764{
    17541765#ifdef VBOX_STRICT
     1766    if (VM_FF_ISSET(pVM, VM_FF_SELM_SYNC_TSS))
     1767        return true;
    17551768
    17561769    RTSEL SelTss = CPUMGetGuestTR(pVM);
     
    17681781            cbTss = (cbTss << PAGE_SHIFT) | PAGE_OFFSET_MASK;
    17691782        cbTss++;
    1770 # if 1
    1771         /* Don't bother with anything but the core structure. (Actually all we care for is the r0 ss.) */
     1783
     1784        /*
     1785         * We only care about the Ring-0 ESP and SS values and the interrupt redirection bitmap.
     1786         * See SELMR3SyncTSS for details.
     1787         */
    17721788        if (cbTss > sizeof(VBOXTSS))
    17731789            cbTss = sizeof(VBOXTSS);
    1774 # endif
    1775 # ifndef DEBUG_michael
    1776         AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + sizeof(VBOXTSS) - 1) >> PAGE_SHIFT),
     1790        AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + cbTss - 1) >> PAGE_SHIFT),
    17771791                  ("GCPtrTss=%RGv cbTss=%#x - We assume everything is inside one page!\n", GCPtrTss, cbTss));
    1778 # endif
    17791792
    17801793        // All system GDTs are marked not present above. That explains why this check fails.
     
    18011814            if (RT_SUCCESS(rc))
    18021815            {
    1803                 RTSEL SelSS0;
     1816                RTSEL   SelSS0;
    18041817                rc = PGMPhysSimpleReadGCPtr(pVM, &SelSS0, GCPtrGuestTSS + RT_OFFSETOF(VBOXTSS, ss0), sizeof(SelSS0));
    18051818                if (RT_SUCCESS(rc))
     
    18101823
    18111824                    RTGCPHYS GCPhys;
    1812                     uint64_t fFlags;
    1813 
    1814                     rc = PGMGstGetPage(pVM, GCPtrGuestTSS, &fFlags, &GCPhys);
    1815                     AssertRC(rc);
     1825                    rc = PGMGstGetPage(pVM, GCPtrGuestTSS, NULL, &GCPhys); AssertRC(rc);
    18161826                    AssertMsgFailed(("TSS out of sync!! (%04X:%08X vs %04X:%08X (guest)) Tss=%RGv Phys=%RGp\n",
    18171827                                     (pVM->selm.s.Tss.ss1 & ~1), pVM->selm.s.Tss.esp1, SelSS0, ESPR0, GCPtrGuestTSS, GCPhys));
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