Index: trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 87546)
+++ trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 87547)
@@ -3879,5 +3879,5 @@
 
     /* Enable unrestricted guest execution. */
-    if (pVM->hm.s.vmx.fUnrestrictedGuest)
+    if (pVM->hmr0.s.vmx.fUnrestrictedGuest)
         fVal |= VMX_PROC_CTLS2_UNRESTRICTED_GUEST;
 
@@ -3971,5 +3971,5 @@
     if (!pVM->hmr0.s.fNestedPaging)
     {
-        Assert(!pVM->hm.s.vmx.fUnrestrictedGuest);
+        Assert(!pVM->hmr0.s.vmx.fUnrestrictedGuest);
         fVal |= VMX_PROC_CTLS_INVLPG_EXIT
              |  VMX_PROC_CTLS_CR3_LOAD_EXIT
@@ -4029,5 +4029,5 @@
 
     /* Sanity check, should not really happen. */
-    if (RT_LIKELY(!pVM->hm.s.vmx.fUnrestrictedGuest))
+    if (RT_LIKELY(!pVM->hmr0.s.vmx.fUnrestrictedGuest))
     { /* likely */ }
     else
@@ -4512,17 +4512,4 @@
 
     /*
-     * Without unrestricted guest execution, pRealModeTSS and pNonPagingModeEPTPageTable *must*
-     * always be allocated. We no longer support the highly unlikely case of unrestricted guest
-     * without pRealModeTSS, see hmR3InitFinalizeR0Intel().
-     */
-    if (   !pVM->hm.s.vmx.fUnrestrictedGuest
-        &&  (   !pVM->hm.s.vmx.pNonPagingModeEPTPageTable
-             || !pVM->hm.s.vmx.pRealModeTSS))
-    {
-        LogRelFunc(("Invalid real-on-v86 state.\n"));
-        return VERR_INTERNAL_ERROR;
-    }
-
-    /*
      * Check that nested paging is supported if enabled and copy over the flag to the
      * ring-0 only structure.
@@ -4534,4 +4521,23 @@
     pVM->hmr0.s.fNestedPaging = fNestedPaging;
     pVM->hmr0.s.fAllow64BitGuests = pVM->hm.s.fAllow64BitGuestsCfg;
+
+    /*
+     * Without unrestricted guest execution, pRealModeTSS and pNonPagingModeEPTPageTable *must*
+     * always be allocated. We no longer support the highly unlikely case of unrestricted guest
+     * without pRealModeTSS, see hmR3InitFinalizeR0Intel().
+     */
+    bool const fUnrestrictedGuest = pVM->hm.s.vmx.fUnrestrictedGuestCfg;
+    AssertReturn(   !fUnrestrictedGuest
+                || (   (g_HmMsrs.u.vmx.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_UNRESTRICTED_GUEST)
+                    && fNestedPaging),
+                    VERR_INCOMPATIBLE_CONFIG);
+    if (   !fUnrestrictedGuest
+        &&  (   !pVM->hm.s.vmx.pNonPagingModeEPTPageTable
+             || !pVM->hm.s.vmx.pRealModeTSS))
+    {
+        LogRelFunc(("Invalid real-on-v86 state.\n"));
+        return VERR_INTERNAL_ERROR;
+    }
+    pVM->hmr0.s.vmx.fUnrestrictedGuest = fUnrestrictedGuest;
 
     /* Initialize these always, see hmR3InitFinalizeR0().*/
@@ -5652,5 +5658,5 @@
         uint64_t       fSetCr0 = g_HmMsrs.u.vmx.u64Cr0Fixed0;
         uint64_t const fZapCr0 = g_HmMsrs.u.vmx.u64Cr0Fixed1;
-        if (pVM->hm.s.vmx.fUnrestrictedGuest)
+        if (pVM->hmr0.s.vmx.fUnrestrictedGuest)
             fSetCr0 &= ~(uint64_t)(X86_CR0_PE | X86_CR0_PG);
         else
@@ -5684,5 +5690,5 @@
 
                 /* If we have unrestricted guest execution, we never have to intercept CR3 reads. */
-                if (pVM->hm.s.vmx.fUnrestrictedGuest)
+                if (pVM->hmr0.s.vmx.fUnrestrictedGuest)
                     uProcCtls &= ~VMX_PROC_CTLS_CR3_STORE_EXIT;
             }
@@ -5863,5 +5869,5 @@
             uint64_t  u64GuestCr3;
             PCCPUMCTX pCtx = &pVCpu->cpum.GstCtx;
-            if (   pVM->hm.s.vmx.fUnrestrictedGuest
+            if (   pVM->hmr0.s.vmx.fUnrestrictedGuest
                 || CPUMIsGuestPagingEnabledEx(pCtx))
             {
@@ -5973,5 +5979,5 @@
         {
             if (   !CPUMIsGuestPagingEnabledEx(pCtx)
-                && !pVM->hm.s.vmx.fUnrestrictedGuest)
+                && !pVM->hmr0.s.vmx.fUnrestrictedGuest)
             {
                 /* We use 4 MB pages in our identity mapping page table when the guest doesn't have paging. */
@@ -6235,5 +6241,5 @@
     PCCPUMCTX pCtx = &pVCpu->cpum.GstCtx;
     hmR0VmxImportGuestState(pVCpu, pVmcsInfo, CPUMCTX_EXTRN_CR0);
-    if (   !pVM->hm.s.vmx.fUnrestrictedGuest
+    if (   !pVM->hmr0.s.vmx.fUnrestrictedGuest
         && (   !CPUMIsGuestInRealModeEx(pCtx)
             && !CPUMIsGuestInV86ModeEx(pCtx)))
@@ -6341,5 +6347,5 @@
     else if (   CPUMIsGuestInV86ModeEx(pCtx)
              || (   CPUMIsGuestInRealModeEx(pCtx)
-                 && !pVM->hm.s.vmx.fUnrestrictedGuest))
+                 && !pVM->hmr0.s.vmx.fUnrestrictedGuest))
     {
         /* Real and v86 mode checks. */
@@ -6782,5 +6788,5 @@
              */
             uint64_t uGuestEferMsr = pCtx->msrEFER;
-            if (!pVM->hm.s.vmx.fUnrestrictedGuest)
+            if (!pVM->hmr0.s.vmx.fUnrestrictedGuest)
             {
                 if (!(pCtx->msrEFER & MSR_K6_EFER_LMA))
@@ -7885,5 +7891,5 @@
                 {
                     /* CR0.PG bit changes are always intercepted, so it's up to date. */
-                    if (   pVM->hm.s.vmx.fUnrestrictedGuest
+                    if (   pVM->hmr0.s.vmx.fUnrestrictedGuest
                         || (   pVM->hmr0.s.fNestedPaging
                             && CPUMIsGuestPagingEnabledEx(pCtx)))
@@ -8798,5 +8804,5 @@
     if (CPUMIsGuestInRealModeEx(pCtx))     /* CR0.PE bit changes are always intercepted, so it's up to date. */
     {
-        if (pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fUnrestrictedGuest)
+        if (pVCpu->CTX_SUFF(pVM)->hmr0.s.vmx.fUnrestrictedGuest)
         {
             /*
@@ -9485,5 +9491,5 @@
      */
     PVMXVMCSINFOSHARED pVmcsInfoShared = pVmxTransient->pVmcsInfo->pShared;
-    if (    pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fUnrestrictedGuest
+    if (    pVCpu->CTX_SUFF(pVM)->hmr0.s.vmx.fUnrestrictedGuest
         || !CPUMIsGuestInRealModeEx(&pVCpu->cpum.GstCtx))
         pVmcsInfoShared->RealMode.fRealOnV86Active = false;
@@ -9677,5 +9683,5 @@
     uint32_t uError = VMX_IGS_ERROR;
     uint32_t u32IntrState = 0;
-    bool const fUnrestrictedGuest = pVM->hm.s.vmx.fUnrestrictedGuest;
+    bool const fUnrestrictedGuest = pVM->hmr0.s.vmx.fUnrestrictedGuest;
     do
     {
@@ -9887,5 +9893,5 @@
             else if (pCtx->cs.Attr.n.u4Type == 13 || pCtx->cs.Attr.n.u4Type == 15)
                 HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u2Dpl <= pCtx->ss.Attr.n.u2Dpl, VMX_IGS_CS_SS_ATTR_DPL_MISMATCH);
-            else if (pVM->hm.s.vmx.fUnrestrictedGuest && pCtx->cs.Attr.n.u4Type == 3)
+            else if (fUnrestrictedGuest && pCtx->cs.Attr.n.u4Type == 3)
                 HMVMX_CHECK_BREAK(pCtx->cs.Attr.n.u2Dpl == 0, VMX_IGS_CS_ATTR_DPL_INVALID);
             else
@@ -9893,5 +9899,5 @@
 
             /* SS */
-            HMVMX_CHECK_BREAK(   pVM->hm.s.vmx.fUnrestrictedGuest
+            HMVMX_CHECK_BREAK(   fUnrestrictedGuest
                               || (pCtx->ss.Sel & X86_SEL_RPL) == (pCtx->cs.Sel & X86_SEL_RPL), VMX_IGS_SS_CS_RPL_UNEQUAL);
             HMVMX_CHECK_BREAK(pCtx->ss.Attr.n.u2Dpl == (pCtx->ss.Sel & X86_SEL_RPL), VMX_IGS_SS_ATTR_DPL_RPL_UNEQUAL);
@@ -9917,5 +9923,5 @@
                 HMVMX_CHECK_BREAK(pCtx->ds.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_DS_ATTR_A_INVALID);
                 HMVMX_CHECK_BREAK(pCtx->ds.Attr.n.u1Present, VMX_IGS_DS_ATTR_P_INVALID);
-                HMVMX_CHECK_BREAK(   pVM->hm.s.vmx.fUnrestrictedGuest
+                HMVMX_CHECK_BREAK(   fUnrestrictedGuest
                                   || pCtx->ds.Attr.n.u4Type > 11
                                   || pCtx->ds.Attr.n.u2Dpl >= (pCtx->ds.Sel & X86_SEL_RPL), VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL);
@@ -9933,5 +9939,5 @@
                 HMVMX_CHECK_BREAK(pCtx->es.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_ES_ATTR_A_INVALID);
                 HMVMX_CHECK_BREAK(pCtx->es.Attr.n.u1Present, VMX_IGS_ES_ATTR_P_INVALID);
-                HMVMX_CHECK_BREAK(   pVM->hm.s.vmx.fUnrestrictedGuest
+                HMVMX_CHECK_BREAK(   fUnrestrictedGuest
                                   || pCtx->es.Attr.n.u4Type > 11
                                   || pCtx->es.Attr.n.u2Dpl >= (pCtx->es.Sel & X86_SEL_RPL), VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL);
@@ -9949,5 +9955,5 @@
                 HMVMX_CHECK_BREAK(pCtx->fs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_FS_ATTR_A_INVALID);
                 HMVMX_CHECK_BREAK(pCtx->fs.Attr.n.u1Present, VMX_IGS_FS_ATTR_P_INVALID);
-                HMVMX_CHECK_BREAK(   pVM->hm.s.vmx.fUnrestrictedGuest
+                HMVMX_CHECK_BREAK(   fUnrestrictedGuest
                                   || pCtx->fs.Attr.n.u4Type > 11
                                   || pCtx->fs.Attr.n.u2Dpl >= (pCtx->fs.Sel & X86_SEL_RPL), VMX_IGS_FS_ATTR_DPL_RPL_UNEQUAL);
@@ -9965,5 +9971,5 @@
                 HMVMX_CHECK_BREAK(pCtx->gs.Attr.n.u4Type & X86_SEL_TYPE_ACCESSED, VMX_IGS_GS_ATTR_A_INVALID);
                 HMVMX_CHECK_BREAK(pCtx->gs.Attr.n.u1Present, VMX_IGS_GS_ATTR_P_INVALID);
-                HMVMX_CHECK_BREAK(   pVM->hm.s.vmx.fUnrestrictedGuest
+                HMVMX_CHECK_BREAK(   fUnrestrictedGuest
                                   || pCtx->gs.Attr.n.u4Type > 11
                                   || pCtx->gs.Attr.n.u2Dpl >= (pCtx->gs.Sel & X86_SEL_RPL), VMX_IGS_GS_ATTR_DPL_RPL_UNEQUAL);
@@ -10599,5 +10605,5 @@
      */
     PVMXVMCSINFO pVmcsInfoNstGst = &pVCpu->hmr0.s.vmx.VmcsInfoNstGst;
-    Assert(pVM->hm.s.vmx.fUnrestrictedGuest);
+    Assert(pVM->hmr0.s.vmx.fUnrestrictedGuest);
     Assert(g_HmMsrs.u.vmx.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_SECONDARY_CTLS);
     Assert(hmGetVmxActiveVmcsInfo(pVCpu) == pVmcsInfoNstGst);
@@ -14312,5 +14318,5 @@
 
     Assert(CPUMIsGuestInRealModeEx(pCtx));
-    Assert(!pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fUnrestrictedGuest);
+    Assert(!pVCpu->CTX_SUFF(pVM)->hmr0.s.vmx.fUnrestrictedGuest);
     Assert(!pVmxTransient->fIsNestedGuest);
 
@@ -15525,5 +15531,5 @@
             if (   iCrReg == 0
                 && rcStrict == VINF_SUCCESS
-                && !pVM->hm.s.vmx.fUnrestrictedGuest
+                && !pVM->hmr0.s.vmx.fUnrestrictedGuest
                 && CPUMIsGuestInRealModeEx(&pVCpu->cpum.GstCtx)
                 && (uOldCr0 & X86_CR0_PE)
