Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 45452)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 45453)
@@ -203,4 +203,7 @@
 static int                hmR0VmxInjectEventVmcs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint64_t u64IntrInfo,
                                                  uint32_t cbInstr, uint32_t u32ErrCode);
+#if HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+static int                hmR0VmxInitVmcsReadCache(PVM pVM, PVMCPU pVCpu);
+#endif
 #if 0
 DECLINLINE(int)           hmR0VmxHandleExit(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient,
@@ -438,9 +441,10 @@
  *
  * @returns VBox status code.
+ * @param   pVCpu           Pointer to the VMCPU. 
  * @param   pVmxTransient   Pointer to the VMX transient structure.
  *
  * @remarks No-long-jump zone!!!
  */
-DECLINLINE(int) hmR0VmxReadEntryInstrLenVmcs(PVMXTRANSIENT pVmxTransient)
+DECLINLINE(int) hmR0VmxReadEntryInstrLenVmcs(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     int rc = VMXReadVmcs32(VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH, &pVmxTransient->cbEntryInstr);
@@ -455,7 +459,8 @@
  *
  * @returns VBox status code.
+ * @param   pVCpu           Pointer to the VMCPU. 
  * @param   pVmxTransient   Pointer to the VMX transient structure.
  */
-DECLINLINE(int) hmR0VmxReadExitIntrInfoVmcs(PVMXTRANSIENT pVmxTransient)
+DECLINLINE(int) hmR0VmxReadExitIntrInfoVmcs(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     if (!(pVmxTransient->fVmcsFieldsRead & VMX_TRANSIENT_EXIT_INTERRUPTION_INFO))
@@ -474,7 +479,8 @@
  *
  * @returns VBox status code.
+ * @param   pVCpu           Pointer to the VMCPU. 
  * @param   pVmxTransient   Pointer to the VMX transient structure.
  */
-DECLINLINE(int) hmR0VmxReadExitIntrErrorCodeVmcs(PVMXTRANSIENT pVmxTransient)
+DECLINLINE(int) hmR0VmxReadExitIntrErrorCodeVmcs(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     if (!(pVmxTransient->fVmcsFieldsRead & VMX_TRANSIENT_EXIT_INTERRUPTION_ERROR_CODE))
@@ -492,8 +498,9 @@
  * transient structure.
  *
- * @returns VBox status code.
+ * @returns VBox status code. 
+ * @param   pVCpu           Pointer to the VMCPU. 
  * @param   pVmxTransient   Pointer to the VMX transient structure.
  */
-DECLINLINE(int) hmR0VmxReadExitInstrLenVmcs(PVMXTRANSIENT pVmxTransient)
+DECLINLINE(int) hmR0VmxReadExitInstrLenVmcs(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     if (!(pVmxTransient->fVmcsFieldsRead & VMX_TRANSIENT_EXIT_INSTR_LEN))
@@ -510,8 +517,9 @@
  * Reads the exit qualification from the VMCS into the VMX transient structure.
  *
- * @returns VBox status code.
+ * @returns VBox status code. 
+ * @param   pVCpu           Pointer to the VMCPU. 
  * @param   pVmxTransient   Pointer to the VMX transient structure.
  */
-DECLINLINE(int) hmR0VmxReadExitQualificationVmcs(PVMXTRANSIENT pVmxTransient)
+DECLINLINE(int) hmR0VmxReadExitQualificationVmcs(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
 {
     if (!(pVmxTransient->fVmcsFieldsRead & VMX_TRANSIENT_EXIT_QUALIFICATION))
@@ -550,5 +558,5 @@
  * transient structure.
  *
- * @returns VBox status code.
+ * @returns VBox status code. 
  * @param   pVmxTransient   Pointer to the VMX transient structure.
  */
@@ -2316,7 +2324,12 @@
  * @returns VBox status code.
  * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- */
-DECLINLINE(int) hmR0VmxLoadGuestExitCtls(PVM pVM, PVMCPU pVCpu)
+ * @param   pVCpu       Pointer to the VMCPU. 
+ * @param   pMixedCtx   Pointer to the guest-CPU context. The data may be
+ *                      out-of-sync. Make sure to update the required fields
+ *                      before using them.
+ *  
+ * @remarks requires EFER.
+ */
+DECLINLINE(int) hmR0VmxLoadGuestExitCtls(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
     int rc = VINF_SUCCESS;
@@ -2336,5 +2349,5 @@
             Assert(!(val & VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_ADDR_SPACE_SIZE));
 #elif HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS)
-        if (CPUMIsGuestInLongModeEx(pCtx))
+        if (CPUMIsGuestInLongModeEx(pMixedCtx))
             val |= VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_ADDR_SPACE_SIZE;    /* The switcher goes to long mode. */
         else
@@ -3734,5 +3747,5 @@
             int rc = VMXReadVmcs32(VMX_VMCS32_RO_EXIT_REASON, &pVCpu->hm.s.vmx.lasterror.u32ExitReason);
             rc    |= VMXReadVmcs32(VMX_VMCS32_RO_VM_INSTR_ERROR, &pVCpu->hm.s.vmx.lasterror.u32InstrError);
-            rc    |= hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+            rc    |= hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
             AssertRC(rc);
 
@@ -3917,4 +3930,101 @@
 #endif
 
+#ifdef VBOX_STRICT
+static bool hmR0VmxIsValidReadField(uint32_t idxField)
+{
+    switch (idxField)
+    {
+        case VMX_VMCS_GUEST_RIP:
+        case VMX_VMCS_GUEST_RSP:
+        case VMX_VMCS_GUEST_RFLAGS:
+        case VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE:
+        case VMX_VMCS_CTRL_CR0_READ_SHADOW:
+        case VMX_VMCS_GUEST_CR0:
+        case VMX_VMCS_CTRL_CR4_READ_SHADOW:
+        case VMX_VMCS_GUEST_CR4:
+        case VMX_VMCS_GUEST_DR7:
+        case VMX_VMCS32_GUEST_SYSENTER_CS:
+        case VMX_VMCS_GUEST_SYSENTER_EIP:
+        case VMX_VMCS_GUEST_SYSENTER_ESP:
+        case VMX_VMCS32_GUEST_GDTR_LIMIT:
+        case VMX_VMCS_GUEST_GDTR_BASE:
+        case VMX_VMCS32_GUEST_IDTR_LIMIT:
+        case VMX_VMCS_GUEST_IDTR_BASE:
+        case VMX_VMCS16_GUEST_FIELD_CS:
+        case VMX_VMCS32_GUEST_CS_LIMIT:
+        case VMX_VMCS_GUEST_CS_BASE:
+        case VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS:
+        case VMX_VMCS16_GUEST_FIELD_DS:
+        case VMX_VMCS32_GUEST_DS_LIMIT:
+        case VMX_VMCS_GUEST_DS_BASE:
+        case VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS:
+        case VMX_VMCS16_GUEST_FIELD_ES:
+        case VMX_VMCS32_GUEST_ES_LIMIT:
+        case VMX_VMCS_GUEST_ES_BASE:
+        case VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS:
+        case VMX_VMCS16_GUEST_FIELD_FS:
+        case VMX_VMCS32_GUEST_FS_LIMIT:
+        case VMX_VMCS_GUEST_FS_BASE:
+        case VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS:
+        case VMX_VMCS16_GUEST_FIELD_GS:
+        case VMX_VMCS32_GUEST_GS_LIMIT:
+        case VMX_VMCS_GUEST_GS_BASE:
+        case VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS:
+        case VMX_VMCS16_GUEST_FIELD_SS:
+        case VMX_VMCS32_GUEST_SS_LIMIT:
+        case VMX_VMCS_GUEST_SS_BASE:
+        case VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS:
+        case VMX_VMCS16_GUEST_FIELD_LDTR:
+        case VMX_VMCS32_GUEST_LDTR_LIMIT:
+        case VMX_VMCS_GUEST_LDTR_BASE:
+        case VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS:
+        case VMX_VMCS16_GUEST_FIELD_TR:
+        case VMX_VMCS32_GUEST_TR_LIMIT:
+        case VMX_VMCS_GUEST_TR_BASE:
+        case VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS:
+        case VMX_VMCS32_RO_EXIT_REASON:
+        case VMX_VMCS32_RO_VM_INSTR_ERROR:
+        case VMX_VMCS32_RO_EXIT_INSTR_LENGTH:
+        case VMX_VMCS32_RO_EXIT_INTERRUPTION_ERROR_CODE:
+        case VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO:
+        case VMX_VMCS32_RO_EXIT_INSTR_INFO:
+        case VMX_VMCS_RO_EXIT_QUALIFICATION:
+        case VMX_VMCS32_RO_IDT_INFO:
+        case VMX_VMCS32_RO_IDT_ERROR_CODE:
+        case VMX_VMCS_GUEST_CR3:
+        case VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL:
+            return true;
+    }
+    return false;
+}
+
+static bool hmR0VmxIsValidWriteField(uint32_t idxField)
+{
+    switch (idxField)
+    {
+        case VMX_VMCS_GUEST_LDTR_BASE:
+        case VMX_VMCS_GUEST_TR_BASE:
+        case VMX_VMCS_GUEST_GDTR_BASE:
+        case VMX_VMCS_GUEST_IDTR_BASE:
+        case VMX_VMCS_GUEST_SYSENTER_EIP:
+        case VMX_VMCS_GUEST_SYSENTER_ESP:
+        case VMX_VMCS_GUEST_CR0:
+        case VMX_VMCS_GUEST_CR4:
+        case VMX_VMCS_GUEST_CR3:
+        case VMX_VMCS_GUEST_DR7:
+        case VMX_VMCS_GUEST_RIP:
+        case VMX_VMCS_GUEST_RSP:
+        case VMX_VMCS_GUEST_CS_BASE:
+        case VMX_VMCS_GUEST_DS_BASE:
+        case VMX_VMCS_GUEST_ES_BASE:
+        case VMX_VMCS_GUEST_FS_BASE:
+        case VMX_VMCS_GUEST_GS_BASE:
+        case VMX_VMCS_GUEST_SS_BASE:
+            return true;
+    }
+    return false;
+}
+#endif /* VBOX_STRICT */
+
 /**
  * Executes the specified handler in 64-bit mode.
@@ -4202,7 +4312,7 @@
         case VMX_VMCS64_CTRL_IO_BITMAP_B_FULL:
         case VMX_VMCS64_CTRL_MSR_BITMAP_FULL:
-        case VMX_VMCS64_CTRL_VMEXIT_MSR_STORE_FULL:
-        case VMX_VMCS64_CTRL_VMEXIT_MSR_LOAD_FULL:
-        case VMX_VMCS64_CTRL_VMENTRY_MSR_LOAD_FULL:
+        case VMX_VMCS64_CTRL_EXIT_MSR_STORE_FULL:
+        case VMX_VMCS64_CTRL_EXIT_MSR_LOAD_FULL:
+        case VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_FULL:
         case VMX_VMCS64_CTRL_EXEC_VMCS_PTR_FULL:
         case VMX_VMCS64_CTRL_TSC_OFFSET_FULL:
@@ -4256,5 +4366,5 @@
         case VMX_VMCS_GUEST_RIP:
         case VMX_VMCS_GUEST_RFLAGS:
-        case VMX_VMCS_GUEST_DEBUG_EXCEPTIONS:
+        case VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS:
         case VMX_VMCS_GUEST_SYSENTER_ESP:
         case VMX_VMCS_GUEST_SYSENTER_EIP:
@@ -4268,5 +4378,5 @@
             {
                 /* Assert that only the 32->64 switcher case should ever come here. */
-                Assert(pVM->hm.s.fAllow64BitGuests);
+                Assert(pVCpu->CTX_SUFF(pVM)->hm.s.fAllow64BitGuests);
                 rc = VMXWriteCachedVmcsEx(pVCpu, idxField, u64Val);
             }
@@ -4321,8 +4431,11 @@
 /**
  * Loads the VMCS write-cache into the CPU (by executing VMWRITEs).
- *
+ *  
+ * @param   pVCpu           Pointer to the VMCPU. 
  * @param   pCache          Pointer to the VMCS cache.
- */
-VMMR0DECL(void) VMXWriteCachedVmcsLoad(PVMCSCACHE pCache)
+ *  
+ * @remarks No-long-jump zone!!!
+ */
+VMMR0DECL(void) VMXWriteCachedVmcsLoad(PVMCPU pVCpu, PVMCSCACHE pCache)
 {
     AssertPtr(pCache);
@@ -4330,5 +4443,5 @@
     {
         int rc = VMXWriteVmcs64(pCache->Write.aField[i], pCache->Write.aFieldVal[i]);
-        AssertRC(rc,  rc);
+        AssertRC(rc);
     }
     pCache->Write.cValidEntries = 0;
@@ -4339,8 +4452,10 @@
  * Stores the VMCS read-cache from the CPU (by executing VMREADs).
  *
+ * @param   pVCpu           Pointer to the VMCPU. 
  * @param   pCache          Pointer to the VMCS cache.
+ *  
  * @remarks No-long-jump zone!!!
  */
-VMMR0DECL(void) VMXReadCachedVmcsStore(PVMCSCACHE pCache)
+VMMR0DECL(void) VMXReadCachedVmcsStore(PVMCPU pVCpu, PVMCSCACHE pCache)
 {
     AssertPtr(pCache);
@@ -4517,5 +4632,5 @@
     if (VMX_IDT_VECTORING_INFO_VALID(pVmxTransient->uIdtVectoringInfo))
     {
-        rc = hmR0VmxReadExitIntrInfoVmcs(pVmxTransient);
+        rc = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
         AssertRCReturn(rc, rc);
 
@@ -5046,5 +5161,6 @@
  * context.
  *
- * @returns VBox status code.
+ * @returns VBox status code. 
+ * @param   pVCpu       Pointer to the VMCPU. 
  * @param   idxSel      Index of the selector in the VMCS.
  * @param   idxLimit    Index of the segment limit in the VMCS.
@@ -5053,7 +5169,9 @@
  * @param   pSelReg     Pointer to the segment selector.
  *
- * @remarks No-long-jump zone!!!
- */
-DECLINLINE(int) hmR0VmxReadSegmentReg(uint32_t idxSel, uint32_t idxLimit, uint32_t idxBase, uint32_t idxAccess,
+ * @remarks No-long-jump zone!!! 
+ * @remarks Never call this function directly. Use the VMXLOCAL_READ_SEG() macro
+ *          as that takes care of whether to read from the VMCS cache or not.
+ */
+DECLINLINE(int) hmR0VmxReadSegmentReg(PVMCPU pVCpu, uint32_t idxSel, uint32_t idxLimit, uint32_t idxBase, uint32_t idxAccess,
                                     PCPUMSELREG pSelReg)
 {
@@ -5068,5 +5186,5 @@
 
     RTGCUINTREG uGCVal = 0;
-    rc |= VMXReadVmcsGstN(idxBase, &uGCVal);
+    rc |= VMXReadVmcsGstNByIdxVal(idxBase, &uGCVal);
     pSelReg->u64Base = uGCVal;
 
@@ -5103,4 +5221,14 @@
 static int hmR0VmxSaveGuestSegmentRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 {
+#ifdef VMX_USE_CACHED_VMCS_ACCESSES
+#define VMXLOCAL_READ_SEG(Sel, CtxSel) \
+    hmR0VmxReadSegmentReg(pVCpu, VMX_VMCS16_GUEST_FIELD_##Sel, VMX_VMCS32_GUEST_##Sel##_LIMIT,                  \
+                          VMX_VMCS_GUEST_##Sel##_BASE_CACHE_IDX, VMX_VMCS32_GUEST_##Sel##_ACCESS_RIGHTS, &pMixedCtx->##CtxSel)
+#else
+#define VMXLOCAL_READ_SEG(Sel, Val) \
+    hmR0VmxReadSegmentReg(pVCpu, VMX_VMCS16_GUEST_FIELD_##Sel, VMX_VMCS32_GUEST_##Sel##_LIMIT,                  \
+                          VMX_VMCS_GUEST_##Sel##_BASE, VMX_VMCS32_GUEST_##Sel##_ACCESS_RIGHTS, &pMixedCtx->##CtxSel)
+#endif
+
     int rc = VINF_SUCCESS;
 
@@ -5109,17 +5237,10 @@
     {
         rc = hmR0VmxSaveGuestCR0(pVM, pVCpu, pMixedCtx);
-
-        rc |= hmR0VmxReadSegmentReg(VMX_VMCS16_GUEST_FIELD_CS, VMX_VMCS32_GUEST_CS_LIMIT, VMX_VMCS_GUEST_CS_BASE,
-                                    VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS, &pMixedCtx->cs);
-        rc |= hmR0VmxReadSegmentReg(VMX_VMCS16_GUEST_FIELD_SS, VMX_VMCS32_GUEST_SS_LIMIT, VMX_VMCS_GUEST_SS_BASE,
-                                    VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS, &pMixedCtx->ss);
-        rc |= hmR0VmxReadSegmentReg(VMX_VMCS16_GUEST_FIELD_DS, VMX_VMCS32_GUEST_DS_LIMIT, VMX_VMCS_GUEST_DS_BASE,
-                                    VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS, &pMixedCtx->ds);
-        rc |= hmR0VmxReadSegmentReg(VMX_VMCS16_GUEST_FIELD_ES, VMX_VMCS32_GUEST_ES_LIMIT, VMX_VMCS_GUEST_ES_BASE,
-                                    VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS, &pMixedCtx->es);
-        rc |= hmR0VmxReadSegmentReg(VMX_VMCS16_GUEST_FIELD_FS, VMX_VMCS32_GUEST_FS_LIMIT, VMX_VMCS_GUEST_FS_BASE,
-                                    VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS, &pMixedCtx->fs);
-        rc |= hmR0VmxReadSegmentReg(VMX_VMCS16_GUEST_FIELD_GS, VMX_VMCS32_GUEST_GS_LIMIT, VMX_VMCS_GUEST_GS_BASE,
-                                    VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS, &pMixedCtx->gs);
+        rc |= VMXLOCAL_READ_SEG(CS, cs);
+        rc |= VMXLOCAL_READ_SEG(SS, ss);
+        rc |= VMXLOCAL_READ_SEG(DS, ds);
+        rc |= VMXLOCAL_READ_SEG(ES, es);
+        rc |= VMXLOCAL_READ_SEG(FS, fs);
+        rc |= VMXLOCAL_READ_SEG(GS, gs);
         AssertRCReturn(rc, rc);
 
@@ -5134,5 +5255,4 @@
             pMixedCtx->gs.Attr.u = pVCpu->hm.s.vmx.RealMode.uAttrGS.u;
         }
-
         pVCpu->hm.s.vmx.fUpdatedGuestState |= VMX_UPDATED_GUEST_SEGMENT_REGS;
     }
@@ -5141,6 +5261,5 @@
     if (!(pVCpu->hm.s.vmx.fUpdatedGuestState & VMX_UPDATED_GUEST_LDTR))
     {
-        rc = hmR0VmxReadSegmentReg(VMX_VMCS16_GUEST_FIELD_LDTR, VMX_VMCS32_GUEST_LDTR_LIMIT, VMX_VMCS_GUEST_LDTR_BASE,
-                                   VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS, &pMixedCtx->ldtr);
+        rc = VMXLOCAL_READ_SEG(LDTR, ldtr);
         AssertRCReturn(rc, rc);
         pVCpu->hm.s.vmx.fUpdatedGuestState |= VMX_UPDATED_GUEST_LDTR;
@@ -5174,10 +5293,7 @@
         rc = hmR0VmxSaveGuestCR0(pVM, pVCpu, pMixedCtx);
 
-        /* For real-mode emulation using virtual-8086 mode we have the fake TSS (pRealModeTSS) in TR, don't sync the fake one. */
+        /* For real-mode emulation using virtual-8086 mode we have the fake TSS (pRealModeTSS) in TR, don't save the fake one. */
         if (!pVCpu->hm.s.vmx.RealMode.fRealOnV86Active)
-        {
-            rc |= hmR0VmxReadSegmentReg(VMX_VMCS16_GUEST_FIELD_TR, VMX_VMCS32_GUEST_TR_LIMIT, VMX_VMCS_GUEST_TR_BASE,
-                                        VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS, &pMixedCtx->tr);
-        }
+            rc |= VMXLOCAL_READ_SEG(TR, tr);
         AssertRCReturn(rc, rc);
         pVCpu->hm.s.vmx.fUpdatedGuestState |= VMX_UPDATED_GUEST_TR;
@@ -5406,5 +5522,5 @@
         uint32_t uVectorType     = VMX_IDT_VECTORING_INFO_TYPE(pVCpu->hm.s.Event.u64IntrInfo);
         uint32_t uVector         = VMX_IDT_VECTORING_INFO_VECTOR(pVCpu->hm.s.Event.u64IntrInfo);
-        bool     fErrorCodeValid = VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(pVCpu->hm.s.Event.u64IntrInfo);
+        bool     fErrorCodeValid = !!VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(pVCpu->hm.s.Event.u64IntrInfo);
         uint32_t uErrorCode      = pVCpu->hm.s.Event.u32ErrCode;
 
@@ -6171,5 +6287,5 @@
     AssertLogRelMsgRCReturn(rc, ("hmR0VmxLoadGuestEntryCtls! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
 
-    rc = hmR0VmxLoadGuestExitCtls(pVM, pVCpu);
+    rc = hmR0VmxLoadGuestExitCtls(pVM, pVCpu, pCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0VmxSetupExitCtls failed! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
 
@@ -6431,5 +6547,5 @@
     AssertRC(rc);
     pVmxTransient->uExitReason    = (uint16_t)VMX_EXIT_REASON_BASIC(uExitReason);
-    pVmxTransient->fVMEntryFailed = VMX_ENTRY_INTERRUPTION_INFO_VALID(pVmxTransient->uEntryIntrInfo);
+    pVmxTransient->fVMEntryFailed = !!VMX_ENTRY_INTERRUPTION_INFO_VALID(pVmxTransient->uEntryIntrInfo);
 
     VMMRZCallRing3SetNotification(pVCpu, hmR0VmxCallRing3Callback, pMixedCtx);
@@ -6635,5 +6751,5 @@
                 AssertPtr(pVmxTransient);                             \
                 Assert(pVmxTransient->fVMEntryFailed == false);       \
-                Assert(ASMIntAreEnabled() == true);                   \
+                Assert(ASMIntAreEnabled());                           \
                 Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));      \
                 VMX_ASSERT_PREEMPT_CPUID_VAR();                       \
@@ -6673,5 +6789,5 @@
 {
     VMX_VALIDATE_EXIT_HANDLER_PARAMS();
-    int rc = hmR0VmxReadExitIntrInfoVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
     AssertRCReturn(rc, rc);
 
@@ -6729,6 +6845,6 @@
                         Assert(pVM->hm.s.vmx.pRealModeTSS);
                         Assert(PDMVmmDevHeapIsEnabled(pVM));
-                        rc  = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
-                        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVmxTransient);
+                        rc  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
+                        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient);
                         AssertRCReturn(rc, rc);
                         rc = hmR0VmxInjectEventVmcs(pVM, pVCpu, pMixedCtx,
@@ -6795,5 +6911,5 @@
 {
     VMX_VALIDATE_EXIT_HANDLER_PARAMS();
-    int rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
     rc    |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
     AssertRCReturn(rc, rc);
@@ -6813,5 +6929,5 @@
 {
     VMX_VALIDATE_EXIT_HANDLER_PARAMS();
-    int rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
     rc    |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
     AssertRCReturn(rc, rc);
@@ -6835,5 +6951,5 @@
     {
         rc  = hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
-        rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         AssertRCReturn(rc, rc);
         Assert(pVmxTransient->cbInstr == 2);
@@ -6882,5 +6998,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        rc  = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         rc |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
         AssertRCReturn(rc, rc);
@@ -6917,5 +7033,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        rc  = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         rc |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
         AssertRCReturn(rc, rc);
@@ -6952,5 +7068,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        rc  = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         rc |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
         AssertRCReturn(rc, rc);
@@ -6976,5 +7092,5 @@
 {
     VMX_VALIDATE_EXIT_HANDLER_PARAMS();
-    int rc = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
     rc    |= hmR0VmxSaveGuestControlRegs(pVM, pVCpu, pMixedCtx);
     AssertRCReturn(rc, rc);
@@ -6984,5 +7100,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        rc  = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         rc |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
         AssertRCReturn(rc, rc);
@@ -7016,5 +7132,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        rc  = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         rc |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
         AssertRCReturn(rc, rc);
@@ -7049,5 +7165,5 @@
                   || rc == VINF_EM_HALT))
     {
-        int rc3  = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        int rc3  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         rc3     |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
         AssertRCReturn(rc3, rc3);
@@ -7245,5 +7361,5 @@
     int rc  = hmR0VmxReadEntryIntrInfoVmcs(pVmxTransient);
     rc     |= hmR0VmxReadEntryXcptErrorCodeVmcs(pVmxTransient);
-    rc     |= hmR0VmxReadEntryInstrLenVmcs(pVmxTransient);
+    rc     |= hmR0VmxReadEntryInstrLenVmcs(pVCpu, pVmxTransient);
     rc     |= VMXReadVmcs32(VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE, &uIntrState);
     rc     |= hmR0VmxSaveGuestState(pVM, pVCpu, pMixedCtx);
@@ -7360,5 +7476,5 @@
     if (RT_LIKELY(rc == VINF_SUCCESS))
     {
-        rc  = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc  = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         rc |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
         AssertRCReturn(rc, rc);
@@ -7378,5 +7494,5 @@
 {
     VMX_VALIDATE_EXIT_HANDLER_PARAMS();
-    int rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
     AssertRCReturn(rc, rc);
     Assert(pVmxTransient->cbInstr == 2);
@@ -7514,5 +7630,5 @@
 {
     VMX_VALIDATE_EXIT_HANDLER_PARAMS();
-    int rc = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
     AssertRCReturn(rc, rc);
 
@@ -7628,5 +7744,5 @@
     {
         int rc2  = hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
-        rc2     |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc2     |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         AssertRCReturn(rc2, rc2);
         pMixedCtx->rip += pVmxTransient->cbInstr;
@@ -7646,6 +7762,6 @@
     VMX_VALIDATE_EXIT_HANDLER_PARAMS();
 
-    int rc = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
-    rc    |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
+    rc    |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
     rc    |= hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
     rc    |= hmR0VmxSaveGuestRflags(pVM, pVCpu, pMixedCtx);         /* Eflag checks in EMInterpretDisasCurrent(). */
@@ -7816,5 +7932,5 @@
 
     /* Check if this task-switch occurred while delivery an event through the guest IDT. */
-    int rc = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
     AssertRCReturn(rc, rc);
     if (VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(pVmxTransient->uExitQualification) == VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT)
@@ -7869,5 +7985,5 @@
 {
     VMX_VALIDATE_EXIT_HANDLER_PARAMS();
-    int rc = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
 
     /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
@@ -7963,5 +8079,5 @@
 
 #ifdef VBOX_WITH_STATISTICS
-        rc = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+        rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
         AssertRCReturn(rc, rc);
         if (VMX_EXIT_QUALIFICATION_DRX_DIRECTION(pVmxTransient->uExitQualification) == VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE)
@@ -7980,5 +8096,5 @@
      * hmR0VmxSaveGuestAutoLoadStoreMsrs(). Update only the segment registers from the CPU.
      */
-    rc  = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+    rc  = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
     rc |= hmR0VmxSaveGuestSegmentRegs(pVM, pVCpu, pMixedCtx);
     AssertRCReturn(rc, rc);
@@ -8005,5 +8121,5 @@
     {
         int rc2  = hmR0VmxSaveGuestRip(pVM, pVCpu, pMixedCtx);
-        rc2     |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc2     |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         AssertRCReturn(rc2, rc2);
         pMixedCtx->rip += pVmxTransient->cbInstr;
@@ -8083,5 +8199,5 @@
     RTGCPHYS GCPhys = 0;
     rc  = VMXReadVmcs64(VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL, &GCPhys);
-    rc |= hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+    rc |= hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
 #if 0
     rc |= hmR0VmxSaveGuestState(pVM, pVCpu, pMixedCtx);     /** @todo Can we do better?  */
@@ -8177,7 +8293,7 @@
     if (rc == VINF_EM_RAW_GUEST_TRAP)
     {
-        rc  = hmR0VmxReadExitIntrInfoVmcs(pVmxTransient);
-        rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
-        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVmxTransient);
+        rc  = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
+        rc |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
+        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient);
         AssertRCReturn(rc, rc);
 
@@ -8200,5 +8316,5 @@
     VMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS();
 
-    int rc = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
     rc    |= hmR0VmxSaveGuestSegmentRegs(pVM, pVCpu, pMixedCtx);
     rc    |= hmR0VmxSaveGuestRflags(pVM, pVCpu, pMixedCtx);
@@ -8230,7 +8346,7 @@
         rc = VMXWriteVmcsGstN(VMX_VMCS_GUEST_DR7, pMixedCtx->dr[7]);
 
-        rc |= hmR0VmxReadExitIntrInfoVmcs(pVmxTransient);
-        rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
-        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVmxTransient);
+        rc |= hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
+        rc |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
+        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient);
         rc |= hmR0VmxInjectEventVmcs(pVM, pVCpu, pMixedCtx,
                                  VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
@@ -8272,5 +8388,5 @@
     /* Forward #NM to the guest. */
     Assert(rc == VINF_EM_RAW_GUEST_TRAP);
-    rc = hmR0VmxReadExitIntrInfoVmcs(pVmxTransient);
+    rc = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
     AssertRCReturn(rc, rc);
     rc = hmR0VmxInjectEventVmcs(pVM, pVCpu, pMixedCtx,
@@ -8298,7 +8414,7 @@
 #ifdef VBOX_ALWAYS_TRAP_ALL_EXCEPTIONS
         /* If the guest is not in real-mode or we have unrestricted execution support, reflect #GP to the guest. */
-        rc  = hmR0VmxReadExitIntrInfoVmcs(pVmxTransient);
-        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVmxTransient);
-        rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
+        rc  = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
+        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient);
+        rc |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
         rc |= hmR0VmxInjectEventVmcs(pVM, pVCpu, pMixedCtx,
                                         VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
@@ -8547,8 +8663,8 @@
     VMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS();
 
-    int rc = hmR0VmxReadExitQualificationVmcs(pVmxTransient);
-    rc    |= hmR0VmxReadExitIntrInfoVmcs(pVmxTransient);
-    rc    |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
-    rc    |= hmR0VmxReadExitIntrErrorCodeVmcs(pVmxTransient);
+    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
+    rc    |= hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
+    rc    |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
+    rc    |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 45452)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 45453)
@@ -5500,5 +5500,5 @@
 
 
-# ifdef VBOX_STRICT
+#ifdef VBOX_STRICT
 static bool hmR0VmxIsValidReadField(uint32_t idxField)
 {
@@ -5596,5 +5596,5 @@
     return false;
 }
-# endif /* VBOX_STRICT */
+#endif /* VBOX_STRICT */
 
 
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.h
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.h	(revision 45452)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.h	(revision 45453)
@@ -73,7 +73,9 @@
 # define VMXReadVmcsHstN                                 VMXReadVmcs32
 # define VMXReadVmcsGstN(idxField, pVal)                 VMXReadCachedVmcsEx(pVCpu, idxField##_CACHE_IDX, pVal)
+# define VMXReadVmcsGstNByIdxVal(idxField, pVal)         VMXReadCachedVmcsEx(pVCpu, idxField, pVal)
 # else
 # define VMXReadVmcsHstN                                 VMXReadVmcs64
 # define VMXReadVmcsGstN                                 VMXReadVmcs64
+# define VMXReadVmcsGstNByIdxVal                         VMXReadVmcs64
 # endif
 #endif
