VirtualBox

Changeset 68

Show
Ignore:
Timestamp:
01/16/07 16:16:24 (2 years ago)
Author:
vboxsync
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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; 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy