Index: /trunk/include/VBox/dis.h
===================================================================
--- /trunk/include/VBox/dis.h	(revision 42185)
+++ /trunk/include/VBox/dis.h	(revision 42186)
@@ -34,17 +34,4 @@
 RT_C_DECLS_BEGIN
 
-
-/**
- * CPU mode flags (DISSTATE::mode).
- */
-typedef enum DISCPUMODE
-{
-    DISCPUMODE_INVALID = 0,
-    DISCPUMODE_16BIT,
-    DISCPUMODE_32BIT,
-    DISCPUMODE_64BIT,
-    /** hack forcing the size of the enum to 32-bits. */
-    DISCPUMODE_MAKE_32BIT_HACK = 0x7fffffff
-} DISCPUMODE;
 
 /** @name Prefix byte flags (DISSTATE::fPrefix).
@@ -702,5 +689,5 @@
 DISDECL(int) DISFetchReg64(PCCPUMCTXCORE pCtx, unsigned reg64, uint64_t *pVal);
 DISDECL(int) DISFetchRegSeg(PCCPUMCTXCORE pCtx, DISSELREG sel, RTSEL *pVal);
-DISDECL(int) DISFetchRegSegEx(PCCPUMCTXCORE pCtx, DISSELREG sel, RTSEL *pVal, PCPUMSELREGHID *ppSelHidReg);
+DISDECL(int) DISFetchRegSegEx(PCPUMCTXCORE pCtx, DISSELREG sel, PCPUMSELREG *ppSelReg);
 DISDECL(int) DISWriteReg8(PCPUMCTXCORE pRegFrame, unsigned reg8, uint8_t val8);
 DISDECL(int) DISWriteReg16(PCPUMCTXCORE pRegFrame, unsigned reg32, uint16_t val16);
Index: /trunk/include/VBox/types.h
===================================================================
--- /trunk/include/VBox/types.h	(revision 42185)
+++ /trunk/include/VBox/types.h	(revision 42186)
@@ -1029,4 +1029,17 @@
 
 
+/**
+ * CPU mode flags (DISSTATE::mode).
+ */
+typedef enum DISCPUMODE
+{
+    DISCPUMODE_INVALID = 0,
+    DISCPUMODE_16BIT,
+    DISCPUMODE_32BIT,
+    DISCPUMODE_64BIT,
+    /** hack forcing the size of the enum to 32-bits. */
+    DISCPUMODE_MAKE_32BIT_HACK = 0x7fffffff
+} DISCPUMODE;
+
 /** Pointer to the disassembler state. */
 typedef struct DISSTATE *PDISSTATE;
Index: /trunk/include/VBox/vmm/cpum.h
===================================================================
--- /trunk/include/VBox/vmm/cpum.h	(revision 42185)
+++ /trunk/include/VBox/vmm/cpum.h	(revision 42186)
@@ -408,4 +408,6 @@
 VMMDECL(bool)           CPUMAreHiddenSelRegsValid(PVMCPU pVCpu);
 VMMDECL(CPUMMODE)       CPUMGetGuestMode(PVMCPU pVCpu);
+VMMDECL(uint32_t)       CPUMGetGuestCodeBits(PVMCPU pVCpu);
+VMMDECL(DISCPUMODE)     CPUMGetGuestDisMode(PVMCPU pVCpu);
 
 
Index: /trunk/include/VBox/vmm/em.h
===================================================================
--- /trunk/include/VBox/vmm/em.h	(revision 42185)
+++ /trunk/include/VBox/vmm/em.h	(revision 42186)
@@ -154,5 +154,5 @@
 VMMDECL(void)           EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC);
 VMMDECL(RTGCUINTPTR)    EMGetInhibitInterruptsPC(PVMCPU pVCpu);
-VMMDECL(int)            EMInterpretDisasOne(PVM pVM, PVMCPU pVCpu, PCCPUMCTXCORE pCtxCore, PDISCPUSTATE pCpu, unsigned *pcbInstr);
+VMMDECL(int)            EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pCpu, unsigned *pcbInstr);
 VMMDECL(int)            EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore,
                                               PDISCPUSTATE pDISState, unsigned *pcbInstr);
Index: /trunk/include/VBox/vmm/selm.h
===================================================================
--- /trunk/include/VBox/vmm/selm.h	(revision 42185)
+++ /trunk/include/VBox/vmm/selm.h	(revision 42186)
@@ -74,12 +74,10 @@
 /** @} */
 
-VMMDECL(int)        SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCCPUMCTXCORE pCtxCore, RTGCPTR Addr, unsigned fFlags, PRTGCPTR ppvGC);
-VMMDECL(int)        SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, PCCPUMSELREGHID pHiddenSel,
-                                      uint32_t fFlags, PRTGCPTR ppvGC, uint32_t *pcb);
-VMMDECL(int)        SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS,
-                                                 PCCPUMSELREGHID pHiddenCSSel, RTGCPTR Addr, PRTGCPTR ppvFlat);
-VMMDECL(int)        SELMValidateAndConvertCSAddrGCTrap(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr,
-                                                       PRTGCPTR ppvFlat, uint32_t *pcBits);
-VMMDECL(DISCPUMODE) SELMGetCpuModeFromSelector(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, PCCPUMSELREGHID pHiddenSel);
+VMMDECL(int)        SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr, uint32_t fFlags,
+                                 PRTGCPTR ppvGC);
+VMMDECL(int)        SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, uint32_t fFlags,
+                                      PRTGCPTR ppvGC, uint32_t *pcb);
+VMMDECL(int)        SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, PCPUMSELREG pSRegCS,
+                                                 RTGCPTR Addr, PRTGCPTR ppvFlat);
 VMMDECL(int)        SELMGetLDTFromSel(PVM pVM, RTSEL SelLdt, PRTGCPTR ppvLdt, unsigned *pcbLimit);
 #ifdef VBOX_WITH_RAW_MODE
Index: /trunk/src/VBox/Disassembler/DisasmReg.cpp
===================================================================
--- /trunk/src/VBox/Disassembler/DisasmReg.cpp	(revision 42185)
+++ /trunk/src/VBox/Disassembler/DisasmReg.cpp	(revision 42186)
@@ -415,11 +415,8 @@
  *
  */
-DISDECL(int) DISFetchRegSegEx(PCCPUMCTXCORE pCtx, DISSELREG sel, RTSEL *pVal, CPUMSELREGHID **ppSelHidReg)
-{
-    AssertReturn((unsigned)sel < RT_ELEMENTS(g_aRegSegIndex), VERR_INVALID_PARAMETER);
-
-    AssertCompile(sizeof(uint16_t) == sizeof(RTSEL));
-    *pVal = DIS_READ_REGSEG(pCtx, sel);
-    *ppSelHidReg = (CPUMSELREGHID *)((char *)pCtx + g_aRegHidSegIndex[sel]);
+DISDECL(int) DISFetchRegSegEx(PCPUMCTXCORE pCtx, DISSELREG sel, PCPUMSELREG *ppSelReg)
+{
+    AssertReturnStmt((unsigned)sel < RT_ELEMENTS(g_aRegSegIndex), *ppSelReg = NULL, VERR_INVALID_PARAMETER);
+    *ppSelReg = (CPUMSELREG *)((uintptr_t)pCtx + g_aRegHidSegIndex[sel]);
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 42186)
@@ -2602,2 +2602,55 @@
     return enmMode;
 }
+
+
+/**
+ * Figure whether the CPU is currently executing 16, 32 or 64 bit code.
+ *
+ * @returns 16, 32 or 64.
+ * @param   pVCpu               The current virtual CPU.
+ */
+VMMDECL(uint32_t)       CPUMGetGuestCodeBits(PVMCPU pVCpu)
+{
+    if (!(pVCpu->cpum.s.Guest.cr0 & X86_CR0_PE))
+        return 16;
+
+    if (pVCpu->cpum.s.Guest.eflags.Bits.u1VM)
+    {
+        Assert(!(pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA));
+        return 16;
+    }
+
+    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true);
+    if (   pVCpu->cpum.s.Guest.cs.Attr.n.u1Long
+        && (pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA))
+        return 64;
+
+    if (pVCpu->cpum.s.Guest.cs.Attr.n.u1DefBig)
+        return 32;
+
+    return 16;
+}
+
+
+VMMDECL(DISCPUMODE)     CPUMGetGuestDisMode(PVMCPU pVCpu)
+{
+    if (!(pVCpu->cpum.s.Guest.cr0 & X86_CR0_PE))
+        return DISCPUMODE_16BIT;
+
+    if (pVCpu->cpum.s.Guest.eflags.Bits.u1VM)
+    {
+        Assert(!(pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA));
+        return DISCPUMODE_16BIT;
+    }
+
+    CPUMSELREG_LAZY_LOAD_HIDDEN_PARTS(pVCpu, &pVCpu->cpum.s.Guest.cs, true);
+    if (   pVCpu->cpum.s.Guest.cs.Attr.n.u1Long
+        && (pVCpu->cpum.s.Guest.msrEFER & MSR_K6_EFER_LMA))
+        return DISCPUMODE_64BIT;
+
+    if (pVCpu->cpum.s.Guest.cs.Attr.n.u1DefBig)
+        return DISCPUMODE_32BIT;
+
+    return DISCPUMODE_16BIT;
+}
+
Index: /trunk/src/VBox/VMM/VMMAll/EMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 42186)
@@ -365,5 +365,5 @@
 
 /**
- * Disassembles one instruction.
+ * Disassembles the current instruction.
  *
  * @returns VBox status code, see SELMToFlatEx and EMInterpretDisasOneEx for
@@ -373,10 +373,10 @@
  * @param   pVM             Pointer to the VM.
  * @param   pVCpu           Pointer to the VMCPU.
- * @param   pCtxCore        The context core (used for both the mode and instruction).
  * @param   pDis            Where to return the parsed instruction info.
  * @param   pcbInstr        Where to return the instruction size. (optional)
  */
-VMMDECL(int) EMInterpretDisasOne(PVM pVM, PVMCPU pVCpu, PCCPUMCTXCORE pCtxCore, PDISCPUSTATE pDis, unsigned *pcbInstr)
-{
+VMMDECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, unsigned *pcbInstr)
+{
+    PCPUMCTXCORE pCtxCore = CPUMCTX2CORE(CPUMQueryGuestCtxPtr(pVCpu));
     RTGCPTR GCPtrInstr;
 #if 0
@@ -384,6 +384,6 @@
 #else
 /** @todo Get the CPU mode as well while we're at it! */
-    int rc = SELMValidateAndConvertCSAddr(pVCpu, pCtxCore->eflags, pCtxCore->ss.Sel, pCtxCore->cs.Sel,
-                                          &pCtxCore->cs, pCtxCore->rip, &GCPtrInstr);
+    int rc = SELMValidateAndConvertCSAddr(pVCpu, pCtxCore->eflags, pCtxCore->ss.Sel, pCtxCore->cs.Sel, &pCtxCore->cs,
+                                          pCtxCore->rip, &GCPtrInstr);
 #endif
     if (RT_FAILURE(rc))
@@ -415,5 +415,6 @@
                                    PDISCPUSTATE pDis, unsigned *pcbInstr)
 {
-    DISCPUMODE enmCpuMode = SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs.Sel, (PCPUMSELREGHID)&pCtxCore->cs);
+    Assert(pCtxCore == CPUMGetGuestCtxCore(pVCpu));
+    DISCPUMODE enmCpuMode = CPUMGetGuestDisMode(pVCpu);
     /** @todo Deal with too long instruction (=> \#GP), opcode read errors (=>
      *        \#PF, \#GP, \#??), undefined opcodes (=> \#UD), and such. */
@@ -462,5 +463,5 @@
         uint32_t     cbOp;
         PDISCPUSTATE pDis = &pVCpu->em.s.DisState;
-        pDis->uCpuMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs);
+        pDis->uCpuMode = CPUMGetGuestDisMode(pVCpu);
         rc = emDisCoreOne(pVCpu->CTX_SUFF(pVM), pVCpu, pDis, (RTGCUINTPTR)pbCode, &cbOp);
         if (RT_SUCCESS(rc))
@@ -517,5 +518,5 @@
         uint32_t     cbOp;
         PDISCPUSTATE pDis = &pVCpu->em.s.DisState;
-        pDis->uCpuMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs);
+        pDis->uCpuMode = CPUMGetGuestDisMode(pVCpu);
         rc = emDisCoreOne(pVCpu->CTX_SUFF(pVM), pVCpu, pDis, (RTGCUINTPTR)pbCode, &cbOp);
         if (RT_SUCCESS(rc))
@@ -1547,5 +1548,5 @@
 
             /* Read stack value first */
-            if (SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, &pRegFrame->ss) == DISCPUMODE_16BIT)
+            if (CPUMGetGuestCodeBits(pVCpu) == 16)
                 return VERR_EM_INTERPRETER; /* No legacy 16 bits stuff here, please. */
 
Index: /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp	(revision 42186)
@@ -1521,5 +1521,5 @@
     PDISCPUSTATE    pDis  = &pVCpu->iom.s.DisState;
     unsigned        cbOp;
-    rc = EMInterpretDisasOne(pVM, pVCpu, pCtxCore, pDis, &cbOp);
+    rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
     if (RT_FAILURE(rc))
     {
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 42186)
@@ -908,5 +908,5 @@
                 PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState;
                 uint32_t     cbOp;
-                rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, pDis, &cbOp);
+                rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
 
                 /* For now we'll restrict this to rep movsw/d instructions */
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 42186)
@@ -105,5 +105,5 @@
             uint32_t     cbOp;
             PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState;
-            rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, pDis, &cbOp);
+            rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
             if (     RT_SUCCESS(rc)
                 &&   pDis->uCpuMode == DISCPUMODE_32BIT  /** @todo why does this matter? */
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 42186)
@@ -1089,5 +1089,5 @@
      */
     PDISCPUSTATE pDis = &pVCpu->pgm.s.DisState;
-    int rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, pDis, NULL);
+    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
     if (RT_UNLIKELY(rc != VINF_SUCCESS))
     {
Index: /trunk/src/VBox/VMM/VMMAll/SELMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/SELMAll.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMAll/SELMAll.cpp	(revision 42186)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -25,4 +25,5 @@
 #include <VBox/vmm/mm.h>
 #include <VBox/vmm/pgm.h>
+#include <VBox/vmm/hwaccm.h>
 #include "SELMInternal.h"
 #include <VBox/vmm/vm.h>
@@ -36,6 +37,5 @@
 
 
-#ifndef IN_RING0
-
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
 /**
  * Converts a GC selector based address to a flat address.
@@ -67,5 +67,5 @@
     return (RTGCPTR)(((RTGCUINTPTR)Addr + X86DESC_BASE(Desc)) & 0xffffffff);
 }
-#endif /* !IN_RING0 */
+#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
 
 
@@ -84,10 +84,8 @@
 VMMDECL(RTGCPTR) SELMToFlat(PVM pVM, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr)
 {
-    PCPUMSELREGHID pHiddenSel;
-    RTSEL          Sel;
-    int            rc;
+    PCPUMSELREG    pSReg;
     PVMCPU         pVCpu = VMMGetCpu(pVM);
 
-    rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel); AssertRC(rc);
+    int rc = DISFetchRegSegEx(pCtxCore, SelReg, &pSReg); AssertRC(rc);
 
     /*
@@ -99,19 +97,23 @@
         RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff;
         if (CPUMAreHiddenSelRegsValid(pVCpu))
-            uFlat += pHiddenSel->u64Base;
+            uFlat += pSReg->u64Base;
         else
-            uFlat += ((RTGCUINTPTR)Sel << 4);
+            uFlat += ((RTGCUINTPTR)pSReg->Sel << 4);
         return (RTGCPTR)uFlat;
     }
 
-#ifdef IN_RING0
-    Assert(CPUMAreHiddenSelRegsValid(pVCpu));
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
+    /** @todo when we're in 16 bits mode, we should cut off the address as well?? */
+    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
+        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg);
+    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs))
+        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, &pCtxCore->cs);
 #else
-    /** @todo when we're in 16 bits mode, we should cut off the address as well.. */
-    if (!CPUMAreHiddenSelRegsValid(pVCpu))
-        return SELMToFlatBySel(pVM, Sel, Addr);
+    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg));
+    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs));
 #endif
 
-    /* 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). */
+    /* 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). */
     if (    pCtxCore->cs.Attr.n.u1Long
         &&  CPUMIsGuestInLongMode(pVCpu))
@@ -121,5 +123,5 @@
             case DISSELREG_FS:
             case DISSELREG_GS:
-                return (RTGCPTR)(pHiddenSel->u64Base + Addr);
+                return (RTGCPTR)(pSReg->u64Base + Addr);
 
             default:
@@ -129,6 +131,6 @@
 
     /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
-    Assert(pHiddenSel->u64Base <= 0xffffffff);
-    return ((pHiddenSel->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff);
+    Assert(pSReg->u64Base <= 0xffffffff);
+    return ((pSReg->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff);
 }
 
@@ -148,14 +150,12 @@
  * @param   ppvGC       Where to store the GC flat address.
  */
-VMMDECL(int) SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCCPUMCTXCORE pCtxCore, RTGCPTR Addr, unsigned fFlags, PRTGCPTR ppvGC)
+VMMDECL(int) SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr, uint32_t fFlags, PRTGCPTR ppvGC)
 {
     /*
      * Fetch the selector first.
      */
-    PCPUMSELREGHID pHiddenSel;
-    RTSEL          Sel;
-
-    int rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel);
-    AssertRC(rc);
+    PCPUMSELREG pSReg;
+    int rc = DISFetchRegSegEx(pCtxCore, SelReg, &pSReg);
+    AssertRCReturn(rc, rc); AssertPtr(pSReg);
 
     /*
@@ -168,9 +168,8 @@
         if (ppvGC)
         {
-            if (    pHiddenSel
-                &&  CPUMAreHiddenSelRegsValid(pVCpu))
-                *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat);
+            if (CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
+                *ppvGC = pSReg->u64Base + uFlat;
             else
-                *ppvGC = (RTGCPTR)(((RTGCUINTPTR)Sel << 4) + uFlat);
+                *ppvGC = ((RTGCUINTPTR)pSReg->Sel << 4) + uFlat;
         }
         return VINF_SUCCESS;
@@ -178,268 +177,117 @@
 
 
-    uint32_t    u32Limit;
-    RTGCPTR     pvFlat;
-    uint32_t    u1Present, u1DescType, u1Granularity, u4Type;
-
-    /** @todo when we're in 16 bits mode, we should cut off the address as well.. */
-#ifndef IN_RC
-    if (    pHiddenSel
-        &&  CPUMAreHiddenSelRegsValid(pVCpu))
-    {
-        bool fCheckLimit = true;
-
-        u1Present     = pHiddenSel->Attr.n.u1Present;
-        u1Granularity = pHiddenSel->Attr.n.u1Granularity;
-        u1DescType    = pHiddenSel->Attr.n.u1DescType;
-        u4Type        = pHiddenSel->Attr.n.u4Type;
-        u32Limit      = pHiddenSel->u32Limit;
-
-        /* 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). */
-        if (    pCtxCore->cs.Attr.n.u1Long
-            &&  CPUMIsGuestInLongMode(pVCpu))
-        {
-            fCheckLimit = false;
-            switch (SelReg)
-            {
-                case DISSELREG_FS:
-                case DISSELREG_GS:
-                    pvFlat = (pHiddenSel->u64Base + Addr);
-                    break;
-
-                default:
-                    pvFlat = Addr;
-                    break;
-            }
-        }
-        else
-        {
-            /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
-            Assert(pHiddenSel->u64Base <= 0xffffffff);
-            pvFlat = (RTGCPTR)((pHiddenSel->u64Base + (RTGCUINTPTR)Addr) & 0xffffffff);
-        }
-
-        /*
-        * Check if present.
-        */
-        if (u1Present)
-        {
-            /*
-            * Type check.
-            */
-            switch (u4Type)
-            {
-
-                /** Read only selector type. */
-                case X86_SEL_TYPE_RO:
-                case X86_SEL_TYPE_RO_ACC:
-                case X86_SEL_TYPE_RW:
-                case X86_SEL_TYPE_RW_ACC:
-                case X86_SEL_TYPE_EO:
-                case X86_SEL_TYPE_EO_ACC:
-                case X86_SEL_TYPE_ER:
-                case X86_SEL_TYPE_ER_ACC:
-                    if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
-                    {
-                        /** @todo fix this mess */
-                    }
-                    /* check limit. */
-                    if (fCheckLimit && (RTGCUINTPTR)Addr > u32Limit)
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
+    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
+        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSReg);
+    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs))
+        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, &pCtxCore->cs);
+#else
+    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg));
+    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(&pCtxCore->cs));
+#endif
+
+    /* 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). */
+    RTGCPTR  pvFlat;
+    bool     fCheckLimit   = true;
+    if (    pCtxCore->cs.Attr.n.u1Long
+        &&  CPUMIsGuestInLongMode(pVCpu))
+    {
+        fCheckLimit = false;
+        switch (SelReg)
+        {
+            case DISSELREG_FS:
+            case DISSELREG_GS:
+                pvFlat = pSReg->u64Base + Addr;
+                break;
+
+            default:
+                pvFlat = Addr;
+                break;
+        }
+    }
+    else
+    {
+        /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
+        Assert(pSReg->u64Base <= UINT32_C(0xffffffff));
+        pvFlat  = pSReg->u64Base + Addr;
+        pvFlat &= UINT32_C(0xffffffff);
+    }
+
+    /*
+     * Check type if present.
+     */
+    if (pSReg->Attr.n.u1Present)
+    {
+        switch (pSReg->Attr.n.u4Type)
+        {
+            /* Read only selector type. */
+            case X86_SEL_TYPE_RO:
+            case X86_SEL_TYPE_RO_ACC:
+            case X86_SEL_TYPE_RW:
+            case X86_SEL_TYPE_RW_ACC:
+            case X86_SEL_TYPE_EO:
+            case X86_SEL_TYPE_EO_ACC:
+            case X86_SEL_TYPE_ER:
+            case X86_SEL_TYPE_ER_ACC:
+                if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
+                {
+                    /** @todo fix this mess */
+                }
+                /* check limit. */
+                if (fCheckLimit && Addr > pSReg->u32Limit)
+                    return VERR_OUT_OF_SELECTOR_BOUNDS;
+                /* ok */
+                if (ppvGC)
+                    *ppvGC = pvFlat;
+                return VINF_SUCCESS;
+
+            case X86_SEL_TYPE_EO_CONF:
+            case X86_SEL_TYPE_EO_CONF_ACC:
+            case X86_SEL_TYPE_ER_CONF:
+            case X86_SEL_TYPE_ER_CONF_ACC:
+                if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
+                {
+                    /** @todo fix this mess */
+                }
+                /* check limit. */
+                if (fCheckLimit && Addr > pSReg->u32Limit)
+                    return VERR_OUT_OF_SELECTOR_BOUNDS;
+                /* ok */
+                if (ppvGC)
+                    *ppvGC = pvFlat;
+                return VINF_SUCCESS;
+
+            case X86_SEL_TYPE_RO_DOWN:
+            case X86_SEL_TYPE_RO_DOWN_ACC:
+            case X86_SEL_TYPE_RW_DOWN:
+            case X86_SEL_TYPE_RW_DOWN_ACC:
+                if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
+                {
+                    /** @todo fix this mess */
+                }
+                /* check limit. */
+                if (fCheckLimit)
+                {
+                    if (!pSReg->Attr.n.u1Granularity && Addr > UINT32_C(0xffff))
                         return VERR_OUT_OF_SELECTOR_BOUNDS;
-                    /* ok */
-                    if (ppvGC)
-                        *ppvGC = pvFlat;
-                    return VINF_SUCCESS;
-
-                case X86_SEL_TYPE_EO_CONF:
-                case X86_SEL_TYPE_EO_CONF_ACC:
-                case X86_SEL_TYPE_ER_CONF:
-                case X86_SEL_TYPE_ER_CONF_ACC:
-                    if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
-                    {
-                        /** @todo fix this mess */
-                    }
-                    /* check limit. */
-                    if (fCheckLimit && (RTGCUINTPTR)Addr > u32Limit)
+                    if (Addr <= pSReg->u32Limit)
                         return VERR_OUT_OF_SELECTOR_BOUNDS;
-                    /* ok */
-                    if (ppvGC)
-                        *ppvGC = pvFlat;
-                    return VINF_SUCCESS;
-
-                case X86_SEL_TYPE_RO_DOWN:
-                case X86_SEL_TYPE_RO_DOWN_ACC:
-                case X86_SEL_TYPE_RW_DOWN:
-                case X86_SEL_TYPE_RW_DOWN_ACC:
-                    if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
-                    {
-                        /** @todo fix this mess */
-                    }
-                    /* check limit. */
-                    if (fCheckLimit)
-                    {
-                        if (!u1Granularity && (RTGCUINTPTR)Addr > (RTGCUINTPTR)0xffff)
-                            return VERR_OUT_OF_SELECTOR_BOUNDS;
-                        if ((RTGCUINTPTR)Addr <= u32Limit)
-                            return VERR_OUT_OF_SELECTOR_BOUNDS;
-                    }
-                    /* ok */
-                    if (ppvGC)
-                        *ppvGC = pvFlat;
-                    return VINF_SUCCESS;
-
-                default:
-                    return VERR_INVALID_SELECTOR;
-
-            }
-        }
-    }
-# ifndef IN_RING0
-    else
-# endif
-#endif /* !IN_RC */
-#ifndef IN_RING0
-    {
-        X86DESC Desc;
-
-        PVM pVM = pVCpu->CTX_SUFF(pVM);
-        if (!(Sel & X86_SEL_LDT))
-        {
-            if (   !(fFlags & SELMTOFLAT_FLAGS_HYPER)
-                && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
+                }
+                /* ok */
+                if (ppvGC)
+                    *ppvGC = pvFlat;
+                return VINF_SUCCESS;
+
+            default:
                 return VERR_INVALID_SELECTOR;
-            Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
-        }
-        else
-        {
-            if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit)
-                return VERR_INVALID_SELECTOR;
-
-            /** @todo handle LDT page(s) not present! */
-            PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
-            Desc = paLDT[Sel >> X86_SEL_SHIFT];
-        }
-
-        /* calc limit. */
-        u32Limit = X86DESC_LIMIT(Desc);
-        if (Desc.Gen.u1Granularity)
-            u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
-
-        /* calc address assuming straight stuff. */
-        pvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc));
-
-        /* Cut the address to 32 bits. */
-        Assert(!CPUMIsGuestInLongMode(pVCpu));
-        pvFlat &= 0xffffffff;
-
-        u1Present     = Desc.Gen.u1Present;
-        u1Granularity = Desc.Gen.u1Granularity;
-        u1DescType    = Desc.Gen.u1DescType;
-        u4Type        = Desc.Gen.u4Type;
-
-        /*
-        * Check if present.
-        */
-        if (u1Present)
-        {
-            /*
-            * Type check.
-            */
-# define BOTH(a, b) ((a << 16) | b)
-            switch (BOTH(u1DescType, u4Type))
-            {
-
-                /** Read only selector type. */
-                case BOTH(1,X86_SEL_TYPE_RO):
-                case BOTH(1,X86_SEL_TYPE_RO_ACC):
-                case BOTH(1,X86_SEL_TYPE_RW):
-                case BOTH(1,X86_SEL_TYPE_RW_ACC):
-                case BOTH(1,X86_SEL_TYPE_EO):
-                case BOTH(1,X86_SEL_TYPE_EO_ACC):
-                case BOTH(1,X86_SEL_TYPE_ER):
-                case BOTH(1,X86_SEL_TYPE_ER_ACC):
-                    if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
-                    {
-                        /** @todo fix this mess */
-                    }
-                    /* check limit. */
-                    if ((RTGCUINTPTR)Addr > u32Limit)
-                        return VERR_OUT_OF_SELECTOR_BOUNDS;
-                    /* ok */
-                    if (ppvGC)
-                        *ppvGC = pvFlat;
-                    return VINF_SUCCESS;
-
-                case BOTH(1,X86_SEL_TYPE_EO_CONF):
-                case BOTH(1,X86_SEL_TYPE_EO_CONF_ACC):
-                case BOTH(1,X86_SEL_TYPE_ER_CONF):
-                case BOTH(1,X86_SEL_TYPE_ER_CONF_ACC):
-                    if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
-                    {
-                        /** @todo fix this mess */
-                    }
-                    /* check limit. */
-                    if ((RTGCUINTPTR)Addr > u32Limit)
-                        return VERR_OUT_OF_SELECTOR_BOUNDS;
-                    /* ok */
-                    if (ppvGC)
-                        *ppvGC = pvFlat;
-                    return VINF_SUCCESS;
-
-                case BOTH(1,X86_SEL_TYPE_RO_DOWN):
-                case BOTH(1,X86_SEL_TYPE_RO_DOWN_ACC):
-                case BOTH(1,X86_SEL_TYPE_RW_DOWN):
-                case BOTH(1,X86_SEL_TYPE_RW_DOWN_ACC):
-                    if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
-                    {
-                        /** @todo fix this mess */
-                    }
-                    /* check limit. */
-                    if (!u1Granularity && (RTGCUINTPTR)Addr > (RTGCUINTPTR)0xffff)
-                        return VERR_OUT_OF_SELECTOR_BOUNDS;
-                    if ((RTGCUINTPTR)Addr <= u32Limit)
-                        return VERR_OUT_OF_SELECTOR_BOUNDS;
-
-                    /* ok */
-                    if (ppvGC)
-                        *ppvGC = pvFlat;
-                    return VINF_SUCCESS;
-
-                case BOTH(0,X86_SEL_TYPE_SYS_286_TSS_AVAIL):
-                case BOTH(0,X86_SEL_TYPE_SYS_LDT):
-                case BOTH(0,X86_SEL_TYPE_SYS_286_TSS_BUSY):
-                case BOTH(0,X86_SEL_TYPE_SYS_286_CALL_GATE):
-                case BOTH(0,X86_SEL_TYPE_SYS_TASK_GATE):
-                case BOTH(0,X86_SEL_TYPE_SYS_286_INT_GATE):
-                case BOTH(0,X86_SEL_TYPE_SYS_286_TRAP_GATE):
-                case BOTH(0,X86_SEL_TYPE_SYS_386_TSS_AVAIL):
-                case BOTH(0,X86_SEL_TYPE_SYS_386_TSS_BUSY):
-                case BOTH(0,X86_SEL_TYPE_SYS_386_CALL_GATE):
-                case BOTH(0,X86_SEL_TYPE_SYS_386_INT_GATE):
-                case BOTH(0,X86_SEL_TYPE_SYS_386_TRAP_GATE):
-                    if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL))
-                    {
-                        /** @todo fix this mess */
-                    }
-                    /* check limit. */
-                    if ((RTGCUINTPTR)Addr > u32Limit)
-                        return VERR_OUT_OF_SELECTOR_BOUNDS;
-                    /* ok */
-                    if (ppvGC)
-                        *ppvGC = pvFlat;
-                    return VINF_SUCCESS;
-
-                default:
-                    return VERR_INVALID_SELECTOR;
-
-            }
-# undef BOTH
-        }
-    }
-#endif /* !IN_RING0 */
+
+        }
+    }
     return VERR_SELECTOR_NOT_PRESENT;
 }
 
 
-#ifndef IN_RING0
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
 /**
  * Converts a GC selector based address to a flat address.
@@ -452,5 +300,4 @@
  * @param   Sel         Selector part.
  * @param   Addr        Address part.
- * @param   pHiddenSel  Hidden selector register (can be NULL)
  * @param   fFlags      SELMTOFLAT_FLAGS_*
  *                      GDT entires are valid.
@@ -460,7 +307,8 @@
  * @remarks Don't use when in long mode.
  */
-VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, PCCPUMSELREGHID pHiddenSel, uint32_t fFlags, PRTGCPTR ppvGC, uint32_t *pcb)
-{
-    Assert(!CPUMIsGuestInLongMode(pVCpu));    /* DON'T USE! */
+VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr,
+                               uint32_t fFlags, PRTGCPTR ppvGC, uint32_t *pcb)
+{
+    Assert(!CPUMIsGuestInLongMode(pVCpu));    /* DON'T USE! (Accessing shadow GDT/LDT.) */
 
     /*
@@ -472,11 +320,5 @@
         RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff;
         if (ppvGC)
-        {
-            if (    pHiddenSel
-                &&  CPUMAreHiddenSelRegsValid(pVCpu))
-                *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat);
-            else
-                *ppvGC = (RTGCPTR)(((RTGCUINTPTR)Sel << 4) + uFlat);
-        }
+            *ppvGC = ((RTGCUINTPTR)Sel << 4) + uFlat;
         if (pcb)
             *pcb = 0x10000 - uFlat;
@@ -484,67 +326,40 @@
     }
 
-
-    uint32_t    u32Limit;
-    RTGCPTR     pvFlat;
-    uint32_t    u1Present, u1DescType, u1Granularity, u4Type;
-
-    /** @todo when we're in 16 bits mode, we should cut off the address as well.. */
-    if (    pHiddenSel
-        &&  CPUMAreHiddenSelRegsValid(pVCpu))
-    {
-        u1Present     = pHiddenSel->Attr.n.u1Present;
-        u1Granularity = pHiddenSel->Attr.n.u1Granularity;
-        u1DescType    = pHiddenSel->Attr.n.u1DescType;
-        u4Type        = pHiddenSel->Attr.n.u4Type;
-
-        u32Limit      = pHiddenSel->u32Limit;
-        pvFlat        = (RTGCPTR)(pHiddenSel->u64Base + (RTGCUINTPTR)Addr);
-
-        if (   !pHiddenSel->Attr.n.u1Long
-            || !CPUMIsGuestInLongMode(pVCpu))
-        {
-            /* AMD64 manual: compatibility mode ignores the high 32 bits when calculating an effective address. */
-            pvFlat &= 0xffffffff;
-        }
+    /** @todo when we're in 16 bits mode, we should cut off the address as well?? */
+    X86DESC Desc;
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+    if (!(Sel & X86_SEL_LDT))
+    {
+        if (   !(fFlags & SELMTOFLAT_FLAGS_HYPER)
+            && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
+            return VERR_INVALID_SELECTOR;
+        Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
     }
     else
     {
-        X86DESC Desc;
-
-        PVM pVM = pVCpu->CTX_SUFF(pVM);
-        if (!(Sel & X86_SEL_LDT))
-        {
-            if (   !(fFlags & SELMTOFLAT_FLAGS_HYPER)
-                && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt)
-                return VERR_INVALID_SELECTOR;
-            Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
-        }
-        else
-        {
-            if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit)
-                return VERR_INVALID_SELECTOR;
-
-            /** @todo handle LDT page(s) not present! */
-            PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
-            Desc = paLDT[Sel >> X86_SEL_SHIFT];
-        }
-
-        /* calc limit. */
-        u32Limit = X86DESC_LIMIT(Desc);
-        if (Desc.Gen.u1Granularity)
-            u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
-
-        /* calc address assuming straight stuff. */
-        pvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc));
-
-        /* Cut the address to 32 bits. */
-        Assert(!CPUMIsGuestInLongMode(pVCpu));
-        pvFlat &= 0xffffffff;
-
-        u1Present     = Desc.Gen.u1Present;
-        u1Granularity = Desc.Gen.u1Granularity;
-        u1DescType    = Desc.Gen.u1DescType;
-        u4Type        = Desc.Gen.u4Type;
-    }
+        if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit)
+            return VERR_INVALID_SELECTOR;
+
+        /** @todo handle LDT page(s) not present! */
+        PX86DESC    paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
+        Desc = paLDT[Sel >> X86_SEL_SHIFT];
+    }
+
+    /* calc limit. */
+    uint32_t u32Limit = X86DESC_LIMIT(Desc);
+    if (Desc.Gen.u1Granularity)
+        u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK;
+
+    /* calc address assuming straight stuff. */
+    RTGCPTR pvFlat = Addr + X86DESC_BASE(Desc);
+
+    /* Cut the address to 32 bits. */
+    Assert(!CPUMIsGuestInLongMode(pVCpu));
+    pvFlat &= 0xffffffff;
+
+    uint8_t u1Present     = Desc.Gen.u1Present;
+    uint8_t u1Granularity = Desc.Gen.u1Granularity;
+    uint8_t u1DescType    = Desc.Gen.u1DescType;
+    uint8_t u4Type        = Desc.Gen.u4Type;
 
     /*
@@ -656,8 +471,8 @@
     return VERR_SELECTOR_NOT_PRESENT;
 }
-#endif /* !IN_RING0 */
-
-
-#ifdef VBOX_WITH_RAW_MODE
+#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
+
+
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
 /**
  * CPUM helper that loads the hidden selector register from the descriptor table
@@ -687,4 +502,5 @@
     RTSEL const Sel = pSReg->Sel;
 
+/** @todo Consider loading these from the shadow tables when possible? */
     /*
      * Calculate descriptor table entry address.
@@ -763,34 +579,35 @@
  * @param   ppvFlat Where to store the flat address.
  */
-DECLINLINE(int) selmValidateAndConvertCSAddrRealMode(PVMCPU pVCpu, RTSEL SelCS, PCCPUMSELREGHID pHidCS, RTGCPTR Addr,
+DECLINLINE(int) selmValidateAndConvertCSAddrRealMode(PVMCPU pVCpu, RTSEL SelCS, PCCPUMSELREGHID pSReg, RTGCPTR Addr,
                                                      PRTGCPTR ppvFlat)
 {
-    RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff;
-    if (!pHidCS || !CPUMAreHiddenSelRegsValid(pVCpu))
-        uFlat += ((RTGCUINTPTR)SelCS << 4);
+    RTGCUINTPTR uFlat = Addr & 0xffff;
+    if (!pSReg || !CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSReg))
+        uFlat += (RTGCUINTPTR)SelCS << 4;
     else
-        uFlat += pHidCS->u64Base;
-    *ppvFlat = (RTGCPTR)uFlat;
+        uFlat += pSReg->u64Base;
+    *ppvFlat = uFlat;
     return VINF_SUCCESS;
 }
 
 
-#ifndef IN_RING0
-/**
- * Validates and converts a GC selector based code address to a flat
- * address when in protected/long mode using the standard algorithm.
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
+/**
+ * Validates and converts a GC selector based code address to a flat address
+ * when in protected/long mode using the raw-mode algorithm.
  *
  * @returns VBox status code.
- * @param   pVM     Pointer to the VM.
- * @param   pVCpu   Pointer to the VMCPU.
- * @param   SelCPL  Current privilege level. Get this from SS - CS might be conforming!
- *                  A full selector can be passed, we'll only use the RPL part.
- * @param   SelCS   Selector part.
- * @param   Addr    Address part.
- * @param   ppvFlat Where to store the flat address.
- * @param   pcBits  Where to store the segment bitness (16/32/64). Optional.
- */
-DECLINLINE(int) selmValidateAndConvertCSAddrStd(PVM pVM, PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr,
-                                                PRTGCPTR ppvFlat, uint32_t *pcBits)
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   SelCPL      Current privilege level. Get this from SS - CS might be
+ *                      conforming! A full selector can be passed, we'll only
+ *                      use the RPL part.
+ * @param   SelCS       Selector part.
+ * @param   Addr        Address part.
+ * @param   ppvFlat     Where to store the flat address.
+ * @param   pcBits      Where to store the segment bitness (16/32/64). Optional.
+ */
+DECLINLINE(int) selmValidateAndConvertCSAddrRawMode(PVM pVM, PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr,
+                                                    PRTGCPTR ppvFlat, uint32_t *pcBits)
 {
     NOREF(pVCpu);
@@ -850,20 +667,22 @@
     return VERR_SELECTOR_NOT_PRESENT;
 }
-#endif /* !IN_RING0 */
-
-
-/**
- * Validates and converts a GC selector based code address to a flat
- * address when in protected/long mode using the standard algorithm.
+#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
+
+
+/**
+ * Validates and converts a GC selector based code address to a flat address
+ * when in protected/long mode using the standard hidden selector registers
  *
  * @returns VBox status code.
- * @param   pVCpu   Pointer to the VMCPU.
- * @param   SelCPL  Current privilege level. Get this from SS - CS might be conforming!
- *                  A full selector can be passed, we'll only use the RPL part.
- * @param   SelCS   Selector part.
- * @param   Addr    Address part.
- * @param   ppvFlat Where to store the flat address.
- */
-DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pHidCS,
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   SelCPL      Current privilege level.  Get this from SS - CS might be
+ *                      conforming!  A full selector can be passed, we'll only
+ *                      use the RPL part.
+ * @param   SelCS       Selector part.
+ * @param   pSRegCS     The full CS selector register.
+ * @param   Addr        The address (think IP/EIP/RIP).
+ * @param   ppvFlat     Where to store the flat address upon successful return.
+ */
+DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pSRegCS,
                                                    RTGCPTR Addr, PRTGCPTR ppvFlat)
 {
@@ -871,11 +690,11 @@
      * Check if present.
      */
-    if (pHidCS->Attr.n.u1Present)
+    if (pSRegCS->Attr.n.u1Present)
     {
         /*
          * Type check.
          */
-        if (     pHidCS->Attr.n.u1DescType == 1
-            &&  (pHidCS->Attr.n.u4Type & X86_SEL_TYPE_CODE))
+        if (     pSRegCS->Attr.n.u1DescType == 1
+            &&  (pSRegCS->Attr.n.u4Type & X86_SEL_TYPE_CODE))
         {
             /*
@@ -883,11 +702,12 @@
              */
             unsigned uLevel = RT_MAX(SelCPL & X86_SEL_RPL, SelCS & X86_SEL_RPL);
-            if (    !(pHidCS->Attr.n.u4Type & X86_SEL_TYPE_CONF)
-                ?   uLevel <= pHidCS->Attr.n.u2Dpl
-                :   uLevel >= pHidCS->Attr.n.u2Dpl /* hope I got this right now... */
-                    )
+            if (    !(pSRegCS->Attr.n.u4Type & X86_SEL_TYPE_CONF)
+                ?   uLevel <= pSRegCS->Attr.n.u2Dpl
+                :   uLevel >= pSRegCS->Attr.n.u2Dpl /* hope I got this right now... */
+               )
             {
-                /* 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). */
-                if (    pHidCS->Attr.n.u1Long
+                /* 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). */
+                if (    pSRegCS->Attr.n.u1Long
                     &&  CPUMIsGuestInLongMode(pVCpu))
                 {
@@ -900,13 +720,15 @@
                  * final value. The granularity bit was included in its calculation.
                  */
-                uint32_t u32Limit = pHidCS->u32Limit;
+                uint32_t u32Limit = pSRegCS->u32Limit;
                 if ((RTGCUINTPTR)Addr <= u32Limit)
                 {
-                    *ppvFlat = (RTGCPTR)(  (RTGCUINTPTR)Addr + pHidCS->u64Base );
+                    *ppvFlat = Addr + pSRegCS->u64Base;
                     return VINF_SUCCESS;
                 }
+
                 return VERR_OUT_OF_SELECTOR_BOUNDS;
             }
-            Log(("Invalid RPL Attr.n.u4Type=%x cpl=%x dpl=%x\n", pHidCS->Attr.n.u4Type, uLevel, pHidCS->Attr.n.u2Dpl));
+            Log(("selmValidateAndConvertCSAddrHidden: Invalid RPL Attr.n.u4Type=%x cpl=%x dpl=%x\n",
+                 pSRegCS->Attr.n.u4Type, uLevel, pSRegCS->Attr.n.u2Dpl));
             return VERR_INVALID_RPL;
         }
@@ -917,129 +739,45 @@
 
 
-#ifdef IN_RC
 /**
  * Validates and converts a GC selector based code address to a flat address.
- *
- * This is like SELMValidateAndConvertCSAddr + SELMIsSelector32Bit but with
- * invalid hidden CS data. It's customized for dealing efficiently with CS
- * at GC trap time.
  *
  * @returns VBox status code.
  * @param   pVCpu       Pointer to the VMCPU.
- * @param   eflags      Current eflags
- * @param   SelCPL      Current privilege level. Get this from SS - CS might be
- *                      conforming! A full selector can be passed, we'll only
+ * @param   Efl         Current EFLAGS.
+ * @param   SelCPL      Current privilege level.  Get this from SS - CS might be
+ *                      conforming!  A full selector can be passed, we'll only
  *                      use the RPL part.
  * @param   SelCS       Selector part.
- * @param   Addr        Address part.
- * @param   ppvFlat     Where to store the flat address.
- * @param   pcBits      Where to store the 64-bit/32-bit/16-bit indicator.
- */
-VMMDECL(int) SELMValidateAndConvertCSAddrGCTrap(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr, PRTGCPTR ppvFlat, uint32_t *pcBits)
-{
-    if (    eflags.Bits.u1VM
+ * @param   pSRegCS     The full CS selector register.
+ * @param   Addr        The address (think IP/EIP/RIP).
+ * @param   ppvFlat     Where to store the flat address upon successful return.
+ */
+VMMDECL(int) SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS Efl, RTSEL SelCPL, RTSEL SelCS, PCPUMSELREG pSRegCS,
+                                          RTGCPTR Addr, PRTGCPTR ppvFlat)
+{
+    if (    Efl.Bits.u1VM
         ||  CPUMIsGuestInRealMode(pVCpu))
-    {
-        *pcBits = 16;
-        return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, NULL, Addr, ppvFlat);
-    }
-    Assert(!CPUMAreHiddenSelRegsValid(pVCpu));
-    return selmValidateAndConvertCSAddrStd(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, pcBits);
-}
-#endif /* IN_RC */
-
-
-/**
- * Validates and converts a GC selector based code address to a flat address.
- *
- * @returns VBox status code.
- * @param   pVCpu        Pointer to the VMCPU.
- * @param   eflags       Current eflags
- * @param   SelCPL       Current privilege level. Get this from SS - CS might be conforming!
- *                       A full selector can be passed, we'll only use the RPL part.
- * @param   SelCS        Selector part.
- * @param   pHiddenSel   The hidden CS selector register.
- * @param   Addr         Address part.
- * @param   ppvFlat      Where to store the flat address.
- */
-VMMDECL(int) SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pHiddenCSSel,
-                                          RTGCPTR Addr, PRTGCPTR ppvFlat)
-{
-    if (    eflags.Bits.u1VM
-        ||  CPUMIsGuestInRealMode(pVCpu))
-        return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, pHiddenCSSel, Addr, ppvFlat);
-
-#ifdef IN_RING0
-    Assert(CPUMAreHiddenSelRegsValid(pVCpu));
+        return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, pSRegCS, Addr, ppvFlat);
+
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
+    /* Use the hidden registers when possible, updating them if outdate. */
+    if (!pSRegCS)
+        return selmValidateAndConvertCSAddrRawMode(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, NULL);
+
+    if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSRegCS))
+        CPUMGuestLazyLoadHiddenSelectorReg(pVCpu, pSRegCS);
+
+    /* Undo ring compression. */
+    if ((SelCPL & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+        SelCPL &= ~X86_SEL_RPL;
+    Assert(pSRegCS->Sel == SelCS);
+    if ((SelCS  & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+        SelCS  &= ~X86_SEL_RPL;
 #else
-    /** @todo when we're in 16 bits mode, we should cut off the address as well? (like in selmValidateAndConvertCSAddrRealMode) */
-    if (!CPUMAreHiddenSelRegsValid(pVCpu) || !pHiddenCSSel)
-        return selmValidateAndConvertCSAddrStd(pVCpu->CTX_SUFF(pVM), pVCpu, SelCPL, SelCS, Addr, ppvFlat, NULL);
+    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pSRegCS));
+    Assert(pSRegCS->Sel == SelCS);
 #endif
-    return selmValidateAndConvertCSAddrHidden(pVCpu, SelCPL, SelCS, pHiddenCSSel, Addr, ppvFlat);
-}
-
-
-#ifndef IN_RING0
-/**
- * Return the cpu mode corresponding to the (CS) selector
- *
- * @returns DISCPUMODE according to the selector type (16, 32 or 64 bits)
- * @param   pVM     Pointer to the VM.
- * @param   pVCpu   Pointer to the VMCPU.
- * @param   Sel     The selector.
- */
-static DISCPUMODE selmGetCpuModeFromSelector(PVM pVM, PVMCPU pVCpu, RTSEL Sel)
-{
-    Assert(!CPUMAreHiddenSelRegsValid(pVCpu));
-
-    /** @todo validate limit! */
-    X86DESC Desc;
-    if (!(Sel & X86_SEL_LDT))
-        Desc = pVM->selm.s.CTX_SUFF(paGdt)[Sel >> X86_SEL_SHIFT];
-    else
-    {
-        /** @todo handle LDT page(s) not present! */
-        PX86DESC   paLDT = (PX86DESC)((char *)pVM->selm.s.CTX_SUFF(pvLdt) + pVM->selm.s.offLdtHyper);
-        Desc = paLDT[Sel >> X86_SEL_SHIFT];
-    }
-    return (Desc.Gen.u1DefBig) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT;
-}
-#endif /* !IN_RING0 */
-
-
-/**
- * Return the cpu mode corresponding to the (CS) selector
- *
- * @returns DISCPUMODE according to the selector type (16, 32 or 64 bits)
- * @param   pVCpu      Pointer to the VMCPU.
- * @param   eflags     Current eflags register
- * @param   Sel        The selector.
- * @param   pHiddenSel The hidden selector register.
- */
-VMMDECL(DISCPUMODE) SELMGetCpuModeFromSelector(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, PCCPUMSELREGHID pHiddenSel)
-{
-#ifdef IN_RING0
-    Assert(CPUMAreHiddenSelRegsValid(pVCpu));
-    NOREF(eflags); NOREF(Sel);
-#else  /* !IN_RING0 */
-    if (!CPUMAreHiddenSelRegsValid(pVCpu))
-    {
-        /*
-         * Deal with real & v86 mode first.
-         */
-        if (    eflags.Bits.u1VM
-            ||  CPUMIsGuestInRealMode(pVCpu))
-            return DISCPUMODE_16BIT;
-
-        return selmGetCpuModeFromSelector(pVCpu->CTX_SUFF(pVM), pVCpu, Sel);
-    }
-#endif /* !IN_RING0 */
-    if (    pHiddenSel->Attr.n.u1Long
-        &&  CPUMIsGuestInLongMode(pVCpu))
-        return DISCPUMODE_64BIT;
-
-    /* Else compatibility or 32 bits mode. */
-    return pHiddenSel->Attr.n.u1DefBig ? DISCPUMODE_32BIT : DISCPUMODE_16BIT;
+
+    return selmValidateAndConvertCSAddrHidden(pVCpu, SelCPL, SelCS, pSRegCS, Addr, ppvFlat);
 }
 
@@ -1084,5 +822,5 @@
 
 
-#ifndef IN_RING0
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
 /**
  * Gets ss:esp for ring1 in main Hypervisor's TSS.
@@ -1165,5 +903,5 @@
     return VINF_SUCCESS;
 }
-#endif /* !IN_RING0 */
+#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
 
 
@@ -1179,6 +917,5 @@
 }
 
-
-#ifndef IN_RING0
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
 
 /**
@@ -1254,5 +991,5 @@
 }
 
-#endif /* !IN_RING0 */
+#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
 
 /**
@@ -1305,2 +1042,3 @@
     pVM->selm.s.TssTrap08.cr3 = PGMGetInterRCCR3(pVM, pVCpu);
 }
+
Index: /trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp	(revision 42186)
@@ -341,5 +341,5 @@
 
 
-#ifndef IN_RING0
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
 /**
  * Forward trap or interrupt to the guest's handler
@@ -554,5 +554,5 @@
                         || !ss_r0
                         || (ss_r0 & X86_SEL_RPL) != ((dpl == 0) ? 1 : dpl)
-                        || SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL, SELMTOFLAT_FLAGS_CPL1,
+                        || SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, SELMTOFLAT_FLAGS_CPL1,
                                              (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS
                        )
@@ -569,5 +569,5 @@
 
                     if (    eflags.Bits.u1VM    /* illegal */
-                        ||  SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL, SELMTOFLAT_FLAGS_CPL1,
+                        ||  SELMToFlatBySelEx(pVCpu, fakeflags, ss_r0, (RTGCPTR)esp_r0, SELMTOFLAT_FLAGS_CPL1,
                                               (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS)
                     {
@@ -743,5 +743,5 @@
     return VINF_EM_RAW_GUEST_TRAP;
 }
-#endif /* !IN_RING0 */
+#endif /* VBOX_WITH_RAW_MODE_NOT_R0 */
 
 
Index: /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 42186)
@@ -2428,5 +2428,5 @@
 
             /* Disassemble manually to deal with segment prefixes. */
-            rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, NULL);
+            rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
             if (rc == VINF_SUCCESS)
             {
@@ -2990,9 +2990,8 @@
      * Only allow 32 & 64 bit code.
      */
-    DISCPUMODE enmMode = SELMGetCpuModeFromSelector(pVCpu, pRegFrame->eflags, pRegFrame->cs.Sel, &pRegFrame->cs);
-    if (enmMode != DISCPUMODE_16BIT)
+    if (CPUMGetGuestCodeBits(pVCpu) != 16)
     {
         PDISSTATE pDis = &pVCpu->hwaccm.s.DisState;
-        int rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, pDis, NULL);
+        int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
         if (RT_SUCCESS(rc) && pDis->pCurInstr->uOpcode == OP_INVLPG)
         {
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 42186)
@@ -3657,5 +3657,5 @@
                 LogFlow(("Real mode X86_XCPT_GP instruction emulation at %x:%RGv\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
 
-                rc2 = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
+                rc2 = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
                 if (RT_SUCCESS(rc2))
                 {
@@ -4442,5 +4442,5 @@
             /** @todo VMX_VMCS_EXIT_GUEST_LINEAR_ADDR contains the flat pointer operand of the instruction. */
             /** @todo VMX_VMCS32_RO_EXIT_INSTR_INFO also contains segment prefix info. */
-            rc2 = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, NULL);
+            rc2 = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
             if (RT_SUCCESS(rc))
             {
Index: /trunk/src/VBox/VMM/VMMR3/CSAM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CSAM.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMR3/CSAM.cpp	(revision 42186)
@@ -2295,5 +2295,5 @@
     {
         /* Assuming 32 bits code for now. */
-        Assert(SELMGetCpuModeFromSelector(VMMGetCpu0(pVM), pCtxCore->eflags, pCtxCore->cs.Sel, &pCtxCore->cs) == DISCPUMODE_32BIT);
+        Assert(CPUMGetGuestCodeBits(VMMGetCpu0(pVM)) == 32);
 
         pInstrGC = SELMToFlat(pVM, DISSELREG_CS, pCtxCore, pInstrGC);
Index: /trunk/src/VBox/VMM/VMMR3/EMRaw.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/EMRaw.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMR3/EMRaw.cpp	(revision 42186)
@@ -685,6 +685,5 @@
             {
                 rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
-                                           SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs)
-                                        == DISCPUMODE_32BIT ? PATMFL_CODE32 : 0);
+                                        CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0);
                 if (RT_SUCCESS(rc))
                 {
@@ -936,6 +935,5 @@
         {
             int rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
-                                        (   SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs)
-                                         == DISCPUMODE_32BIT) ? PATMFL_CODE32 : 0);
+                                        CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0);
             if (RT_SUCCESS(rc))
             {
@@ -1044,5 +1042,5 @@
         if (    (pCtx->ss.Sel & X86_SEL_RPL) == 0
             &&  !pCtx->eflags.Bits.u1VM
-            &&  SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs) == DISCPUMODE_32BIT)
+            &&  CPUMGetGuestCodeBits(pVCpu) == 32)
         {
             STAM_PROFILE_START(&pVCpu->em.s.StatPrivEmu, a);
Index: /trunk/src/VBox/VMM/VMMR3/HWACCM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/HWACCM.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMR3/HWACCM.cpp	(revision 42186)
@@ -1868,5 +1868,5 @@
     PDISCPUSTATE    pDis = &pVCpu->hwaccm.s.DisState;
     uint32_t        cbOp;
-    int rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
+    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
     AssertRC(rc);
     if (    rc == VINF_SUCCESS
@@ -1920,5 +1920,5 @@
 
             pCtx->rip += cbOp;
-            rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
+            rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
             DBGFR3DisasInstrCurrentLog(pVCpu, "Following read");
             pCtx->rip = uSavedRip;
@@ -2041,5 +2041,5 @@
     PDISCPUSTATE    pDis   = &pVCpu->hwaccm.s.DisState;
     uint32_t        cbOp;
-    int rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
+    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
     AssertRC(rc);
     if (    rc == VINF_SUCCESS
Index: /trunk/src/VBox/VMM/VMMRC/PATMRC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/PATMRC.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMRC/PATMRC.cpp	(revision 42186)
@@ -507,5 +507,6 @@
             }
 
-            DISCPUMODE enmCpuMode = SELMGetCpuModeFromSelector(VMMGetCpu0(pVM), pRegFrame->eflags, pRegFrame->cs.Sel, 0);
+            PVMCPU     pVCpu      = VMMGetCpu0(pVM);
+            DISCPUMODE enmCpuMode = CPUMGetGuestDisMode(pVCpu);
             if (enmCpuMode != DISCPUMODE_32BIT)
             {
@@ -516,5 +517,5 @@
 #ifdef VBOX_WITH_IEM
             VBOXSTRICTRC rcStrict;
-            rcStrict = IEMExecOneWithPrefetchedByPC(VMMGetCpu0(pVM), pRegFrame, pRegFrame->rip,
+            rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, pRegFrame, pRegFrame->rip,
                                                     pRec->patch.aPrivInstr, pRec->patch.cbPrivInstr);
             rc = VBOXSTRICTRC_TODO(rcStrict);
@@ -531,5 +532,5 @@
             }
 
-            rc = EMInterpretInstructionDisasState(VMMGetCpu0(pVM), &cpu, pRegFrame, 0 /* not relevant here */,
+            rc = EMInterpretInstructionDisasState(pVCpu, &cpu, pRegFrame, 0 /* not relevant here */,
                                                   EMCODETYPE_SUPERVISOR);
 #endif
Index: /trunk/src/VBox/VMM/VMMRC/TRPMRC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/TRPMRC.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMRC/TRPMRC.cpp	(revision 42186)
@@ -179,5 +179,5 @@
      */
     DISSTATE Dis;
-    int rc = EMInterpretDisasOne(pVM, pVCpu, pRegFrame, &Dis, NULL);
+    int rc = EMInterpretDisasCurrent(pVM, pVCpu, &Dis, NULL);
     if (rc == VINF_SUCCESS)
     {
Index: /trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp	(revision 42185)
+++ /trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp	(revision 42186)
@@ -953,7 +953,6 @@
     STAM_PROFILE_START(&pVM->trpm.s.StatTrap0dDisasm, a);
     RTGCPTR PC;
-    uint32_t cBits;
-    int rc = SELMValidateAndConvertCSAddrGCTrap(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel,
-                                                pRegFrame->rip, &PC, &cBits);
+    int rc = SELMValidateAndConvertCSAddr(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel, &pRegFrame->cs,
+                                          pRegFrame->rip, &PC);
     if (RT_FAILURE(rc))
     {
Index: /trunk/src/VBox/VMM/include/EMHandleRCTmpl.h
===================================================================
--- /trunk/src/VBox/VMM/include/EMHandleRCTmpl.h	(revision 42185)
+++ /trunk/src/VBox/VMM/include/EMHandleRCTmpl.h	(revision 42186)
@@ -113,6 +113,5 @@
             rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
                                       PATMFL_MMIO_ACCESS
-                                    | (    SELMGetCpuModeFromSelector(pVCpu, pCtx->eflags, pCtx->cs.Sel, &pCtx->cs)
-                                        == DISCPUMODE_32BIT ? PATMFL_CODE32 : 0));
+                                    | (CPUMGetGuestCodeBits(pVCpu) == 32 ? PATMFL_CODE32 : 0));
             if (RT_FAILURE(rc))
                 rc = emR3ExecuteInstruction(pVM, pVCpu, "MMIO");
