VirtualBox

Changeset 45485 in vbox for trunk


Ignore:
Timestamp:
Apr 11, 2013 2:46:04 PM (12 years ago)
Author:
vboxsync
Message:
  • *: Where possible, drop the #ifdef VBOX_WITH_RAW_RING1 when EMIsRawRing1Enabled is used.
  • SELM: Don't shadow TSS.esp1/ss1 unless ring-1 compression is enabled (also fixed a log statement there).
  • SELM: selmGuestToShadowDesc should not push ring-1 selectors into ring-2 unless EMIsRawRing1Enabled() holds true.
  • REM: Don't set CPU_INTERRUPT_EXTERNAL_EXIT in helper_ltr() for now.
Location:
trunk
Files:
21 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpum.h

    r45291 r45485  
    491491
    492492
    493 /**
    494  * Get the current privilege level of the guest.
    495  *
    496  * @returns CPL
    497  * @param   pVCpu       The current virtual CPU.
    498  * @param   pRegFrame   Pointer to the register frame.
    499  */
    500493VMMDECL(uint32_t)       CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
    501 
    502494#ifdef VBOX_WITH_RAW_RING1
    503 /**
    504  * Transforms the guest CPU state to raw-ring mode.
    505  *
    506  * This function will change the any of the cs and ss register with DPL=0 to DPL=1.
    507  *
    508  * @returns VBox status. (recompiler failure)
    509  * @param   pVCpu       Pointer to the VMCPU.
    510  * @param   pCtxCore    The context core (for trap usage).
    511  * @see     @ref pg_raw
    512  */
    513 VMMDECL(void)         CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
     495VMMDECL(void)           CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
    514496#endif
    515497
  • trunk/include/VBox/vmm/em.h

    r45276 r45485  
    122122 * @param   pVM         The VM to operate on.
    123123 */
    124 #define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser)
     124#define EMIsRawRing3Enabled(pVM)            (!(pVM)->fRecompileUser)
    125125
    126126/**
     
    131131 * @param   pVM         The VM to operate on.
    132132 */
    133 #define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor)
     133#define EMIsRawRing0Enabled(pVM)            (!(pVM)->fRecompileSupervisor)
    134134
    135135#ifdef VBOX_WITH_RAW_RING1
     
    141141 * @param   pVM         The VM to operate on.
    142142 */
    143 #define EMIsRawRing1Enabled(pVM) ((pVM)->fRawRing1Enabled)
     143# define EMIsRawRing1Enabled(pVM)          ((pVM)->fRawRing1Enabled)
    144144#else
    145 #define EMIsRawRing1Enabled(pVM) false
     145# define EMIsRawRing1Enabled(pVM)          false
    146146#endif
    147147
     
    153153 * @param   pVM         The VM to operate on.
    154154 */
    155 #define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser)
     155#define EMIsHwVirtExecutionEnabled(pVM)     (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser)
    156156
    157157/**
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r45291 r45485  
    26662666                if (pVCpu->cpum.s.fRawEntered)
    26672667                {
    2668                     if (    EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM))
    2669                         &&  uCpl == 2)
     2668                    if (   uCpl == 2
     2669                        && EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM)))
    26702670                        uCpl = 1;
    2671                     else
    2672                     if (uCpl == 1)
     2671                    else if (uCpl == 1)
    26732672                        uCpl = 0;
    26742673                }
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r45479 r45485  
    5757
    5858#ifdef VBOX_WITH_RAW_RING1
    59 #define EM_EMULATE_SMSW
    60 #endif
     59# define EM_EMULATE_SMSW
     60#endif
     61
    6162
    6263/*******************************************************************************
     
    36743675            || pRegFrame->eflags.Bits.u2IOPL > cpl
    36753676           )
     3677#endif
    36763678        {
    3677 #endif
    36783679            if (    cpl != 0
    36793680                ||  pDis->pCurInstr->uOpcode != OP_RDTSC)    /* rdtsc requires emulation in ring 3 as well */
     
    36833684                return VERR_EM_INTERPRETER;
    36843685            }
    3685 #ifdef VBOX_WITH_RAW_RING1
    36863686        }
    3687 #endif
    36883687    }
    36893688    else
  • trunk/src/VBox/VMM/VMMAll/SELMAll.cpp

    r45276 r45485  
    2323#include <VBox/vmm/selm.h>
    2424#include <VBox/vmm/stam.h>
     25#include <VBox/vmm/em.h>
    2526#include <VBox/vmm/mm.h>
    2627#include <VBox/vmm/pgm.h>
     
    3334#include <VBox/vmm/vmm.h>
    3435#include <iprt/x86.h>
     36
     37#include "SELMInline.h"
    3538
    3639
     
    838841}
    839842
     843
    840844#ifdef VBOX_WITH_RAW_RING1
    841845/**
     
    853857}
    854858#endif
     859
    855860
    856861#ifdef VBOX_WITH_RAW_MODE_NOT_R0
  • trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp

    r45276 r45485  
    625625                    if (!fConforming && dpl < cpl)
    626626                    {
    627 #ifdef IN_RC /* Only in GC mode we still see tracing of our ring modifications */
    628                         if (    (pRegFrame->ss.Sel & X86_SEL_RPL) == 1 
     627#ifdef IN_RC /* Only in RC we still see tracing of our ring modifications. */
     628                        if (    (pRegFrame->ss.Sel & X86_SEL_RPL) == 1
    629629                            &&  !eflags.Bits.u1VM)
    630630                            pTrapStack[--idx] = pRegFrame->ss.Sel & ~1;         /* Mask away traces of raw ring 0 execution (ring 1). */
    631 # ifdef VBOX_WITH_RAW_RING1
    632                         else
    633                         if (    EMIsRawRing1Enabled(pVM)
    634                             &&  (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)
     631                        else if (   EMIsRawRing1Enabled(pVM)
     632                                 && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)
    635633                            pTrapStack[--idx] = (pRegFrame->ss.Sel & ~2) | 1;   /* Mask away traces of raw ring 1 execution (ring 2). */
    636 # endif
    637634                        else
    638635#endif  /* IN_RC */
     
    645642                    /* Note: Not really necessary as we grab include those bits in the trap/irq handler trampoline */
    646643                    pTrapStack[--idx] = eflags.u32;
    647 #ifdef IN_RC /* Only in GC mode we still see tracing of our ring modifications */
    648                     if (    (pRegFrame->cs.Sel & X86_SEL_RPL) == 1
     644
     645#ifdef IN_RC /* Only in RC mode we still see tracing of our ring modifications */
     646                    if (    (pRegFrame->cs.Sel & X86_SEL_RPL) == 1
    649647                        &&  !eflags.Bits.u1VM)
    650648                        pTrapStack[--idx] = pRegFrame->cs.Sel & ~1;         /* Mask away traces of raw ring execution (ring 1). */
    651 # ifdef VBOX_WITH_RAW_RING1
    652                     else
    653                     if (    EMIsRawRing1Enabled(pVM)
    654                         &&  (pRegFrame->cs.Sel & X86_SEL_RPL) == 2)
     649                    else if (   EMIsRawRing1Enabled(pVM)
     650                             && (pRegFrame->cs.Sel & X86_SEL_RPL) == 2)
    655651                        pTrapStack[--idx] = (pRegFrame->cs.Sel & ~2) | 1;   /* Mask away traces of raw ring 1 execution (ring 2). */
    656 # endif
    657652                    else
    658653#endif  /* IN_RC */
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r45276 r45485  
    41934193     * Are we in Ring-0?
    41944194     */
    4195     if (    pCtxCore->ss.Sel 
     4195    if (    pCtxCore->ss.Sel
    41964196        &&  (pCtxCore->ss.Sel & X86_SEL_RPL) == 0
    41974197        &&  !pCtxCore->eflags.Bits.u1VM)
     
    42064206         */
    42074207        pCtxCore->ss.Sel |= 1;
    4208         if (    pCtxCore->cs.Sel 
     4208        if (    pCtxCore->cs.Sel
    42094209            &&  (pCtxCore->cs.Sel & X86_SEL_RPL) == 0)
    42104210            pCtxCore->cs.Sel |= 1;
     
    42364236     */
    42374237    AssertMsg((pCtxCore->eflags.u32 & X86_EFL_IF), ("X86_EFL_IF is clear\n"));
    4238     AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0, 
     4238    AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0,
    42394239                     ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss.Sel & X86_SEL_RPL));
    42404240    Assert((pVCpu->cpum.s.Guest.cr0 & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) == (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP));
     
    42454245    return VINF_SUCCESS;
    42464246}
    4247 
    42484247
    42494248
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r45276 r45485  
    849849    /* removing breaks win2k guests? */
    850850    case OP_IRET:
    851 #ifdef VBOX_WITH_RAW_RING1
    852851        if (EMIsRawRing1Enabled(pVM))
    853852            break;
    854 #endif
    855853        /* no break */
    856854
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r45301 r45485  
    13201320            return EMSTATE_REM;
    13211321
    1322 # ifdef VBOX_WITH_RAW_RING1
    1323         /* Only ring 0 and 1 supervisor code. */
    13241322        if (EMIsRawRing1Enabled(pVM))
    13251323        {
     1324            /* Only ring 0 and 1 supervisor code. */
    13261325            if ((uSS & X86_SEL_RPL) == 2)   /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */
    13271326            {
     
    13301329            }
    13311330        }
    1332         else
    1333 # endif
    13341331        /* Only ring 0 supervisor code. */
    1335         if ((uSS & X86_SEL_RPL) != 0)
     1332        else if ((uSS & X86_SEL_RPL) != 0)
    13361333        {
    13371334            Log2(("raw r0 mode refused: CPL %d\n", uSS & X86_SEL_RPL));
  • trunk/src/VBox/VMM/VMMR3/EMRaw.cpp

    r45305 r45485  
    13621362        Assert(REMR3QueryPendingInterrupt(pVM, pVCpu) == REM_NO_PENDING_IRQ);
    13631363# endif
    1364 # ifdef VBOX_WITH_RAW_RING1
    1365         Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0 || (EMIsRawRing1Enabled(pVM) && (pCtx->ss.Sel & X86_SEL_RPL) == 1));
    1366 # else
    1367         Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0);
    1368 # endif
     1364        Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0
     1365               || (EMIsRawRing1Enabled(pVM) && (pCtx->ss.Sel & X86_SEL_RPL) == 1));
    13691366        AssertMsg(   (pCtx->eflags.u32 & X86_EFL_IF)
    13701367                  || PATMShouldUseRawMode(pVM, (RTGCPTR)pCtx->eip),
     
    14461443
    14471444
     1445
    14481446        /*
    14491447         * Execute the code.
     
    15511549            ||  VMCPU_FF_ISPENDING(pVCpu, ~VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
    15521550        {
    1553             Assert(pCtx->eflags.Bits.u1VM || (EMIsRawRing1Enabled(pVM) ? ((pCtx->ss.Sel & X86_SEL_RPL) != 2) : ((pCtx->ss.Sel & X86_SEL_RPL) != 1)));
     1551            Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) != (EMIsRawRing1Enabled(pVM) ? 2 : 1));
    15541552
    15551553            STAM_REL_PROFILE_ADV_SUSPEND(&pVCpu->em.s.StatRAWTotal, a);
  • trunk/src/VBox/VMM/VMMR3/PATM.cpp

    r45276 r45485  
    15351535        break;
    15361536
    1537 #ifdef VBOX_WITH_SAFE_STR   /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */
     1537#ifdef VBOX_WITH_SAFE_STR   /** @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */
    15381538    case OP_STR:
    15391539        break;
     
    16511651        return VINF_SUCCESS;
    16521652
    1653 #ifdef VBOX_WITH_SAFE_STR   /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */
     1653#ifdef VBOX_WITH_SAFE_STR   /** @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */
    16541654    case OP_STR:
    16551655        break;
  • trunk/src/VBox/VMM/VMMR3/PATMPatch.cpp

    r45276 r45485  
    439439    callInfo.pCurInstrGC = pCurInstrGC;
    440440
    441 #ifdef VBOX_WITH_RAW_RING1
    442441    if (EMIsRawRing1Enabled(pVM))
    443     {
    444442        size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRing1Record, 0, false, &callInfo);
    445     }
    446443    else
    447 #endif
    448444        size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRecord, 0, false, &callInfo);
    449445
     
    10831079    int rc = VINF_SUCCESS;
    10841080
    1085 #ifdef VBOX_WITH_RAW_RING1
    1086     if (!EMIsRawRing1Enabled(pVM))    /* direct passthru of interrupts is not allowed in the ring-1 support case as we can't deal with the ring-1/2 ambiguity in the patm asm code and we don't need it either as TRPMForwardTrap takes care of the details. */
    1087     {
    1088 #endif
     1081    if (!EMIsRawRing1Enabled(pVM))    /* direct passthru of interrupts is not allowed in the ring-1 support case as we can't
     1082                                         deal with the ring-1/2 ambiguity in the patm asm code and we don't need it either as
     1083                                         TRPMForwardTrap takes care of the details. */
     1084    {
    10891085        uint32_t size;
    10901086        PATCHGEN_PROLOG(pVM, pPatch);
     
    10991095
    11001096        PATCHGEN_EPILOG(pPatch, size);
    1101 #ifdef VBOX_WITH_RAW_RING1
    1102     }
    1103 #endif
     1097    }
    11041098
    11051099    // Interrupt gates set IF to 0
  • trunk/src/VBox/VMM/VMMR3/SELM.cpp

    r45276 r45485  
    6363#include <VBox/vmm/cpum.h>
    6464#include <VBox/vmm/stam.h>
     65#include <VBox/vmm/em.h>
    6566#include <VBox/vmm/mm.h>
    6667#include <VBox/vmm/ssm.h>
     
    8081#include <iprt/string.h>
    8182
     83#include "SELMInline.h"
    8284
    8385
     
    957959
    958960#ifdef VBOX_WITH_SAFE_STR
    959     /** Use the guest's TR selector to plug the str virtualization hole. */
     961    /* Use the guest's TR selector to plug the str virtualization hole. */
    960962    if (CPUMGetGuestTR(pVCpu, NULL) != 0)
    961963    {
     
    10291031    {
    10301032        Log(("SELMR3UpdateFromCPUM: Guest's GDT is changed to pGdt=%016RX64 cbGdt=%08X\n", GDTR.pGdt, GDTR.cbGdt));
     1033
    10311034#ifdef SELM_TRACK_GUEST_GDT_CHANGES
    10321035        /*
     
    10441047                                         "Guest GDT write access handler");
    10451048# ifdef VBOX_WITH_RAW_RING1
    1046         /* Some guest OSes (QNX) share code and the GDT on the same page; PGMR3HandlerVirtualRegister doesn't support more than one handler, so we kick out the
    1047          * PATM handler as this one is more important.
    1048          * @todo fix this properly in PGMR3HandlerVirtualRegister
     1049        /** @todo !HACK ALERT!
     1050         * Some guest OSes (QNX) share code and the GDT on the same page;
     1051         * PGMR3HandlerVirtualRegister doesn't support more than one handler,
     1052         * so we kick out the  PATM handler as this one is more important.
     1053         * Fix this properly in PGMR3HandlerVirtualRegister?
    10491054         */
    10501055        if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
     
    10621067        if (RT_FAILURE(rc))
    10631068            return rc;
    1064 #endif
     1069#endif /* SELM_TRACK_GUEST_GDT_CHANGES */
     1070
    10651071        /* Update saved Guest GDTR. */
    10661072        pVM->selm.s.GuestGdtr = GDTR;
     
    12431249    /** @todo investigate how intel handle various operations on half present cross page entries. */
    12441250    off = GCPtrLdt & (sizeof(X86DESC) - 1);
    1245 ////    AssertMsg(!off, ("LDT is not aligned on entry size! GCPtrLdt=%08x\n", GCPtrLdt));
     1251    AssertMsg(!off, ("LDT is not aligned on entry size! GCPtrLdt=%08x\n", GCPtrLdt));
    12461252
    12471253    /* Note: Do not skip the first selector; unlike the GDT, a zero LDT selector is perfectly valid. */
     
    14731479    STAM_PROFILE_STOP(&pVM->selm.s.StatUpdateFromCPUM, a);
    14741480    return rcStrict;
    1475 #endif
    1476 }
     1481#endif /* VBOX_WITH_RAW_MODE */
     1482}
     1483
    14771484
    14781485#ifdef SELM_TRACK_GUEST_GDT_CHANGES
     
    15681575}
    15691576#endif
     1577
    15701578
    15711579/**
     
    17191727#ifdef VBOX_WITH_RAW_RING1
    17201728            /* Update our TSS structure for the guest's ring 2 stack */
    1721             selmSetRing2Stack(pVM, (Tss.ss1 & ~1) | 2, Tss.esp1);
    1722 
    1723             if (    (pVM->selm.s.Tss.ss2 != ((Tss.ss1 & ~2) | 1))
    1724                 ||  pVM->selm.s.Tss.esp2 != Tss.esp1)
     1729            if (EMIsRawRing1Enabled(pVM))
    17251730            {
    1726                 Log(("SELMR3SyncTSS: Updating TSS ring 1 stack to %04X:%08X from %04X:%08X\n", Tss.ss1, Tss.esp1, (pVM->selm.s.Tss.ss2 & ~2) | 1, pVM->selm.s.Tss.esp2));
     1731                if (    (pVM->selm.s.Tss.ss2 != ((Tss.ss1 & ~2) | 1))
     1732                    ||  pVM->selm.s.Tss.esp2 != Tss.esp1)
     1733                    Log(("SELMR3SyncTSS: Updating TSS ring 1 stack to %04X:%08X from %04X:%08X\n", Tss.ss1, Tss.esp1, (pVM->selm.s.Tss.ss2 & ~2) | 1, pVM->selm.s.Tss.esp2));
     1734                selmSetRing2Stack(pVM, (Tss.ss1 & ~1) | 2, Tss.esp1);
    17271735            }
    17281736#endif
     
    17701778            {
    17711779# ifdef VBOX_WITH_RAW_RING1
    1772                 /* Some guest OSes (QNX) share code and the TSS on the same page; PGMR3HandlerVirtualRegister doesn't support more than one handler, so we kick out the
    1773                  * PATM handler as this one is more important.
    1774                  * @todo fix this properly in PGMR3HandlerVirtualRegister
     1780                /** @todo !HACK ALERT!
     1781                 * Some guest OSes (QNX) share code and the TSS on the same page;
     1782                 * PGMR3HandlerVirtualRegister doesn't support more than one
     1783                 * handler, so we kick out the PATM handler as this one is more
     1784                 * important. Fix this properly in PGMR3HandlerVirtualRegister?
    17751785                 */
    17761786                if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
     
    17941804# endif
    17951805           }
    1796 #endif
     1806#endif /* SELM_TRACK_GUEST_TSS_CHANGES */
     1807
    17971808            /* Update saved Guest TSS info. */
    17981809            pVM->selm.s.GCPtrGuestTss       = GCPtrTss;
     
    20952106}
    20962107
     2108
    20972109# ifdef VBOX_WITH_SAFE_STR
    20982110/**
    2099  * Validates the RawR0 TR shadow GDT entry
     2111 * Validates the RawR0 TR shadow GDT entry.
    21002112 *
    21012113 * @returns true if it matches.
     
    21352147    return true;
    21362148}
    2137 # endif
     2149# endif /* VBOX_WITH_SAFE_STR */
    21382150
    21392151#endif /* VBOX_WITH_RAW_MODE */
  • trunk/src/VBox/VMM/VMMR3/TRPM.cpp

    r45276 r45485  
    13311331
    13321332    if (    EMIsRawRing0Enabled(pVM)
    1333 #ifdef VBOX_WITH_RAW_RING1
    1334         && !EMIsRawRing1Enabled(pVM)    /* can't deal with the ambiguity of ring 1 & 2 in the patch code. */
    1335 #endif
    1336        )
     1333        && !EMIsRawRing1Enabled(pVM))   /* can't deal with the ambiguity of ring 1 & 2 in the patch code. */
    13371334    {
    13381335        /*
  • trunk/src/VBox/VMM/VMMRC/CPUMRC.cpp

    r45276 r45485  
    115115 * @param   pVCpu       The current virtual CPU.
    116116 * @param   pRegFrame   Pointer to the register frame.
     117 *
     118 * @todo    r=bird: This is very similar to CPUMGetGuestCPL and I cannot quite
     119 *          see why this variant of the code is necessary.
    117120 */
    118121VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame)
     
    142145        if (pVCpu->cpum.s.fRawEntered)
    143146        {
    144             if (    EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM))
    145                 &&  uCpl == 2)
     147            if (   uCpl == 2
     148                && EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM)) )
    146149                uCpl = 1;
    147             else
    148             if (uCpl == 1)
     150            else if (uCpl == 1)
    149151                uCpl = 0;
    150152        }
     
    162164}
    163165
     166
    164167#ifdef VBOX_WITH_RAW_RING1
    165168/**
     
    168171 * This function will change the any of the cs and ss register with DPL=0 to DPL=1.
    169172 *
    170  * @returns VBox status. (recompiler failure)
     173 * Used by emInterpretIret() after the new state has been loaded.
     174 *
    171175 * @param   pVCpu       Pointer to the VMCPU.
    172176 * @param   pCtxCore    The context core (for trap usage).
    173177 * @see     @ref pg_raw
     178 * @remarks Will be probably obsoleted by #5653 (it will leave and reenter raw
     179 *          mode instead, I think).
    174180 */
    175181VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore)
     
    213219}
    214220#endif /* VBOX_WITH_RAW_RING1 */
     221
  • trunk/src/VBox/VMM/VMMRC/PATMRC.cpp

    r45276 r45485  
    155155
    156156    /* Very important check -> otherwise we have a security leak. */
    157 #ifdef VBOX_WITH_RAW_RING1
    158     AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) <= (unsigned) (EMIsRawRing1Enabled(pVM) ? 2 : 1), VERR_ACCESS_DENIED);
    159 #else
    160     AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1, VERR_ACCESS_DENIED);
    161 #endif
     157    AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) <= (EMIsRawRing1Enabled(pVM) ? 2U : 1U),
     158                 VERR_ACCESS_DENIED);
    162159    Assert(PATMIsPatchGCAddr(pVM, pRegFrame->eip));
    163160
     
    459456    int rc;
    460457
    461 #ifdef VBOX_WITH_RAW_RING1
    462     AssertReturn(!pRegFrame->eflags.Bits.u1VM && ((pRegFrame->ss.Sel & X86_SEL_RPL) == 1 || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)), VERR_ACCESS_DENIED);
    463 #else
    464     AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1, VERR_ACCESS_DENIED);
    465 #endif
     458    AssertReturn(!pRegFrame->eflags.Bits.u1VM
     459                 && (   (pRegFrame->ss.Sel & X86_SEL_RPL) == 1
     460                     || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)), VERR_ACCESS_DENIED);
    466461
    467462    /* Int 3 in PATM generated code? (most common case) */
  • trunk/src/VBox/VMM/VMMRC/SELMRC.cpp

    r45276 r45485  
    3535#include <iprt/asm.h>
    3636
     37#include "SELMInline.h"
     38
    3739
    3840/*******************************************************************************
     
    4345static char const g_aszSRegNms[X86_SREG_COUNT][4] = { "ES", "CS", "SS", "DS", "FS", "GS" };
    4446#endif
     47
    4548
    4649#ifdef SELM_TRACK_GUEST_GDT_CHANGES
     
    308311#endif /* SELM_TRACK_GUEST_GDT_CHANGES */
    309312
     313
    310314#ifdef SELM_TRACK_GUEST_LDT_CHANGES
    311315/**
     
    332336}
    333337#endif
     338
    334339
    335340#ifdef SELM_TRACK_GUEST_TSS_CHANGES
     
    407412        }
    408413#ifdef VBOX_WITH_RAW_RING1
    409         else
    410         if (    EMIsRawRing1Enabled(pVM)
    411             &&  PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS(&pGuestTss->padding_ss1)
    412             &&  PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS((uint8_t *)pGuestTss + offRange)
    413             &&  (    pGuestTss->esp1 !=  pVM->selm.s.Tss.esp2
    414                  ||  pGuestTss->ss1  != ((pVM->selm.s.Tss.ss2 & ~2) | 1)) /* undo raw-r1 */
    415            )
     414        else if (    EMIsRawRing1Enabled(pVM)
     415                 &&  PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS(&pGuestTss->padding_ss1)
     416                 &&  PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS((uint8_t *)pGuestTss + offRange)
     417                 &&  (    pGuestTss->esp1 !=  pVM->selm.s.Tss.esp2
     418                      ||  pGuestTss->ss1  != ((pVM->selm.s.Tss.ss2 & ~2) | 1)) /* undo raw-r1 */
     419                )
    416420        {
    417421            Log(("selmRCGuestTSSWriteHandler: R1 stack: %RTsel:%RGv -> %RTsel:%RGv\n",
     
    513517#endif /* SELM_TRACK_GUEST_TSS_CHANGES */
    514518
     519
    515520#ifdef SELM_TRACK_SHADOW_GDT_CHANGES
    516521/**
     
    534539#endif
    535540
     541
    536542#ifdef SELM_TRACK_SHADOW_LDT_CHANGES
    537543/**
     
    556562#endif
    557563
     564
    558565#ifdef SELM_TRACK_SHADOW_TSS_CHANGES
    559566/**
  • trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp

    r45305 r45485  
    304304    PVM         pVM   = TRPMCPU_2_VM(pTrpmCpu);
    305305    PVMCPU      pVCpu = TRPMCPU_2_VMCPU(pTrpmCpu);
    306     //LogFlow(("TRPMGC01: cs:eip=%04x:%08x uDr6=%RTreg EFL=%x\n", pRegFrame->cs.Sel, pRegFrame->eip, uDr6, CPUMRawGetEFlags(pVCpu)));
     306    LogFlow(("TRPMGC01: cs:eip=%04x:%08x uDr6=%RTreg EFL=%x\n", pRegFrame->cs.Sel, pRegFrame->eip, uDr6, CPUMRawGetEFlags(pVCpu)));
    307307    TRPM_ENTER_DBG_HOOK(1);
    308308
     
    445445     * PATM is using INT3s, let them have a go first.
    446446     */
    447 #ifdef VBOX_WITH_RAW_RING1
    448     if (    (   (pRegFrame->ss.Sel & X86_SEL_RPL) == 1
    449              || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2))
    450 #else
    451     if (    (pRegFrame->ss.Sel & X86_SEL_RPL) == 1
    452 #endif
    453         &&  !pRegFrame->eflags.Bits.u1VM)
     447    if (   (   (pRegFrame->ss.Sel & X86_SEL_RPL) == 1
     448            || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2) )
     449        && !pRegFrame->eflags.Bits.u1VM)
    454450    {
    455451        rc = PATMRCHandleInt3PatchTrap(pVM, pRegFrame);
     
    528524    PGMRZDynMapStartAutoSet(pVCpu);
    529525
    530 #ifdef VBOX_WITH_RAW_RING1
    531     if (CPUMGetGuestCPL(pVCpu) <= (unsigned)(EMIsRawRing1Enabled(pVM) ? 1 : 0))
    532 #else
    533     if (CPUMGetGuestCPL(pVCpu) == 0)
    534 #endif
     526    if (CPUMGetGuestCPL(pVCpu) <= (EMIsRawRing1Enabled(pVM) ? 1U : 0U))
    535527    {
    536528        /*
  • trunk/src/VBox/VMM/include/SELMInline.h

    r45473 r45485  
    1616 */
    1717
    18 #ifndef ___SELMInternal_h
    19 #define ___SELMInternal_h
    20 
    21 #include <VBox/cdefs.h>
    22 #include <VBox/types.h>
    23 #include <VBox/vmm/stam.h>
    24 #include <VBox/vmm/cpum.h>
    25 #include <VBox/log.h>
    26 #include <iprt/x86.h>
    27 #include <VBox/vmm/em.h>
    28 
    29 
    30 
    31 /** @defgroup grp_selm_int   Internals
    32  * @ingroup grp_selm
    33  * @internal
    34  * @{
    35  */
    36 
    37 /**
    38  * Enable or disable tracking of Shadow GDT/LDT/TSS.
    39  * @{
    40  */
    41 #define SELM_TRACK_SHADOW_GDT_CHANGES
    42 #define SELM_TRACK_SHADOW_LDT_CHANGES
    43 #define SELM_TRACK_SHADOW_TSS_CHANGES
    44 /** @} */
    45 
    46 /**
    47  * Enable or disable tracking of Guest GDT/LDT/TSS.
    48  * @{
    49  */
    50 #define SELM_TRACK_GUEST_GDT_CHANGES
    51 #define SELM_TRACK_GUEST_LDT_CHANGES
    52 #define SELM_TRACK_GUEST_TSS_CHANGES
    53 /** @} */
    54 
    55 
    56 /** The number of GDTS allocated for our GDT. (full size) */
    57 #define SELM_GDT_ELEMENTS                   8192
    58 
    59 /** aHyperSel index to retrieve hypervisor selectors */
    60 /** The Flat CS selector used by the VMM inside the GC. */
    61 #define SELM_HYPER_SEL_CS                   0
    62 /** The Flat DS selector used by the VMM inside the GC. */
    63 #define SELM_HYPER_SEL_DS                   1
    64 /** The 64-bit mode CS selector used by the VMM inside the GC. */
    65 #define SELM_HYPER_SEL_CS64                 2
    66 /** The TSS selector used by the VMM inside the GC. */
    67 #define SELM_HYPER_SEL_TSS                  3
    68 /** The TSS selector for taking trap 08 (\#DF). */
    69 #define SELM_HYPER_SEL_TSS_TRAP08           4
    70 /** Number of GDTs we need for internal use */
    71 #define SELM_HYPER_SEL_MAX                  (SELM_HYPER_SEL_TSS_TRAP08 + 1)
    72 
    73 
    74 /** Default GDT selectors we use for the hypervisor. */
    75 #define SELM_HYPER_DEFAULT_SEL_CS           ((SELM_GDT_ELEMENTS - 0x1) << 3)
    76 #define SELM_HYPER_DEFAULT_SEL_DS           ((SELM_GDT_ELEMENTS - 0x2) << 3)
    77 #define SELM_HYPER_DEFAULT_SEL_CS64         ((SELM_GDT_ELEMENTS - 0x3) << 3)
    78 #define SELM_HYPER_DEFAULT_SEL_TSS          ((SELM_GDT_ELEMENTS - 0x4) << 3)
    79 #define SELM_HYPER_DEFAULT_SEL_TSS_TRAP08   ((SELM_GDT_ELEMENTS - 0x5) << 3)
    80 /** The lowest value default we use. */
    81 #define SELM_HYPER_DEFAULT_BASE             SELM_HYPER_DEFAULT_SEL_TSS_TRAP08
    82 
    83 /**
    84  * Converts a SELM pointer into a VM pointer.
    85  * @returns Pointer to the VM structure the SELM is part of.
    86  * @param   pSELM   Pointer to SELM instance data.
    87  */
    88 #define SELM2VM(pSELM)  ( (PVM)((char *)pSELM - pSELM->offVM) )
    89 
    90 
    91 
    92 /**
    93  * SELM Data (part of VM)
    94  */
    95 typedef struct SELM
    96 {
    97     /** Offset to the VM structure.
    98      * See SELM2VM(). */
    99     RTINT                   offVM;
    100 
    101     /** Flat CS, DS, 64 bit mode CS, TSS & trap 8 TSS. */
    102     RTSEL                   aHyperSel[SELM_HYPER_SEL_MAX];
    103 
    104     /** Pointer to the GCs - R3 Ptr.
    105      * This size is governed by SELM_GDT_ELEMENTS. */
    106     R3PTRTYPE(PX86DESC)     paGdtR3;
    107     /** Pointer to the GCs - RC Ptr.
    108      * This is not initialized until the first relocation because it's used to
    109      * check if the shadow GDT virtual handler requires deregistration. */
    110     RCPTRTYPE(PX86DESC)     paGdtRC;
    111     /** Current (last) Guest's GDTR.
    112      * The pGdt member is set to RTRCPTR_MAX if we're not monitoring the guest GDT. */
    113     VBOXGDTR                GuestGdtr;
    114     /** The current (last) effective Guest GDT size. */
    115     RTUINT                  cbEffGuestGdtLimit;
    116 
    117     uint32_t                padding0;
    118 
    119     /** R3 pointer to the LDT shadow area in HMA. */
    120     R3PTRTYPE(void *)       pvLdtR3;
    121     /** RC pointer to the LDT shadow area in HMA. */
    122     RCPTRTYPE(void *)       pvLdtRC;
    123 #if GC_ARCH_BITS == 64
    124     RTRCPTR                 padding1;
    125 #endif
    126     /** The address of the guest LDT.
    127      * RTRCPTR_MAX if not monitored. */
    128     RTGCPTR                 GCPtrGuestLdt;
    129     /** Current LDT limit, both Guest and Shadow. */
    130     RTUINT                  cbLdtLimit;
    131     /** Current LDT offset relative to pvLdtR3/pvLdtRC. */
    132     RTUINT                  offLdtHyper;
    133 #if HC_ARCH_BITS == 32 && GC_ARCH_BITS == 64
    134     uint32_t                padding2[2];
    135 #endif
    136     /** TSS. (This is 16 byte aligned!)
    137       * @todo I/O bitmap & interrupt redirection table? */
    138     VBOXTSS                 Tss;
    139 
    140     /** TSS for trap 08 (\#DF). */
    141     VBOXTSS                 TssTrap08;
    142 
    143     /** Monitored shadow TSS address. */
    144     RCPTRTYPE(void *)       pvMonShwTssRC;
    145 #if GC_ARCH_BITS == 64
    146     RTRCPTR                 padding3;
    147 #endif
    148     /** GC Pointer to the current Guest's TSS.
    149      * RTRCPTR_MAX if not monitored. */
    150     RTGCPTR                 GCPtrGuestTss;
    151     /** The size of the guest TSS. */
    152     RTUINT                  cbGuestTss;
    153     /** Set if it's a 32-bit TSS. */
    154     bool                    fGuestTss32Bit;
    155     /** The size of the Guest's TSS part we're monitoring. */
    156     RTUINT                  cbMonitoredGuestTss;
    157     /** The guest TSS selector at last sync (part of monitoring).
    158      * Contains RTSEL_MAX if not set. */
    159     RTSEL                   GCSelTss;
    160     /** The last known offset of the I/O bitmap.
    161      * This is only used if we monitor the bitmap. */
    162     uint16_t                offGuestIoBitmap;
    163 
    164     /** Indicates that the Guest GDT access handler have been registered. */
    165     bool                    fGDTRangeRegistered;
    166 
    167     /** Indicates whether LDT/GDT/TSS monitoring and syncing is disabled. */
    168     bool                    fDisableMonitoring;
    169 
    170     /** Indicates whether the TSS stack selector & base address need to be refreshed.  */
    171     bool                    fSyncTSSRing0Stack;
    172     bool                    fPadding2[1+2];
    173 
    174     /** SELMR3UpdateFromCPUM() profiling. */
    175     STAMPROFILE             StatUpdateFromCPUM;
    176     /** SELMR3SyncTSS() profiling. */
    177     STAMPROFILE             StatTSSSync;
    178 
    179     /** GC: The number of handled writes to the Guest's GDT. */
    180     STAMCOUNTER             StatRCWriteGuestGDTHandled;
    181     /** GC: The number of unhandled write to the Guest's GDT. */
    182     STAMCOUNTER             StatRCWriteGuestGDTUnhandled;
    183     /** GC: The number of times writes to Guest's LDT was detected. */
    184     STAMCOUNTER             StatRCWriteGuestLDT;
    185     /** GC: The number of handled writes to the Guest's TSS. */
    186     STAMCOUNTER             StatRCWriteGuestTSSHandled;
    187     /** GC: The number of handled writes to the Guest's TSS where we detected a change. */
    188     STAMCOUNTER             StatRCWriteGuestTSSHandledChanged;
    189     /** GC: The number of handled redir writes to the Guest's TSS where we detected a change. */
    190     STAMCOUNTER             StatRCWriteGuestTSSRedir;
    191     /** GC: The number of unhandled writes to the Guest's TSS. */
    192     STAMCOUNTER             StatRCWriteGuestTSSUnhandled;
    193     /** The number of times we had to relocate our hypervisor selectors. */
    194     STAMCOUNTER             StatHyperSelsChanged;
    195     /** The number of times we had find free hypervisor selectors. */
    196     STAMCOUNTER             StatScanForHyperSels;
    197     /** Counts the times we detected state selectors in SELMR3UpdateFromCPUM. */
    198     STAMCOUNTER             aStatDetectedStaleSReg[X86_SREG_COUNT];
    199     /** Counts the times we were called with already state selectors in
    200      * SELMR3UpdateFromCPUM. */
    201     STAMCOUNTER             aStatAlreadyStaleSReg[X86_SREG_COUNT];
    202     /** Counts the times we found a stale selector becomming valid again. */
    203     STAMCOUNTER             StatStaleToUnstaleSReg;
    204 #ifdef VBOX_WITH_STATISTICS
    205     /** Times we updated hidden selector registers in CPUMR3UpdateFromCPUM. */
    206     STAMCOUNTER             aStatUpdatedSReg[X86_SREG_COUNT];
    207     STAMCOUNTER             StatLoadHidSelGst;
    208     STAMCOUNTER             StatLoadHidSelShw;
    209 #endif
    210     STAMCOUNTER             StatLoadHidSelReadErrors;
    211     STAMCOUNTER             StatLoadHidSelGstNoGood;
    212 } SELM, *PSELM;
    213 
    214 RT_C_DECLS_BEGIN
    215 
    216 VMMRCDECL(int) selmRCGuestGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    217 VMMRCDECL(int) selmRCGuestLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    218 VMMRCDECL(int) selmRCGuestTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    219 
    220 VMMRCDECL(int) selmRCShadowGDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    221 VMMRCDECL(int) selmRCShadowLDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    222 VMMRCDECL(int) selmRCShadowTSSWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    223 
    224 void           selmSetRing1Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp);
    225 #ifdef VBOX_WITH_RAW_RING1
    226 void           selmSetRing2Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp);
    227 #endif
    228 
    229 RT_C_DECLS_END
    230 
     18#ifndef ___SELMInline_h
     19#define ___SELMInline_h
    23120
    23221#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     
    416205        }
    417206# ifdef VBOX_WITH_RAW_RING1
    418         else
    419         if (    pDesc->Gen.u2Dpl == 1
    420 //            &&  EMIsRawRing1Enabled(pVM)
    421             &&      (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
    422                 !=  (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) )
     207        else if (    pDesc->Gen.u2Dpl == 1
     208                 &&  EMIsRawRing1Enabled(pVM)
     209                 &&      (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
     210                     !=  (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) )
    423211        {
    424212            pDesc->Gen.u2Dpl       = 2;
  • trunk/src/VBox/VMM/include/SELMInternal.h

    r45276 r45485  
    2525#include <VBox/log.h>
    2626#include <iprt/x86.h>
    27 #include <VBox/vmm/em.h>
    2827
    2928
     
    229228RT_C_DECLS_END
    230229
    231 
    232 #ifdef VBOX_WITH_RAW_MODE_NOT_R0
    233 
    234 /**
    235  * Checks if a shadow descriptor table entry is good for the given segment
    236  * register.
    237  *
    238  * @returns @c true if good, @c false if not.
    239  * @param   pSReg               The segment register.
    240  * @param   pShwDesc            The shadow descriptor table entry.
    241  * @param   iSReg               The segment register index (X86_SREG_XXX).
    242  * @param   uCpl                The CPL.
    243  */
    244 DECLINLINE(bool) selmIsShwDescGoodForSReg(PCCPUMSELREG pSReg, PCX86DESC pShwDesc, uint32_t iSReg, uint32_t uCpl)
    245 {
    246     /*
    247      * See iemMiscValidateNewSS, iemCImpl_LoadSReg and intel+amd manuals.
    248      */
    249 
    250     if (!pShwDesc->Gen.u1Present)
    251     {
    252         Log(("selmIsShwDescGoodForSReg: Not present\n"));
    253         return false;
    254     }
    255 
    256     if (!pShwDesc->Gen.u1DescType)
    257     {
    258         Log(("selmIsShwDescGoodForSReg: System descriptor\n"));
    259         return false;
    260     }
    261 
    262     if (iSReg == X86_SREG_SS)
    263     {
    264         if ((pShwDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_WRITE)) != X86_SEL_TYPE_WRITE)
    265         {
    266             Log(("selmIsShwDescGoodForSReg: Stack must be writable\n"));
    267             return false;
    268         }
    269         if (uCpl > (unsigned)pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available)
    270         {
    271             Log(("selmIsShwDescGoodForSReg: CPL(%d) > DPL(%d)\n", uCpl, pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available));
    272             return false;
    273         }
    274     }
    275     else
    276     {
    277         if (iSReg == X86_SREG_CS)
    278         {
    279             if (!(pShwDesc->Gen.u4Type & X86_SEL_TYPE_CODE))
    280             {
    281                 Log(("selmIsShwDescGoodForSReg: CS needs code segment\n"));
    282                 return false;
    283             }
    284         }
    285         else if ((pShwDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE)
    286         {
    287             Log(("selmIsShwDescGoodForSReg: iSReg=%u execute only\n", iSReg));
    288             return false;
    289         }
    290 
    291         if (       (pShwDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
    292                 != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF)
    293             &&  (   (   (pSReg->Sel & X86_SEL_RPL) > (unsigned)pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available
    294                      && (pSReg->Sel & X86_SEL_RPL) != pShwDesc->Gen.u1Available )
    295                  || uCpl > (unsigned)pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available ) )
    296         {
    297             Log(("selmIsShwDescGoodForSReg: iSReg=%u DPL=%u CPL=%u RPL=%u\n", iSReg,
    298                  pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available, uCpl, pSReg->Sel & X86_SEL_RPL));
    299             return false;
    300         }
    301     }
    302 
    303     return true;
    304 }
    305 
    306 
    307 /**
    308  * Checks if a guest descriptor table entry is good for the given segment
    309  * register.
    310  *
    311  * @returns @c true if good, @c false if not.
    312  * @param   pVCpu               The current virtual CPU.
    313  * @param   pSReg               The segment register.
    314  * @param   pGstDesc            The guest descriptor table entry.
    315  * @param   iSReg               The segment register index (X86_SREG_XXX).
    316  * @param   uCpl                The CPL.
    317  */
    318 DECLINLINE(bool) selmIsGstDescGoodForSReg(PVMCPU pVCpu, PCCPUMSELREG pSReg, PCX86DESC pGstDesc, uint32_t iSReg, uint32_t uCpl)
    319 {
    320     /*
    321      * See iemMiscValidateNewSS, iemCImpl_LoadSReg and intel+amd manuals.
    322      */
    323 
    324     if (!pGstDesc->Gen.u1Present)
    325     {
    326         Log(("selmIsGstDescGoodForSReg: Not present\n"));
    327         return false;
    328     }
    329 
    330     if (!pGstDesc->Gen.u1DescType)
    331     {
    332         Log(("selmIsGstDescGoodForSReg: System descriptor\n"));
    333         return false;
    334     }
    335 
    336     if (iSReg == X86_SREG_SS)
    337     {
    338         if ((pGstDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_WRITE)) != X86_SEL_TYPE_WRITE)
    339         {
    340             Log(("selmIsGstDescGoodForSReg: Stack must be writable\n"));
    341             return false;
    342         }
    343         if (uCpl > pGstDesc->Gen.u2Dpl)
    344         {
    345             Log(("selmIsGstDescGoodForSReg: CPL(%d) > DPL(%d)\n", uCpl, pGstDesc->Gen.u2Dpl));
    346             return false;
    347         }
    348     }
    349     else
    350     {
    351         if (iSReg == X86_SREG_CS)
    352         {
    353             if (!(pGstDesc->Gen.u4Type & X86_SEL_TYPE_CODE))
    354             {
    355                 Log(("selmIsGstDescGoodForSReg: CS needs code segment\n"));
    356                 return false;
    357             }
    358         }
    359         else if ((pGstDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE)
    360         {
    361             Log(("selmIsGstDescGoodForSReg: iSReg=%u execute only\n", iSReg));
    362             return false;
    363         }
    364 
    365         if (       (pGstDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
    366                 != (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF)
    367             &&  (   (   (pSReg->Sel & X86_SEL_RPL) > pGstDesc->Gen.u2Dpl
    368                      && (   (pSReg->Sel & X86_SEL_RPL) != 1
    369                          || !CPUMIsGuestInRawMode(pVCpu) ) )
    370                  || uCpl > (unsigned)pGstDesc->Gen.u2Dpl
    371                 )
    372            )
    373         {
    374             Log(("selmIsGstDescGoodForSReg: iSReg=%u DPL=%u CPL=%u RPL=%u InRawMode=%u\n", iSReg,
    375                  pGstDesc->Gen.u2Dpl, uCpl, pSReg->Sel & X86_SEL_RPL, CPUMIsGuestInRawMode(pVCpu)));
    376             return false;
    377         }
    378     }
    379 
    380     return true;
    381 }
    382 
    383 
    384 /**
    385  * Converts a guest GDT or LDT entry to a shadow table entry.
    386  *
    387  * @param   pVM                 The VM handle.
    388  * @param   pDesc       Guest entry on input, shadow entry on return.
    389  */
    390 DECL_FORCE_INLINE(void) selmGuestToShadowDesc(PVM pVM, PX86DESC pDesc)
    391 {
    392     /*
    393      * Code and data selectors are generally 1:1, with the
    394      * 'little' adjustment we do for DPL 0 selectors.
    395      */
    396     if (pDesc->Gen.u1DescType)
    397     {
    398         /*
    399          * Hack for A-bit against Trap E on read-only GDT.
    400          */
    401         /** @todo Fix this by loading ds and cs before turning off WP. */
    402         pDesc->Gen.u4Type |= X86_SEL_TYPE_ACCESSED;
    403 
    404         /*
    405          * All DPL 0 code and data segments are squeezed into DPL 1.
    406          *
    407          * We're skipping conforming segments here because those
    408          * cannot give us any trouble.
    409          */
    410         if (    pDesc->Gen.u2Dpl == 0
    411             &&      (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
    412                 !=  (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) )
    413         {
    414             pDesc->Gen.u2Dpl       = 1;
    415             pDesc->Gen.u1Available = 1;
    416         }
    417 # ifdef VBOX_WITH_RAW_RING1
    418         else
    419         if (    pDesc->Gen.u2Dpl == 1
    420 //            &&  EMIsRawRing1Enabled(pVM)
    421             &&      (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
    422                 !=  (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) )
    423         {
    424             pDesc->Gen.u2Dpl       = 2;
    425             pDesc->Gen.u1Available = 1;
    426         }
    427 # endif
    428         else
    429             pDesc->Gen.u1Available = 0;
    430     }
    431     else
    432     {
    433         /*
    434          * System type selectors are marked not present.
    435          * Recompiler or special handling is required for these.
    436          */
    437         /** @todo what about interrupt gates and rawr0? */
    438         pDesc->Gen.u1Present = 0;
    439     }
    440 }
    441 
    442 
    443 /**
    444  * Checks if a segment register is stale given the shadow descriptor table
    445  * entry.
    446  *
    447  * @returns @c true if stale, @c false if not.
    448  * @param   pSReg               The segment register.
    449  * @param   pShwDesc            The shadow descriptor entry.
    450  * @param   iSReg               The segment register number (X86_SREG_XXX).
    451  */
    452 DECLINLINE(bool) selmIsSRegStale32(PCCPUMSELREG pSReg, PCX86DESC pShwDesc, uint32_t iSReg)
    453 {
    454     if (   pSReg->Attr.n.u1Present     != pShwDesc->Gen.u1Present
    455         || pSReg->Attr.n.u4Type        != pShwDesc->Gen.u4Type
    456         || pSReg->Attr.n.u1DescType    != pShwDesc->Gen.u1DescType
    457         || pSReg->Attr.n.u1DefBig      != pShwDesc->Gen.u1DefBig
    458         || pSReg->Attr.n.u1Granularity != pShwDesc->Gen.u1Granularity
    459         || pSReg->Attr.n.u2Dpl         != pShwDesc->Gen.u2Dpl - pShwDesc->Gen.u1Available)
    460     {
    461         Log(("selmIsSRegStale32: Attributes changed (%#x -> %#x)\n", pSReg->Attr.u, X86DESC_GET_HID_ATTR(pShwDesc)));
    462         return true;
    463     }
    464 
    465     if (pSReg->u64Base != X86DESC_BASE(pShwDesc))
    466     {
    467         Log(("selmIsSRegStale32: base changed (%#llx -> %#llx)\n", pSReg->u64Base, X86DESC_BASE(pShwDesc)));
    468         return true;
    469     }
    470 
    471     if (pSReg->u32Limit != X86DESC_LIMIT_G(pShwDesc))
    472     {
    473         Log(("selmIsSRegStale32: limit changed (%#x -> %#x)\n", pSReg->u32Limit, X86DESC_LIMIT_G(pShwDesc)));
    474         return true;
    475     }
    476 
    477     return false;
    478 }
    479 
    480 
    481 /**
    482  * Loads the hidden bits of a selector register from a shadow descriptor table
    483  * entry.
    484  *
    485  * @param   pSReg               The segment register in question.
    486  * @param   pShwDesc            The shadow descriptor table entry.
    487  */
    488 DECLINLINE(void) selmLoadHiddenSRegFromShadowDesc(PCPUMSELREG pSReg, PCX86DESC pShwDesc)
    489 {
    490     pSReg->Attr.u         = X86DESC_GET_HID_ATTR(pShwDesc);
    491     pSReg->Attr.n.u2Dpl  -= pSReg->Attr.n.u1Available;
    492     Assert(pSReg->Attr.n.u4Type & X86_SEL_TYPE_ACCESSED);
    493     pSReg->u32Limit       = X86DESC_LIMIT_G(pShwDesc);
    494     pSReg->u64Base        = X86DESC_BASE(pShwDesc);
    495     pSReg->ValidSel       = pSReg->Sel;
    496     if (pSReg->Attr.n.u1Available)
    497         pSReg->ValidSel  &= ~(RTSEL)1;
    498     pSReg->fFlags         = CPUMSELREG_FLAGS_VALID;
    499 }
    500 
    501 
    502 /**
    503  * Loads the hidden bits of a selector register from a guest descriptor table
    504  * entry.
    505  *
    506  * @param   pVCpu               The current virtual CPU.
    507  * @param   pSReg               The segment register in question.
    508  * @param   pGstDesc            The guest descriptor table entry.
    509  */
    510 DECLINLINE(void) selmLoadHiddenSRegFromGuestDesc(PVMCPU pVCpu, PCPUMSELREG pSReg, PCX86DESC pGstDesc)
    511 {
    512     pSReg->Attr.u         = X86DESC_GET_HID_ATTR(pGstDesc);
    513     pSReg->Attr.n.u4Type |= X86_SEL_TYPE_ACCESSED;
    514     pSReg->u32Limit       = X86DESC_LIMIT_G(pGstDesc);
    515     pSReg->u64Base        = X86DESC_BASE(pGstDesc);
    516     pSReg->ValidSel       = pSReg->Sel;
    517     if ((pSReg->ValidSel & 1) && CPUMIsGuestInRawMode(pVCpu))
    518         pSReg->ValidSel  &= ~(RTSEL)1;
    519     pSReg->fFlags         = CPUMSELREG_FLAGS_VALID;
    520 }
    521 
    522 #endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
    523 
    524230/** @} */
    525231
  • trunk/src/recompiler/VBoxRecompiler.c

    r45305 r45485  
    16331633        }
    16341634
    1635 # ifdef VBOX_WITH_RAW_RING1
    1636         /* Only ring 0 and 1 supervisor code. */
    16371635        if (EMIsRawRing1Enabled(env->pVM))
    16381636        {
    1639             if (((fFlags >> HF_CPL_SHIFT) & 3) == 2)   /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */
     1637            /* Only ring 0 and 1 supervisor code. */
     1638            if (((fFlags >> HF_CPL_SHIFT) & 3) == 2) /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */
    16401639            {
    16411640                Log2(("raw r0 mode refused: CPL %d\n", (fFlags >> HF_CPL_SHIFT) & 3));
     
    16431642            }
    16441643        }
    1645         else
    1646 # endif
    1647         // Only R0
    1648         if (((fFlags >> HF_CPL_SHIFT) & 3) != 0)
     1644        /* Only R0. */
     1645        else if (((fFlags >> HF_CPL_SHIFT) & 3) != 0)
    16491646        {
    16501647            STAM_COUNTER_INC(&gStatRefuseRing1or2);
  • trunk/src/recompiler/target-i386/op_helper.c

    r45276 r45485  
    232232#ifdef VBOX
    233233    /* Trying to load a selector with CPL=1? */
    234     /* @todo this is a hack to correct the incorrect checking order for pending interrupts in the patm iret replacement code (corrected in the ring-1 version) */
    235     /* @todo in theory the iret could fault and we'd still need this. */
     234    /** @todo this is a hack to correct the incorrect checking order for pending interrupts in the patm iret replacement code (corrected in the ring-1 version) */
     235    /** @todo in theory the iret could fault and we'd still need this. */
    236236    if ((env->hflags & HF_CPL_MASK) == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0) && !EMIsRawRing1Enabled(env->pVM))
    237237    {
     
    25612561         (RTGCPTR)env->eip, (RTSEL)env->tr.selector, (RTGCPTR)env->tr.base, (RTGCPTR)env->tr.limit,
    25622562         env->tr.flags, (RTSEL)(selector & 0xffff)));
     2563# if 0 /** @todo r=bird: This looks very fishy, need good reason to re-enable it. */
    25632564    ASMAtomicOrS32((int32_t volatile *)&env->interrupt_request,
    25642565                    CPU_INTERRUPT_EXTERNAL_EXIT);
     2566# endif
    25652567#endif
    25662568    selector &= 0xffff;
     
    31863188        if ((new_cs & 0x3) == 1 && (env->state & CPU_RAW_RING0))
    31873189        {
    3188 # ifdef VBOX_WITH_RAW_RING1
    31893190            if (   !EMIsRawRing1Enabled(env->pVM)
    31903191                ||  env->segs[R_CS].selector == (new_cs & 0xfffc))
     
    31983199                Log(("Genuine switch to ring-1 (iret)\n"));
    31993200            }
    3200 # else
    3201             Log(("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc));
    3202             new_cs = new_cs & 0xfffc;
    3203 # endif
    3204         }
    3205 # ifdef VBOX_WITH_RAW_RING1
    3206         else
    3207         if ((new_cs & 0x3) == 2 && (env->state & CPU_RAW_RING0) && EMIsRawRing1Enabled(env->pVM))
     3201        }
     3202        else if ((new_cs & 0x3) == 2 && (env->state & CPU_RAW_RING0) && EMIsRawRing1Enabled(env->pVM))
    32083203        {
    32093204            Log(("RPL 2 -> new_cs %04X -> %04X\n", new_cs, (new_cs & 0xfffc) | 1));
    32103205            new_cs = (new_cs & 0xfffc) | 1;
    32113206        }
    3212 # endif
    32133207#endif
    32143208    } else {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette