VirtualBox

Changeset 1416 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 12, 2007 12:00:27 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
19422
Message:

Initial code for allowing a fully sized guest GDT.

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

Legend:

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

    r1411 r1416  
    164164    STAM_REG(pVM, &pVM->selm.s.StatUpdateFromCPUM,             STAMTYPE_PROFILE, "/PROF/SELM/UpdateFromCPUM",    STAMUNIT_TICKS_PER_CALL, "Profiling of the SELMR3UpdateFromCPUM() body.");
    165165
     166    STAM_REG(pVM, &pVM->selm.s.StatHyperSelsChanged,           STAMTYPE_COUNTER, "/SELM/HyperSels/Changed",      STAMUNIT_OCCURENCES,     "The number of times we had to relocate our hypervisor selectors.");
     167
    166168    /*
    167169     * Default action when entering raw mode for the first time
     
    227229
    228230/**
    229  * Applies relocations to data and code managed by this
    230  * component. This function will be called at init and
    231  * whenever the VMM need to relocate it self inside the GC.
    232  *
    233  * @param   pVM     The VM.
    234  */
    235 SELMR3DECL(void) SELMR3Relocate(PVM pVM)
    236 {
    237     LogFlow(("SELMR3Relocate\n"));
     231 * Save hypervisor GDT selectors in our shadow table
     232 *
     233 * @param   pVM     The VM handle.
     234 */
     235static void selmR3SaveHyperGDTSelectors(PVM pVM)
     236{
    238237    PVBOXDESC paGdt = pVM->selm.s.paGdtHC;
    239 
    240     /*
    241      * Update GDTR and selector.
    242      */
    243     CPUMSetHyperGDTR(pVM, MMHyperHC2GC(pVM, paGdt), SELM_GDT_ELEMENTS * sizeof(paGdt[0]) - 1);
    244 
    245     /** @todo selector relocations should be a seperate operation? */
    246     CPUMSetHyperCS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]);
    247     CPUMSetHyperDS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);
    248     CPUMSetHyperES(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);
    249     CPUMSetHyperSS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);
    250     CPUMSetHyperTR(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]);
    251238
    252239    /*
     
    338325    pDesc->Gen.u1DefBig         = 0;
    339326    pDesc->Gen.u1Granularity    = 0; /* byte limit */
     327}
     328
     329/**
     330 * Applies relocations to data and code managed by this
     331 * component. This function will be called at init and
     332 * whenever the VMM need to relocate it self inside the GC.
     333 *
     334 * @param   pVM     The VM.
     335 */
     336SELMR3DECL(void) SELMR3Relocate(PVM pVM)
     337{
     338    PVBOXDESC paGdt = pVM->selm.s.paGdtHC;
     339    LogFlow(("SELMR3Relocate\n"));
     340
     341    /*
     342     * Update GDTR and selector.
     343     */
     344    CPUMSetHyperGDTR(pVM, MMHyperHC2GC(pVM, paGdt), SELM_GDT_ELEMENTS * sizeof(paGdt[0]) - 1);
     345
     346    /** @todo selector relocations should be a seperate operation? */
     347    CPUMSetHyperCS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]);
     348    CPUMSetHyperDS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);
     349    CPUMSetHyperES(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);
     350    CPUMSetHyperSS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);
     351    CPUMSetHyperTR(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]);
     352
     353    selmR3SaveHyperGDTSelectors(pVM);
    340354
    341355/** @todo SELM must be called when any of the CR3s changes during a cpu mode change. */
     
    667681    RTSEL SelTSSTrap08;
    668682    SSMR3GetSel(pSSM, &SelTSSTrap08);
    669     if (u32Version == 1)
    670     {
    671         RTSEL SelTSSTrap0a;
    672         int rc = SSMR3GetSel(pSSM, &SelTSSTrap0a);
    673         if (VBOX_FAILURE(rc))
    674             return rc;
    675     }
    676 
    677     /* Check that no selectors have be relocated. */
     683
     684    /* Copy the selectors; they will be checked during relocation. */
    678685    PSELM pSelm = &pVM->selm.s;
    679     if (    SelCS        != pSelm->aHyperSel[SELM_HYPER_SEL_CS]
    680         ||  SelDS        != pSelm->aHyperSel[SELM_HYPER_SEL_DS]
    681         ||  SelCS64      != pSelm->aHyperSel[SELM_HYPER_SEL_CS64]
    682         ||  SelDS64      != pSelm->aHyperSel[SELM_HYPER_SEL_CS64]
    683         ||  SelTSS       != pSelm->aHyperSel[SELM_HYPER_SEL_TSS]
    684         ||  SelTSSTrap08 != pSelm->aHyperSel[SELM_HYPER_SEL_TSS_TRAP08])
    685     {
    686         AssertMsgFailed(("Some selector have been relocated - this cannot happen!\n"));
    687         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    688     }
     686    pSelm->aHyperSel[SELM_HYPER_SEL_CS]         = SelCS;
     687    pSelm->aHyperSel[SELM_HYPER_SEL_DS]         = SelDS;
     688    pSelm->aHyperSel[SELM_HYPER_SEL_CS64]       = SelCS64;
     689    pSelm->aHyperSel[SELM_HYPER_SEL_TSS]        = SelTSS;
     690    pSelm->aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] = SelTSSTrap08;
    689691
    690692    return VINF_SUCCESS;
     
    735737
    736738
     739#if 0 /* obsolete */
    737740/**
    738741 * Sets up the virtualization of a guest GDT.
     
    745748SELMR3DECL(int) SELMR3GdtSetup(PVM pVM, PCVBOXDESC paGDTEs, unsigned cGDTEs)
    746749{
    747     AssertMsg(cGDTEs <= (unsigned)(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] >> 3), ("Oops! the loaded GDT is as large as our.. we assume no clashes!!!\n"));
    748 
    749750    /*
    750751     * Enumerate the array.
     
    772773    return VINF_SUCCESS;
    773774}
    774 
     775#endif
    775776
    776777/**
     
    895896         * Check if the Guest GDT intrudes on our GDT entries.
    896897         */
    897     //    RTSEL aHyperGDT[MAX_NEEDED_HYPERVISOR_GDTS];
    898         if (cbEffLimit >= pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08])
    899         {
    900 #if 0
     898        /** @todo we should try to minimize relocations by making sure our current selectors can be reused. */
     899        RTSEL aHyperGDT[SELM_HYPER_SEL_MAX];
     900        if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE)
     901        {
    901902            PVBOXDESC pGDTEStart = pVM->selm.s.paGdtHC;
    902903            PVBOXDESC pGDTE = (PVBOXDESC)((char *)pGDTEStart + GDTR.cbGdt + 1 - sizeof(VBOXDESC));
    903904            int       iGDT = 0;
    904905
    905             /* Disabling this for now; previously saw triple faults with OS/2, before fixing the above if statement  */
    906906            Log(("Internal SELM GDT conflict: use non-present entries\n"));
    907             while (pGDTE > pGDTEStart && iGDT < MAX_NEEDED_HYPERVISOR_GDTS)
     907            while (pGDTE > pGDTEStart && iGDT < SELM_HYPER_SEL_MAX)
    908908            {
    909909                /* We can reuse non-present entries */
     
    918918                pGDTE--;
    919919            }
    920             if (iGDT != MAX_NEEDED_HYPERVISOR_GDTS)
    921 #endif
     920            if (iGDT != SELM_HYPER_SEL_MAX)
    922921            {
    923922                AssertReleaseMsgFailed(("Internal SELM GDT conflict.\n"));
     
    925924                return VERR_NOT_IMPLEMENTED;
    926925            }
     926        }
     927        else
     928        {
     929            aHyperGDT[SELM_HYPER_SEL_CS]         = SELM_HYPER_DEFAULT_SEL_CS;
     930            aHyperGDT[SELM_HYPER_SEL_DS]         = SELM_HYPER_DEFAULT_SEL_DS;
     931            aHyperGDT[SELM_HYPER_SEL_CS64]       = SELM_HYPER_DEFAULT_SEL_CS64;
     932            aHyperGDT[SELM_HYPER_SEL_TSS]        = SELM_HYPER_DEFAULT_SEL_TSS;
     933            aHyperGDT[SELM_HYPER_SEL_TSS_TRAP08] = SELM_HYPER_DEFAULT_SEL_TSS_TRAP08;
    927934        }
    928935
     
    973980        }
    974981
    975 #if 0 /** @todo r=bird: The relocation code won't be working right. Start with the IF below. */
    976         /*
    977          * Check if the Guest GDT intrudes on our GDT entries.
    978          */
    979         if (cbEffLimit >= pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08])
     982        /*
     983         * Check if our hypervisor selectors were changed.
     984         */
     985        if (    aHyperGDT[SELM_HYPER_SEL_CS]         != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]
     986            ||  aHyperGDT[SELM_HYPER_SEL_DS]         != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]
     987            ||  aHyperGDT[SELM_HYPER_SEL_CS64]       != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64]
     988            ||  aHyperGDT[SELM_HYPER_SEL_TSS]        != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]
     989            ||  aHyperGDT[SELM_HYPER_SEL_TSS_TRAP08] != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08])
    980990        {
    981991            /* Reinitialize our hypervisor GDTs */
    982             pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]        = aHyperGDT[0];
    983             pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]        = aHyperGDT[1];
    984             pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64]      = aHyperGDT[2];
    985             pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]       = aHyperGDT[3];
    986             pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] = aHyperGDT[4];
    987             SELMR3Relocate(pVM); /** @todo r=bird: Must call VMR3Relocate! */
    988         }
    989 #endif
     992            pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]         = aHyperGDT[SELM_HYPER_SEL_CS];
     993            pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]         = aHyperGDT[SELM_HYPER_SEL_DS];
     994            pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64]       = aHyperGDT[SELM_HYPER_SEL_CS64];
     995            pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]        = aHyperGDT[SELM_HYPER_SEL_TSS];
     996            pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] = aHyperGDT[SELM_HYPER_SEL_TSS_TRAP08];
     997
     998            STAM_COUNTER_INC(&pVM->selm.s.StatHyperSelsChanged);
     999            /** Relocate (switcher and selector data needs to update their selectors) */
     1000            VMR3Relocate(pVM, 0);
     1001        }
     1002        else
     1003        if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE)
     1004            /* We overwrote all entries above, so we have to save them again. */
     1005            selmR3SaveHyperGDTSelectors(pVM);
    9901006
    9911007        /*
     
    15451561        return VINF_SUCCESS;
    15461562
    1547 #if 0
    15481563    if (GDTR.cbGdt >= (unsigned)(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] >> X86_SEL_SHIFT))
    1549     {
    1550         AssertReleaseMsgFailed(("Internal SELM GDT conflict.\n"));
    1551         return VERR_NOT_IMPLEMENTED;
    1552     }
    1553 #endif
     1564        Log(("SELMR3DebugCheck: guest GDT size forced us to look for unused selectors.\n"));
    15541565
    15551566    if (GDTR.cbGdt != pVM->selm.s.GuestGdtr.cbGdt)
  • trunk/src/VBox/VMM/SELMInternal.h

    r1411 r1416  
    3939 */
    4040
    41 /** Number of GDTs we need for internal use */
    42 #define MAX_NEEDED_HYPERVISOR_GDTS          5
    43 
    4441/** The number of GDTS allocated for our GDT. (full size) */
    4542#define SELM_GDT_ELEMENTS                   8192
     
    5653/** The TSS selector for taking trap 08 (\#DF). */
    5754#define SELM_HYPER_SEL_TSS_TRAP08           4
     55/** Number of GDTs we need for internal use */
    5856#define SELM_HYPER_SEL_MAX                  (SELM_HYPER_SEL_TSS_TRAP08+1)
     57
     58
     59/** Default GDT selectors we use for the hypervisor. */
     60#define SELM_HYPER_DEFAULT_SEL_CS           ((SELM_GDT_ELEMENTS - 0x1) << 3)
     61#define SELM_HYPER_DEFAULT_SEL_DS           ((SELM_GDT_ELEMENTS - 0x2) << 3)
     62#define SELM_HYPER_DEFAULT_SEL_CS64         ((SELM_GDT_ELEMENTS - 0x3) << 3)
     63#define SELM_HYPER_DEFAULT_SEL_TSS          ((SELM_GDT_ELEMENTS - 0x4) << 3)
     64#define SELM_HYPER_DEFAULT_SEL_TSS_TRAP08   ((SELM_GDT_ELEMENTS - 0x5) << 3)
     65/** @note SELM_HYPER_DEFAULT_BASE is the lowest value we use. */
     66#define SELM_HYPER_DEFAULT_BASE             SELM_HYPER_DEFAULT_SEL_TSS_TRAP08
    5967
    6068/**
     
    156164    /** GC: The number of unhandled write to the Guest's TSS. */
    157165    STAMCOUNTER             StatGCWriteGuestTSSUnhandled;
     166    /** The number of times we had to relocate our hypervisor selectors. */
     167    STAMCOUNTER             StatHyperSelsChanged;
    158168} SELM, *PSELM;
    159169
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