VirtualBox

Changeset 42407 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Jul 26, 2012 11:41:35 AM (12 years ago)
Author:
vboxsync
Message:

VMM: Futher work on dealing with hidden segment register, esp. when going stale.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r42193 r42407  
    6565 */
    6666#if defined(VBOX_WITH_RAW_MODE) && !defined(IN_RING0)
    67 # define CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(a_pVCpu, a_pSReg, a_fIsCS) \
     67# define CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(a_pVCpu, a_pSReg) \
    6868    do \
    6969    { \
    70         if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pSReg)) \
    71             cpumGuestLazyLoadHiddenSelectorReg(a_pVCpu, a_pSReg, a_fIsCS); \
     70        if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pVCpu, a_pSReg)) \
     71            cpumGuestLazyLoadHiddenSelectorReg(a_pVCpu, a_pSReg); \
    7272    } while (0)
    7373#else
    74 # define CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(a_pVCpu, a_pSReg, a_fIsCS) \
    75     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pSReg));
     74# define CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(a_pVCpu, a_pSReg) \
     75    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pVCpu, a_pSReg));
    7676#endif
    7777
     
    8585 * @param   pVCpu       The current Virtual CPU.
    8686 * @param   pSReg       The selector register to lazily load hidden parts of.
    87  * @param   fIsCS
    88  */
    89 static void cpumGuestLazyLoadHiddenSelectorReg(PVMCPU pVCpu, PCPUMSELREG pSReg, bool fIsCS)
    90 {
    91     Assert(!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg));
     87 */
     88static void cpumGuestLazyLoadHiddenSelectorReg(PVMCPU pVCpu, PCPUMSELREG pSReg)
     89{
     90    Assert(!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
    9291    Assert(!HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)));
     92    Assert((uintptr_t)(pSReg - &pVCpu->cpum.s.Guest.es) < X86_SREG_COUNT);
    9393
    9494    if (pVCpu->cpum.s.Guest.eflags.Bits.u1VM)
     
    9696        /* V8086 mode - Tightly controlled environment, no question about the limit or flags. */
    9797        pSReg->Attr.u               = 0;
     98        pSReg->Attr.n.u4Type        = pSReg == &pVCpu->cpum.s.Guest.cs ? X86_SEL_TYPE_ER_ACC : X86_SEL_TYPE_RW_ACC;
    9899        pSReg->Attr.n.u1DescType    = 1; /* code/data segment */
     100        pSReg->Attr.n.u2Dpl         = 3;
    99101        pSReg->Attr.n.u1Present     = 1;
    100         pSReg->Attr.n.u4Type        = fIsCS ? X86_SEL_TYPE_ER_ACC : X86_SEL_TYPE_RW_ACC;
    101102        pSReg->u32Limit             = 0x0000ffff;
    102103        pSReg->u64Base              = (uint32_t)pSReg->Sel << 4;
     
    140141VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenCsAndSs(PVMCPU pVCpu)
    141142{
    142     CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true);
    143     CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.ss, false);
     143    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs);
     144    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.ss);
    144145}
    145146
     
    152153VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenSelectorReg(PVMCPU pVCpu, PCPUMSELREG pSReg)
    153154{
    154     CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, pSReg, pSReg == &pVCpu->cpum.s.Guest.cs);
     155    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, pSReg);
    155156}
    156157
     
    565566VMMDECL(int) CPUMSetGuestLDTR(PVMCPU pVCpu, uint16_t ldtr)
    566567{
    567     pVCpu->cpum.s.Guest.ldtr.Sel = ldtr;
     568    pVCpu->cpum.s.Guest.ldtr.Sel      = ldtr;
     569    /* The caller will set more hidden bits if it has them. */
     570    pVCpu->cpum.s.Guest.ldtr.ValidSel = 0;
     571    pVCpu->cpum.s.Guest.ldtr.fFlags   = 0;
    568572    pVCpu->cpum.s.fChanged  |= CPUM_CHANGED_LDTR;
    569573    return VINF_SUCCESS;
     
    23322336    if (!CPUMIsGuestInLongMode(pVCpu))
    23332337        return false;
    2334     CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true);
     2338    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs);
    23352339    return pVCpu->cpum.s.Guest.cs.Attr.n.u1Long;
    23362340}
     
    23492353}
    23502354
     2355#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     2356/**
     2357 *
     2358 * @returns @c true if we've entered raw-mode and selectors with RPL=1 are
     2359 *          really RPL=0, @c false if we've not (RPL=1 really is RPL=1).
     2360 * @param   pVCpu       The current virtual CPU.
     2361 */
     2362VMM_INT_DECL(bool) CPUMIsGuestInRawMode(PVMCPU pVCpu)
     2363{
     2364    return pVCpu->cpum.s.fRawEntered;
     2365}
     2366#endif
    23512367
    23522368#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     
    25612577        if (!pVCpu->cpum.s.Guest.eflags.Bits.u1VM)
    25622578        {
    2563             if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pVCpu->cpum.s.Guest.ss))
     2579            if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.s.Guest.ss))
    25642580                uCpl = pVCpu->cpum.s.Guest.ss.Attr.n.u2Dpl;
    25652581            else
     
    26202636    }
    26212637
    2622     CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true);
     2638    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs);
    26232639    if (   pVCpu->cpum.s.Guest.cs.Attr.n.u1Long
    26242640        && (pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA))
     
    26432659    }
    26442660
    2645     CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true);
     2661    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs);
    26462662    if (   pVCpu->cpum.s.Guest.cs.Attr.n.u1Long
    26472663        && (pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA))
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r42193 r42407  
    15361536    }
    15371537
    1538     if (   (pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
    1539         || !(pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
    1540     {
    1541         Log(("iemMiscValidateNewSSandRsp: %#x - code or read only (%#x) -> #GP\n", NewSS, pDesc->Legacy.Gen.u4Type));
    1542         return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, NewSS);
    1543     }
    15441538    if (    (pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
    15451539        || !(pDesc->Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
     
    19141908                           ? Idte.Gate.u16OffsetLow
    19151909                           : Idte.Gate.u16OffsetLow | ((uint32_t)Idte.Gate.u16OffsetHigh << 16);
    1916     uint32_t cbLimitCS = X86DESC_LIMIT(DescCS.Legacy);
    1917     if (DescCS.Legacy.Gen.u1Granularity)
    1918         cbLimitCS = (cbLimitCS << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     1910    uint32_t cbLimitCS = X86DESC_LIMIT_G(&DescCS.Legacy);
    19191911    if (uNewEip > cbLimitCS)
    19201912    {
     
    19511943
    19521944        /* Check that there is sufficient space for the stack frame. */
    1953         uint32_t cbLimitSS = X86DESC_LIMIT(DescSS.Legacy);
    1954         if (DescSS.Legacy.Gen.u1Granularity)
    1955             cbLimitSS = (cbLimitSS << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     1945        uint32_t cbLimitSS = X86DESC_LIMIT_G(&DescSS.Legacy);
    19561946        AssertReturn(!(DescSS.Legacy.Gen.u4Type & X86_SEL_TYPE_DOWN), VERR_IEM_ASPECT_NOT_IMPLEMENTED);
    19571947
     
    19721962        RTPTRUNION uStackFrame;
    19731963        rcStrict = iemMemMap(pIemCpu, &uStackFrame.pv, cbStackFrame, UINT8_MAX,
    1974                              uNewEsp - cbStackFrame + X86DESC_BASE(DescSS.Legacy), IEM_ACCESS_STACK_W | IEM_ACCESS_WHAT_SYS); /* _SYS is a hack ... */
     1964                             uNewEsp - cbStackFrame + X86DESC_BASE(&DescSS.Legacy), IEM_ACCESS_STACK_W | IEM_ACCESS_WHAT_SYS); /* _SYS is a hack ... */
    19751965        if (rcStrict != VINF_SUCCESS)
    19761966            return rcStrict;
     
    20162006        pCtx->ss.fFlags         = CPUMSELREG_FLAGS_VALID;
    20172007        pCtx->ss.u32Limit       = cbLimitSS;
    2018         pCtx->ss.u64Base        = X86DESC_BASE(DescSS.Legacy);
    2019         pCtx->ss.Attr.u         = X86DESC_GET_HID_ATTR(DescSS.Legacy);
     2008        pCtx->ss.u64Base        = X86DESC_BASE(&DescSS.Legacy);
     2009        pCtx->ss.Attr.u         = X86DESC_GET_HID_ATTR(&DescSS.Legacy);
    20202010        pCtx->rsp               = uNewEsp - cbStackFrame; /** @todo Is the high word cleared for 16-bit stacks and/or interrupt handlers? */
    20212011        pIemCpu->uCpl           = uNewCpl;
     
    20642054    pCtx->cs.fFlags         = CPUMSELREG_FLAGS_VALID;
    20652055    pCtx->cs.u32Limit       = cbLimitCS;
    2066     pCtx->cs.u64Base        = X86DESC_BASE(DescCS.Legacy);
    2067     pCtx->cs.Attr.u         = X86DESC_GET_HID_ATTR(DescCS.Legacy);
     2056    pCtx->cs.u64Base        = X86DESC_BASE(&DescCS.Legacy);
     2057    pCtx->cs.Attr.u         = X86DESC_GET_HID_ATTR(&DescCS.Legacy);
    20682058
    20692059    pCtx->rip               = uNewEip;
     
    26822672    }
    26832673#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    2684     if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     2674    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg))
    26852675        CPUMGuestLazyLoadHiddenSelectorReg(IEMCPU_TO_VMCPU(pIemCpu), pSReg);
    26862676#else
    2687     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg));
     2677    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg));
    26882678#endif
    26892679    return pSReg;
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r41906 r42407  
    986986       here, but that is ruled out by offSeg being 32-bit, right?) */
    987987    uint64_t u64Base;
    988     uint32_t cbLimit = X86DESC_LIMIT(Desc.Legacy);
    989     if (Desc.Legacy.Gen.u1Granularity)
    990         cbLimit = (cbLimit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     988    uint32_t cbLimit = X86DESC_LIMIT_G(&Desc.Legacy);
    991989    if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
    992990        u64Base = 0;
     
    998996            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    999997        }
    1000         u64Base = X86DESC_BASE(Desc.Legacy);
     998        u64Base = X86DESC_BASE(&Desc.Legacy);
    1001999    }
    10021000
     
    10211019    pCtx->cs.ValidSel    = pCtx->cs.Sel;
    10221020    pCtx->cs.fFlags      = CPUMSELREG_FLAGS_VALID;
    1023     pCtx->cs.Attr.u      = X86DESC_GET_HID_ATTR(Desc.Legacy);
     1021    pCtx->cs.Attr.u      = X86DESC_GET_HID_ATTR(&Desc.Legacy);
    10241022    pCtx->cs.u32Limit    = cbLimit;
    10251023    pCtx->cs.u64Base     = u64Base;
     
    11801178    /* Limit / canonical check. */
    11811179    uint64_t u64Base;
    1182     uint32_t cbLimit = X86DESC_LIMIT(Desc.Legacy);
    1183     if (Desc.Legacy.Gen.u1Granularity)
    1184         cbLimit = (cbLimit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
    1185 
     1180    uint32_t cbLimit = X86DESC_LIMIT_G(&Desc.Legacy);
    11861181    if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
    11871182    {
     
    12001195            return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    12011196        }
    1202         u64Base = X86DESC_BASE(Desc.Legacy);
     1197        u64Base = X86DESC_BASE(&Desc.Legacy);
    12031198    }
    12041199
     
    12451240    pCtx->cs.ValidSel    = pCtx->cs.Sel;
    12461241    pCtx->cs.fFlags      = CPUMSELREG_FLAGS_VALID;
    1247     pCtx->cs.Attr.u      = X86DESC_GET_HID_ATTR(Desc.Legacy);
     1242    pCtx->cs.Attr.u      = X86DESC_GET_HID_ATTR(&Desc.Legacy);
    12481243    pCtx->cs.u32Limit    = cbLimit;
    12491244    pCtx->cs.u64Base     = u64Base;
     
    14851480
    14861481        /* Calc SS limit.*/
    1487         uint32_t cbLimitSs = X86DESC_LIMIT(DescSs.Legacy);
    1488         if (DescSs.Legacy.Gen.u1Granularity)
    1489             cbLimitSs = (cbLimitSs << PAGE_SHIFT) | PAGE_OFFSET_MASK;
    1490 
     1482        uint32_t cbLimitSs = X86DESC_LIMIT_G(&DescSs.Legacy);
    14911483
    14921484        /* Is RIP canonical or within CS.limit? */
    14931485        uint64_t u64Base;
    1494         uint32_t cbLimitCs = X86DESC_LIMIT(DescCs.Legacy);
    1495         if (DescCs.Legacy.Gen.u1Granularity)
    1496             cbLimitCs = (cbLimitCs << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     1486        uint32_t cbLimitCs = X86DESC_LIMIT_G(&DescCs.Legacy);
    14971487
    14981488        if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
     
    15131503                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewCs);
    15141504            }
    1515             u64Base = X86DESC_BASE(DescCs.Legacy);
     1505            u64Base = X86DESC_BASE(&DescCs.Legacy);
    15161506        }
    15171507
     
    15531543        pCtx->cs.ValidSel       = uNewCs;
    15541544        pCtx->cs.fFlags         = CPUMSELREG_FLAGS_VALID;
    1555         pCtx->cs.Attr.u         = X86DESC_GET_HID_ATTR(DescCs.Legacy);
     1545        pCtx->cs.Attr.u         = X86DESC_GET_HID_ATTR(&DescCs.Legacy);
    15561546        pCtx->cs.u32Limit       = cbLimitCs;
    15571547        pCtx->cs.u64Base        = u64Base;
     
    15601550        pCtx->ss.ValidSel       = uNewOuterSs;
    15611551        pCtx->ss.fFlags         = CPUMSELREG_FLAGS_VALID;
    1562         pCtx->ss.Attr.u         = X86DESC_GET_HID_ATTR(DescSs.Legacy);
     1552        pCtx->ss.Attr.u         = X86DESC_GET_HID_ATTR(&DescSs.Legacy);
    15631553        pCtx->ss.u32Limit       = cbLimitSs;
    15641554        if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
    15651555            pCtx->ss.u64Base    = 0;
    15661556        else
    1567             pCtx->ss.u64Base    = X86DESC_BASE(DescSs.Legacy);
     1557            pCtx->ss.u64Base    = X86DESC_BASE(&DescSs.Legacy);
    15681558
    15691559        pIemCpu->uCpl           = (uNewCs & X86_SEL_RPL);
     
    15881578        /* Limit / canonical check. */
    15891579        uint64_t u64Base;
    1590         uint32_t cbLimitCs = X86DESC_LIMIT(DescCs.Legacy);
    1591         if (DescCs.Legacy.Gen.u1Granularity)
    1592             cbLimitCs = (cbLimitCs << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     1580        uint32_t cbLimitCs = X86DESC_LIMIT_G(&DescCs.Legacy);
    15931581
    15941582        if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
     
    16081596                return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uNewCs);
    16091597            }
    1610             u64Base = X86DESC_BASE(DescCs.Legacy);
     1598            u64Base = X86DESC_BASE(&DescCs.Legacy);
    16111599        }
    16121600
     
    16381626        pCtx->cs.ValidSel   = uNewCs;
    16391627        pCtx->cs.fFlags     = CPUMSELREG_FLAGS_VALID;
    1640         pCtx->cs.Attr.u     = X86DESC_GET_HID_ATTR(DescCs.Legacy);
     1628        pCtx->cs.Attr.u     = X86DESC_GET_HID_ATTR(&DescCs.Legacy);
    16411629        pCtx->cs.u32Limit   = cbLimitCs;
    16421630        pCtx->cs.u64Base    = u64Base;
     
    20192007            }
    20202008
    2021             uint32_t cbLimitCS = X86DESC_LIMIT(DescCS.Legacy);
    2022             if (DescCS.Legacy.Gen.u1Granularity)
    2023                 cbLimitCS = (cbLimitCS << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     2009            uint32_t cbLimitCS = X86DESC_LIMIT_G(&DescCS.Legacy);
    20242010
    20252011            /*
     
    21002086                }
    21012087
    2102                 uint32_t cbLimitSs = X86DESC_LIMIT(DescSS.Legacy);
    2103                 if (DescSS.Legacy.Gen.u1Granularity)
    2104                     cbLimitSs = (cbLimitSs << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     2088                uint32_t cbLimitSs = X86DESC_LIMIT_G(&DescSS.Legacy);
    21052089
    21062090                /* Check EIP. */
     
    21352119                pCtx->cs.ValidSel   = uNewCs;
    21362120                pCtx->cs.fFlags     = CPUMSELREG_FLAGS_VALID;
    2137                 pCtx->cs.Attr.u     = X86DESC_GET_HID_ATTR(DescCS.Legacy);
     2121                pCtx->cs.Attr.u     = X86DESC_GET_HID_ATTR(&DescCS.Legacy);
    21382122                pCtx->cs.u32Limit   = cbLimitCS;
    2139                 pCtx->cs.u64Base    = X86DESC_BASE(DescCS.Legacy);
     2123                pCtx->cs.u64Base    = X86DESC_BASE(&DescCS.Legacy);
    21402124                pCtx->rsp           = uNewESP;
    21412125                pCtx->ss.Sel        = uNewSS;
    21422126                pCtx->ss.ValidSel   = uNewSS;
    21432127                pCtx->ss.fFlags     = CPUMSELREG_FLAGS_VALID;
    2144                 pCtx->ss.Attr.u     = X86DESC_GET_HID_ATTR(DescSS.Legacy);
     2128                pCtx->ss.Attr.u     = X86DESC_GET_HID_ATTR(&DescSS.Legacy);
    21452129                pCtx->ss.u32Limit   = cbLimitSs;
    2146                 pCtx->ss.u64Base    = X86DESC_BASE(DescSS.Legacy);
     2130                pCtx->ss.u64Base    = X86DESC_BASE(&DescSS.Legacy);
    21472131
    21482132                uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF  | X86_EFL_SF
     
    21932177                pCtx->cs.ValidSel   = uNewCs;
    21942178                pCtx->cs.fFlags     = CPUMSELREG_FLAGS_VALID;
    2195                 pCtx->cs.Attr.u     = X86DESC_GET_HID_ATTR(DescCS.Legacy);
     2179                pCtx->cs.Attr.u     = X86DESC_GET_HID_ATTR(&DescCS.Legacy);
    21962180                pCtx->cs.u32Limit   = cbLimitCS;
    2197                 pCtx->cs.u64Base    = X86DESC_BASE(DescCS.Legacy);
     2181                pCtx->cs.u64Base    = X86DESC_BASE(&DescCS.Legacy);
    21982182                pCtx->rsp           = uNewRsp;
    21992183
     
    23572341    if (iSegReg == X86_SREG_SS) /* SS gets different treatment */
    23582342    {
    2359         if (   (Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
    2360             || !(Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
    2361         {
    2362             Log(("load sreg SS, %#x - code or read only (%#x) -> #GP\n", uSel, Desc.Legacy.Gen.u4Type));
    2363             return iemRaiseGeneralProtectionFaultBySelector(pIemCpu, uSel);
    2364         }
    23652343        if (    (Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_CODE)
    23662344            || !(Desc.Legacy.Gen.u4Type & X86_SEL_TYPE_WRITE) )
     
    24232401
    24242402    /* The base and limit. */
     2403    uint32_t cbLimit = X86DESC_LIMIT_G(&Desc.Legacy);
    24252404    uint64_t u64Base;
    2426     uint32_t cbLimit = X86DESC_LIMIT(Desc.Legacy);
    2427     if (Desc.Legacy.Gen.u1Granularity)
    2428         cbLimit = (cbLimit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
    2429 
    24302405    if (   pIemCpu->enmCpuMode == IEMMODE_64BIT
    24312406        && iSegReg < X86_SREG_FS)
    24322407        u64Base = 0;
    24332408    else
    2434         u64Base = X86DESC_BASE(Desc.Legacy);
     2409        u64Base = X86DESC_BASE(&Desc.Legacy);
    24352410
    24362411    /*
     
    24482423    /* commit */
    24492424    *pSel = uSel;
    2450     pHid->Attr.u   = X86DESC_GET_HID_ATTR(Desc.Legacy);
     2425    pHid->Attr.u   = X86DESC_GET_HID_ATTR(&Desc.Legacy);
    24512426    pHid->u32Limit = cbLimit;
    24522427    pHid->u64Base  = u64Base;
     
    27232698    uint64_t u64Base;
    27242699    if (!IEM_IS_LONG_MODE(pIemCpu))
    2725         u64Base = X86DESC_BASE(Desc.Legacy);
     2700        u64Base = X86DESC_BASE(&Desc.Legacy);
    27262701    else
    27272702    {
     
    27322707        }
    27332708
    2734         u64Base = X86DESC64_BASE(Desc.Long);
     2709        u64Base = X86DESC64_BASE(&Desc.Long);
    27352710        if (!IEM_IS_CANONICAL(u64Base))
    27362711        {
     
    27572732    pCtx->ldtr.ValidSel = uNewLdt & X86_SEL_MASK;
    27582733    pCtx->ldtr.fFlags   = CPUMSELREG_FLAGS_VALID;
    2759     pCtx->ldtr.Attr.u   = X86DESC_GET_HID_ATTR(Desc.Legacy);
    2760     pCtx->ldtr.u32Limit = X86DESC_LIMIT(Desc.Legacy);
     2734    pCtx->ldtr.Attr.u   = X86DESC_GET_HID_ATTR(&Desc.Legacy);
     2735    pCtx->ldtr.u32Limit = X86DESC_LIMIT_G(&Desc.Legacy);
    27612736    pCtx->ldtr.u64Base  = u64Base;
    27622737
     
    28222797    uint64_t u64Base;
    28232798    if (!IEM_IS_LONG_MODE(pIemCpu))
    2824         u64Base = X86DESC_BASE(Desc.Legacy);
     2799        u64Base = X86DESC_BASE(&Desc.Legacy);
    28252800    else
    28262801    {
     
    28312806        }
    28322807
    2833         u64Base = X86DESC64_BASE(Desc.Long);
     2808        u64Base = X86DESC64_BASE(&Desc.Long);
    28342809        if (!IEM_IS_CANONICAL(u64Base))
    28352810        {
     
    28782853    pCtx->tr.ValidSel = uNewTr & X86_SEL_MASK;
    28792854    pCtx->tr.fFlags   = CPUMSELREG_FLAGS_VALID;
    2880     pCtx->tr.Attr.u   = X86DESC_GET_HID_ATTR(Desc.Legacy);
    2881     pCtx->tr.u32Limit = X86DESC_LIMIT(Desc.Legacy);
     2855    pCtx->tr.Attr.u   = X86DESC_GET_HID_ATTR(&Desc.Legacy);
     2856    pCtx->tr.u32Limit = X86DESC_LIMIT_G(&Desc.Legacy);
    28822857    pCtx->tr.u64Base  = u64Base;
    28832858
  • trunk/src/VBox/VMM/VMMAll/SELMAll.cpp

    r42186 r42407  
    3131#include <VBox/param.h>
    3232#include <iprt/assert.h>
    33 #include <VBox/log.h>
    3433#include <VBox/vmm/vmm.h>
    3534#include <iprt/x86.h>
     35
     36
     37/*******************************************************************************
     38*   Global Variables                                                           *
     39*******************************************************************************/
     40#if defined(LOG_ENABLED) && defined(VBOX_WITH_RAW_MODE_NOT_R0)
     41/** Segment register names. */
     42static char const g_aszSRegNms[X86_SREG_COUNT][4] = { "ES", "CS", "SS", "DS", "FS", "GS" };
     43#endif
    3644
    3745
     
    6573    }
    6674
    67     return (RTGCPTR)(((RTGCUINTPTR)Addr + X86DESC_BASE(Desc)) & 0xffffffff);
     75    return (RTGCPTR)(((RTGCUINTPTR)Addr + X86DESC_BASE(&Desc)) & 0xffffffff);
    6876}
    6977#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
     
    105113#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    106114    /** @todo when we're in 16 bits mode, we should cut off the address as well?? */
    107     if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     115    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg))
    108116        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg);
    109     if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs))
     117    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtxCore->cs))
    110118        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, &pCtxCore->cs);
    111119#else
    112     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg));
    113     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs));
     120    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
     121    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtxCore->cs));
    114122#endif
    115123
     
    168176        if (ppvGC)
    169177        {
    170             if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     178            if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg))
    171179                *ppvGC = pSReg->u64Base + uFlat;
    172180            else
     
    178186
    179187#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    180     if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     188    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg))
    181189        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg);
    182     if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs))
     190    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtxCore->cs))
    183191        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, &pCtxCore->cs);
    184192#else
    185     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg));
    186     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs));
     193    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
     194    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtxCore->cs));
    187195#endif
    188196
     
    347355
    348356    /* calc limit. */
    349     uint32_t u32Limit = X86DESC_LIMIT(Desc);
    350     if (Desc.Gen.u1Granularity)
    351         u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     357    uint32_t u32Limit = X86DESC_LIMIT_G(&Desc);
    352358
    353359    /* calc address assuming straight stuff. */
    354     RTGCPTR pvFlat = Addr + X86DESC_BASE(Desc);
     360    RTGCPTR pvFlat = Addr + X86DESC_BASE(&Desc);
    355361
    356362    /* Cut the address to 32 bits. */
     
    475481
    476482#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     483
     484static void selLoadHiddenSelectorRegFromGuestTable(PVMCPU pVCpu, PCCPUMCTX pCtx, PCPUMSELREG pSReg,
     485                                                   RTGCPTR GCPtrDesc, RTSEL const Sel, uint32_t const iSReg)
     486{
     487    /*
     488     * Try read the entry.
     489     */
     490    X86DESC GstDesc;
     491    int rc = PGMPhysReadGCPtr(pVCpu, &GstDesc, GCPtrDesc, sizeof(GstDesc));
     492    if (RT_FAILURE(rc))
     493    {
     494        Log(("SELMLoadHiddenSelectorReg: Error reading descriptor %s=%#x: %Rrc\n", g_aszSRegNms[iSReg], Sel, rc));
     495        STAM_REL_COUNTER_INC(&pVCpu->CTX_SUFF(pVM)->selm.s.StatLoadHidSelReadErrors);
     496        return;
     497    }
     498
     499    /*
     500     * Validate it and load it.
     501     */
     502    if (!selmIsGstDescGoodForSReg(pVCpu, pSReg, &GstDesc, iSReg, CPUMGetGuestCPL(pVCpu)))
     503    {
     504        Log(("SELMLoadHiddenSelectorReg: Guest table entry is no good (%s=%#x): %.8Rhxs\n", g_aszSRegNms[iSReg], Sel, &GstDesc));
     505        STAM_REL_COUNTER_INC(&pVCpu->CTX_SUFF(pVM)->selm.s.StatLoadHidSelGstNoGood);
     506        return;
     507    }
     508
     509    selmLoadHiddenSRegFromGuestDesc(pVCpu, pSReg, &GstDesc);
     510    Log(("SELMLoadHiddenSelectorReg: loaded %s=%#x:{b=%llx, l=%x, a=%x, vs=%x} (gst)\n",
     511         g_aszSRegNms[iSReg], Sel, pSReg->u64Base, pSReg->u32Limit, pSReg->Attr.u, pSReg->ValidSel));
     512    STAM_COUNTER_INC(&pVCpu->CTX_SUFF(pVM)->selm.s.StatLoadHidSelGst);
     513}
     514
     515
    477516/**
    478517 * CPUM helper that loads the hidden selector register from the descriptor table
     
    500539    Assert(pVM->cCpus == 1);
    501540
    502     RTSEL const Sel = pSReg->Sel;
    503 
    504 /** @todo Consider loading these from the shadow tables when possible? */
    505     /*
    506      * Calculate descriptor table entry address.
    507      */
    508     RTGCPTR GCPtrDesc;
     541
     542    /*
     543     * Get the shadow descriptor table entry and validate it.
     544     * Should something go amiss, try the guest table.
     545     */
     546    RTSEL const     Sel   = pSReg->Sel;
     547    uint32_t const  iSReg = pSReg - CPUMCTX_FIRST_SREG(pCtx); Assert(iSReg < X86_SREG_COUNT);
     548    PCX86DESC       pShwDesc;
    509549    if (!(Sel & X86_SEL_LDT))
    510550    {
    511         if ((Sel & X86_SEL_MASK) >= pCtx->gdtr.cbGdt)
     551        /** @todo this shall not happen, we shall check for these things when executing
     552         *        LGDT */
     553        AssertReturnVoid((Sel | X86_SEL_RPL | X86_SEL_LDT) <= pCtx->gdtr.cbGdt);
     554
     555        pShwDesc = &pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
     556        if (   VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT)
     557            || !selmIsShwDescGoodForSReg(pSReg, pShwDesc, iSReg, CPUMGetGuestCPL(pVCpu)))
    512558        {
    513             AssertFailed(); /** @todo count these. */
     559            selLoadHiddenSelectorRegFromGuestTable(pVCpu, pCtx, pSReg, pCtx->gdtr.pGdt + (Sel & X86_SEL_MASK), Sel, iSReg);
    514560            return;
    515561        }
    516         GCPtrDesc = pCtx->gdtr.pGdt + (Sel & X86_SEL_MASK);
    517         /** @todo Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT]; for cases
    518          *        where we don't change it too much. */
    519562    }
    520563    else
    521564    {
    522         if ((Sel & X86_SEL_MASK) >= pCtx->ldtr.u32Limit)
     565        /** @todo this shall not happen, we shall check for these things when executing
     566         *        LLDT */
     567        AssertReturnVoid((Sel | X86_SEL_RPL | X86_SEL_LDT) <= pCtx->ldtr.u32Limit);
     568
     569        pShwDesc = (PCX86DESC)((uintptr_t)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper + (Sel & X86_SEL_MASK));
     570        if (   VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT)
     571            || !selmIsShwDescGoodForSReg(pSReg, pShwDesc, iSReg, CPUMGetGuestCPL(pVCpu)))
    523572        {
    524             AssertFailed(); /** @todo count these. */
     573            selLoadHiddenSelectorRegFromGuestTable(pVCpu, pCtx, pSReg, pCtx->ldtr.u64Base + (Sel & X86_SEL_MASK), Sel, iSReg);
    525574            return;
    526575        }
    527         GCPtrDesc = pCtx->ldtr.u64Base + (Sel & X86_SEL_MASK);
    528     }
    529 
    530     /*
    531      * Try read the entry.
    532      */
    533     X86DESC Desc;
    534     int rc = PGMPhysReadGCPtr(pVCpu, &Desc, GCPtrDesc, sizeof(Desc));
    535     if (RT_FAILURE(rc))
    536     {
    537         //RT_ZERO(Desc);
    538         //if (!(Sel & X86_SEL_LDT))
    539         //    Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    540         //if (!Desc.Gen.u1Present)
    541         {
    542             AssertFailed(); /** @todo count these. */
    543             return;
    544         }
    545     }
    546 
    547     /*
    548      * Digest it and store the result.
    549      */
    550     if (   !Desc.Gen.u1Present
    551         || !Desc.Gen.u1DescType)
    552     {
    553         AssertFailed(); /** @todo count these. */
    554         return;
    555     }
    556 
    557     uint32_t u32Limit = X86DESC_LIMIT(Desc);
    558     if (Desc.Gen.u1Granularity)
    559         u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
    560     pSReg->u32Limit = u32Limit;
    561 
    562     pSReg->u64Base  = X86DESC_BASE(Desc);
    563     pSReg->Attr.u   = X86DESC_GET_HID_ATTR(Desc);
    564     pSReg->fFlags   = CPUMSELREG_FLAGS_VALID;
    565     pSReg->ValidSel = Sel;
    566 }
    567 #endif /* VBOX_WITH_RAW_MODE */
    568 
     576    }
     577
     578    /*
     579     * All fine, load it.
     580     */
     581    selmLoadHiddenSRegFromShadowDesc(pSReg, pShwDesc);
     582    STAM_COUNTER_INC(&pVCpu->CTX_SUFF(pVM)->selm.s.StatLoadHidSelShw);
     583    Log(("SELMLoadHiddenSelectorReg: loaded %s=%#x:{b=%llx, l=%x, a=%x, vs=%x} (shw)\n",
     584         g_aszSRegNms[iSReg], Sel, pSReg->u64Base, pSReg->u32Limit, pSReg->Attr.u, pSReg->ValidSel));
     585}
     586
     587#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
    569588
    570589/**
     
    583602{
    584603    RTGCUINTPTR uFlat = Addr & 0xffff;
    585     if (!pSReg || !CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     604    if (!pSReg || !CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg))
    586605        uFlat += (RTGCUINTPTR)SelCS << 4;
    587606    else
     
    646665                 * Limit check.
    647666                 */
    648                 uint32_t    u32Limit = X86DESC_LIMIT(Desc);
    649                 if (Desc.Gen.u1Granularity)
    650                     u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     667                uint32_t    u32Limit = X86DESC_LIMIT_G(&Desc);
    651668                if ((RTGCUINTPTR)Addr <= u32Limit)
    652669                {
    653                     *ppvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc));
     670                    *ppvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(&Desc));
    654671                    /* Cut the address to 32 bits. */
    655672                    *ppvFlat &= 0xffffffff;
     
    765782        return selmValidateAndConvertCSAddrRawMode(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, NULL);
    766783
    767     if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSRegCS))
     784    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSRegCS))
    768785        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSRegCS);
    769786
     
    775792        SelCS  &= ~X86_SEL_RPL;
    776793#else
    777     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSRegCS));
     794    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSRegCS));
    778795    Assert(pSRegCS->Sel == SelCS);
    779796#endif
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