VirtualBox

Changeset 13577 in vbox for trunk/src


Ignore:
Timestamp:
Oct 27, 2008 1:53:04 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
38476
Message:

#1865: SELM.

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

Legend:

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

    r13232 r13577  
    11/* $Id$ */
    22/** @file
    3  * SELM - The Selector manager.
     3 * SELM - The Selector Manager.
    44 */
    55
     
    2222/** @page pg_selm   SELM - The Selector Manager
    2323 *
    24  * Manages the hypervisor GDT entires, monitors and shadows the guest GDT, LDT
    25  * and TSS. Only active in raw-mode.
     24 * SELM takes care of GDT, LDT and TSS shadowing in raw-mode, and the injection
     25 * of a few hyper selector for the raw-mode context.  In the hardware assisted
     26 * virtualization mode its only task is to decode entries in the guest GDT or
     27 * LDT once in a while.
    2628 *
    2729 * @see grp_selm
     30 *
     31 *
     32 * @section seg_selm_shadowing   Shadowing
     33 *
     34 * SELMR3UpdateFromCPUM() and SELMR3SyncTSS() does the bulk synchronization
     35 * work.  The three structures (GDT, LDT, TSS) are all shadowed wholesale atm.
     36 * The idea is to do it in a more on-demand fashion when we get time.  There
     37 * also a whole bunch of issues with the current synchronization of all three
     38 * tables, see notes and todos in the code.
     39 *
     40 * When the guest makes changes to the GDT we will try update the shadow copy
     41 * without involving SELMR3UpdateFromCPUM(), see selmGCSyncGDTEntry().
     42 *
     43 * When the guest make LDT changes we'll trigger a full resync of the LDT
     44 * (SELMR3UpdateFromCPUM()), which, needless to say, isn't optimal.
     45 *
     46 * The TSS shadowing is limited to the fields we need to care about, namely SS0
     47 * and ESP0.  The Patch Manager makes use of these.  We monitor updates to the
     48 * guest TSS and will try keep our SS0 and ESP0 copies up to date this way
     49 * rather than go the SELMR3SyncTSS() route.
     50 *
     51 * When in raw-mode SELM also injects a few extra GDT selectors which are used
     52 * by the raw-mode (hyper) context.  These start their life at the high end of
     53 * the table and will be relocated when the guest tries to make use of them...
     54 * Well, that was that idea at least, only the code isn't quite there yet which
     55 * is why we have trouble with guests which actually have a full sized GDT.
     56 *
     57 * So, the summary of the current GDT, LDT and TSS shadowing is that there is a
     58 * lot of relatively simple and enjoyable work to be done, see @bugref{3267}.
    2859 *
    2960 */
     
    76107#define SELM_SAVED_STATE_VERSION    5
    77108
     109
    78110/*******************************************************************************
    79111*   Internal Functions                                                         *
    80112*******************************************************************************/
    81 static DECLCALLBACK(int) selmR3Save(PVM pVM, PSSMHANDLE pSSM);
    82 static DECLCALLBACK(int) selmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version);
    83 static DECLCALLBACK(int) selmR3LoadDone(PVM pVM, PSSMHANDLE pSSM);
     113static DECLCALLBACK(int)  selmR3Save(PVM pVM, PSSMHANDLE pSSM);
     114static DECLCALLBACK(int)  selmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version);
     115static DECLCALLBACK(int)  selmR3LoadDone(PVM pVM, PSSMHANDLE pSSM);
     116static DECLCALLBACK(int)  selmR3GuestGDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
     117static DECLCALLBACK(int)  selmR3GuestLDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
     118static DECLCALLBACK(int)  selmR3GuestTSSWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
    84119static DECLCALLBACK(void) selmR3InfoGdt(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    85120static DECLCALLBACK(void) selmR3InfoGdtGuest(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
     
    88123//static DECLCALLBACK(void) selmR3InfoTss(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    89124//static DECLCALLBACK(void) selmR3InfoTssGuest(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    90 static DECLCALLBACK(int) selmGuestGDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
    91 static DECLCALLBACK(int) selmGuestLDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
    92 static DECLCALLBACK(int) selmGuestTSSWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
    93125
    94126
     
    131163     * Allocate GDT table.
    132164     */
    133     int rc = MMR3HyperAllocOnceNoRel(pVM, sizeof(pVM->selm.s.paGdtHC[0]) * SELM_GDT_ELEMENTS,
    134                                      PAGE_SIZE, MM_TAG_SELM, (void **)&pVM->selm.s.paGdtHC);
     165    int rc = MMR3HyperAllocOnceNoRel(pVM, sizeof(pVM->selm.s.paGdtR3[0]) * SELM_GDT_ELEMENTS,
     166                                     PAGE_SIZE, MM_TAG_SELM, (void **)&pVM->selm.s.paGdtR3);
    135167    AssertRCReturn(rc, rc);
    136168
     
    138170     * Allocate LDT area.
    139171     */
    140     rc = MMR3HyperAllocOnceNoRel(pVM, _64K + PAGE_SIZE, PAGE_SIZE, MM_TAG_SELM, &pVM->selm.s.HCPtrLdt);
     172    rc = MMR3HyperAllocOnceNoRel(pVM, _64K + PAGE_SIZE, PAGE_SIZE, MM_TAG_SELM, &pVM->selm.s.pvLdtR3);
    141173    AssertRCReturn(rc, rc);
    142174
     
    149181    pVM->selm.s.GCPtrGuestTss      = RTRCPTR_MAX;
    150182
    151     pVM->selm.s.paGdtGC            = 0;
    152     pVM->selm.s.GCPtrLdt           = RTRCPTR_MAX;
    153     pVM->selm.s.GCPtrTss           = RTRCPTR_MAX;
    154     pVM->selm.s.GCSelTss           = ~0;
     183    pVM->selm.s.paGdtRC            = NIL_RTRCPTR; /* Must be set in SELMR3Relocate because of monitoring. */
     184    pVM->selm.s.pvLdtRC            = RTRCPTR_MAX;
     185    pVM->selm.s.pvMonShwTssRC      = RTRCPTR_MAX;
     186    pVM->selm.s.GCSelTss           = RTSEL_MAX;
    155187
    156188    pVM->selm.s.fDisableMonitoring = false;
     
    175207     * Statistics.
    176208     */
    177     STAM_REG(pVM, &pVM->selm.s.StatGCWriteGuestGDTHandled,     STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/GDTInt",  STAMUNIT_OCCURENCES,     "The number of handled writes to the Guest GDT.");
    178     STAM_REG(pVM, &pVM->selm.s.StatGCWriteGuestGDTUnhandled,   STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/GDTEmu",  STAMUNIT_OCCURENCES,     "The number of unhandled writes to the Guest GDT.");
    179     STAM_REG(pVM, &pVM->selm.s.StatGCWriteGuestLDT,            STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/LDT",     STAMUNIT_OCCURENCES,     "The number of writes to the Guest LDT was detected.");
    180     STAM_REG(pVM, &pVM->selm.s.StatGCWriteGuestTSSHandled,     STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/TSSInt",  STAMUNIT_OCCURENCES,     "The number of handled writes to the Guest TSS.");
    181     STAM_REG(pVM, &pVM->selm.s.StatGCWriteGuestTSSRedir,       STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/TSSRedir",STAMUNIT_OCCURENCES,     "The number of handled redir bitmap writes to the Guest TSS.");
    182     STAM_REG(pVM, &pVM->selm.s.StatGCWriteGuestTSSHandledChanged,STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/TSSIntChg", STAMUNIT_OCCURENCES, "The number of handled writes to the Guest TSS where the R0 stack changed.");
    183     STAM_REG(pVM, &pVM->selm.s.StatGCWriteGuestTSSUnhandled,   STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/TSSEmu",  STAMUNIT_OCCURENCES,     "The number of unhandled writes to the Guest TSS.");
     209    STAM_REG(pVM, &pVM->selm.s.StatRCWriteGuestGDTHandled,     STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/GDTInt",  STAMUNIT_OCCURENCES,     "The number of handled writes to the Guest GDT.");
     210    STAM_REG(pVM, &pVM->selm.s.StatRCWriteGuestGDTUnhandled,   STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/GDTEmu",  STAMUNIT_OCCURENCES,     "The number of unhandled writes to the Guest GDT.");
     211    STAM_REG(pVM, &pVM->selm.s.StatRCWriteGuestLDT,            STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/LDT",     STAMUNIT_OCCURENCES,     "The number of writes to the Guest LDT was detected.");
     212    STAM_REG(pVM, &pVM->selm.s.StatRCWriteGuestTSSHandled,     STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/TSSInt",  STAMUNIT_OCCURENCES,     "The number of handled writes to the Guest TSS.");
     213    STAM_REG(pVM, &pVM->selm.s.StatRCWriteGuestTSSRedir,       STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/TSSRedir",STAMUNIT_OCCURENCES,     "The number of handled redir bitmap writes to the Guest TSS.");
     214    STAM_REG(pVM, &pVM->selm.s.StatRCWriteGuestTSSHandledChanged,STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/TSSIntChg", STAMUNIT_OCCURENCES, "The number of handled writes to the Guest TSS where the R0 stack changed.");
     215    STAM_REG(pVM, &pVM->selm.s.StatRCWriteGuestTSSUnhandled,   STAMTYPE_COUNTER, "/SELM/GC/Write/Guest/TSSEmu",  STAMUNIT_OCCURENCES,     "The number of unhandled writes to the Guest TSS.");
    184216    STAM_REG(pVM, &pVM->selm.s.StatTSSSync,                    STAMTYPE_PROFILE, "/PROF/SELM/TSSSync",           STAMUNIT_TICKS_PER_CALL, "Profiling of the SELMR3SyncTSS() body.");
    185217    STAM_REG(pVM, &pVM->selm.s.StatUpdateFromCPUM,             STAMTYPE_PROFILE, "/PROF/SELM/UpdateFromCPUM",    STAMUNIT_TICKS_PER_CALL, "Profiling of the SELMR3UpdateFromCPUM() body.");
     
    217249VMMR3DECL(int) SELMR3InitFinalize(PVM pVM)
    218250{
    219     /*
    220      * Make Double Fault work with WP enabled?
    221      *
    222      * The double fault is a task switch and thus requires write access to the GDT of the TSS
    223      * (to set it busy), to the old TSS (to store state), and to the Trap 8 TSS for the back link.
    224      *
    225      * Since we in enabling write access to these pages make ourself vulnerable to attacks,
    226      * it is not possible to do this by default.
     251    /** @cfgm{/DoubleFault,bool,false}
     252     * Enables catching of double faults in the raw-mode context VMM code.  This can
     253     * be used when the tripple faults or hangs occure and one suspect an unhandled
     254     * double fault.  This is not enabled by default because it means making the
     255     * hyper selectors writeable for all supervisor code, including the guest's.
     256     * The double fault is a task switch and thus requires write access to the GDT
     257     * of the TSS (to set it busy), to the old TSS (to store state), and to the Trap
     258     * 8 TSS for the back link.
    227259     */
    228260    bool f;
    229     int rc = CFGMR3QueryBool(CFGMR3GetRoot(pVM), "DoubleFault", &f);
    230 #if !defined(DEBUG_bird)
    231     if (VBOX_SUCCESS(rc) && f)
     261#if defined(DEBUG_bird)
     262    int rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "DoubleFault", &f, true);
     263#else
     264    int rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "DoubleFault", &f, false);
    232265#endif
    233     {
    234         PX86DESC paGdt = pVM->selm.s.paGdtHC;
     266    AssertLogRelRCReturn(rc, rc);
     267    if (f)
     268    {
     269        PX86DESC paGdt = pVM->selm.s.paGdtR3;
    235270        rc = PGMMapSetPage(pVM, MMHyperHC2GC(pVM, &paGdt[pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] >> 3]), sizeof(paGdt[0]),
    236271                           X86_PTE_RW | X86_PTE_P | X86_PTE_A | X86_PTE_D);
     
    257292static void selmR3SetupHyperGDTSelectors(PVM pVM)
    258293{
    259     PX86DESC paGdt = pVM->selm.s.paGdtHC;
     294    PX86DESC paGdt = pVM->selm.s.paGdtR3;
    260295
    261296    /*
     
    358393VMMR3DECL(void) SELMR3Relocate(PVM pVM)
    359394{
    360     PX86DESC paGdt = pVM->selm.s.paGdtHC;
     395    PX86DESC paGdt = pVM->selm.s.paGdtR3;
    361396    LogFlow(("SELMR3Relocate\n"));
    362397
     
    419454        int rc;
    420455#ifdef SELM_TRACK_SHADOW_GDT_CHANGES
    421         if (pVM->selm.s.paGdtGC != 0)
    422         {
    423             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.paGdtGC);
     456        if (pVM->selm.s.paGdtRC != NIL_RTRCPTR)
     457        {
     458            rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.paGdtRC);
    424459            AssertRC(rc);
    425460        }
    426         pVM->selm.s.paGdtGC = MMHyperHC2GC(pVM, paGdt);
    427         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.paGdtGC,
    428                                          pVM->selm.s.paGdtGC + SELM_GDT_ELEMENTS * sizeof(paGdt[0]) - 1,
    429                                          0, 0, "selmgcShadowGDTWriteHandler", 0, "Shadow GDT write access handler");
     461        pVM->selm.s.paGdtRC = MMHyperR3ToRC(pVM, paGdt);
     462        rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.paGdtRC,
     463                                         pVM->selm.s.paGdtRC + SELM_GDT_ELEMENTS * sizeof(paGdt[0]) - 1,
     464                                         0, 0, "selmRCShadowGDTWriteHandler", 0, "Shadow GDT write access handler");
    430465        AssertRC(rc);
    431466#endif
    432467#ifdef SELM_TRACK_SHADOW_TSS_CHANGES
    433         if (pVM->selm.s.GCPtrTss != RTRCPTR_MAX)
    434         {
    435             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrTss);
     468        if (pVM->selm.s.pvMonShwTssRC != RTRCPTR_MAX)
     469        {
     470            rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.pvMonShwTssRC);
    436471            AssertRC(rc);
    437472        }
    438         pVM->selm.s.GCPtrTss = VM_GUEST_ADDR(pVM, &pVM->selm.s.Tss);
    439         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.GCPtrTss,
    440                                          pVM->selm.s.GCPtrTss + sizeof(pVM->selm.s.Tss) - 1,
    441                                          0, 0, "selmgcShadowTSSWriteHandler", 0, "Shadow TSS write access handler");
     473        pVM->selm.s.pvMonShwTssRC = VM_RC_ADDR(pVM, &pVM->selm.s.Tss);
     474        rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.pvMonShwTssRC,
     475                                         pVM->selm.s.pvMonShwTssRC + sizeof(pVM->selm.s.Tss) - 1,
     476                                         0, 0, "selmRCShadowTSSWriteHandler", 0, "Shadow TSS write access handler");
    442477        AssertRC(rc);
    443478#endif
     
    447482         */
    448483#ifdef SELM_TRACK_SHADOW_LDT_CHANGES
    449         if (pVM->selm.s.GCPtrLdt != RTRCPTR_MAX)
    450         {
    451             rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrLdt);
     484        if (pVM->selm.s.pvLdtRC != RTRCPTR_MAX)
     485        {
     486            rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.pvLdtRC);
    452487            AssertRC(rc);
    453488        }
    454489#endif
    455         pVM->selm.s.GCPtrLdt = MMHyperHC2GC(pVM, pVM->selm.s.HCPtrLdt);
     490        pVM->selm.s.pvLdtRC = MMHyperR3ToRC(pVM, pVM->selm.s.pvLdtR3);
    456491#ifdef SELM_TRACK_SHADOW_LDT_CHANGES
    457         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.GCPtrLdt,
    458                                          pVM->selm.s.GCPtrLdt + _64K + PAGE_SIZE - 1,
    459                                          0, 0, "selmgcShadowLDTWriteHandler", 0, "Shadow LDT write access handler");
     492        rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->selm.s.pvLdtRC,
     493                                         pVM->selm.s.pvLdtRC + _64K + PAGE_SIZE - 1,
     494                                         0, 0, "selmRCShadowLDTWriteHandler", 0, "Shadow LDT write access handler");
    460495        AssertRC(rc);
    461496#endif
     
    534569        AssertRC(rc);
    535570        pVM->selm.s.GCPtrGuestTss = RTRCPTR_MAX;
    536         pVM->selm.s.GCSelTss      = ~0;
     571        pVM->selm.s.GCSelTss      = RTSEL_MAX;
    537572    }
    538573#endif
     
    590625        AssertRC(rc);
    591626        pVM->selm.s.GCPtrGuestTss = RTRCPTR_MAX;
    592         pVM->selm.s.GCSelTss      = ~0;
     627        pVM->selm.s.GCSelTss      = RTSEL_MAX;
    593628    }
    594629#endif
     
    598633     */
    599634#ifdef SELM_TRACK_SHADOW_GDT_CHANGES
    600     if (pVM->selm.s.paGdtGC != 0)
    601     {
    602         rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.paGdtGC);
     635    if (pVM->selm.s.paGdtRC != NIL_RTRCPTR)
     636    {
     637        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.paGdtRC);
    603638        AssertRC(rc);
    604         pVM->selm.s.paGdtGC = 0;
     639        pVM->selm.s.paGdtRC = NIL_RTRCPTR;
    605640    }
    606641#endif
    607642#ifdef SELM_TRACK_SHADOW_TSS_CHANGES
    608     if (pVM->selm.s.GCPtrTss != RTRCPTR_MAX)
    609     {
    610         rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrTss);
     643    if (pVM->selm.s.pvMonShwTssRC != RTRCPTR_MAX)
     644    {
     645        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.pvMonShwTssRC);
    611646        AssertRC(rc);
    612         pVM->selm.s.GCPtrTss = RTRCPTR_MAX;
     647        pVM->selm.s.pvMonShwTssRC = RTRCPTR_MAX;
    613648    }
    614649#endif
    615650#ifdef SELM_TRACK_SHADOW_LDT_CHANGES
    616     if (pVM->selm.s.GCPtrLdt != RTRCPTR_MAX)
    617     {
    618         rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrLdt);
     651    if (pVM->selm.s.pvLdtRC != RTRCPTR_MAX)
     652    {
     653        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.pvLdtRC);
    619654        AssertRC(rc);
    620         pVM->selm.s.GCPtrLdt = RTRCPTR_MAX;
     655        pVM->selm.s.pvLdtRC = RTRCPTR_MAX;
    621656    }
    622657#endif
     
    628663    pVM->selm.s.fDisableMonitoring = true;
    629664}
     665
    630666
    631667/**
     
    650686    SSMR3PutSel(pSSM, pSelm->aHyperSel[SELM_HYPER_SEL_DS]);
    651687    SSMR3PutSel(pSSM, pSelm->aHyperSel[SELM_HYPER_SEL_CS64]);
    652     SSMR3PutSel(pSSM, pSelm->aHyperSel[SELM_HYPER_SEL_CS64]); //reserved for DS64.
     688    SSMR3PutSel(pSSM, pSelm->aHyperSel[SELM_HYPER_SEL_CS64]); /* reserved for DS64. */
    653689    SSMR3PutSel(pSSM, pSelm->aHyperSel[SELM_HYPER_SEL_TSS]);
    654690    return SSMR3PutSel(pSSM, pSelm->aHyperSel[SELM_HYPER_SEL_TSS_TRAP08]);
     
    813849         */
    814850        RTUINT      cbEffLimit = GDTR.cbGdt;
    815         PX86DESC   pGDTE = &pVM->selm.s.paGdtHC[1];
     851        PX86DESC   pGDTE = &pVM->selm.s.paGdtR3[1];
    816852        rc = PGMPhysSimpleReadGCPtr(pVM, pGDTE, GDTR.pGdt + sizeof(X86DESC), cbEffLimit + 1 - sizeof(X86DESC));
    817853        if (VBOX_FAILURE(rc))
     
    828864            RTUINT  cbLeft = cbEffLimit + 1 - sizeof(X86DESC);
    829865            RTGCPTR GCPtrSrc = (RTGCPTR)GDTR.pGdt + sizeof(X86DESC);
    830             uint8_t *pu8Dst = (uint8_t *)&pVM->selm.s.paGdtHC[1];
     866            uint8_t *pu8Dst = (uint8_t *)&pVM->selm.s.paGdtR3[1];
    831867            uint8_t *pu8DstInvalid = pu8Dst;
    832868
     
    862898            if (pu8DstInvalid != pu8Dst)
    863899            {
    864                 cbEffLimit = pu8DstInvalid - (uint8_t *)pVM->selm.s.paGdtHC - 1;
     900                cbEffLimit = pu8DstInvalid - (uint8_t *)pVM->selm.s.paGdtR3 - 1;
    865901                /* If any GDTEs was invalidated, zero them. */
    866902                if (cbEffLimit < pVM->selm.s.cbEffGuestGdtLimit)
     
    884920        if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE)
    885921        {
    886             PX86DESC pGDTEStart = pVM->selm.s.paGdtHC;
     922            PX86DESC pGDTEStart = pVM->selm.s.paGdtR3;
    887923            PX86DESC pGDTE = (PX86DESC)((char *)pGDTEStart + GDTR.cbGdt + 1 - sizeof(X86DESC));
    888924            int       iGDT = 0;
     
    895931                if (!pGDTE->Gen.u1Present)
    896932                {
    897                     aHyperSel[iGDT] = ((uintptr_t)pGDTE - (uintptr_t)pVM->selm.s.paGdtHC) / sizeof(X86DESC);
     933                    aHyperSel[iGDT] = ((uintptr_t)pGDTE - (uintptr_t)pVM->selm.s.paGdtR3) / sizeof(X86DESC);
    898934                    aHyperSel[iGDT] = aHyperSel[iGDT] << X86_SEL_SHIFT;
    899935                    Log(("SELM: Found unused GDT %04X\n", aHyperSel[iGDT]));
     
    10271063
    10281064            rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GDTR.pGdt, GDTR.pGdt + GDTR.cbGdt /* already inclusive */,
    1029                                              0, selmGuestGDTWriteHandler, "selmgcGuestGDTWriteHandler", 0, "Guest GDT write access handler");
     1065                                             0, selmR3GuestGDTWriteHandler, "selmRCGuestGDTWriteHandler", 0, "Guest GDT write access handler");
    10301066            if (VBOX_FAILURE(rc))
    10311067                return rc;
     
    10911127         * Get the LDT selector.
    10921128         */
    1093         PX86DESC   pDesc = &pVM->selm.s.paGdtHC[SelLdt >> X86_SEL_SHIFT];
     1129        PX86DESC    pDesc = &pVM->selm.s.paGdtR3[SelLdt >> X86_SEL_SHIFT];
    10941130        RTGCPTR     GCPtrLdt = X86DESC_BASE(*pDesc);
    10951131        unsigned    cbLdt = X86DESC_LIMIT(*pDesc);
     
    11301166         * (this is necessary due to redundant LDT updates; see todo above at GDT sync)
    11311167         */
    1132         if (MMHyperIsInsideArea(pVM, GCPtrLdt) == true)
     1168        if (MMHyperIsInsideArea(pVM, GCPtrLdt))
    11331169            GCPtrLdt = pVM->selm.s.GCPtrGuestLdt;   /* use the old one */
    11341170
     
    11611197#endif
    11621198                rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrLdt, GCPtrLdt + cbLdt /* already inclusive */,
    1163                                                  0, selmGuestLDTWriteHandler, "selmgcGuestLDTWriteHandler", 0, "Guest LDT write access handler");
     1199                                                 0, selmR3GuestLDTWriteHandler, "selmRCGuestLDTWriteHandler", 0, "Guest LDT write access handler");
    11641200                if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
    11651201                {
     
    11901226        unsigned    off;
    11911227        pVM->selm.s.offLdtHyper = off = (GCPtrLdt & PAGE_OFFSET_MASK);
    1192         RTGCPTR     GCPtrShadowLDT  = (RTGCPTR)((RTGCUINTPTR)pVM->selm.s.GCPtrLdt + off);
    1193         PX86DESC   pShadowLDT      = (PX86DESC)((uintptr_t)pVM->selm.s.HCPtrLdt + off);
     1228        RTGCPTR     GCPtrShadowLDT  = (RTGCPTR)((RTGCUINTPTR)pVM->selm.s.pvLdtRC + off);
     1229        PX86DESC    pShadowLDT      = (PX86DESC)((uintptr_t)pVM->selm.s.pvLdtR3 + off);
    11941230
    11951231        /*
     
    12951331            else
    12961332            {
    1297                 AssertMsg(rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT, ("rc=%d\n", rc));
     1333                AssertMsg(rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT, ("rc=%Rrc\n", rc));
    12981334                rc = PGMMapSetPage(pVM, GCPtrShadowLDT & PAGE_BASE_GC_MASK, PAGE_SIZE, 0);
    12991335                AssertRC(rc);
     
    13311367 * @param   pvUser          User argument.
    13321368 */
    1333 static DECLCALLBACK(int) selmGuestGDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
     1369static DECLCALLBACK(int) selmR3GuestGDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
    13341370{
    13351371    Assert(enmAccessType == PGMACCESSTYPE_WRITE);
    1336     Log(("selmGuestGDTWriteHandler: write to %VGv size %d\n", GCPtr, cbBuf));
     1372    Log(("selmR3GuestGDTWriteHandler: write to %VGv size %d\n", GCPtr, cbBuf));
    13371373    VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
    13381374
    13391375    return VINF_PGM_HANDLER_DO_DEFAULT;
    13401376}
     1377
    13411378
    13421379/**
     
    13561393 * @param   pvUser          User argument.
    13571394 */
    1358 static DECLCALLBACK(int) selmGuestLDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
     1395static DECLCALLBACK(int) selmR3GuestLDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
    13591396{
    13601397    Assert(enmAccessType == PGMACCESSTYPE_WRITE);
    1361     Log(("selmGuestLDTWriteHandler: write to %VGv size %d\n", GCPtr, cbBuf));
     1398    Log(("selmR3GuestLDTWriteHandler: write to %VGv size %d\n", GCPtr, cbBuf));
    13621399    VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
    13631400    return VINF_PGM_HANDLER_DO_DEFAULT;
    13641401}
     1402
    13651403
    13661404/**
     
    13801418 * @param   pvUser          User argument.
    13811419 */
    1382 static DECLCALLBACK(int) selmGuestTSSWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
     1420static DECLCALLBACK(int) selmR3GuestTSSWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
    13831421{
    13841422    Assert(enmAccessType == PGMACCESSTYPE_WRITE);
    1385     Log(("selmGuestTSSWriteHandler: write to %VGv size %d\n", GCPtr, cbBuf));
     1423    Log(("selmR3GuestTSSWriteHandler: write to %VGv size %d\n", GCPtr, cbBuf));
    13861424    VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
    13871425    return VINF_PGM_HANDLER_DO_DEFAULT;
    13881426}
     1427
    13891428
    13901429/**
     
    14281467         * Guest TR is not NULL.
    14291468         */
    1430         PX86DESC   pDesc = &pVM->selm.s.paGdtHC[SelTss >> X86_SEL_SHIFT];
     1469        PX86DESC    pDesc = &pVM->selm.s.paGdtR3[SelTss >> X86_SEL_SHIFT];
    14311470        RTGCPTR     GCPtrTss = X86DESC_BASE(*pDesc);
    14321471        unsigned    cbTss = X86DESC_LIMIT(*pDesc);
     
    14891528
    14901529                    rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrTss, GCPtrTss + cbTss - 1,
    1491                                                      0, selmGuestTSSWriteHandler, "selmgcGuestTSSWriteHandler", 0, "Guest TSS write access handler");
     1530                                                     0, selmR3GuestTSSWriteHandler, "selmRCGuestTSSWriteHandler", 0, "Guest TSS write access handler");
    14921531                    if (VBOX_FAILURE(rc))
    14931532                    {
     
    15091548            if (VBOX_SUCCESS(rc))
    15101549            {
    1511             #ifdef DEBUG
     1550#ifdef LOG_ENABLED
    15121551                uint32_t ssr0, espr0;
    15131552
     
    15181557                    Log(("SELMR3SyncTSS: Updating TSS ring 0 stack to %04X:%08X\n", tss.ss0, tss.esp0));
    15191558                Log(("offIoBitmap=%#x\n", tss.offIoBitmap));
    1520             #endif
     1559#endif /* LOG_ENABLED */
    15211560                /* Update our TSS structure for the guest's ring 1 stack */
    15221561                SELMSetRing1Stack(pVM, tss.ss0 | 1, tss.esp0);
     
    15851624     */
    15861625    RTGCPTR     GCPtrGDTEGuest = GDTR.pGdt;
    1587     PX86DESC   pGDTE = pVM->selm.s.paGdtHC;
     1626    PX86DESC   pGDTE = pVM->selm.s.paGdtR3;
    15881627    PX86DESC   pGDTEEnd = (PX86DESC)((uintptr_t)pGDTE + GDTR.cbGdt);
    15891628    while (pGDTE < pGDTEEnd)
     
    16031642                    || pGDTE->Gen.u1DescType  != GDTEGuest.Gen.u1DescType)
    16041643                {
    1605                     unsigned iGDT = pGDTE - pVM->selm.s.paGdtHC;
     1644                    unsigned iGDT = pGDTE - pVM->selm.s.paGdtR3;
    16061645                    SELMR3DumpDescriptor(*pGDTE, iGDT << 3, "SELMR3DebugCheck: GDT mismatch, shadow");
    16071646                    SELMR3DumpDescriptor(GDTEGuest, iGDT << 3, "SELMR3DebugCheck: GDT mismatch,  guest");
     
    16581697     */
    16591698    unsigned    off = (GCPtrLDTEGuest & PAGE_OFFSET_MASK);
    1660     PX86DESC   pLDTE = (PX86DESC)((uintptr_t)pVM->selm.s.HCPtrLdt + off);
    1661     PX86DESC   pLDTEEnd = (PX86DESC)((uintptr_t)pGDTE + cbLdt);
     1699    PX86DESC    pLDTE = (PX86DESC)((uintptr_t)pVM->selm.s.pvLdtR3 + off);
     1700    PX86DESC    pLDTEEnd = (PX86DESC)((uintptr_t)pGDTE + cbLdt);
    16621701    while (pLDTE < pLDTEEnd)
    16631702    {
     
    16741713                || pLDTE->Gen.u1DescType  != LDTEGuest.Gen.u1DescType)
    16751714            {
    1676                 unsigned iLDT = pLDTE - (PX86DESC)((uintptr_t)pVM->selm.s.HCPtrLdt + off);
     1715                unsigned iLDT = pLDTE - (PX86DESC)((uintptr_t)pVM->selm.s.pvLdtR3 + off);
    16771716                SELMR3DumpDescriptor(*pLDTE, iLDT << 3, "SELMR3DebugCheck: LDT mismatch, shadow");
    16781717                SELMR3DumpDescriptor(LDTEGuest, iLDT << 3, "SELMR3DebugCheck: LDT mismatch,  guest");
     
    16851724    }
    16861725
    1687 #else
     1726#else  /* !VBOX_STRICT */
    16881727    NOREF(pVM);
    1689 #endif
     1728#endif /* !VBOX_STRICT */
    16901729
    16911730    return VINF_SUCCESS;
     
    17121751         * Guest TR is not NULL.
    17131752         */
    1714         PX86DESC   pDesc = &pVM->selm.s.paGdtHC[SelTss >> X86_SEL_SHIFT];
     1753        PX86DESC    pDesc = &pVM->selm.s.paGdtR3[SelTss >> X86_SEL_SHIFT];
    17151754        RTGCPTR     GCPtrTss = X86DESC_BASE(*pDesc);
    17161755        unsigned    cbTss = X86DESC_LIMIT(*pDesc);
     
    17181757            cbTss = (cbTss << PAGE_SHIFT) | PAGE_OFFSET_MASK;
    17191758        cbTss++;
    1720 #if 1
     1759# if 1
    17211760        /* Don't bother with anything but the core structure. (Actually all we care for is the r0 ss.) */
    17221761        if (cbTss > sizeof(VBOXTSS))
    17231762            cbTss = sizeof(VBOXTSS);
    1724 #endif
     1763# endif
    17251764        AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + sizeof(VBOXTSS) - 1) >> PAGE_SHIFT),
    17261765                  ("GCPtrTss=%VGv cbTss=%#x - We assume everything is inside one page!\n", GCPtrTss, cbTss));
     
    17741813    }
    17751814    return false;
    1776 #else
     1815#else  /* !VBOX_STRICT */
    17771816    NOREF(pVM);
    17781817    return true;
    1779 #endif
     1818#endif /* !VBOX_STRICT */
    17801819}
    17811820
     
    18311870}
    18321871
    1833 /**
    1834  * Gets information about a selector.
    1835  * Intended for the debugger mostly and will prefer the guest
    1836  * descriptor tables over the shadow ones.
    1837  *
    1838  * @returns VINF_SUCCESS on success.
    1839  * @returns VERR_INVALID_SELECTOR if the selector isn't fully inside the descriptor table.
    1840  * @returns VERR_SELECTOR_NOT_PRESENT if the selector wasn't present.
    1841  * @returns VERR_PAGE_TABLE_NOT_PRESENT or VERR_PAGE_NOT_PRESENT if the pagetable or page
    1842  *          backing the selector table wasn't present.
    1843  * @returns Other VBox status code on other errors.
     1872
     1873/**
     1874 * Gets information about a 64-bit selector, SELMR3GetSelectorInfo helper.
     1875 *
     1876 * See SELMR3GetSelectorInfo for details.
     1877 *
     1878 * @returns VBox status code, see SELMR3GetSelectorInfo for details.
    18441879 *
    18451880 * @param   pVM         VM handle.
     
    18471882 * @param   pSelInfo    Where to store the information.
    18481883 */
    1849 static int selmr3GetSelectorInfo64(PVM pVM, RTSEL Sel, PSELMSELINFO pSelInfo)
    1850 {
    1851     X86DESC64 Desc;
    1852 
    1853     Assert(pSelInfo);
     1884static int selmR3GetSelectorInfo64(PVM pVM, RTSEL Sel, PSELMSELINFO pSelInfo)
     1885{
     1886    pSelInfo->fHyper = false;
    18541887
    18551888    /*
    18561889     * Read it from the guest descriptor table.
    18571890     */
    1858     pSelInfo->fHyper = false;
    1859 
     1891    X86DESC64   Desc;
    18601892    VBOXGDTR    Gdtr;
    18611893    RTGCPTR     GCPtrDesc;
     
    18711903    {
    18721904        /*
    1873             * LDT - must locate the LDT first...
    1874             */
     1905         * LDT - must locate the LDT first...
     1906         */
    18751907        RTSEL SelLdt = CPUMGetGuestLDTR(pVM);
    18761908        if (    (unsigned)(SelLdt & X86_SEL_MASK) < sizeof(X86DESC) /* the first selector is invalid, right? */
     
    19211953
    19221954/**
    1923  * Gets information about a selector.
    1924  * Intended for the debugger mostly and will prefer the guest
    1925  * descriptor tables over the shadow ones.
    1926  *
    1927  * @returns VINF_SUCCESS on success.
    1928  * @returns VERR_INVALID_SELECTOR if the selector isn't fully inside the descriptor table.
    1929  * @returns VERR_SELECTOR_NOT_PRESENT if the selector wasn't present.
    1930  * @returns VERR_PAGE_TABLE_NOT_PRESENT or VERR_PAGE_NOT_PRESENT if the pagetable or page
    1931  *          backing the selector table wasn't present.
    1932  * @returns Other VBox status code on other errors.
     1955 * Gets information about a 64-bit selector, SELMR3GetSelectorInfo helper.
     1956 *
     1957 * See SELMR3GetSelectorInfo for details.
     1958 *
     1959 * @returns VBox status code, see SELMR3GetSelectorInfo for details.
    19331960 *
    19341961 * @param   pVM         VM handle.
     
    19361963 * @param   pSelInfo    Where to store the information.
    19371964 */
    1938 VMMR3DECL(int) SELMR3GetSelectorInfo(PVM pVM, RTSEL Sel, PSELMSELINFO pSelInfo)
    1939 {
    1940     Assert(pSelInfo);
    1941 
    1942     if (CPUMIsGuestInLongMode(pVM))
    1943         return selmr3GetSelectorInfo64(pVM, Sel, pSelInfo);
    1944 
     1965static int selmR3GetSelectorInfo32(PVM pVM, RTSEL Sel, PSELMSELINFO pSelInfo)
     1966{
    19451967    /*
    19461968     * Read the descriptor entry
     
    19591981         */
    19601982        pSelInfo->fHyper = true;
    1961         Desc = pVM->selm.s.paGdtHC[Sel >> X86_SEL_SHIFT];
     1983        Desc = pVM->selm.s.paGdtR3[Sel >> X86_SEL_SHIFT];
    19621984    }
    19631985    else if (CPUMIsGuestInProtectedMode(pVM))
     
    20452067
    20462068/**
    2047  * Gets information about a selector from the shadow tables.
    2048  *
    2049  * This is intended to be faster than the SELMR3GetSelectorInfo() method, but requires
    2050  * that the caller ensures that the shadow tables are up to date.
     2069 * Gets information about a selector.
     2070 * Intended for the debugger mostly and will prefer the guest
     2071 * descriptor tables over the shadow ones.
    20512072 *
    20522073 * @returns VINF_SUCCESS on success.
     
    20612082 * @param   pSelInfo    Where to store the information.
    20622083 */
     2084VMMR3DECL(int) SELMR3GetSelectorInfo(PVM pVM, RTSEL Sel, PSELMSELINFO pSelInfo)
     2085{
     2086    AssertPtr(pSelInfo);
     2087    if (CPUMIsGuestInLongMode(pVM))
     2088        return selmR3GetSelectorInfo64(pVM, Sel, pSelInfo);
     2089    return selmR3GetSelectorInfo32(pVM, Sel, pSelInfo);
     2090}
     2091
     2092
     2093/**
     2094 * Gets information about a selector from the shadow tables.
     2095 *
     2096 * This is intended to be faster than the SELMR3GetSelectorInfo() method, but requires
     2097 * that the caller ensures that the shadow tables are up to date.
     2098 *
     2099 * @returns VINF_SUCCESS on success.
     2100 * @returns VERR_INVALID_SELECTOR if the selector isn't fully inside the descriptor table.
     2101 * @returns VERR_SELECTOR_NOT_PRESENT if the selector wasn't present.
     2102 * @returns VERR_PAGE_TABLE_NOT_PRESENT or VERR_PAGE_NOT_PRESENT if the pagetable or page
     2103 *          backing the selector table wasn't present.
     2104 * @returns Other VBox status code on other errors.
     2105 *
     2106 * @param   pVM         VM handle.
     2107 * @param   Sel         The selector to get info about.
     2108 * @param   pSelInfo    Where to store the information.
     2109 */
    20632110VMMR3DECL(int) SELMR3GetShadowSelectorInfo(PVM pVM, RTSEL Sel, PSELMSELINFO pSelInfo)
    20642111{
     
    20742121         * Global descriptor.
    20752122         */
    2076         Desc = pVM->selm.s.paGdtHC[Sel >> X86_SEL_SHIFT];
     2123        Desc = pVM->selm.s.paGdtR3[Sel >> X86_SEL_SHIFT];
    20772124        pSelInfo->fHyper = pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS] == (Sel & X86_SEL_MASK)
    20782125                        || pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS] == (Sel & X86_SEL_MASK)
     
    20872134         * Local Descriptor.
    20882135         */
    2089         PX86DESC paLDT = (PX86DESC)((char *)pVM->selm.s.HCPtrLdt + pVM->selm.s.offLdtHyper);
     2136        PX86DESC paLDT = (PX86DESC)((char *)pVM->selm.s.pvLdtR3 + pVM->selm.s.offLdtHyper);
    20902137        Desc = paLDT[Sel >> X86_SEL_SHIFT];
    20912138        /** @todo check if the LDT page is actually available. */
     
    21282175    } const aTypes[32] =
    21292176    {
    2130         #define STRENTRY(str) { sizeof(str) - 1, str }
     2177#define STRENTRY(str) { sizeof(str) - 1, str }
    21312178        /* system */
    21322179        STRENTRY("Reserved0 "),                  /* 0x00 */
     
    21632210        STRENTRY("CodeConfER "),                 /* 0x1e */
    21642211        STRENTRY("CodeConfER Accessed ")         /* 0x1f */
    2165         #undef SYSENTRY
     2212#undef SYSENTRY
    21662213    };
    2167     #define ADD_STR(psz, pszAdd) do { strcpy(psz, pszAdd); psz += strlen(pszAdd); } while (0)
     2214#define ADD_STR(psz, pszAdd) do { strcpy(psz, pszAdd); psz += strlen(pszAdd); } while (0)
    21682215    char        szMsg[128];
    21692216    char       *psz = &szMsg[0];
     
    21822229    else
    21832230        ADD_STR(psz, "16-bit ");
    2184     #undef ADD_STR
     2231#undef ADD_STR
    21852232    *psz = '\0';
    21862233
     
    22232270static DECLCALLBACK(void) selmR3InfoGdt(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
    22242271{
    2225     pHlp->pfnPrintf(pHlp, "Shadow GDT (GCAddr=%VGv):\n", MMHyperHC2GC(pVM, pVM->selm.s.paGdtHC));
     2272    pHlp->pfnPrintf(pHlp, "Shadow GDT (GCAddr=%VGv):\n", MMHyperHC2GC(pVM, pVM->selm.s.paGdtR3));
    22262273    for (unsigned iGDT = 0; iGDT < SELM_GDT_ELEMENTS; iGDT++)
    22272274    {
    2228         if (pVM->selm.s.paGdtHC[iGDT].Gen.u1Present)
     2275        if (pVM->selm.s.paGdtR3[iGDT].Gen.u1Present)
    22292276        {
    22302277            char szOutput[128];
    2231             selmR3FormatDescriptor(pVM->selm.s.paGdtHC[iGDT], iGDT << X86_SEL_SHIFT, &szOutput[0], sizeof(szOutput));
     2278            selmR3FormatDescriptor(pVM->selm.s.paGdtR3[iGDT], iGDT << X86_SEL_SHIFT, &szOutput[0], sizeof(szOutput));
    22322279            const char *psz = "";
    22332280            if (iGDT == ((unsigned)pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS] >> X86_SEL_SHIFT))
     
    22962343{
    22972344    unsigned    cLDTs = ((unsigned)pVM->selm.s.cbLdtLimit + 1) >> X86_SEL_SHIFT;
    2298     PX86DESC   paLDT = (PX86DESC)((char *)pVM->selm.s.HCPtrLdt + pVM->selm.s.offLdtHyper);
    2299     pHlp->pfnPrintf(pHlp, "Shadow LDT (GCAddr=%VGv limit=%d):\n", pVM->selm.s.GCPtrLdt + pVM->selm.s.offLdtHyper, pVM->selm.s.cbLdtLimit);
     2345    PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.pvLdtR3 + pVM->selm.s.offLdtHyper);
     2346    pHlp->pfnPrintf(pHlp, "Shadow LDT (GCAddr=%VGv limit=%d):\n", pVM->selm.s.pvLdtRC + pVM->selm.s.offLdtHyper, pVM->selm.s.cbLdtLimit);
    23002347    for (unsigned iLDT = 0; iLDT < cLDTs; iLDT++)
    23012348    {
     
    23312378    if (VBOX_FAILURE(rc))
    23322379    {
    2333         pHlp->pfnPrintf(pHlp, "Guest LDT (Sel=%x): rc=%Vrc\n", SelLdt, rc);
     2380        pHlp->pfnPrintf(pHlp, "Guest LDT (Sel=%x): rc=%Rrc\n", SelLdt, rc);
    23342381        return;
    23352382    }
     
    23712418}
    23722419
     2420
    23732421/**
    23742422 * Dumps the hypervisor LDT
     
    23812429}
    23822430
     2431
    23832432/**
    23842433 * Dumps the guest GDT
     
    23912440}
    23922441
     2442
    23932443/**
    23942444 * Dumps the guest LDT
  • trunk/src/VBox/VMM/SELMInternal.h

    r12989 r13577  
    6868 * @param   pSELM   Pointer to SELM instance data.
    6969 */
    70 #define SELM2VM(pSELM)  ( (PVM)((char*)pSELM - pSELM->offVM) )
     70#define SELM2VM(pSELM)  ( (PVM)((char *)pSELM - pSELM->offVM) )
    7171
    7272
     
    8181    RTINT                   offVM;
    8282
    83     /* Flat CS, DS, 64 bit mode CS, TSS & trap 8 TSS. */
     83    /** Flat CS, DS, 64 bit mode CS, TSS & trap 8 TSS. */
    8484    RTSEL                   aHyperSel[SELM_HYPER_SEL_MAX];
    8585
    86     /** Pointer to the GCs - HC Ptr.
     86    /** Pointer to the GCs - R3 Ptr.
    8787     * This size is governed by SELM_GDT_ELEMENTS. */
    88     R3R0PTRTYPE(PX86DESC)   paGdtHC;
    89     /** Pointer to the GCs - GC Ptr.
     88    R3PTRTYPE(PX86DESC)     paGdtR3;
     89    /** Pointer to the GCs - RC Ptr.
    9090     * This is not initialized until the first relocation because it's used to
    9191     * check if the shadow GDT virtual handler requires deregistration. */
    92     RCPTRTYPE(PX86DESC)     paGdtGC;
    93     /** Current (last) Guest's GDTR. */
     92    RCPTRTYPE(PX86DESC)     paGdtRC;
     93    /** Current (last) Guest's GDTR.
     94     * The pGdt member is set to RTRCPTR_MAX if we're not monitoring the guest GDT. */
    9495    VBOXGDTR                GuestGdtr;
    9596    /** The current (last) effective Guest GDT size. */
     
    9899    uint32_t                padding0;
    99100
    100     /** HC Pointer to the LDT shadow area placed in Hypervisor memory arena. */
    101     R3PTRTYPE(void *)       HCPtrLdt;
    102     /** GC Pointer to the LDT shadow area placed in Hypervisor memory arena. */
    103     RCPTRTYPE(void *)       GCPtrLdt;
     101    /** R3 pointer to the LDT shadow area in HMA. */
     102    R3PTRTYPE(void *)       pvLdtR3;
     103    /** RC pointer to the LDT shadow area in HMA. */
     104    RCPTRTYPE(void *)       pvLdtRC;
    104105#if GC_ARCH_BITS == 64
    105106    RTRCPTR                 padding1;
    106107#endif
    107     /** GC Pointer to the current Guest's LDT. */
     108    /** The address of the guest LDT.
     109     * RTRCPTR_MAX if not monitored. */
    108110    RTGCPTR                 GCPtrGuestLdt;
    109111    /** Current LDT limit, both Guest and Shadow. */
    110112    RTUINT                  cbLdtLimit;
    111     /** Current LDT offset relative to pvLdt*. */
     113    /** Current LDT offset relative to pvLdtR3/pvLdtRC. */
    112114    RTUINT                  offLdtHyper;
    113115#if HC_ARCH_BITS == 32 && GC_ARCH_BITS == 64
     
    121123    VBOXTSS                 TssTrap08;
    122124
    123     /** GC Pointer to the TSS shadow area (Tss) placed in Hypervisor memory arena. */
    124     RCPTRTYPE(void *)       GCPtrTss;
     125    /** Monitored shadow TSS address. */
     126    RCPTRTYPE(void *)       pvMonShwTssRC;
    125127#if GC_ARCH_BITS == 64
    126128    RTRCPTR                 padding3;
    127129#endif
    128     /** GC Pointer to the current Guest's TSS. */
     130    /** GC Pointer to the current Guest's TSS.
     131     * RTRCPTR_MAX if not monitored. */
    129132    RTGCPTR                 GCPtrGuestTss;
    130133    /** The size of the guest TSS. */
     
    134137    /** The size of the Guest's TSS part we're monitoring. */
    135138    RTUINT                  cbMonitoredGuestTss;
    136     /** GC shadow TSS selector */
     139    /** The guest TSS selector at last sync (part of monitoring).
     140     * Contains RTSEL_MAX if not set. */
    137141    RTSEL                   GCSelTss;
    138142
     
    154158
    155159    /** GC: The number of handled writes to the Guest's GDT. */
    156     STAMCOUNTER             StatGCWriteGuestGDTHandled;
     160    STAMCOUNTER             StatRCWriteGuestGDTHandled;
    157161    /** GC: The number of unhandled write to the Guest's GDT. */
    158     STAMCOUNTER             StatGCWriteGuestGDTUnhandled;
     162    STAMCOUNTER             StatRCWriteGuestGDTUnhandled;
    159163    /** GC: The number of times writes to Guest's LDT was detected. */
    160     STAMCOUNTER             StatGCWriteGuestLDT;
     164    STAMCOUNTER             StatRCWriteGuestLDT;
    161165    /** GC: The number of handled writes to the Guest's TSS. */
    162     STAMCOUNTER             StatGCWriteGuestTSSHandled;
     166    STAMCOUNTER             StatRCWriteGuestTSSHandled;
    163167    /** GC: The number of handled writes to the Guest's TSS where we detected a change. */
    164     STAMCOUNTER             StatGCWriteGuestTSSHandledChanged;
     168    STAMCOUNTER             StatRCWriteGuestTSSHandledChanged;
    165169    /** GC: The number of handled redir writes to the Guest's TSS where we detected a change. */
    166     STAMCOUNTER             StatGCWriteGuestTSSRedir;
     170    STAMCOUNTER             StatRCWriteGuestTSSRedir;
    167171    /** GC: The number of unhandled writes to the Guest's TSS. */
    168     STAMCOUNTER             StatGCWriteGuestTSSUnhandled;
     172    STAMCOUNTER             StatRCWriteGuestTSSUnhandled;
    169173    /** The number of times we had to relocate our hypervisor selectors. */
    170174    STAMCOUNTER             StatHyperSelsChanged;
     
    175179__BEGIN_DECLS
    176180
    177 VMMRCDECL(int) selmgcGuestGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    178 VMMRCDECL(int) selmgcGuestLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    179 VMMRCDECL(int) selmgcGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
     181VMMRCDECL(int) selmRCGuestGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
     182VMMRCDECL(int) selmRCGuestLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
     183VMMRCDECL(int) selmRCGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    180184
    181 VMMRCDECL(int) selmgcShadowGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    182 VMMRCDECL(int) selmgcShadowLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    183 VMMRCDECL(int) selmgcShadowTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
     185VMMRCDECL(int) selmRCShadowGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
     186VMMRCDECL(int) selmRCShadowLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
     187VMMRCDECL(int) selmRCShadowTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    184188
    185189__END_DECLS
  • trunk/src/VBox/VMM/VMMAll/SELMAll.cpp

    r13144 r13577  
    3939
    4040
     41#ifndef IN_RING0
     42
    4143/**
    4244 * Converts a GC selector based address to a flat address.
     
    5860    X86DESC    Desc;
    5961    if (!(Sel & X86_SEL_LDT))
    60         Desc = pVM->selm.s.CTXSUFF(paGdt)[Sel >> X86_SEL_SHIFT];
     62        Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    6163    else
    6264    {
    6365        /** @todo handle LDT pages not present! */
    64 #ifdef IN_GC
    65         PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.GCPtrLdt + pVM->selm.s.offLdtHyper);
    66 #else
    67         PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.HCPtrLdt + pVM->selm.s.offLdtHyper);
    68 #endif
     66        PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    6967        Desc = paLDT[Sel >> X86_SEL_SHIFT];
    7068    }
     
    7270    return (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc));
    7371}
     72#endif /* !IN_RING0 */
    7473
    7574
     
    101100    {
    102101        RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff;
    103 
    104102        if (CPUMAreHiddenSelRegsValid(pVM))
    105103            uFlat += pHiddenSel->u64Base;
     
    109107    }
    110108
     109#ifdef IN_RING0
     110    Assert(CPUMAreHiddenSelRegsValid(pVM));
     111#else
    111112    /** @todo when we're in 16 bits mode, we should cut off the address as well.. */
    112113    if (!CPUMAreHiddenSelRegsValid(pVM))
    113114        return SELMToFlatBySel(pVM, Sel, Addr);
     115#endif
    114116
    115117    /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0 (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */
     
    119121        switch (SelReg)
    120122        {
    121         case DIS_SELREG_FS:
    122         case DIS_SELREG_GS:
    123             return (RTGCPTR)(pHiddenSel->u64Base + Addr);
    124 
    125         default:
    126             return Addr;    /* base 0 */
    127         }
    128     }
     123            case DIS_SELREG_FS:
     124            case DIS_SELREG_GS:
     125                return (RTGCPTR)(pHiddenSel->u64Base + Addr);
     126
     127            default:
     128                return Addr;    /* base 0 */
     129        }
     130    }
     131
    129132    /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
    130133    Assert(pHiddenSel->u64Base <= 0xffffffff);
     
    149152VMMDECL(int) SELMToFlatEx(PVM pVM, DIS_SELREG SelReg, PCCPUMCTXCORE pCtxCore, RTGCPTR Addr, unsigned fFlags, PRTGCPTR ppvGC)
    150153{
     154    /*
     155     * Fetch the selector first.
     156     */
    151157    PCPUMSELREGHID pHiddenSel;
    152158    RTSEL          Sel;
    153     int            rc;
    154 
    155     rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel); AssertRC(rc);
     159    int rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel);
     160    AssertRC(rc);
    156161
    157162    /*
     
    189194        u1DescType    = pHiddenSel->Attr.n.u1DescType;
    190195        u4Type        = pHiddenSel->Attr.n.u4Type;
    191 
    192196        u32Limit      = pHiddenSel->u32Limit;
    193197
     
    199203            switch (SelReg)
    200204            {
    201             case DIS_SELREG_FS:
    202             case DIS_SELREG_GS:
    203                 pvFlat = (pHiddenSel->u64Base + Addr);
    204                 break;
    205 
    206             default:
    207                 pvFlat = Addr;
    208                 break;
     205                case DIS_SELREG_FS:
     206                case DIS_SELREG_GS:
     207                    pvFlat = (pHiddenSel->u64Base + Addr);
     208                    break;
     209
     210                default:
     211                    pvFlat = Addr;
     212                    break;
    209213            }
    210214        }
     
    304308                && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
    305309                return VERR_INVALID_SELECTOR;
    306             Desc = pVM->selm.s.CTXSUFF(paGdt)[Sel >> X86_SEL_SHIFT];
     310            Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    307311        }
    308312        else
     
    312316
    313317            /** @todo handle LDT page(s) not present! */
    314 #ifdef IN_GC
    315             PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.GCPtrLdt + pVM->selm.s.offLdtHyper);
    316 #else
    317             PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.HCPtrLdt + pVM->selm.s.offLdtHyper);
    318 #endif
     318            PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    319319            Desc = paLDT[Sel >> X86_SEL_SHIFT];
    320320        }
     
    341341            * Type check.
    342342            */
    343 #define BOTH(a, b) ((a << 16) | b)
     343# define BOTH(a, b) ((a << 16) | b)
    344344            switch (BOTH(u1DescType, u4Type))
    345345            {
     
    429429
    430430            }
    431 #undef BOTH
     431# undef BOTH
    432432        }
    433433    }
     
    435435    return VERR_SELECTOR_NOT_PRESENT;
    436436}
     437
    437438
    438439#ifndef IN_RING0
     
    512513                && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
    513514                return VERR_INVALID_SELECTOR;
    514             Desc = pVM->selm.s.CTXSUFF(paGdt)[Sel >> X86_SEL_SHIFT];
     515            Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    515516        }
    516517        else
     
    520521
    521522            /** @todo handle LDT page(s) not present! */
    522 #ifdef IN_GC
    523             PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.GCPtrLdt + pVM->selm.s.offLdtHyper);
    524 #else
    525             PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.HCPtrLdt + pVM->selm.s.offLdtHyper);
    526 #endif
     523            PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    527524            Desc = paLDT[Sel >> X86_SEL_SHIFT];
    528525        }
     
    652649#endif /* !IN_RING0 */
    653650
     651
    654652/**
    655653 * Validates and converts a GC selector based code address to a flat
     
    675673
    676674
     675#ifndef IN_RING0
    677676/**
    678677 * Validates and converts a GC selector based code address to a flat
     
    695694    X86DESC    Desc;
    696695    if (!(SelCS & X86_SEL_LDT))
    697         Desc = pVM->selm.s.CTXSUFF(paGdt)[SelCS >> X86_SEL_SHIFT];
     696        Desc = pVM->selm.s.CTX_SUFF(paGdt)[SelCS >> X86_SEL_SHIFT];
    698697    else
    699698    {
    700699        /** @todo handle LDT page(s) not present! */
    701 #ifdef IN_GC
    702         PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.GCPtrLdt + pVM->selm.s.offLdtHyper);
    703 #else
    704         PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.HCPtrLdt + pVM->selm.s.offLdtHyper);
    705 #endif
     700        PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    706701        Desc = paLDT[SelCS >> X86_SEL_SHIFT];
    707702    }
     
    748743    return VERR_SELECTOR_NOT_PRESENT;
    749744}
     745#endif /* !IN_RING0 */
    750746
    751747
     
    813809
    814810
     811#ifdef IN_GC
    815812/**
    816813 * Validates and converts a GC selector based code address to a flat address.
     
    840837    return selmValidateAndConvertCSAddrStd(pVM, SelCPL, SelCS, Addr, ppvFlat, pcBits);
    841838}
     839#endif /* IN_GC */
    842840
    843841
     
    861859        return selmValidateAndConvertCSAddrRealMode(pVM, SelCS, pHiddenCSSel, Addr, ppvFlat);
    862860
     861#ifdef IN_RING0
     862    Assert(CPUMAreHiddenSelRegsValid(pVM));
     863#else
    863864    /** @todo when we're in 16 bits mode, we should cut off the address as well? (like in selmValidateAndConvertCSAddrRealMode) */
    864865    if (!CPUMAreHiddenSelRegsValid(pVM))
    865866        return selmValidateAndConvertCSAddrStd(pVM, SelCPL, SelCS, Addr, ppvFlat, NULL);
     867#endif
    866868    return selmValidateAndConvertCSAddrHidden(pVM, SelCPL, SelCS, pHiddenCSSel, Addr, ppvFlat);
    867869}
    868870
    869871
     872#ifndef IN_RING0
    870873/**
    871874 * Return the cpu mode corresponding to the (CS) selector
     
    882885    X86DESC Desc;
    883886    if (!(Sel & X86_SEL_LDT))
    884         Desc = pVM->selm.s.CTXSUFF(paGdt)[Sel >> X86_SEL_SHIFT];
     887        Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    885888    else
    886889    {
    887890        /** @todo handle LDT page(s) not present! */
    888         PX86DESC   paLDT = (PX86DESC)((char *)pVM->selm.s.CTXMID(,PtrLdt) + pVM->selm.s.offLdtHyper);
     891        PX86DESC   paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    889892        Desc = paLDT[Sel >> X86_SEL_SHIFT];
    890893    }
    891894    return (Desc.Gen.u1DefBig) ? CPUMODE_32BIT : CPUMODE_16BIT;
    892895}
     896#endif /* !IN_RING0 */
    893897
    894898
     
    904908VMMDECL(DISCPUMODE) SELMGetCpuModeFromSelector(PVM pVM, X86EFLAGS eflags, RTSEL Sel, CPUMSELREGHID *pHiddenSel)
    905909{
     910#ifdef IN_RING0
     911    Assert(CPUMAreHiddenSelRegsValid(pVM));
     912#else  /* !IN_RING0 */
    906913    if (!CPUMAreHiddenSelRegsValid(pVM))
    907914    {
     
    915922        return selmGetCpuModeFromSelector(pVM, Sel);
    916923    }
     924#endif /* !IN_RING0 */
    917925    if (    CPUMIsGuestInLongMode(pVM)
    918926        &&  pHiddenSel->Attr.n.u1Long)
     
    924932}
    925933
     934
    926935/**
    927936 * Returns Hypervisor's Trap 08 (\#DF) selector.
     
    960969    pVM->selm.s.Tss.esp1 = (uint32_t)esp;
    961970}
     971
    962972
    963973#ifndef IN_RING0
     
    969979 * @param   pSS     Ring1 SS register value.
    970980 * @param   pEsp    Ring1 ESP register value.
     981 *
     982 * @todo Merge in the GC version of this, eliminating it - or move this to
     983 *       SELM.cpp, making it SELMR3GetRing1Stack.
    971984 */
    972985VMMDECL(int) SELMGetRing1Stack(PVM pVM, uint32_t *pSS, PRTGCPTR32 pEsp)
     
    980993        Assert(pVM->selm.s.GCPtrGuestTss && pVM->selm.s.cbMonitoredGuestTss);
    981994
    982 #ifdef IN_GC
     995# ifdef IN_GC
    983996        bool    fTriedAlready = false;
    984997
     
    986999        rc  = MMGCRamRead(pVM, &tss.ss0,  (RCPTRTYPE(void *))(GCPtrTss + RT_OFFSETOF(VBOXTSS, ss0)), sizeof(tss.ss0));
    9871000        rc |= MMGCRamRead(pVM, &tss.esp0, (RCPTRTYPE(void *))(GCPtrTss + RT_OFFSETOF(VBOXTSS, esp0)), sizeof(tss.esp0));
    988   #ifdef DEBUG
     1001ifdef DEBUG
    9891002        rc |= MMGCRamRead(pVM, &tss.offIoBitmap, (RCPTRTYPE(void *))(GCPtrTss + RT_OFFSETOF(VBOXTSS, offIoBitmap)), sizeof(tss.offIoBitmap));
    990   #endif
     1003endif
    9911004
    9921005        if (VBOX_FAILURE(rc))
     
    10061019        }
    10071020
    1008 #else /* !IN_GC */
     1021# else /* !IN_GC */
    10091022        /* Reading too much. Could be cheaper than two seperate calls though. */
    10101023        rc = PGMPhysSimpleReadGCPtr(pVM, &tss, GCPtrTss, sizeof(VBOXTSS));
     
    10141027            return rc;
    10151028        }
    1016 #endif /* !IN_GC */
    1017 
    1018 #ifdef LOG_ENABLED
     1029# endif /* !IN_GC */
     1030
     1031# ifdef LOG_ENABLED
    10191032        uint32_t ssr0  = pVM->selm.s.Tss.ss1;
    10201033        uint32_t espr0 = pVM->selm.s.Tss.esp1;
     
    10251038
    10261039        Log(("offIoBitmap=%#x\n", tss.offIoBitmap));
    1027 #endif
     1040# endif
    10281041        /* Update our TSS structure for the guest's ring 1 stack */
    10291042        SELMSetRing1Stack(pVM, tss.ss0 | 1, (RTGCPTR32)tss.esp0);
     
    10361049    return VINF_SUCCESS;
    10371050}
    1038 #endif
     1051#endif /* !IN_RING0 */
     1052
    10391053
    10401054/**
    10411055 * Returns Guest TSS pointer
    10421056 *
     1057 * @returns Pointer to the guest TSS, RTRCPTR_MAX if not being monitored.
    10431058 * @param   pVM     VM Handle.
    10441059 */
     
    10861101
    10871102#ifndef IN_RING0
     1103
    10881104/**
    10891105 * Gets the hypervisor code selector (CS).
     
    11481164 *          switchers. Don't exploit this API!
    11491165 */
    1150 VMMDECL(RTGCPTR) SELMGetHyperGDT(PVM pVM)
     1166VMMDECL(RTRCPTR) SELMGetHyperGDT(PVM pVM)
    11511167{
    11521168    /*
    1153      * Always convert this from the HC pointer since. We're can be
     1169     * Always convert this from the HC pointer since we can be
    11541170     * called before the first relocation and have to work correctly
    11551171     * without having dependencies on the relocation order.
    11561172     */
    1157     return (RTGCPTR)MMHyperHC2GC(pVM, pVM->selm.s.paGdtHC);
    1158 }
    1159 #endif /* IN_RING0 */
     1173    return (RTRCPTR)MMHyperR3ToRC(pVM, pVM->selm.s.paGdtR3);
     1174}
     1175
     1176#endif /* !IN_RING0 */
    11601177
    11611178/**
     
    11781195         * Do we have a valid TSS?
    11791196         */
    1180         if (    pVM->selm.s.GCSelTss == (RTSEL)~0
     1197        if (    pVM->selm.s.GCSelTss == RTSEL_MAX
    11811198            || !pVM->selm.s.fGuestTss32Bit)
    11821199            return VERR_SELM_NO_TSS;
     
    12051222    return VINF_SUCCESS;
    12061223}
     1224
  • trunk/src/VBox/VMM/VMMGC/SELMGC.cpp

    r13144 r13577  
    100100     * 'little' adjustment we do for DPL 0 selectors.
    101101     */
    102     PX86DESC   pShadowDescr = &pVM->selm.s.paGdtGC[iGDTEntry];
     102    PX86DESC   pShadowDescr = &pVM->selm.s.paGdtRC[iGDTEntry];
    103103    if (Desc.Gen.u1DescType)
    104104    {
     
    150150    if (Sel == (pRegFrame->cs & X86_SEL_MASK))
    151151        Log(("GDT write to selector in CS register %04X\n", pRegFrame->cs));
    152     else
    153     if (Sel == (pRegFrame->ds & X86_SEL_MASK))
     152    else if (Sel == (pRegFrame->ds & X86_SEL_MASK))
    154153        Log(("GDT write to selector in DS register %04X\n", pRegFrame->ds));
    155     else
    156     if (Sel == (pRegFrame->es & X86_SEL_MASK))
     154    else if (Sel == (pRegFrame->es & X86_SEL_MASK))
    157155        Log(("GDT write to selector in ES register %04X\n", pRegFrame->es));
    158     else
    159     if (Sel == (pRegFrame->fs & X86_SEL_MASK))
     156    else if (Sel == (pRegFrame->fs & X86_SEL_MASK))
    160157        Log(("GDT write to selector in FS register %04X\n", pRegFrame->fs));
    161     else
    162     if (Sel == (pRegFrame->gs & X86_SEL_MASK))
     158    else if (Sel == (pRegFrame->gs & X86_SEL_MASK))
    163159        Log(("GDT write to selector in GS register %04X\n", pRegFrame->gs));
    164     else
    165     if (Sel == (pRegFrame->ss & X86_SEL_MASK))
     160    else if (Sel == (pRegFrame->ss & X86_SEL_MASK))
    166161        Log(("GDT write to selector in SS register %04X\n", pRegFrame->ss));
    167162#endif
     
    182177 *                      (If it's a EIP range this's the EIP, if not it's pvFault.)
    183178 */
    184 VMMRCDECL(int) selmgcGuestGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
    185 {
    186     LogFlow(("selmgcGuestGDTWriteHandler errcode=%x fault=%VGv offRange=%08x\n", (uint32_t)uErrorCode, pvFault, offRange));
     179VMMRCDECL(int) selmRCGuestGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
     180{
     181    LogFlow(("selmRCGuestGDTWriteHandler errcode=%x fault=%VGv offRange=%08x\n", (uint32_t)uErrorCode, pvFault, offRange));
    187182
    188183    /*
     
    218213                if (rc2 == VINF_SUCCESS)
    219214                {
    220                     STAM_COUNTER_INC(&pVM->selm.s.StatGCWriteGuestGDTHandled);
     215                    STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestGDTHandled);
    221216                    return rc;
    222217                }
     
    238233        VM_FF_SET(pVM, VM_FF_SELM_SYNC_GDT);
    239234    }
    240     STAM_COUNTER_INC(&pVM->selm.s.StatGCWriteGuestGDTUnhandled);
     235    STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestGDTUnhandled);
    241236    return rc;
    242237}
     
    255250 *                      (If it's a EIP range this's the EIP, if not it's pvFault.)
    256251 */
    257 VMMRCDECL(int) selmgcGuestLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
     252VMMRCDECL(int) selmRCGuestLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
    258253{
    259254    /** @todo To be implemented. */
    260     ////LogCom(("selmgcGuestLDTWriteHandler: eip=%08X pvFault=%VGv pvRange=%VGv\r\n", pRegFrame->eip, pvFault, pvRange));
     255    ////LogCom(("selmRCGuestLDTWriteHandler: eip=%08X pvFault=%VGv pvRange=%VGv\r\n", pRegFrame->eip, pvFault, pvRange));
    261256
    262257    VM_FF_SET(pVM, VM_FF_SELM_SYNC_LDT);
    263     STAM_COUNTER_INC(&pVM->selm.s.StatGCWriteGuestLDT);
     258    STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestLDT);
    264259    return VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT;
    265260}
     
    278273 *                      (If it's a EIP range this's the EIP, if not it's pvFault.)
    279274 */
    280 VMMRCDECL(int) selmgcGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
    281 {
    282     LogFlow(("selmgcGuestTSSWriteHandler errcode=%x fault=%VGv offRange=%08x\n", (uint32_t)uErrorCode, pvFault, offRange));
     275VMMRCDECL(int) selmRCGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
     276{
     277    LogFlow(("selmRCGuestTSSWriteHandler errcode=%x fault=%VGv offRange=%08x\n", (uint32_t)uErrorCode, pvFault, offRange));
    283278
    284279    /*
     
    298293            ||  pGuestTSS->ss0  != (pVM->selm.s.Tss.ss1 & ~1)) /* undo raw-r0 */
    299294        {
    300             Log(("selmgcGuestTSSWriteHandler: R0 stack: %RTsel:%VGv -> %RTsel:%VGv\n",
     295            Log(("selmRCGuestTSSWriteHandler: R0 stack: %RTsel:%VGv -> %RTsel:%VGv\n",
    301296                 (RTSEL)(pVM->selm.s.Tss.ss1 & ~1), pVM->selm.s.Tss.esp1, (RTSEL)pGuestTSS->ss0, pGuestTSS->esp0));
    302297            pVM->selm.s.Tss.esp1 = pGuestTSS->esp0;
    303298            pVM->selm.s.Tss.ss1 = pGuestTSS->ss0 | 1;
    304             STAM_COUNTER_INC(&pVM->selm.s.StatGCWriteGuestTSSHandledChanged);
     299            STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSHandledChanged);
    305300        }
    306301        if (CPUMGetGuestCR4(pVM) & X86_CR4_VME)
     
    331326                    AssertMsg(rc == VINF_SUCCESS, ("MMGCRamRead %VGv failed with %Vrc\n", (uint8_t *)pGuestTSS + offIntRedirBitmap + i * 8, rc));
    332327                }
    333                 STAM_COUNTER_INC(&pVM->selm.s.StatGCWriteGuestTSSRedir);
     328                STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSRedir);
    334329            }
    335330        }
    336         STAM_COUNTER_INC(&pVM->selm.s.StatGCWriteGuestTSSHandled);
     331        STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSHandled);
    337332    }
    338333    else
     
    340335        Assert(VBOX_FAILURE(rc));
    341336        VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS);
    342         STAM_COUNTER_INC(&pVM->selm.s.StatGCWriteGuestTSSUnhandled);
     337        STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSUnhandled);
    343338        if (rc == VERR_EM_INTERPRETER)
    344339            rc = VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT;
     
    348343
    349344
    350 
    351345/**
    352346 * \#PF Virtual Handler callback for Guest write access to the VBox shadow GDT.
     
    361355 *                      (If it's a EIP range this's the EIP, if not it's pvFault.)
    362356 */
    363 VMMRCDECL(int) selmgcShadowGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
    364 {
    365     LogRel(("FATAL ERROR: selmgcShadowGDTWriteHandler: eip=%08X pvFault=%VGv pvRange=%VGv\r\n", pRegFrame->eip, pvFault, pvRange));
     357VMMRCDECL(int) selmRCShadowGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
     358{
     359    LogRel(("FATAL ERROR: selmRCShadowGDTWriteHandler: eip=%08X pvFault=%VGv pvRange=%VGv\r\n", pRegFrame->eip, pvFault, pvRange));
    366360    return VERR_SELM_SHADOW_GDT_WRITE;
    367361}
    368362
     363
    369364/**
    370365 * \#PF Virtual Handler callback for Guest write access to the VBox shadow LDT.
     
    379374 *                      (If it's a EIP range this's the EIP, if not it's pvFault.)
    380375 */
    381 VMMRCDECL(int) selmgcShadowLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
    382 {
    383     LogRel(("FATAL ERROR: selmgcShadowLDTWriteHandler: eip=%08X pvFault=%VGv pvRange=%VGv\r\n", pRegFrame->eip, pvFault, pvRange));
    384     Assert((RTRCPTR)pvFault >= pVM->selm.s.GCPtrLdt && (RTRCUINTPTR)pvFault < (RTRCUINTPTR)pVM->selm.s.GCPtrLdt + 65536 + PAGE_SIZE);
     376VMMRCDECL(int) selmRCShadowLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
     377{
     378    LogRel(("FATAL ERROR: selmRCShadowLDTWriteHandler: eip=%08X pvFault=%VGv pvRange=%VGv\r\n", pRegFrame->eip, pvFault, pvRange));
     379    Assert((RTRCPTR)pvFault >= pVM->selm.s.pvLdtRC && (RTRCUINTPTR)pvFault < (RTRCUINTPTR)pVM->selm.s.pvLdtRC + 65536 + PAGE_SIZE);
    385380    return VERR_SELM_SHADOW_LDT_WRITE;
    386381}
    387382
     383
    388384/**
    389385 * \#PF Virtual Handler callback for Guest write access to the VBox shadow TSS.
     
    398394 *                      (If it's a EIP range this's the EIP, if not it's pvFault.)
    399395 */
    400 VMMRCDECL(int) selmgcShadowTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
    401 {
    402     LogRel(("FATAL ERROR: selmgcShadowTSSWriteHandler: eip=%08X pvFault=%VGv pvRange=%VGv\r\n", pRegFrame->eip, pvFault, pvRange));
     396VMMRCDECL(int) selmRCShadowTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
     397{
     398    LogRel(("FATAL ERROR: selmRCShadowTSSWriteHandler: eip=%08X pvFault=%VGv pvRange=%VGv\r\n", pRegFrame->eip, pvFault, pvRange));
    403399    return VERR_SELM_SHADOW_TSS_WRITE;
    404400}
     
    417413    if (pVM->selm.s.fSyncTSSRing0Stack)
    418414    {
    419         RCPTRTYPE(uint8_t *) GCPtrTss = (RCPTRTYPE(uint8_t *))pVM->selm.s.GCPtrGuestTss;
    420         int     rc;
    421         VBOXTSS tss;
     415        uint8_t *   GCPtrGuestTss = (uint8_t *)(uintptr_t)pVM->selm.s.GCPtrGuestTss;
     416        bool        fTriedAlready = false;
     417        int         rc;
     418        VBOXTSS     tss;
    422419
    423420        Assert(pVM->selm.s.GCPtrGuestTss && pVM->selm.s.cbMonitoredGuestTss);
    424421
    425 #ifdef IN_GC
    426         bool    fTriedAlready = false;
    427 
    428422l_tryagain:
    429         rc  = MMGCRamRead(pVM, &tss.ss0,  GCPtrTss + RT_OFFSETOF(VBOXTSS, ss0), sizeof(tss.ss0));
    430         rc |= MMGCRamRead(pVM, &tss.esp0, GCPtrTss + RT_OFFSETOF(VBOXTSS, esp0), sizeof(tss.esp0));
    431   #ifdef DEBUG
    432         rc |= MMGCRamRead(pVM, &tss.offIoBitmap, GCPtrTss + RT_OFFSETOF(VBOXTSS, offIoBitmap), sizeof(tss.offIoBitmap));
    433   #endif
     423        rc  = MMGCRamRead(pVM, &tss.ss0,  GCPtrGuestTss + RT_OFFSETOF(VBOXTSS, ss0), sizeof(tss.ss0));
     424        rc |= MMGCRamRead(pVM, &tss.esp0, GCPtrGuestTss + RT_OFFSETOF(VBOXTSS, esp0), sizeof(tss.esp0));
     425#ifdef DEBUG
     426        rc |= MMGCRamRead(pVM, &tss.offIoBitmap, GCPtrGuestTss + RT_OFFSETOF(VBOXTSS, offIoBitmap), sizeof(tss.offIoBitmap));
     427#endif
    434428
    435429        if (VBOX_FAILURE(rc))
     
    440434                /** @todo might cross page boundary */
    441435                fTriedAlready = true;
    442                 rc = PGMPrefetchPage(pVM, (RTGCPTR)(RTRCUINTPTR)GCPtrTss);
     436                rc = PGMPrefetchPage(pVM, (RTGCPTR)(uintptr_t)GCPtrGuestTss);
    443437                if (rc != VINF_SUCCESS)
    444438                    return rc;
    445439                goto l_tryagain;
    446440            }
    447             AssertMsgFailed(("Unable to read TSS structure at %08X\n", GCPtrTss));
     441            AssertMsgFailed(("Unable to read TSS structure at %RRv\n", GCPtrGuestTss));
    448442            return rc;
    449443        }
    450 
    451 #else /* !IN_GC */
    452         /* Reading too much. Could be cheaper than two seperate calls though. */
    453         rc = PGMPhysSimpleReadGCPtr(pVM, &tss, GCPtrTss, sizeof(VBOXTSS));
    454         if (VBOX_FAILURE(rc))
    455         {
    456             AssertReleaseMsgFailed(("Unable to read TSS structure at %08X\n", GCPtrTss));
    457             return rc;
    458         }
    459 #endif /* !IN_GC */
    460444
    461445#ifdef LOG_ENABLED
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r13067 r13577  
    704704    GEN_CHECK_OFF(SELM, aHyperSel[SELM_HYPER_SEL_TSS]);
    705705    GEN_CHECK_OFF(SELM, aHyperSel[SELM_HYPER_SEL_TSS_TRAP08]);
    706     GEN_CHECK_OFF(SELM, paGdtHC);
    707     GEN_CHECK_OFF(SELM, paGdtGC);
     706    GEN_CHECK_OFF(SELM, paGdtR3);
     707    GEN_CHECK_OFF(SELM, paGdtRC);
    708708    GEN_CHECK_OFF(SELM, GuestGdtr);
    709709    GEN_CHECK_OFF(SELM, cbEffGuestGdtLimit);
    710     GEN_CHECK_OFF(SELM, HCPtrLdt);
    711     GEN_CHECK_OFF(SELM, GCPtrLdt);
     710    GEN_CHECK_OFF(SELM, pvLdtR3);
     711    GEN_CHECK_OFF(SELM, pvLdtRC);
    712712    GEN_CHECK_OFF(SELM, GCPtrGuestLdt);
    713713    GEN_CHECK_OFF(SELM, cbLdtLimit);
     
    715715    GEN_CHECK_OFF(SELM, Tss);
    716716    GEN_CHECK_OFF(SELM, TssTrap08);
    717     GEN_CHECK_OFF(SELM, GCPtrTss);
     717    GEN_CHECK_OFF(SELM, pvMonShwTssRC);
    718718    GEN_CHECK_OFF(SELM, GCPtrGuestTss);
    719719    GEN_CHECK_OFF(SELM, cbGuestTss);
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