VirtualBox

Changeset 68 in vbox


Ignore:
Timestamp:
Jan 16, 2007 3:16:24 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
17508
Message:

Sync the TSS ring 0 stack selector and base address on-demand.

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

Legend:

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

    r60 r68  
    6666
    6767/** SELM saved state version. */
    68 #define SELM_SAVED_STATE_VERSION    4
     68#define SELM_SAVED_STATE_VERSION    5
    6969
    7070/*******************************************************************************
     
    139139
    140140    pVM->selm.s.fDisableMonitoring = false;
     141    pVM->selm.s.fSyncTSSRing0Stack = false;
    141142
    142143    /*
     
    506507    pVM->selm.s.cbMonitoredGuestTss = 0;
    507508
     509    pVM->selm.s.fSyncTSSRing0Stack = false;
     510
    508511    /*
    509512     * Default action when entering raw mode for the first time
     
    604607    PSELM pSelm = &pVM->selm.s;
    605608
    606     SSMR3PutUInt(pSSM, pSelm->fDisableMonitoring);
     609    SSMR3PutBool(pSSM, pSelm->fDisableMonitoring);
     610    SSMR3PutBool(pSSM, pSelm->fSyncTSSRing0Stack);
    607611    SSMR3PutSel(pSSM, pSelm->SelCS);
    608612    SSMR3PutSel(pSSM, pSelm->SelDS);
     
    641645
    642646    /* Get the monitoring flag. */
    643     SSMR3GetUInt(pSSM, &pVM->selm.s.fDisableMonitoring);
     647    SSMR3GetBool(pSSM, &pVM->selm.s.fDisableMonitoring);
     648
     649    /* Get the TSS state flag. */
     650    SSMR3GetBool(pSSM, &pVM->selm.s.fSyncTSSRing0Stack);
    644651
    645652    /*
     
    14471454            }
    14481455
    1449             /* Update the ring 0 stack selector and base address */
    1450             /* feeling very lazy; reading too much */
    1451             VBOXTSS tss;
    1452             rc = PGMPhysReadGCPtr(pVM, &tss, GCPtrTss, sizeof(VBOXTSS));
    1453             if (VBOX_FAILURE(rc))
    1454             {
    1455                 /// @todo this might not be as fatal as it seems!
    1456                 AssertReleaseMsgFailed(("Unable to read TSS structure at %08X\n", GCPtrTss));
    1457                 STAM_PROFILE_STOP(&pVM->selm.s.StatTSSSync, a);
    1458                 return VERR_NOT_IMPLEMENTED;
    1459             }
    1460 #ifdef DEBUG
    1461             uint32_t ssr0, espr0;
    1462 
    1463             SELMGetRing1Stack(pVM, &ssr0, &espr0);
    1464             ssr0 &= ~1;
    1465 
    1466             if (ssr0 != tss.ss0 || espr0 != tss.esp0)
    1467             {
    1468                 Log(("SELMR3SyncTSS: Updating TSS ring 0 stack to %04X:%08X\n", tss.ss0, tss.esp0));
    1469             }
    1470 Log(("offIoBitmap=%#x\n", tss.offIoBitmap));
    1471 #endif
    1472             /* Update our TSS structure for the guest's ring 1 stack */
    1473             SELMSetRing1Stack(pVM, tss.ss0 | 1, tss.esp0);
     1456            /** @note the ring 0 stack selector and base address are updated on demand (as it should) */
     1457            pVM->selm.s.fSyncTSSRing0Stack = true;
     1458
    14741459            VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_TSS);
    14751460        }
     
    16701655    }
    16711656
    1672     RTGCPTR     pGuestTSS = pVM->selm.s.GCPtrGuestTss;
    1673     uint32_t    ESPR0;
    1674     int rc = PGMPhysReadGCPtr(pVM, &ESPR0, pGuestTSS + RT_OFFSETOF(VBOXTSS, esp0), sizeof(ESPR0));
    1675     if (VBOX_SUCCESS(rc))
    1676     {
    1677         RTSEL SelSS0;
    1678         rc = PGMPhysReadGCPtr(pVM, &SelSS0, pGuestTSS + RT_OFFSETOF(VBOXTSS, ss0), sizeof(SelSS0));
     1657    if (!pVM->selm.s.fSyncTSSRing0Stack)
     1658    {
     1659        RTGCPTR     pGuestTSS = pVM->selm.s.GCPtrGuestTss;
     1660        uint32_t    ESPR0;
     1661        int rc = PGMPhysReadGCPtr(pVM, &ESPR0, pGuestTSS + RT_OFFSETOF(VBOXTSS, esp0), sizeof(ESPR0));
    16791662        if (VBOX_SUCCESS(rc))
    16801663        {
    1681             if (    ESPR0 == pVM->selm.s.Tss.esp1
    1682                 &&  SelSS0 == (pVM->selm.s.Tss.ss1 & ~1))
    1683                 return true;
    1684 
    1685             RTGCPHYS GCPhys;
    1686             uint64_t fFlags;
    1687 
    1688             rc = PGMGstGetPage(pVM, pGuestTSS, &fFlags, &GCPhys);
    1689             AssertRC(rc);
    1690             AssertMsgFailed(("TSS out of sync!! (%04X:%08X vs %04X:%08X (guest)) Tss=%VGv Phys=%VGp\n",
    1691                              (pVM->selm.s.Tss.ss1 & ~1), pVM->selm.s.Tss.esp1, SelSS0, ESPR0, pGuestTSS, GCPhys));
     1664            RTSEL SelSS0;
     1665            rc = PGMPhysReadGCPtr(pVM, &SelSS0, pGuestTSS + RT_OFFSETOF(VBOXTSS, ss0), sizeof(SelSS0));
     1666            if (VBOX_SUCCESS(rc))
     1667            {
     1668                if (    ESPR0 == pVM->selm.s.Tss.esp1
     1669                    &&  SelSS0 == (pVM->selm.s.Tss.ss1 & ~1))
     1670                    return true;
     1671
     1672                RTGCPHYS GCPhys;
     1673                uint64_t fFlags;
     1674
     1675                rc = PGMGstGetPage(pVM, pGuestTSS, &fFlags, &GCPhys);
     1676                AssertRC(rc);
     1677                AssertMsgFailed(("TSS out of sync!! (%04X:%08X vs %04X:%08X (guest)) Tss=%VGv Phys=%VGp\n",
     1678                                 (pVM->selm.s.Tss.ss1 & ~1), pVM->selm.s.Tss.esp1, SelSS0, ESPR0, pGuestTSS, GCPhys));
     1679            }
     1680            else
     1681                AssertRC(rc);
    16921682        }
    16931683        else
    1694             AssertRC(rc);
    1695     }
    1696     else
    1697         /* Happens during early Windows XP boot when it is switching page tables. */
    1698         Assert(rc == VINF_SUCCESS || ((rc == VERR_PAGE_TABLE_NOT_PRESENT || rc == VERR_PAGE_NOT_PRESENT) && !(CPUMGetGuestEFlags(pVM) & X86_EFL_IF)));
     1684            /* Happens during early Windows XP boot when it is switching page tables. */
     1685            Assert(rc == VINF_SUCCESS || ((rc == VERR_PAGE_TABLE_NOT_PRESENT || rc == VERR_PAGE_NOT_PRESENT) && !(CPUMGetGuestEFlags(pVM) & X86_EFL_IF)));
     1686    }
    16991687    return false;
    17001688#else
  • trunk/src/VBox/VMM/SELMInternal.h

    r23 r68  
    124124
    125125    /** Indicates that the Guest GDT access handler have been registered. */
    126     RTUINT                  fGDTRangeRegistered; /** @todo r=bird: use bool when we mean bool. Just keep in mind that it's a 1 byte byte. */
     126    bool                    fGDTRangeRegistered;
    127127
    128128    /** Indicates whether LDT/GDT/TSS monitoring and syncing is disabled. */
    129     RTUINT                  fDisableMonitoring;
     129    bool                    fDisableMonitoring;
     130
     131    /** Indicates whether the TSS stack selector & base address need to be refreshed.  */
     132    bool                    fSyncTSSRing0Stack;
    130133
    131134    /** SELMR3UpdateFromCPUM() profiling. */
  • trunk/src/VBox/VMM/VMMAll/SELMAll.cpp

    r23 r68  
    3535#include <iprt/assert.h>
    3636#include <VBox/log.h>
     37#include <VBox/pgm.h>
    3738
    3839
     
    499500SELMDECL(void) SELMGetRing1Stack(PVM pVM, uint32_t *pSS, uint32_t *pEsp)
    500501{
     502
     503    if (pVM->selm.s.fSyncTSSRing0Stack)
     504    {
     505        GCPTRTYPE(uint8_t *)GCPtrTss = (GCPTRTYPE(uint8_t *))pVM->selm.s.GCPtrGuestTss;
     506        int     rc;
     507        VBOXTSS tss;
     508
     509        Assert(pVM->selm.s.GCPtrGuestTss && pVM->selm.s.cbMonitoredGuestTss);
     510
     511#ifdef IN_GC
     512        rc  = MMGCRamRead(pVM, &tss.ss0,  GCPtrTss + RT_OFFSETOF(VBOXTSS, ss0), sizeof(tss.ss0));
     513        rc |= MMGCRamRead(pVM, &tss.esp0, GCPtrTss + RT_OFFSETOF(VBOXTSS, esp0), sizeof(tss.esp0));
     514  #ifdef DEBUG
     515        rc |= MMGCRamRead(pVM, &tss.offIoBitmap, GCPtrTss + RT_OFFSETOF(VBOXTSS, offIoBitmap), sizeof(tss.offIoBitmap));
     516  #endif
     517#else /* IN_GC */
     518        /* Reading too much. Could be cheaper than two seperate calls though. */
     519        rc = PGMPhysReadGCPtr(pVM, &tss, GCPtrTss, sizeof(VBOXTSS));
     520#endif /* IN_GC */
     521        if (VBOX_FAILURE(rc))
     522        {
     523            AssertReleaseMsgFailed(("Unable to read TSS structure at %08X\n", GCPtrTss));
     524            return;
     525        }
     526#ifdef DEBUG
     527        uint32_t ssr0  = pVM->selm.s.Tss.ss1;
     528        uint32_t espr0 = pVM->selm.s.Tss.esp1;
     529        ssr0 &= ~1;
     530
     531        if (ssr0 != tss.ss0 || espr0 != tss.esp0)
     532            Log(("SELMGetRing1Stack: Updating TSS ring 0 stack to %04X:%08X\n", tss.ss0, tss.esp0));
     533
     534        Log(("offIoBitmap=%#x\n", tss.offIoBitmap));
     535#endif
     536        /* Update our TSS structure for the guest's ring 1 stack */
     537        SELMSetRing1Stack(pVM, tss.ss0 | 1, tss.esp0);
     538        pVM->selm.s.fSyncTSSRing0Stack = false;
     539    }
     540
    501541    *pSS  = pVM->selm.s.Tss.ss1;
    502542    *pEsp = pVM->selm.s.Tss.esp1;
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