Index: trunk/src/VBox/VMM/HWACCM.cpp
===================================================================
--- trunk/src/VBox/VMM/HWACCM.cpp	(revision 2895)
+++ trunk/src/VBox/VMM/HWACCM.cpp	(revision 2896)
@@ -115,18 +115,21 @@
     memset(pVM->hwaccm.s.vmx.pVMCS, 0, PAGE_SIZE);
 
-    /* Reuse those two pages for AMD SVM. (one is active; never both) */
-    pVM->hwaccm.s.svm.pHState     = pVM->hwaccm.s.vmx.pVMXON;
-    pVM->hwaccm.s.svm.pHStatePhys = pVM->hwaccm.s.vmx.pVMXONPhys;
-    pVM->hwaccm.s.svm.pVMCB       = pVM->hwaccm.s.vmx.pVMCS;
-    pVM->hwaccm.s.svm.pVMCBPhys   = pVM->hwaccm.s.vmx.pVMCSPhys;
-
-    /* Allocate one page for the SVM host control structure (used for vmsave/vmload). */
-    pVM->hwaccm.s.svm.pVMCBHost = SUPContAlloc(1, &pVM->hwaccm.s.svm.pVMCBHostPhys);
-    if (pVM->hwaccm.s.svm.pVMCBHost == 0)
+    /* Allocate one page for the TSS we need for real mode emulation. */
+    pVM->hwaccm.s.vmx.pRealModeTSS = (PVBOXTSS)SUPContAlloc(1, &pVM->hwaccm.s.vmx.pRealModeTSSPhys);
+    if (pVM->hwaccm.s.vmx.pRealModeTSS == 0)
     {
         AssertMsgFailed(("SUPContAlloc failed!!\n"));
         return VERR_NO_MEMORY;
     }
-    memset(pVM->hwaccm.s.svm.pVMCBHost, 0, PAGE_SIZE);
+    /* We initialize it properly later as we can reuse it for SVM */
+    memset(pVM->hwaccm.s.vmx.pRealModeTSS, 0, PAGE_SIZE);
+
+    /* Reuse those three pages for AMD SVM. (one is active; never both) */
+    pVM->hwaccm.s.svm.pHState       = pVM->hwaccm.s.vmx.pVMXON;
+    pVM->hwaccm.s.svm.pHStatePhys   = pVM->hwaccm.s.vmx.pVMXONPhys;
+    pVM->hwaccm.s.svm.pVMCB         = pVM->hwaccm.s.vmx.pVMCS;
+    pVM->hwaccm.s.svm.pVMCBPhys     = pVM->hwaccm.s.vmx.pVMCSPhys;
+    pVM->hwaccm.s.svm.pVMCBHost     = pVM->hwaccm.s.vmx.pRealModeTSS;
+    pVM->hwaccm.s.svm.pVMCBHostPhys = pVM->hwaccm.s.vmx.pRealModeTSSPhys;
 
     /* Allocate 12 KB for the IO bitmap (doesn't seem to be a way to convince SVM not to use it) */
@@ -419,4 +422,10 @@
             pVM->hwaccm.s.fInitialized = true;
 
+            /* The I/O bitmap starts right after the virtual interrupt redirection bitmap. Outside the TSS on purpose; the CPU will not check it
+             * for I/O operations. */
+            pVM->hwaccm.s.vmx.pRealModeTSS->offIoBitmap = sizeof(*pVM->hwaccm.s.vmx.pRealModeTSS);
+            /* Bit set to 0 means redirection enabled. */
+            memset(pVM->hwaccm.s.vmx.pRealModeTSS->IntRedirBitmap, 0x0, sizeof(pVM->hwaccm.s.vmx.pRealModeTSS->IntRedirBitmap));
+
             int rc = SUPCallVMMR0(pVM->pVMR0, VMMR0_DO_HWACC_SETUP_VM, NULL);
             AssertRC(rc);
@@ -524,8 +533,8 @@
         pVM->hwaccm.s.vmx.pVMCS = 0;
     }
-    if (pVM->hwaccm.s.svm.pVMCBHost)
-    {
-        SUPContFree(pVM->hwaccm.s.svm.pVMCBHost, 1);
-        pVM->hwaccm.s.svm.pVMCBHost = 0;
+    if (pVM->hwaccm.s.vmx.pRealModeTSS)
+    {
+        SUPContFree(pVM->hwaccm.s.vmx.pRealModeTSS, 1);
+        pVM->hwaccm.s.vmx.pRealModeTSS = 0;
     }
     if (pVM->hwaccm.s.svm.pIOBitmap)
@@ -595,4 +604,5 @@
     /** @note The context supplied by REM is partial. If we add more checks here, be sure to verify that REM provides this info! */
 
+#ifndef HWACCM_VMX_EMULATE_ALL
     /* Too early for VMX. */
     if (pCtx->idtr.pIdt == 0 || pCtx->idtr.cbIdt == 0 || pCtx->tr == 0)
@@ -608,4 +618,5 @@
     if (!(pCtx->cr0 & X86_CR0_WRITE_PROTECT))
         return false;
+#endif
 
     if (pVM->hwaccm.s.vmx.fEnabled)
@@ -613,7 +624,10 @@
         /* if bit N is set in cr0_fixed0, then it must be set in the guest's cr0. */
         mask = (uint32_t)pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed0;
-        /** @note We ignore the NE bit here on purpose; see vmmr0\hwaccmr0.cpp for details. */
+        /* Note: We ignore the NE bit here on purpose; see vmmr0\hwaccmr0.cpp for details. */
         mask &= ~X86_CR0_NE;
-
+#ifdef HWACCM_VMX_EMULATE_ALL
+        /* Note: We ignore the PE & PG bits here on purpose; we emulate real and protected mode without paging. */
+        mask &= ~(X86_CR0_PG|X86_CR0_PE);
+#endif
         if ((pCtx->cr0 & mask) != mask)
             return false;
@@ -638,12 +652,4 @@
         return true;
     }
-#if 0
-    else
-    if (pVM->hwaccm.s.svm.fEnabled)
-    {
-        pVM->hwaccm.s.fActive = true;
-        return true;
-    }
-#endif
 
     return false;
Index: trunk/src/VBox/VMM/HWACCMInternal.h
===================================================================
--- trunk/src/VBox/VMM/HWACCMInternal.h	(revision 2895)
+++ trunk/src/VBox/VMM/HWACCMInternal.h	(revision 2896)
@@ -113,5 +113,5 @@
 /** @name HWACCM SSM version
  */
-#define HWACCM_SSM_VERSION                  2
+#define HWACCM_SSM_VERSION                  3
 
 /**
@@ -159,4 +159,9 @@
         /** Virtual address of the VMXON page. */
         void                       *pVMXON;
+
+        /** Physical address of the TSS page used for real mode emulation. */
+        RTHCPHYS                    pRealModeTSSPhys;
+        /** Virtual address of the TSS page used for real mode emulation. */
+        PVBOXTSS                    pRealModeTSS;
 
         /** Host CR4 value (set by ring-0 VMX init) */
