Index: trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 78927)
+++ trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 78951)
@@ -15788,10 +15788,9 @@
 
     VBOXSTRICTRC rcStrict;
-    if (!fWrite)
+    if (fWrite)
+        rcStrict = iemVmxVirtApicAccessMsrWrite(pVCpu, idMsr, *pu64Value);
+    else
         rcStrict = iemVmxVirtApicAccessMsrRead(pVCpu, idMsr, pu64Value);
-    else
-        rcStrict = iemVmxVirtApicAccessMsrWrite(pVCpu, idMsr, *pu64Value);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 
@@ -15807,25 +15806,16 @@
  *
  * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
- * @param   offAccess   The offset of the register being accessed (within the
- *                      APIC-access page).
- * @param   cbAccess    The size of the access in bytes.
- * @param   pvData      Pointer to the data being written or where to store the data
- *                      being read.
- * @param   fWrite      Whether this is a write or read access.
+ * @param   pExitInfo       Pointer to the VM-exit information.
+ * @param   pExitEventInfo  Pointer to the VM-exit event information.
  * @thread  EMT(pVCpu)
  */
-VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVirtApicAccessMem(PVMCPU pVCpu, uint16_t offAccess, size_t cbAccess, void *pvData,
-                                                       bool fWrite)
-{
-    Assert(pvData);
-
-    /** @todo NSTVMX: Unfortunately, the caller has no idea about instruction fetch
-     *        accesses, so we only use read/write here. Maybe in the future the PGM
-     *        physical handler will be extended to include this information? */
-    uint32_t const fAccess = fWrite ? IEM_ACCESS_TYPE_WRITE : IEM_ACCESS_TYPE_READ;
-    VBOXSTRICTRC rcStrict = iemVmxVirtApicAccessMem(pVCpu, offAccess, cbAccess, pvData, fAccess);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVmexitApicAccess(PVMCPU pVCpu, PCVMXVEXITINFO pExitInfo, PCVMXVEXITEVENTINFO pExitEventInfo)
+{
+    Assert(pExitInfo);
+    Assert(pExitEventInfo);
+    VBOXSTRICTRC rcStrict = iemVmxVmexitApicAccessWithInfo(pVCpu, pExitInfo, pExitEventInfo);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
+
 }
 
@@ -15842,6 +15832,5 @@
 {
     VBOXSTRICTRC rcStrict = iemVmxApicWriteEmulation(pVCpu);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -15858,6 +15847,5 @@
 {
     VBOXSTRICTRC rcStrict = iemVmxVmexitPreemptTimer(pVCpu);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -15878,6 +15866,5 @@
 {
     VBOXSTRICTRC rcStrict = iemVmxVmexitExtInt(pVCpu, uVector, fIntPending);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -15894,6 +15881,5 @@
 {
     VBOXSTRICTRC rcStrict = iemVmxVmexitNmi(pVCpu);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -15910,6 +15896,5 @@
 {
     VBOXSTRICTRC rcStrict = iemVmxVmexitTripleFault(pVCpu);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -15927,6 +15912,5 @@
 {
     VBOXSTRICTRC rcStrict = iemVmxVmexitStartupIpi(pVCpu, uVector);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -15948,6 +15932,5 @@
     iemVmxVmcsSetExitQual(pVCpu, uExitQual);
     VBOXSTRICTRC rcStrict = iemVmxVmexit(pVCpu, uExitReason);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -15968,6 +15951,5 @@
 {
     VBOXSTRICTRC rcStrict = iemVmxVmexitInstrWithInfo(pVCpu, pExitInfo);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -15989,6 +15971,5 @@
 {
     VBOXSTRICTRC rcStrict = iemVmxVmexitInstr(pVCpu, uExitReason, cbInstr);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
@@ -16004,9 +15985,8 @@
  * @thread  EMT(pVCpu)
  */
-VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVmexitTaskSwitch(PVMCPU pVCpu, PVMXVEXITINFO pExitInfo, PVMXVEXITEVENTINFO pExitEventInfo)
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVmexitTaskSwitch(PVMCPU pVCpu, PCVMXVEXITINFO pExitInfo, PCVMXVEXITEVENTINFO pExitEventInfo)
 {
     VBOXSTRICTRC rcStrict = iemVmxVmexitTaskSwitchWithInfo(pVCpu, pExitInfo, pExitEventInfo);
-    if (pVCpu->iem.s.cActiveMappings)
-        iemMemRollback(pVCpu);
+    Assert(!pVCpu->iem.s.cActiveMappings);
     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
 }
Index: trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 78927)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 78951)
@@ -3691,5 +3691,6 @@
  * @param   pExitEventInfo      Pointer to the VM-exit event information.
  */
-IEM_STATIC VBOXSTRICTRC iemVmxVmexitTaskSwitchWithInfo(PVMCPU pVCpu, PVMXVEXITINFO pExitInfo, PVMXVEXITEVENTINFO pExitEventInfo)
+IEM_STATIC VBOXSTRICTRC iemVmxVmexitTaskSwitchWithInfo(PVMCPU pVCpu, PCVMXVEXITINFO pExitInfo,
+                                                       PCVMXVEXITEVENTINFO pExitEventInfo)
 {
     Assert(pExitInfo);
@@ -4105,5 +4106,5 @@
 
 /**
- * VMX VM-exit handler for APIC-accesses.
+ * VMX VM-exit handler for APIC accesses.
  *
  * @param   pVCpu       The cross context virtual CPU structure.
@@ -4130,4 +4131,32 @@
                              | RT_BF_MAKE(VMX_BF_EXIT_QUAL_APIC_ACCESS_TYPE,   enmAccess);
     iemVmxVmcsSetExitQual(pVCpu, uExitQual);
+    return iemVmxVmexit(pVCpu, VMX_EXIT_APIC_ACCESS);
+}
+
+
+/**
+ * VMX VM-exit handler for APIC accesses.
+ *
+ * This is intended for APIC accesses where the caller provides all the
+ * relevant VM-exit information.
+ *
+ * @returns VBox strict status code.
+ * @param   pVCpu               The cross context virtual CPU structure.
+ * @param   pExitInfo           Pointer to the VM-exit information.
+ * @param   pExitEventInfo      Pointer to the VM-exit event information.
+ */
+IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicAccessWithInfo(PVMCPU pVCpu, PCVMXVEXITINFO pExitInfo,
+                                                       PCVMXVEXITEVENTINFO pExitEventInfo)
+{
+    Assert(pExitInfo);
+    Assert(pExitEventInfo);
+
+    /* VM-exit interruption information should not be valid for APIC-access VM-exits. */
+    Assert(!VMX_EXIT_INT_INFO_IS_VALID(pExitEventInfo->uExitIntInfo));
+    iemVmxVmcsSetExitIntInfo(pVCpu, 0);
+    iemVmxVmcsSetExitIntErrCode(pVCpu, 0);
+    iemVmxVmcsSetExitQual(pVCpu, pExitInfo->u64Qual);
+    iemVmxVmcsSetIdtVectoringInfo(pVCpu, pExitEventInfo->uIdtVectoringInfo);
+    iemVmxVmcsSetIdtVectoringErrCode(pVCpu, pExitEventInfo->uIdtVectoringErrCode);
     return iemVmxVmexit(pVCpu, VMX_EXIT_APIC_ACCESS);
 }
@@ -4540,5 +4569,5 @@
     }
 
-    /* The APIC-access is virtualized, does not cause a VM-exit. */
+    /* The APIC access is virtualized, does not cause a VM-exit. */
     return false;
 }
@@ -4546,5 +4575,5 @@
 
 /**
- * Virtualizes a memory-based APIC-access where the address is not used to access
+ * Virtualizes a memory-based APIC access where the address is not used to access
  * memory.
  *
@@ -4584,5 +4613,5 @@
 
 /**
- * Virtualizes a memory-based APIC-access.
+ * Virtualizes a memory-based APIC access.
  *
  * @returns VBox strict status code.
