Index: /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 42482)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 42483)
@@ -836,5 +836,6 @@
     if (cbToTryRead > sizeof(pIemCpu->abOpcode))
         cbToTryRead = sizeof(pIemCpu->abOpcode);
-    /** @todo patch manager */
+    /** @todo PATM: Read original, unpatched bytes? EMAll.cpp doesn't seem to be
+     *        doing that. */
     if (!pIemCpu->fByPassHandlers)
         rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhys, pIemCpu->abOpcode, cbToTryRead);
@@ -3215,5 +3216,5 @@
  * @param   pCtx                Where to get the current stack mode.
  */
-DECLINLINE(void) iemRegAddToRspEx(PRTUINT64U pTmpRsp, uint8_t cbToAdd, PCCPUMCTX pCtx)
+DECLINLINE(void) iemRegAddToRspEx(PRTUINT64U pTmpRsp, uint16_t cbToAdd, PCCPUMCTX pCtx)
 {
     if (pCtx->ss.Attr.n.u1Long)
@@ -3232,6 +3233,8 @@
  * @param   cbToSub             The number of bytes to subtract.
  * @param   pCtx                Where to get the current stack mode.
- */
-DECLINLINE(void) iemRegSubFromRspEx(PRTUINT64U pTmpRsp, uint8_t cbToSub, PCCPUMCTX pCtx)
+ * @remarks The @a cbToSub argument *MUST* be 16-bit, iemCImpl_enter is
+ *          expecting that.
+ */
+DECLINLINE(void) iemRegSubFromRspEx(PRTUINT64U pTmpRsp, uint16_t cbToSub, PCCPUMCTX pCtx)
 {
     if (pCtx->ss.Attr.n.u1Long)
@@ -4675,5 +4678,5 @@
         rc = VINF_SUCCESS;
 
-#ifdef IEM_VERIFICATION_MODE
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     /*
      * Record the write(s).
@@ -4786,5 +4789,5 @@
         }
 
-#ifdef IEM_VERIFICATION_MODE
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
         if (   !pIemCpu->fNoRem
             && (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC)) )
@@ -4883,5 +4886,5 @@
         }
 
-#ifdef IEM_VERIFICATION_MODE
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
         if (   !pIemCpu->fNoRem
             && (fAccess & (IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_EXEC)) )
@@ -5590,5 +5593,4 @@
 
 
-#ifdef SOME_UNUSED_FUNCTION
 /**
  * Pushes a dword onto the stack, using a temporary stack pointer.
@@ -5621,5 +5623,4 @@
     return rc;
 }
-#endif
 
 
@@ -7160,5 +7161,5 @@
 #endif
 #if 1 /* Auto enable DSL - fstp st0 stuff. */
-        &&  pOrgCtx->cs  == 0x23
+        &&  pOrgCtx->cs.Sel  == 0x23
         &&  pOrgCtx->rip == 0x804aff7
 #endif
@@ -7449,5 +7450,5 @@
 
     char szInstr1[256];
-    DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, pCtx->cs, pCtx->rip - pIemCpu->offOpcode,
+    DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, pCtx->cs.Sel, pCtx->rip - pIemCpu->offOpcode,
                        DBGF_DISAS_FLAGS_DEFAULT_MODE,
                        szInstr1, sizeof(szInstr1), NULL);
@@ -7645,13 +7646,9 @@
         do \
         { \
-            CHECK_FIELD(a_Sel); \
-            if (   pOrgCtx->a_Sel##Hid.Attr.u != pDebugCtx->a_Sel##Hid.Attr.u \
-                && (pOrgCtx->a_Sel##Hid.Attr.u | X86_SEL_TYPE_ACCESSED) != pDebugCtx->a_Sel##Hid.Attr.u) \
-            { \
-                RTAssertMsg2Weak("  %8sHid.Attr differs - iem=%02x - rem=%02x\n", #a_Sel, pDebugCtx->a_Sel##Hid.Attr.u, pOrgCtx->a_Sel##Hid.Attr.u); \
-                cDiffs++; \
-            } \
-            CHECK_FIELD(a_Sel##Hid.u64Base); \
-            CHECK_FIELD(a_Sel##Hid.u32Limit); \
+            CHECK_FIELD(a_Sel.Sel); \
+            CHECK_FIELD(a_Sel.Attr.u); \
+            CHECK_FIELD(a_Sel.u64Base); \
+            CHECK_FIELD(a_Sel.u32Limit); \
+            CHECK_FIELD(a_Sel.fFlags); \
         } while (0)
 
@@ -7776,12 +7773,6 @@
         CHECK_FIELD(idtr.cbIdt);
         CHECK_FIELD(idtr.pIdt);
-        CHECK_FIELD(ldtr);
-        CHECK_FIELD(ldtrHid.u64Base);
-        CHECK_FIELD(ldtrHid.u32Limit);
-        CHECK_FIELD(ldtrHid.Attr.u);
-        CHECK_FIELD(tr);
-        CHECK_FIELD(trHid.u64Base);
-        CHECK_FIELD(trHid.u32Limit);
-        CHECK_FIELD(trHid.Attr.u);
+        CHECK_SEL(ldtr);
+        CHECK_SEL(tr);
         CHECK_FIELD(SysEnter.cs);
         CHECK_FIELD(SysEnter.eip);
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 42482)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 42483)
@@ -909,9 +909,4 @@
         pCtx->cs.fFlags     = CPUMSELREG_FLAGS_VALID;
         pCtx->cs.u64Base    = (uint32_t)uSel << 4;
-        /** @todo REM reset the accessed bit (see on jmp far16 after disabling
-         *        PE.  Check with VT-x and AMD-V. */
-#ifdef IEM_VERIFICATION_MODE
-        pCtx->cs.Attr.u    &= ~X86_SEL_TYPE_ACCESSED;
-#endif
         return VINF_SUCCESS;
     }
@@ -1092,9 +1087,4 @@
         pCtx->cs.fFlags     = CPUMSELREG_FLAGS_VALID;
         pCtx->cs.u64Base    = (uint32_t)uSel << 4;
-        /** @todo Does REM reset the accessed bit here too? (See on jmp far16
-         *        after disabling PE.) Check with VT-x and AMD-V. */
-#ifdef IEM_VERIFICATION_MODE
-        pCtx->cs.Attr.u    &= ~X86_SEL_TYPE_ACCESSED;
-#endif
         return VINF_SUCCESS;
     }
@@ -1714,4 +1704,119 @@
 
 /**
+ * Implements enter.
+ *
+ * We're doing this in C because the instruction is insane, even for the
+ * u8NestingLevel=0 case dealing with the stack is tedious.
+ *
+ * @param   enmEffOpSize    The effective operand size.
+ */
+IEM_CIMPL_DEF_3(iemCImpl_enter, IEMMODE, enmEffOpSize, uint16_t, cbFrame, uint8_t, cParameters)
+{
+    PCPUMCTX        pCtx = pIemCpu->CTX_SUFF(pCtx);
+
+    /* Push RBP, saving the old value in TmpRbp. */
+    RTUINT64U       NewRsp; NewRsp.u = pCtx->rsp;
+    RTUINT64U       TmpRbp; TmpRbp.u = pCtx->rbp;
+    RTUINT64U       NewRbp;
+    VBOXSTRICTRC    rcStrict;
+    if (enmEffOpSize == IEMMODE_64BIT)
+    {
+        rcStrict = iemMemStackPushU64Ex(pIemCpu, TmpRbp.u, &NewRsp);
+        NewRbp = NewRsp;
+    }
+    else if (pCtx->ss.Attr.n.u1DefBig)
+    {
+        rcStrict = iemMemStackPushU32Ex(pIemCpu, TmpRbp.DWords.dw0, &NewRsp);
+        NewRbp = NewRsp;
+    }
+    else
+    {
+        rcStrict = iemMemStackPushU16Ex(pIemCpu, TmpRbp.Words.w0, &NewRsp);
+        NewRbp = NewRsp;
+    }
+    if (rcStrict != VINF_SUCCESS)
+        return rcStrict;
+
+    /* Copy the parameters (aka nesting levels by Intel). */
+    cParameters &= 0x1f;
+    if (cParameters > 0)
+    {
+        switch (enmEffOpSize)
+        {
+            case IEMMODE_16BIT:
+                if (pCtx->ss.Attr.n.u1DefBig)
+                    TmpRbp.DWords.dw0 -= 2;
+                else
+                    TmpRbp.Words.w0   -= 2;
+                do
+                {
+                    uint16_t u16Tmp;
+                    rcStrict = iemMemStackPopU16Ex(pIemCpu, &u16Tmp, &TmpRbp);
+                    if (rcStrict != VINF_SUCCESS)
+                        break;
+                    rcStrict = iemMemStackPushU16Ex(pIemCpu, u16Tmp, &NewRsp);
+                } while (--cParameters > 0 && rcStrict == VINF_SUCCESS);
+                break;
+
+            case IEMMODE_32BIT:
+                if (pCtx->ss.Attr.n.u1DefBig)
+                    TmpRbp.DWords.dw0 -= 4;
+                else
+                    TmpRbp.Words.w0   -= 4;
+                do
+                {
+                    uint32_t u32Tmp;
+                    rcStrict = iemMemStackPopU32Ex(pIemCpu, &u32Tmp, &TmpRbp);
+                    if (rcStrict != VINF_SUCCESS)
+                        break;
+                    rcStrict = iemMemStackPushU32Ex(pIemCpu, u32Tmp, &NewRsp);
+                } while (--cParameters > 0 && rcStrict == VINF_SUCCESS);
+                break;
+
+            case IEMMODE_64BIT:
+                TmpRbp.u -= 8;
+                do
+                {
+                    uint64_t u64Tmp;
+                    rcStrict = iemMemStackPopU64Ex(pIemCpu, &u64Tmp, &TmpRbp);
+                    if (rcStrict != VINF_SUCCESS)
+                        break;
+                    rcStrict = iemMemStackPushU64Ex(pIemCpu, u64Tmp, &NewRsp);
+                } while (--cParameters > 0 && rcStrict == VINF_SUCCESS);
+                break;
+
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+        if (rcStrict != VINF_SUCCESS)
+            return VINF_SUCCESS;
+
+        /* Push the new RBP */
+        if (enmEffOpSize == IEMMODE_64BIT)
+            rcStrict = iemMemStackPushU64Ex(pIemCpu, NewRbp.u, &NewRsp);
+        else if (pCtx->ss.Attr.n.u1DefBig)
+            rcStrict = iemMemStackPushU32Ex(pIemCpu, NewRbp.DWords.dw0, &NewRsp);
+        else
+            rcStrict = iemMemStackPushU16Ex(pIemCpu, NewRbp.Words.w0, &NewRsp);
+        if (rcStrict != VINF_SUCCESS)
+            return rcStrict;
+
+    }
+
+    /* Recalc RSP. */
+    iemRegSubFromRspEx(&NewRsp, cbFrame, pCtx);
+
+    /** @todo Should probe write access at the new RSP according to AMD. */
+
+    /* Commit it. */
+    pCtx->rbp = NewRbp.u;
+    pCtx->rsp = NewRsp.u;
+    iemRegAddToRip(pIemCpu, cbInstr);
+
+    return VINF_SUCCESS;
+}
+
+
+
+/**
  * Implements leave.
  *
@@ -1728,4 +1833,8 @@
     RTUINT64U       NewRsp;
     if (pCtx->ss.Attr.n.u1Long)
+        NewRsp.u = pCtx->rbp;
+    else if (pCtx->ss.Attr.n.u1DefBig)
+        NewRsp.u = pCtx->ebp;
+    else
     {
         /** @todo Check that LEAVE actually preserve the high EBP bits. */
@@ -1733,8 +1842,4 @@
         NewRsp.Words.w0 = pCtx->bp;
     }
-    else if (pCtx->ss.Attr.n.u1DefBig)
-        NewRsp.u = pCtx->ebp;
-    else
-        NewRsp.u = pCtx->rbp;
 
     /* Pop RBP according to the operand size. */
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h	(revision 42482)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h	(revision 42483)
@@ -10252,5 +10252,13 @@
 
 /** Opcode 0xc8. */
-FNIEMOP_STUB(iemOp_enter_Iw_Ib);
+FNIEMOP_DEF(iemOp_enter_Iw_Ib)
+{
+    IEMOP_MNEMONIC("enter Iw,Ib");
+    IEMOP_HLP_DEFAULT_64BIT_OP_SIZE();
+    IEMOP_HLP_NO_LOCK_PREFIX();
+    uint16_t cbFrame;        IEM_OPCODE_GET_NEXT_U16(&cbFrame);
+    uint8_t  u8NestingLevel; IEM_OPCODE_GET_NEXT_U8(&u8NestingLevel);
+    return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_enter, pIemCpu->enmEffOpSize, cbFrame, u8NestingLevel);
+}
 
 
