VirtualBox

Changeset 42186 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 17, 2012 1:32:15 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
79186
Message:

SELM,DIS,CPUM,EM: Hidden selector register cleanups.

Location:
trunk/src/VBox
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Disassembler/DisasmReg.cpp

    r41906 r42186  
    415415 *
    416416 */
    417 DISDECL(int) DISFetchRegSegEx(PCCPUMCTXCORE pCtx, DISSELREG sel, RTSEL *pVal, CPUMSELREGHID **ppSelHidReg)
    418 {
    419     AssertReturn((unsigned)sel < RT_ELEMENTS(g_aRegSegIndex), VERR_INVALID_PARAMETER);
    420 
    421     AssertCompile(sizeof(uint16_t) == sizeof(RTSEL));
    422     *pVal = DIS_READ_REGSEG(pCtx, sel);
    423     *ppSelHidReg = (CPUMSELREGHID *)((char *)pCtx + g_aRegHidSegIndex[sel]);
     417DISDECL(int) DISFetchRegSegEx(PCPUMCTXCORE pCtx, DISSELREG sel, PCPUMSELREG *ppSelReg)
     418{
     419    AssertReturnStmt((unsigned)sel < RT_ELEMENTS(g_aRegSegIndex), *ppSelReg = NULL, VERR_INVALID_PARAMETER);
     420    *ppSelReg = (CPUMSELREG *)((uintptr_t)pCtx + g_aRegHidSegIndex[sel]);
    424421    return VINF_SUCCESS;
    425422}
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r42166 r42186  
    26022602    return enmMode;
    26032603}
     2604
     2605
     2606/**
     2607 * Figure whether the CPU is currently executing 16, 32 or 64 bit code.
     2608 *
     2609 * @returns 16, 32 or 64.
     2610 * @param   pVCpu               The current virtual CPU.
     2611 */
     2612VMMDECL(uint32_t)       CPUMGetGuestCodeBits(PVMCPU pVCpu)
     2613{
     2614    if (!(pVCpu->cpum.s.Guest.cr0 & X86_CR0_PE))
     2615        return 16;
     2616
     2617    if (pVCpu->cpum.s.Guest.eflags.Bits.u1VM)
     2618    {
     2619        Assert(!(pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA));
     2620        return 16;
     2621    }
     2622
     2623    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true);
     2624    if (   pVCpu->cpum.s.Guest.cs.Attr.n.u1Long
     2625        && (pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA))
     2626        return 64;
     2627
     2628    if (pVCpu->cpum.s.Guest.cs.Attr.n.u1DefBig)
     2629        return 32;
     2630
     2631    return 16;
     2632}
     2633
     2634
     2635VMMDECL(DISCPUMODE)     CPUMGetGuestDisMode(PVMCPU pVCpu)
     2636{
     2637    if (!(pVCpu->cpum.s.Guest.cr0 & X86_CR0_PE))
     2638        return DISCPUMODE_16BIT;
     2639
     2640    if (pVCpu->cpum.s.Guest.eflags.Bits.u1VM)
     2641    {
     2642        Assert(!(pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA));
     2643        return DISCPUMODE_16BIT;
     2644    }
     2645
     2646    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true);
     2647    if (   pVCpu->cpum.s.Guest.cs.Attr.n.u1Long
     2648        && (pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA))
     2649        return DISCPUMODE_64BIT;
     2650
     2651    if (pVCpu->cpum.s.Guest.cs.Attr.n.u1DefBig)
     2652        return DISCPUMODE_32BIT;
     2653
     2654    return DISCPUMODE_16BIT;
     2655}
     2656
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r42165 r42186  
    365365
    366366/**
    367  * Disassembles one instruction.
     367 * Disassembles the current instruction.
    368368 *
    369369 * @returns VBox status code, see SELMToFlatEx and EMInterpretDisasOneEx for
     
    373373 * @param   pVM             Pointer to the VM.
    374374 * @param   pVCpu           Pointer to the VMCPU.
    375  * @param   pCtxCore        The context core (used for both the mode and instruction).
    376375 * @param   pDis            Where to return the parsed instruction info.
    377376 * @param   pcbInstr        Where to return the instruction size. (optional)
    378377 */
    379 VMMDECL(int) EMInterpretDisasOne(PVM pVM, PVMCPU pVCpu, PCCPUMCTXCORE pCtxCore, PDISCPUSTATE pDis, unsigned *pcbInstr)
    380 {
     378VMMDECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, unsigned *pcbInstr)
     379{
     380    PCPUMCTXCORE pCtxCore = CPUMCTX2CORE(CPUMQueryGuestCtxPtr(pVCpu));
    381381    RTGCPTR GCPtrInstr;
    382382#if 0
     
    384384#else
    385385/** @todo Get the CPU mode as well while we're at it! */
    386     int rc = SELMValidateAndConvertCSAddr(pVCpu, pCtxCore->eflags, pCtxCore->ss.Sel, pCtxCore->cs.Sel,
    387                                           &pCtxCore->cs, pCtxCore->rip, &GCPtrInstr);
     386    int rc = SELMValidateAndConvertCSAddr(pVCpu, pCtxCore->eflags, pCtxCore->ss.Sel, pCtxCore->cs.Sel, &pCtxCore->cs,
     387                                          pCtxCore->rip, &GCPtrInstr);
    388388#endif
    389389    if (RT_FAILURE(rc))
     
    415415                                   PDISCPUSTATE pDis, unsigned *pcbInstr)
    416416{
    417     DISCPUMODE enmCpuMode = SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs.Sel, (PCPUMSELREGHID)&pCtxCore->cs);
     417    Assert(pCtxCore == CPUMGetGuestCtxCore(pVCpu));
     418    DISCPUMODE enmCpuMode = CPUMGetGuestDisMode(pVCpu);
    418419    /** @todo Deal with too long instruction (=> \#GP), opcode read errors (=>
    419420     *        \#PF, \#GP, \#??), undefined opcodes (=> \#UD), and such. */
     
    462463        uint32_t     cbOp;
    463464        PDISCPUSTATE pDis = &pVCpu->em.s.DisState;
    464         pDis->uCpuMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs);
     465        pDis->uCpuMode = CPUMGetGuestDisMode(pVCpu);
    465466        rc = emDisCoreOne(pVCpu->CTX_SUFF(pVM), pVCpu, pDis, (RTGCUINTPTR)pbCode, &cbOp);
    466467        if (RT_SUCCESS(rc))
     
    517518        uint32_t     cbOp;
    518519        PDISCPUSTATE pDis = &pVCpu->em.s.DisState;
    519         pDis->uCpuMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs);
     520        pDis->uCpuMode = CPUMGetGuestDisMode(pVCpu);
    520521        rc = emDisCoreOne(pVCpu->CTX_SUFF(pVM), pVCpu, pDis, (RTGCUINTPTR)pbCode, &cbOp);
    521522        if (RT_SUCCESS(rc))
     
    15471548
    15481549            /* Read stack value first */
    1549             if (SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, &pRegFrame->ss) == DISCPUMODE_16BIT)
     1550            if (CPUMGetGuestCodeBits(pVCpu) == 16)
    15501551                return VERR_EM_INTERPRETER; /* No legacy 16 bits stuff here, please. */
    15511552
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r42165 r42186  
    15211521    PDISCPUSTATE    pDis  = &pVCpu->iom.s.DisState;
    15221522    unsigned        cbOp;
    1523     rc = EMInterpretDisasOne(pVM, pVCpu, pCtxCore, pDis, &cbOp);
     1523    rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
    15241524    if (RT_FAILURE(rc))
    15251525    {
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r41939 r42186  
    908908                PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState;
    909909                uint32_t     cbOp;
    910                 rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, pDis, &cbOp);
     910                rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
    911911
    912912                /* For now we'll restrict this to rep movsw/d instructions */
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r41965 r42186  
    105105            uint32_t     cbOp;
    106106            PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState;
    107             rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, pDis, &cbOp);
     107            rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
    108108            if (     RT_SUCCESS(rc)
    109109                &&   pDis->uCpuMode == DISCPUMODE_32BIT  /** @todo why does this matter? */
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r42185 r42186  
    10891089     */
    10901090    PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState;
    1091     int rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, pDis, NULL);
     1091    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
    10921092    if (RT_UNLIKELY(rc != VINF_SUCCESS))
    10931093    {
  • trunk/src/VBox/VMM/VMMAll/SELMAll.cpp

    r42165 r42186  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2525#include <VBox/vmm/mm.h>
    2626#include <VBox/vmm/pgm.h>
     27#include <VBox/vmm/hwaccm.h>
    2728#include "SELMInternal.h"
    2829#include <VBox/vmm/vm.h>
     
    3637
    3738
    38 #ifndef IN_RING0
    39 
     39#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    4040/**
    4141 * Converts a GC selector based address to a flat address.
     
    6767    return (RTGCPTR)(((RTGCUINTPTR)Addr + X86DESC_BASE(Desc)) & 0xffffffff);
    6868}
    69 #endif /* !IN_RING0 */
     69#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
    7070
    7171
     
    8484VMMDECL(RTGCPTR) SELMToFlat(PVM pVM, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr)
    8585{
    86     PCPUMSELREGHID pHiddenSel;
    87     RTSEL          Sel;
    88     int            rc;
     86    PCPUMSELREG    pSReg;
    8987    PVMCPU         pVCpu = VMMGetCpu(pVM);
    9088
    91     rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel); AssertRC(rc);
     89    int rc = DISFetchRegSegEx(pCtxCore, SelReg, &pSReg); AssertRC(rc);
    9290
    9391    /*
     
    9997        RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff;
    10098        if (CPUMAreHiddenSelRegsValid(pVCpu))
    101             uFlat += pHiddenSel->u64Base;
     99            uFlat += pSReg->u64Base;
    102100        else
    103             uFlat += ((RTGCUINTPTR)Sel << 4);
     101            uFlat += ((RTGCUINTPTR)pSReg->Sel << 4);
    104102        return (RTGCPTR)uFlat;
    105103    }
    106104
    107 #ifdef IN_RING0
    108     Assert(CPUMAreHiddenSelRegsValid(pVCpu));
     105#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     106    /** @todo when we're in 16 bits mode, we should cut off the address as well?? */
     107    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     108        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg);
     109    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs))
     110        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, &pCtxCore->cs);
    109111#else
    110     /** @todo when we're in 16 bits mode, we should cut off the address as well.. */
    111     if (!CPUMAreHiddenSelRegsValid(pVCpu))
    112         return SELMToFlatBySel(pVM, Sel, Addr);
     112    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg));
     113    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs));
    113114#endif
    114115
    115     /* 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). */
     116    /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0
     117       (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */
    116118    if (    pCtxCore->cs.Attr.n.u1Long
    117119        &&  CPUMIsGuestInLongMode(pVCpu))
     
    121123            case DISSELREG_FS:
    122124            case DISSELREG_GS:
    123                 return (RTGCPTR)(pHiddenSel->u64Base + Addr);
     125                return (RTGCPTR)(pSReg->u64Base + Addr);
    124126
    125127            default:
     
    129131
    130132    /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
    131     Assert(pHiddenSel->u64Base <= 0xffffffff);
    132     return ((pHiddenSel->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff);
     133    Assert(pSReg->u64Base <= 0xffffffff);
     134    return ((pSReg->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff);
    133135}
    134136
     
    148150 * @param   ppvGC       Where to store the GC flat address.
    149151 */
    150 VMMDECL(int) SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCCPUMCTXCORE pCtxCore, RTGCPTR Addr, unsigned fFlags, PRTGCPTR ppvGC)
     152VMMDECL(int) SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr, uint32_t fFlags, PRTGCPTR ppvGC)
    151153{
    152154    /*
    153155     * Fetch the selector first.
    154156     */
    155     PCPUMSELREGHID pHiddenSel;
    156     RTSEL          Sel;
    157 
    158     int rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel);
    159     AssertRC(rc);
     157    PCPUMSELREG pSReg;
     158    int rc = DISFetchRegSegEx(pCtxCore, SelReg, &pSReg);
     159    AssertRCReturn(rc, rc); AssertPtr(pSReg);
    160160
    161161    /*
     
    168168        if (ppvGC)
    169169        {
    170             if (    pHiddenSel
    171                 &&  CPUMAreHiddenSelRegsValid(pVCpu))
    172                 *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat);
     170            if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     171                *ppvGC = pSReg->u64Base + uFlat;
    173172            else
    174                 *ppvGC = (RTGCPTR)(((RTGCUINTPTR)Sel << 4) + uFlat);
     173                *ppvGC = ((RTGCUINTPTR)pSReg->Sel << 4) + uFlat;
    175174        }
    176175        return VINF_SUCCESS;
     
    178177
    179178
    180     uint32_t    u32Limit;
    181     RTGCPTR     pvFlat;
    182     uint32_t    u1Present, u1DescType, u1Granularity, u4Type;
    183 
    184     /** @todo when we're in 16 bits mode, we should cut off the address as well.. */
    185 #ifndef IN_RC
    186     if (    pHiddenSel
    187         &&  CPUMAreHiddenSelRegsValid(pVCpu))
    188     {
    189         bool fCheckLimit = true;
    190 
    191         u1Present     = pHiddenSel->Attr.n.u1Present;
    192         u1Granularity = pHiddenSel->Attr.n.u1Granularity;
    193         u1DescType    = pHiddenSel->Attr.n.u1DescType;
    194         u4Type        = pHiddenSel->Attr.n.u4Type;
    195         u32Limit      = pHiddenSel->u32Limit;
    196 
    197         /* 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). */
    198         if (    pCtxCore->cs.Attr.n.u1Long
    199             &&  CPUMIsGuestInLongMode(pVCpu))
    200         {
    201             fCheckLimit = false;
    202             switch (SelReg)
    203             {
    204                 case DISSELREG_FS:
    205                 case DISSELREG_GS:
    206                     pvFlat = (pHiddenSel->u64Base + Addr);
    207                     break;
    208 
    209                 default:
    210                     pvFlat = Addr;
    211                     break;
    212             }
    213         }
    214         else
    215         {
    216             /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
    217             Assert(pHiddenSel->u64Base <= 0xffffffff);
    218             pvFlat = (RTGCPTR)((pHiddenSel->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff);
    219         }
    220 
    221         /*
    222         * Check if present.
    223         */
    224         if (u1Present)
    225         {
    226             /*
    227             * Type check.
    228             */
    229             switch (u4Type)
    230             {
    231 
    232                 /** Read only selector type. */
    233                 case X86_SEL_TYPE_RO:
    234                 case X86_SEL_TYPE_RO_ACC:
    235                 case X86_SEL_TYPE_RW:
    236                 case X86_SEL_TYPE_RW_ACC:
    237                 case X86_SEL_TYPE_EO:
    238                 case X86_SEL_TYPE_EO_ACC:
    239                 case X86_SEL_TYPE_ER:
    240                 case X86_SEL_TYPE_ER_ACC:
    241                     if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
    242                     {
    243                         /** @todo fix this mess */
    244                     }
    245                     /* check limit. */
    246                     if (fCheckLimit && (RTGCUINTPTR)Addr > u32Limit)
     179#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     180    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     181        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg);
     182    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs))
     183        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, &pCtxCore->cs);
     184#else
     185    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg));
     186    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs));
     187#endif
     188
     189    /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0
     190       (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */
     191    RTGCPTR  pvFlat;
     192    bool     fCheckLimit   = true;
     193    if (    pCtxCore->cs.Attr.n.u1Long
     194        &&  CPUMIsGuestInLongMode(pVCpu))
     195    {
     196        fCheckLimit = false;
     197        switch (SelReg)
     198        {
     199            case DISSELREG_FS:
     200            case DISSELREG_GS:
     201                pvFlat = pSReg->u64Base + Addr;
     202                break;
     203
     204            default:
     205                pvFlat = Addr;
     206                break;
     207        }
     208    }
     209    else
     210    {
     211        /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
     212        Assert(pSReg->u64Base <= UINT32_C(0xffffffff));
     213        pvFlat  = pSReg->u64Base + Addr;
     214        pvFlat &= UINT32_C(0xffffffff);
     215    }
     216
     217    /*
     218     * Check type if present.
     219     */
     220    if (pSReg->Attr.n.u1Present)
     221    {
     222        switch (pSReg->Attr.n.u4Type)
     223        {
     224            /* Read only selector type. */
     225            case X86_SEL_TYPE_RO:
     226            case X86_SEL_TYPE_RO_ACC:
     227            case X86_SEL_TYPE_RW:
     228            case X86_SEL_TYPE_RW_ACC:
     229            case X86_SEL_TYPE_EO:
     230            case X86_SEL_TYPE_EO_ACC:
     231            case X86_SEL_TYPE_ER:
     232            case X86_SEL_TYPE_ER_ACC:
     233                if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
     234                {
     235                    /** @todo fix this mess */
     236                }
     237                /* check limit. */
     238                if (fCheckLimit && Addr > pSReg->u32Limit)
     239                    return VERR_OUT_OF_SELECTOR_BOUNDS;
     240                /* ok */
     241                if (ppvGC)
     242                    *ppvGC = pvFlat;
     243                return VINF_SUCCESS;
     244
     245            case X86_SEL_TYPE_EO_CONF:
     246            case X86_SEL_TYPE_EO_CONF_ACC:
     247            case X86_SEL_TYPE_ER_CONF:
     248            case X86_SEL_TYPE_ER_CONF_ACC:
     249                if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
     250                {
     251                    /** @todo fix this mess */
     252                }
     253                /* check limit. */
     254                if (fCheckLimit && Addr > pSReg->u32Limit)
     255                    return VERR_OUT_OF_SELECTOR_BOUNDS;
     256                /* ok */
     257                if (ppvGC)
     258                    *ppvGC = pvFlat;
     259                return VINF_SUCCESS;
     260
     261            case X86_SEL_TYPE_RO_DOWN:
     262            case X86_SEL_TYPE_RO_DOWN_ACC:
     263            case X86_SEL_TYPE_RW_DOWN:
     264            case X86_SEL_TYPE_RW_DOWN_ACC:
     265                if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
     266                {
     267                    /** @todo fix this mess */
     268                }
     269                /* check limit. */
     270                if (fCheckLimit)
     271                {
     272                    if (!pSReg->Attr.n.u1Granularity && Addr > UINT32_C(0xffff))
    247273                        return VERR_OUT_OF_SELECTOR_BOUNDS;
    248                     /* ok */
    249                     if (ppvGC)
    250                         *ppvGC = pvFlat;
    251                     return VINF_SUCCESS;
    252 
    253                 case X86_SEL_TYPE_EO_CONF:
    254                 case X86_SEL_TYPE_EO_CONF_ACC:
    255                 case X86_SEL_TYPE_ER_CONF:
    256                 case X86_SEL_TYPE_ER_CONF_ACC:
    257                     if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
    258                     {
    259                         /** @todo fix this mess */
    260                     }
    261                     /* check limit. */
    262                     if (fCheckLimit && (RTGCUINTPTR)Addr > u32Limit)
     274                    if (Addr <= pSReg->u32Limit)
    263275                        return VERR_OUT_OF_SELECTOR_BOUNDS;
    264                     /* ok */
    265                     if (ppvGC)
    266                         *ppvGC = pvFlat;
    267                     return VINF_SUCCESS;
    268 
    269                 case X86_SEL_TYPE_RO_DOWN:
    270                 case X86_SEL_TYPE_RO_DOWN_ACC:
    271                 case X86_SEL_TYPE_RW_DOWN:
    272                 case X86_SEL_TYPE_RW_DOWN_ACC:
    273                     if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
    274                     {
    275                         /** @todo fix this mess */
    276                     }
    277                     /* check limit. */
    278                     if (fCheckLimit)
    279                     {
    280                         if (!u1Granularity && (RTGCUINTPTR)Addr > (RTGCUINTPTR)0xffff)
    281                             return VERR_OUT_OF_SELECTOR_BOUNDS;
    282                         if ((RTGCUINTPTR)Addr <= u32Limit)
    283                             return VERR_OUT_OF_SELECTOR_BOUNDS;
    284                     }
    285                     /* ok */
    286                     if (ppvGC)
    287                         *ppvGC = pvFlat;
    288                     return VINF_SUCCESS;
    289 
    290                 default:
    291                     return VERR_INVALID_SELECTOR;
    292 
    293             }
    294         }
    295     }
    296 # ifndef IN_RING0
    297     else
    298 # endif
    299 #endif /* !IN_RC */
    300 #ifndef IN_RING0
    301     {
    302         X86DESC Desc;
    303 
    304         PVM pVM = pVCpu->CTX_SUFF(pVM);
    305         if (!(Sel & X86_SEL_LDT))
    306         {
    307             if (   !(fFlags & SELMTOFLAT_FLAGS_HYPER)
    308                 && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
     276                }
     277                /* ok */
     278                if (ppvGC)
     279                    *ppvGC = pvFlat;
     280                return VINF_SUCCESS;
     281
     282            default:
    309283                return VERR_INVALID_SELECTOR;
    310             Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    311         }
    312         else
    313         {
    314             if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit)
    315                 return VERR_INVALID_SELECTOR;
    316 
    317             /** @todo handle LDT page(s) not present! */
    318             PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    319             Desc = paLDT[Sel >> X86_SEL_SHIFT];
    320         }
    321 
    322         /* calc limit. */
    323         u32Limit = X86DESC_LIMIT(Desc);
    324         if (Desc.Gen.u1Granularity)
    325             u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
    326 
    327         /* calc address assuming straight stuff. */
    328         pvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc));
    329 
    330         /* Cut the address to 32 bits. */
    331         Assert(!CPUMIsGuestInLongMode(pVCpu));
    332         pvFlat &= 0xffffffff;
    333 
    334         u1Present     = Desc.Gen.u1Present;
    335         u1Granularity = Desc.Gen.u1Granularity;
    336         u1DescType    = Desc.Gen.u1DescType;
    337         u4Type        = Desc.Gen.u4Type;
    338 
    339         /*
    340         * Check if present.
    341         */
    342         if (u1Present)
    343         {
    344             /*
    345             * Type check.
    346             */
    347 # define BOTH(a, b) ((a << 16) | b)
    348             switch (BOTH(u1DescType, u4Type))
    349             {
    350 
    351                 /** Read only selector type. */
    352                 case BOTH(1,X86_SEL_TYPE_RO):
    353                 case BOTH(1,X86_SEL_TYPE_RO_ACC):
    354                 case BOTH(1,X86_SEL_TYPE_RW):
    355                 case BOTH(1,X86_SEL_TYPE_RW_ACC):
    356                 case BOTH(1,X86_SEL_TYPE_EO):
    357                 case BOTH(1,X86_SEL_TYPE_EO_ACC):
    358                 case BOTH(1,X86_SEL_TYPE_ER):
    359                 case BOTH(1,X86_SEL_TYPE_ER_ACC):
    360                     if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
    361                     {
    362                         /** @todo fix this mess */
    363                     }
    364                     /* check limit. */
    365                     if ((RTGCUINTPTR)Addr > u32Limit)
    366                         return VERR_OUT_OF_SELECTOR_BOUNDS;
    367                     /* ok */
    368                     if (ppvGC)
    369                         *ppvGC = pvFlat;
    370                     return VINF_SUCCESS;
    371 
    372                 case BOTH(1,X86_SEL_TYPE_EO_CONF):
    373                 case BOTH(1,X86_SEL_TYPE_EO_CONF_ACC):
    374                 case BOTH(1,X86_SEL_TYPE_ER_CONF):
    375                 case BOTH(1,X86_SEL_TYPE_ER_CONF_ACC):
    376                     if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
    377                     {
    378                         /** @todo fix this mess */
    379                     }
    380                     /* check limit. */
    381                     if ((RTGCUINTPTR)Addr > u32Limit)
    382                         return VERR_OUT_OF_SELECTOR_BOUNDS;
    383                     /* ok */
    384                     if (ppvGC)
    385                         *ppvGC = pvFlat;
    386                     return VINF_SUCCESS;
    387 
    388                 case BOTH(1,X86_SEL_TYPE_RO_DOWN):
    389                 case BOTH(1,X86_SEL_TYPE_RO_DOWN_ACC):
    390                 case BOTH(1,X86_SEL_TYPE_RW_DOWN):
    391                 case BOTH(1,X86_SEL_TYPE_RW_DOWN_ACC):
    392                     if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
    393                     {
    394                         /** @todo fix this mess */
    395                     }
    396                     /* check limit. */
    397                     if (!u1Granularity && (RTGCUINTPTR)Addr > (RTGCUINTPTR)0xffff)
    398                         return VERR_OUT_OF_SELECTOR_BOUNDS;
    399                     if ((RTGCUINTPTR)Addr <= u32Limit)
    400                         return VERR_OUT_OF_SELECTOR_BOUNDS;
    401 
    402                     /* ok */
    403                     if (ppvGC)
    404                         *ppvGC = pvFlat;
    405                     return VINF_SUCCESS;
    406 
    407                 case BOTH(0,X86_SEL_TYPE_SYS_286_TSS_AVAIL):
    408                 case BOTH(0,X86_SEL_TYPE_SYS_LDT):
    409                 case BOTH(0,X86_SEL_TYPE_SYS_286_TSS_BUSY):
    410                 case BOTH(0,X86_SEL_TYPE_SYS_286_CALL_GATE):
    411                 case BOTH(0,X86_SEL_TYPE_SYS_TASK_GATE):
    412                 case BOTH(0,X86_SEL_TYPE_SYS_286_INT_GATE):
    413                 case BOTH(0,X86_SEL_TYPE_SYS_286_TRAP_GATE):
    414                 case BOTH(0,X86_SEL_TYPE_SYS_386_TSS_AVAIL):
    415                 case BOTH(0,X86_SEL_TYPE_SYS_386_TSS_BUSY):
    416                 case BOTH(0,X86_SEL_TYPE_SYS_386_CALL_GATE):
    417                 case BOTH(0,X86_SEL_TYPE_SYS_386_INT_GATE):
    418                 case BOTH(0,X86_SEL_TYPE_SYS_386_TRAP_GATE):
    419                     if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
    420                     {
    421                         /** @todo fix this mess */
    422                     }
    423                     /* check limit. */
    424                     if ((RTGCUINTPTR)Addr > u32Limit)
    425                         return VERR_OUT_OF_SELECTOR_BOUNDS;
    426                     /* ok */
    427                     if (ppvGC)
    428                         *ppvGC = pvFlat;
    429                     return VINF_SUCCESS;
    430 
    431                 default:
    432                     return VERR_INVALID_SELECTOR;
    433 
    434             }
    435 # undef BOTH
    436         }
    437     }
    438 #endif /* !IN_RING0 */
     284
     285        }
     286    }
    439287    return VERR_SELECTOR_NOT_PRESENT;
    440288}
    441289
    442290
    443 #ifndef IN_RING0
     291#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    444292/**
    445293 * Converts a GC selector based address to a flat address.
     
    452300 * @param   Sel         Selector part.
    453301 * @param   Addr        Address part.
    454  * @param   pHiddenSel  Hidden selector register (can be NULL)
    455302 * @param   fFlags      SELMTOFLAT_FLAGS_*
    456303 *                      GDT entires are valid.
     
    460307 * @remarks Don't use when in long mode.
    461308 */
    462 VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, PCCPUMSELREGHID pHiddenSel, uint32_t fFlags, PRTGCPTR ppvGC, uint32_t *pcb)
    463 {
    464     Assert(!CPUMIsGuestInLongMode(pVCpu));    /* DON'T USE! */
     309VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr,
     310                               uint32_t fFlags, PRTGCPTR ppvGC, uint32_t *pcb)
     311{
     312    Assert(!CPUMIsGuestInLongMode(pVCpu));    /* DON'T USE! (Accessing shadow GDT/LDT.) */
    465313
    466314    /*
     
    472320        RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff;
    473321        if (ppvGC)
    474         {
    475             if (    pHiddenSel
    476                 &&  CPUMAreHiddenSelRegsValid(pVCpu))
    477                 *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat);
    478             else
    479                 *ppvGC = (RTGCPTR)(((RTGCUINTPTR)Sel << 4) + uFlat);
    480         }
     322            *ppvGC = ((RTGCUINTPTR)Sel << 4) + uFlat;
    481323        if (pcb)
    482324            *pcb = 0x10000 - uFlat;
     
    484326    }
    485327
    486 
    487     uint32_t    u32Limit;
    488     RTGCPTR     pvFlat;
    489     uint32_t    u1Present, u1DescType, u1Granularity, u4Type;
    490 
    491     /** @todo when we're in 16 bits mode, we should cut off the address as well.. */
    492     if (    pHiddenSel
    493         &&  CPUMAreHiddenSelRegsValid(pVCpu))
    494     {
    495         u1Present     = pHiddenSel->Attr.n.u1Present;
    496         u1Granularity = pHiddenSel->Attr.n.u1Granularity;
    497         u1DescType    = pHiddenSel->Attr.n.u1DescType;
    498         u4Type        = pHiddenSel->Attr.n.u4Type;
    499 
    500         u32Limit      = pHiddenSel->u32Limit;
    501         pvFlat        = (RTGCPTR)(pHiddenSel->u64Base + (RTGCUINTPTR)Addr);
    502 
    503         if (   !pHiddenSel->Attr.n.u1Long
    504             || !CPUMIsGuestInLongMode(pVCpu))
    505         {
    506             /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
    507             pvFlat &= 0xffffffff;
    508         }
     328    /** @todo when we're in 16 bits mode, we should cut off the address as well?? */
     329    X86DESC Desc;
     330    PVM pVM = pVCpu->CTX_SUFF(pVM);
     331    if (!(Sel & X86_SEL_LDT))
     332    {
     333        if (   !(fFlags & SELMTOFLAT_FLAGS_HYPER)
     334            && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
     335            return VERR_INVALID_SELECTOR;
     336        Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    509337    }
    510338    else
    511339    {
    512         X86DESC Desc;
    513 
    514         PVM pVM = pVCpu->CTX_SUFF(pVM);
    515         if (!(Sel & X86_SEL_LDT))
    516         {
    517             if (   !(fFlags & SELMTOFLAT_FLAGS_HYPER)
    518                 && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
    519                 return VERR_INVALID_SELECTOR;
    520             Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    521         }
    522         else
    523         {
    524             if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit)
    525                 return VERR_INVALID_SELECTOR;
    526 
    527             /** @todo handle LDT page(s) not present! */
    528             PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    529             Desc = paLDT[Sel >> X86_SEL_SHIFT];
    530         }
    531 
    532         /* calc limit. */
    533         u32Limit = X86DESC_LIMIT(Desc);
    534         if (Desc.Gen.u1Granularity)
    535             u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
    536 
    537         /* calc address assuming straight stuff. */
    538         pvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc));
    539 
    540         /* Cut the address to 32 bits. */
    541         Assert(!CPUMIsGuestInLongMode(pVCpu));
    542         pvFlat &= 0xffffffff;
    543 
    544         u1Present     = Desc.Gen.u1Present;
    545         u1Granularity = Desc.Gen.u1Granularity;
    546         u1DescType    = Desc.Gen.u1DescType;
    547         u4Type        = Desc.Gen.u4Type;
    548     }
     340        if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit)
     341            return VERR_INVALID_SELECTOR;
     342
     343        /** @todo handle LDT page(s) not present! */
     344        PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
     345        Desc = paLDT[Sel >> X86_SEL_SHIFT];
     346    }
     347
     348    /* calc limit. */
     349    uint32_t u32Limit = X86DESC_LIMIT(Desc);
     350    if (Desc.Gen.u1Granularity)
     351        u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
     352
     353    /* calc address assuming straight stuff. */
     354    RTGCPTR pvFlat = Addr + X86DESC_BASE(Desc);
     355
     356    /* Cut the address to 32 bits. */
     357    Assert(!CPUMIsGuestInLongMode(pVCpu));
     358    pvFlat &= 0xffffffff;
     359
     360    uint8_t u1Present     = Desc.Gen.u1Present;
     361    uint8_t u1Granularity = Desc.Gen.u1Granularity;
     362    uint8_t u1DescType    = Desc.Gen.u1DescType;
     363    uint8_t u4Type        = Desc.Gen.u4Type;
    549364
    550365    /*
     
    656471    return VERR_SELECTOR_NOT_PRESENT;
    657472}
    658 #endif /* !IN_RING0 */
    659 
    660 
    661 #ifdef VBOX_WITH_RAW_MODE
     473#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
     474
     475
     476#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    662477/**
    663478 * CPUM helper that loads the hidden selector register from the descriptor table
     
    687502    RTSEL const Sel = pSReg->Sel;
    688503
     504/** @todo Consider loading these from the shadow tables when possible? */
    689505    /*
    690506     * Calculate descriptor table entry address.
     
    763579 * @param   ppvFlat Where to store the flat address.
    764580 */
    765 DECLINLINE(int) selmValidateAndConvertCSAddrRealMode(PVMCPU pVCpu, RTSEL SelCS, PCCPUMSELREGHID pHidCS, RTGCPTR Addr,
     581DECLINLINE(int) selmValidateAndConvertCSAddrRealMode(PVMCPU pVCpu, RTSEL SelCS, PCCPUMSELREGHID pSReg, RTGCPTR Addr,
    766582                                                     PRTGCPTR ppvFlat)
    767583{
    768     RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff;
    769     if (!pHidCS || !CPUMAreHiddenSelRegsValid(pVCpu))
    770         uFlat += ((RTGCUINTPTR)SelCS << 4);
     584    RTGCUINTPTR uFlat = Addr & 0xffff;
     585    if (!pSReg || !CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
     586        uFlat += (RTGCUINTPTR)SelCS << 4;
    771587    else
    772         uFlat += pHidCS->u64Base;
    773     *ppvFlat = (RTGCPTR)uFlat;
     588        uFlat += pSReg->u64Base;
     589    *ppvFlat = uFlat;
    774590    return VINF_SUCCESS;
    775591}
    776592
    777593
    778 #ifndef IN_RING0
    779 /**
    780  * Validates and converts a GC selector based code address to a flat
    781  * address when in protected/long mode using the standard algorithm.
     594#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     595/**
     596 * Validates and converts a GC selector based code address to a flat address
     597 * when in protected/long mode using the raw-mode algorithm.
    782598 *
    783599 * @returns VBox status code.
    784  * @param   pVM     Pointer to the VM.
    785  * @param   pVCpu   Pointer to the VMCPU.
    786  * @param   SelCPL  Current privilege level. Get this from SS - CS might be conforming!
    787  *                  A full selector can be passed, we'll only use the RPL part.
    788  * @param   SelCS   Selector part.
    789  * @param   Addr    Address part.
    790  * @param   ppvFlat Where to store the flat address.
    791  * @param   pcBits  Where to store the segment bitness (16/32/64). Optional.
    792  */
    793 DECLINLINE(int) selmValidateAndConvertCSAddrStd(PVM pVM, PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr,
    794                                                 PRTGCPTR ppvFlat, uint32_t *pcBits)
     600 * @param   pVM         Pointer to the VM.
     601 * @param   pVCpu       Pointer to the VMCPU.
     602 * @param   SelCPL      Current privilege level. Get this from SS - CS might be
     603 *                      conforming! A full selector can be passed, we'll only
     604 *                      use the RPL part.
     605 * @param   SelCS       Selector part.
     606 * @param   Addr        Address part.
     607 * @param   ppvFlat     Where to store the flat address.
     608 * @param   pcBits      Where to store the segment bitness (16/32/64). Optional.
     609 */
     610DECLINLINE(int) selmValidateAndConvertCSAddrRawMode(PVM pVM, PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr,
     611                                                    PRTGCPTR ppvFlat, uint32_t *pcBits)
    795612{
    796613    NOREF(pVCpu);
     
    850667    return VERR_SELECTOR_NOT_PRESENT;
    851668}
    852 #endif /* !IN_RING0 */
    853 
    854 
    855 /**
    856  * Validates and converts a GC selector based code address to a flat
    857  * address when in protected/long mode using the standard algorithm.
     669#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
     670
     671
     672/**
     673 * Validates and converts a GC selector based code address to a flat address
     674 * when in protected/long mode using the standard hidden selector registers
    858675 *
    859676 * @returns VBox status code.
    860  * @param   pVCpu   Pointer to the VMCPU.
    861  * @param   SelCPL  Current privilege level. Get this from SS - CS might be conforming!
    862  *                  A full selector can be passed, we'll only use the RPL part.
    863  * @param   SelCS   Selector part.
    864  * @param   Addr    Address part.
    865  * @param   ppvFlat Where to store the flat address.
    866  */
    867 DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pHidCS,
     677 * @param   pVCpu       Pointer to the VMCPU.
     678 * @param   SelCPL      Current privilege level.  Get this from SS - CS might be
     679 *                      conforming!  A full selector can be passed, we'll only
     680 *                      use the RPL part.
     681 * @param   SelCS       Selector part.
     682 * @param   pSRegCS     The full CS selector register.
     683 * @param   Addr        The address (think IP/EIP/RIP).
     684 * @param   ppvFlat     Where to store the flat address upon successful return.
     685 */
     686DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pSRegCS,
    868687                                                   RTGCPTR Addr, PRTGCPTR ppvFlat)
    869688{
     
    871690     * Check if present.
    872691     */
    873     if (pHidCS->Attr.n.u1Present)
     692    if (pSRegCS->Attr.n.u1Present)
    874693    {
    875694        /*
    876695         * Type check.
    877696         */
    878         if (     pHidCS->Attr.n.u1DescType == 1
    879             &&  (pHidCS->Attr.n.u4Type & X86_SEL_TYPE_CODE))
     697        if (     pSRegCS->Attr.n.u1DescType == 1
     698            &&  (pSRegCS->Attr.n.u4Type & X86_SEL_TYPE_CODE))
    880699        {
    881700            /*
     
    883702             */
    884703            unsigned uLevel = RT_MAX(SelCPL & X86_SEL_RPL, SelCS & X86_SEL_RPL);
    885             if (    !(pHidCS->Attr.n.u4Type & X86_SEL_TYPE_CONF)
    886                 ?   uLevel <= pHidCS->Attr.n.u2Dpl
    887                 :   uLevel >= pHidCS->Attr.n.u2Dpl /* hope I got this right now... */
    888                     )
     704            if (    !(pSRegCS->Attr.n.u4Type & X86_SEL_TYPE_CONF)
     705                ?   uLevel <= pSRegCS->Attr.n.u2Dpl
     706                :   uLevel >= pSRegCS->Attr.n.u2Dpl /* hope I got this right now... */
     707               )
    889708            {
    890                 /* 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). */
    891                 if (    pHidCS->Attr.n.u1Long
     709                /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0
     710                   (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */
     711                if (    pSRegCS->Attr.n.u1Long
    892712                    &&  CPUMIsGuestInLongMode(pVCpu))
    893713                {
     
    900720                 * final value. The granularity bit was included in its calculation.
    901721                 */
    902                 uint32_t u32Limit = pHidCS->u32Limit;
     722                uint32_t u32Limit = pSRegCS->u32Limit;
    903723                if ((RTGCUINTPTR)Addr <= u32Limit)
    904724                {
    905                     *ppvFlat = (RTGCPTR)(  (RTGCUINTPTR)Addr + pHidCS->u64Base );
     725                    *ppvFlat = Addr + pSRegCS->u64Base;
    906726                    return VINF_SUCCESS;
    907727                }
     728
    908729                return VERR_OUT_OF_SELECTOR_BOUNDS;
    909730            }
    910             Log(("Invalid RPL Attr.n.u4Type=%x cpl=%x dpl=%x\n", pHidCS->Attr.n.u4Type, uLevel, pHidCS->Attr.n.u2Dpl));
     731            Log(("selmValidateAndConvertCSAddrHidden: Invalid RPL Attr.n.u4Type=%x cpl=%x dpl=%x\n",
     732                 pSRegCS->Attr.n.u4Type, uLevel, pSRegCS->Attr.n.u2Dpl));
    911733            return VERR_INVALID_RPL;
    912734        }
     
    917739
    918740
    919 #ifdef IN_RC
    920741/**
    921742 * Validates and converts a GC selector based code address to a flat address.
    922  *
    923  * This is like SELMValidateAndConvertCSAddr + SELMIsSelector32Bit but with
    924  * invalid hidden CS data. It's customized for dealing efficiently with CS
    925  * at GC trap time.
    926743 *
    927744 * @returns VBox status code.
    928745 * @param   pVCpu       Pointer to the VMCPU.
    929  * @param   eflags      Current eflags
    930  * @param   SelCPL      Current privilege level. Get this from SS - CS might be
    931  *                      conforming! A full selector can be passed, we'll only
     746 * @param   Efl         Current EFLAGS.
     747 * @param   SelCPL      Current privilege level.  Get this from SS - CS might be
     748 *                      conforming!  A full selector can be passed, we'll only
    932749 *                      use the RPL part.
    933750 * @param   SelCS       Selector part.
    934  * @param   Addr        Address part.
    935  * @param   ppvFlat     Where to store the flat address.
    936  * @param   pcBits      Where to store the 64-bit/32-bit/16-bit indicator.
    937  */
    938 VMMDECL(int) SELMValidateAndConvertCSAddrGCTrap(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr, PRTGCPTR ppvFlat, uint32_t *pcBits)
    939 {
    940     if (    eflags.Bits.u1VM
     751 * @param   pSRegCS     The full CS selector register.
     752 * @param   Addr        The address (think IP/EIP/RIP).
     753 * @param   ppvFlat     Where to store the flat address upon successful return.
     754 */
     755VMMDECL(int) SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS Efl, RTSEL SelCPL, RTSEL SelCS, PCPUMSELREG pSRegCS,
     756                                          RTGCPTR Addr, PRTGCPTR ppvFlat)
     757{
     758    if (    Efl.Bits.u1VM
    941759        ||  CPUMIsGuestInRealMode(pVCpu))
    942     {
    943         *pcBits = 16;
    944         return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, NULL, Addr, ppvFlat);
    945     }
    946     Assert(!CPUMAreHiddenSelRegsValid(pVCpu));
    947     return selmValidateAndConvertCSAddrStd(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, pcBits);
    948 }
    949 #endif /* IN_RC */
    950 
    951 
    952 /**
    953  * Validates and converts a GC selector based code address to a flat address.
    954  *
    955  * @returns VBox status code.
    956  * @param   pVCpu        Pointer to the VMCPU.
    957  * @param   eflags       Current eflags
    958  * @param   SelCPL       Current privilege level. Get this from SS - CS might be conforming!
    959  *                       A full selector can be passed, we'll only use the RPL part.
    960  * @param   SelCS        Selector part.
    961  * @param   pHiddenSel   The hidden CS selector register.
    962  * @param   Addr         Address part.
    963  * @param   ppvFlat      Where to store the flat address.
    964  */
    965 VMMDECL(int) SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pHiddenCSSel,
    966                                           RTGCPTR Addr, PRTGCPTR ppvFlat)
    967 {
    968     if (    eflags.Bits.u1VM
    969         ||  CPUMIsGuestInRealMode(pVCpu))
    970         return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, pHiddenCSSel, Addr, ppvFlat);
    971 
    972 #ifdef IN_RING0
    973     Assert(CPUMAreHiddenSelRegsValid(pVCpu));
     760        return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, pSRegCS, Addr, ppvFlat);
     761
     762#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     763    /* Use the hidden registers when possible, updating them if outdate. */
     764    if (!pSRegCS)
     765        return selmValidateAndConvertCSAddrRawMode(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, NULL);
     766
     767    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSRegCS))
     768        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSRegCS);
     769
     770    /* Undo ring compression. */
     771    if ((SelCPL & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
     772        SelCPL &= ~X86_SEL_RPL;
     773    Assert(pSRegCS->Sel == SelCS);
     774    if ((SelCS  & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
     775        SelCS  &= ~X86_SEL_RPL;
    974776#else
    975     /** @todo when we're in 16 bits mode, we should cut off the address as well? (like in selmValidateAndConvertCSAddrRealMode) */
    976     if (!CPUMAreHiddenSelRegsValid(pVCpu) || !pHiddenCSSel)
    977         return selmValidateAndConvertCSAddrStd(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, NULL);
     777    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSRegCS));
     778    Assert(pSRegCS->Sel == SelCS);
    978779#endif
    979     return selmValidateAndConvertCSAddrHidden(pVCpu, SelCPL, SelCS, pHiddenCSSel, Addr, ppvFlat);
    980 }
    981 
    982 
    983 #ifndef IN_RING0
    984 /**
    985  * Return the cpu mode corresponding to the (CS) selector
    986  *
    987  * @returns DISCPUMODE according to the selector type (16, 32 or 64 bits)
    988  * @param   pVM     Pointer to the VM.
    989  * @param   pVCpu   Pointer to the VMCPU.
    990  * @param   Sel     The selector.
    991  */
    992 static DISCPUMODE selmGetCpuModeFromSelector(PVM pVM, PVMCPU pVCpu, RTSEL Sel)
    993 {
    994     Assert(!CPUMAreHiddenSelRegsValid(pVCpu));
    995 
    996     /** @todo validate limit! */
    997     X86DESC Desc;
    998     if (!(Sel & X86_SEL_LDT))
    999         Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
    1000     else
    1001     {
    1002         /** @todo handle LDT page(s) not present! */
    1003         PX86DESC   paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
    1004         Desc = paLDT[Sel >> X86_SEL_SHIFT];
    1005     }
    1006     return (Desc.Gen.u1DefBig) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT;
    1007 }
    1008 #endif /* !IN_RING0 */
    1009 
    1010 
    1011 /**
    1012  * Return the cpu mode corresponding to the (CS) selector
    1013  *
    1014  * @returns DISCPUMODE according to the selector type (16, 32 or 64 bits)
    1015  * @param   pVCpu      Pointer to the VMCPU.
    1016  * @param   eflags     Current eflags register
    1017  * @param   Sel        The selector.
    1018  * @param   pHiddenSel The hidden selector register.
    1019  */
    1020 VMMDECL(DISCPUMODE) SELMGetCpuModeFromSelector(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, PCCPUMSELREGHID pHiddenSel)
    1021 {
    1022 #ifdef IN_RING0
    1023     Assert(CPUMAreHiddenSelRegsValid(pVCpu));
    1024     NOREF(eflags); NOREF(Sel);
    1025 #else  /* !IN_RING0 */
    1026     if (!CPUMAreHiddenSelRegsValid(pVCpu))
    1027     {
    1028         /*
    1029          * Deal with real & v86 mode first.
    1030          */
    1031         if (    eflags.Bits.u1VM
    1032             ||  CPUMIsGuestInRealMode(pVCpu))
    1033             return DISCPUMODE_16BIT;
    1034 
    1035         return selmGetCpuModeFromSelector(pVCpu->CTX_SUFF(pVM), pVCpu, Sel);
    1036     }
    1037 #endif /* !IN_RING0 */
    1038     if (    pHiddenSel->Attr.n.u1Long
    1039         &&  CPUMIsGuestInLongMode(pVCpu))
    1040         return DISCPUMODE_64BIT;
    1041 
    1042     /* Else compatibility or 32 bits mode. */
    1043     return pHiddenSel->Attr.n.u1DefBig ? DISCPUMODE_32BIT : DISCPUMODE_16BIT;
     780
     781    return selmValidateAndConvertCSAddrHidden(pVCpu, SelCPL, SelCS, pSRegCS, Addr, ppvFlat);
    1044782}
    1045783
     
    1084822
    1085823
    1086 #ifndef IN_RING0
     824#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    1087825/**
    1088826 * Gets ss:esp for ring1 in main Hypervisor's TSS.
     
    1165903    return VINF_SUCCESS;
    1166904}
    1167 #endif /* !IN_RING0 */
     905#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
    1168906
    1169907
     
    1179917}
    1180918
    1181 
    1182 #ifndef IN_RING0
     919#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    1183920
    1184921/**
     
    1254991}
    1255992
    1256 #endif /* !IN_RING0 */
     993#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
    1257994
    1258995/**
     
    13051042    pVM->selm.s.TssTrap08.cr3 = PGMGetInterRCCR3(pVM, pVCpu);
    13061043}
     1044
  • trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp

    r42165 r42186  
    341341
    342342
    343 #ifndef IN_RING0
     343#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    344344/**
    345345 * Forward trap or interrupt to the guest's handler
     
    554554                        || !ss_r0
    555555                        || (ss_r0 & X86_SEL_RPL) != ((dpl == 0) ? 1 : dpl)
    556                         || SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL, SELMTOFLAT_FLAGS_CPL1,
     556                        || SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, SELMTOFLAT_FLAGS_CPL1,
    557557                                             (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS
    558558                       )
     
    569569
    570570                    if (    eflags.Bits.u1VM    /* illegal */
    571                         ||  SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL, SELMTOFLAT_FLAGS_CPL1,
     571                        ||  SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, SELMTOFLAT_FLAGS_CPL1,
    572572                                              (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS)
    573573                    {
     
    743743    return VINF_EM_RAW_GUEST_TRAP;
    744744}
    745 #endif /* !IN_RING0 */
     745#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
    746746
    747747
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r42184 r42186  
    24282428
    24292429            /* Disassemble manually to deal with segment prefixes. */
    2430             rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, NULL);
     2430            rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
    24312431            if (rc == VINF_SUCCESS)
    24322432            {
     
    29902990     * Only allow 32 & 64 bit code.
    29912991     */
    2992     DISCPUMODE enmMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs);
    2993     if (enmMode != DISCPUMODE_16BIT)
     2992    if (CPUMGetGuestCodeBits(pVCpu) != 16)
    29942993    {
    29952994        PDISSTATE pDis = &pVCpu->hwaccm.s.DisState;
    2996         int rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, pDis, NULL);
     2995        int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
    29972996        if (RT_SUCCESS(rc) && pDis->pCurInstr->uOpcode == OP_INVLPG)
    29982997        {
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r42184 r42186  
    36573657                LogFlow(("Real mode X86_XCPT_GP instruction emulation at %x:%RGv\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
    36583658
    3659                 rc2 = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
     3659                rc2 = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
    36603660                if (RT_SUCCESS(rc2))
    36613661                {
     
    44424442            /** @todo VMX_VMCS_EXIT_GUEST_LINEAR_ADDR contains the flat pointer operand of the instruction. */
    44434443            /** @todo VMX_VMCS32_RO_EXIT_INSTR_INFO also contains segment prefix info. */
    4444             rc2 = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, NULL);
     4444            rc2 = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
    44454445            if (RT_SUCCESS(rc))
    44464446            {
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r41965 r42186  
    22952295    {
    22962296        /* Assuming 32 bits code for now. */
    2297         Assert(SELMGetCpuModeFromSelector(VMMGetCpu0(pVM), pCtxCore->eflags, pCtxCore->cs.Sel, &pCtxCore->cs) == DISCPUMODE_32BIT);
     2297        Assert(CPUMGetGuestCodeBits(VMMGetCpu0(pVM)) == 32);
    22982298
    22992299        pInstrGC = SELMToFlat(pVM, DISSELREG_CS, pCtxCore, pInstrGC);
  • trunk/src/VBox/VMM/VMMR3/EMRaw.cpp

    r41939 r42186  
    685685            {
    686686                rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
    687                                            SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs)
    688                                         == DISCPUMODE_32BIT ? PATMFL_CODE32 : 0);
     687                                        CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0);
    689688                if (RT_SUCCESS(rc))
    690689                {
     
    936935        {
    937936            int rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
    938                                         (   SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs)
    939                                          == DISCPUMODE_32BIT) ? PATMFL_CODE32 : 0);
     937                                        CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0);
    940938            if (RT_SUCCESS(rc))
    941939            {
     
    10441042        if (    (pCtx->ss.Sel & X86_SEL_RPL) == 0
    10451043            &&  !pCtx->eflags.Bits.u1VM
    1046             &&  SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs) == DISCPUMODE_32BIT)
     1044            &&  CPUMGetGuestCodeBits(pVCpu) == 32)
    10471045        {
    10481046            STAM_PROFILE_START(&pVCpu->em.s.StatPrivEmu, a);
  • trunk/src/VBox/VMM/VMMR3/HWACCM.cpp

    r42033 r42186  
    18681868    PDISCPUSTATE    pDis = &pVCpu->hwaccm.s.DisState;
    18691869    uint32_t        cbOp;
    1870     int rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
     1870    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
    18711871    AssertRC(rc);
    18721872    if (    rc == VINF_SUCCESS
     
    19201920
    19211921            pCtx->rip += cbOp;
    1922             rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
     1922            rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
    19231923            DBGFR3DisasInstrCurrentLog(pVCpu, "Following read");
    19241924            pCtx->rip = uSavedRip;
     
    20412041    PDISCPUSTATE    pDis   = &pVCpu->hwaccm.s.DisState;
    20422042    uint32_t        cbOp;
    2043     int rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
     2043    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
    20442044    AssertRC(rc);
    20452045    if (    rc == VINF_SUCCESS
  • trunk/src/VBox/VMM/VMMRC/PATMRC.cpp

    r41965 r42186  
    507507            }
    508508
    509             DISCPUMODE enmCpuMode = SELMGetCpuModeFromSelector(VMMGetCpu0(pVM), pRegFrame->eflags, pRegFrame->cs.Sel, 0);
     509            PVMCPU     pVCpu      = VMMGetCpu0(pVM);
     510            DISCPUMODE enmCpuMode = CPUMGetGuestDisMode(pVCpu);
    510511            if (enmCpuMode != DISCPUMODE_32BIT)
    511512            {
     
    516517#ifdef VBOX_WITH_IEM
    517518            VBOXSTRICTRC rcStrict;
    518             rcStrict = IEMExecOneWithPrefetchedByPC(VMMGetCpu0(pVM), pRegFrame, pRegFrame->rip,
     519            rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, pRegFrame, pRegFrame->rip,
    519520                                                    pRec->patch.aPrivInstr, pRec->patch.cbPrivInstr);
    520521            rc = VBOXSTRICTRC_TODO(rcStrict);
     
    531532            }
    532533
    533             rc = EMInterpretInstructionDisasState(VMMGetCpu0(pVM), &cpu, pRegFrame, 0 /* not relevant here */,
     534            rc = EMInterpretInstructionDisasState(pVCpu, &cpu, pRegFrame, 0 /* not relevant here */,
    534535                                                  EMCODETYPE_SUPERVISOR);
    535536#endif
  • trunk/src/VBox/VMM/VMMRC/TRPMRC.cpp

    r41965 r42186  
    179179     */
    180180    DISSTATE Dis;
    181     int rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, &Dis, NULL);
     181    int rc = EMInterpretDisasCurrent(pVM, pVCpu, &Dis, NULL);
    182182    if (rc == VINF_SUCCESS)
    183183    {
  • trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp

    r41965 r42186  
    953953    STAM_PROFILE_START(&pVM->trpm.s.StatTrap0dDisasm, a);
    954954    RTGCPTR PC;
    955     uint32_t cBits;
    956     int rc = SELMValidateAndConvertCSAddrGCTrap(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel,
    957                                                 pRegFrame->rip, &PC, &cBits);
     955    int rc = SELMValidateAndConvertCSAddr(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel, &pRegFrame->cs,
     956                                          pRegFrame->rip, &PC);
    958957    if (RT_FAILURE(rc))
    959958    {
  • trunk/src/VBox/VMM/include/EMHandleRCTmpl.h

    r41906 r42186  
    113113            rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
    114114                                      PATMFL_MMIO_ACCESS
    115                                     | (    SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs)
    116                                         == DISCPUMODE_32BIT ? PATMFL_CODE32 : 0));
     115                                    | (CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0));
    117116            if (RT_FAILURE(rc))
    118117                rc = emR3ExecuteInstruction(pVM, pVCpu, "MMIO");
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