Index: /trunk/include/VBox/vmm/cpum.h
===================================================================
--- /trunk/include/VBox/vmm/cpum.h	(revision 75319)
+++ /trunk/include/VBox/vmm/cpum.h	(revision 75320)
@@ -1962,4 +1962,22 @@
 }
 
+
+/**
+ * Returns the guest-physical address of the APIC-access page when executing a
+ * nested-guest.
+ *
+ * @returns The APIC-access page guest-physical address.
+ * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
+ * @param   pCtx        Pointer to the context.
+ */
+DECLINLINE(uint64_t) CPUMGetGuestVmxApicAccessPageAddr(PVMCPU pVCpu, PCCPUMCTX pCtx)
+{
+    RT_NOREF(pVCpu);
+    Assert(pCtx->hwvirt.enmHwvirt == CPUMHWVIRT_VMX);
+    Assert(pCtx->hwvirt.vmx.fInVmxNonRootMode);
+    Assert(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs));
+    return pCtx->hwvirt.vmx.CTX_SUFF(pVmcs)->u64AddrApicAccess.u;
+}
+
 # endif /* !IN_RC */
 
Index: /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 75319)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 75320)
@@ -447,4 +447,7 @@
     do { return iemVmxVmexitTripleFault(a_pVCpu); } while (0)
 
+# define IEM_VMX_VMEXIT_APIC_ACCESS_RET(a_pVCpu, a_offAccess, a_fAccess) \
+    do { return iemVmxVmexitApicAccess((a_pVCpu), (a_offAccess), (a_fAccess)); } while (0)
+
 #else
 # define IEM_VMX_IS_ROOT_MODE(a_pVCpu)                                          (false)
@@ -458,4 +461,5 @@
 # define IEM_VMX_VMEXIT_MWAIT_RET(a_pVCpu, a_fMonitorArmed, a_cbInstr)          do { return VERR_VMX_IPE_1; } while (0)
 # define IEM_VMX_VMEXIT_TRIPLE_FAULT_RET(a_pVCpu)                               do { return VERR_VMX_IPE_1; } while (0)
+# define IEM_VMX_VMEXIT_APIC_ACCESS_RET(a_pVCpu, a_offAccess, a_fAccess)        do { return VERR_VMX_IPE_1; } while (0)
 
 #endif
@@ -976,6 +980,5 @@
 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
 IEM_STATIC VBOXSTRICTRC     iemVmxVmexitTaskSwitch(PVMCPU pVCpu, IEMTASKSWITCH enmTaskSwitch, RTSEL SelNewTss, uint8_t cbInstr);
-IEM_STATIC VBOXSTRICTRC     iemVmxVmexitEvent(PVMCPU pVCpu, uint8_t uVector, uint32_t fFlags, uint32_t uErrCode, uint64_t uCr2,
-                                              uint8_t cbInstr);
+IEM_STATIC VBOXSTRICTRC     iemVmxVmexitEvent(PVMCPU pVCpu, uint8_t uVector, uint32_t fFlags, uint32_t uErrCode, uint64_t uCr2, uint8_t cbInstr);
 IEM_STATIC VBOXSTRICTRC     iemVmxVmexitTripleFault(PVMCPU pVCpu);
 IEM_STATIC VBOXSTRICTRC     iemVmxVmexitPreemptTimer(PVMCPU pVCpu);
@@ -984,10 +987,11 @@
 IEM_STATIC VBOXSTRICTRC     iemVmxVmexitInitIpi(PVMCPU pVCpu);
 IEM_STATIC VBOXSTRICTRC     iemVmxVmexitIntWindow(PVMCPU pVCpu);
+IEM_STATIC VBOXSTRICTRC     iemVmxVirtApicAccessMem(PVMCPU pVCpu, uint16_t offAccess, size_t cbAccess, void *pvData, uint32_t fAccess);
+IEM_STATIC VBOXSTRICTRC     iemVmxVmexitApicAccess(PVMCPU pVCpu, uint16_t offAccess, uint32_t fAccess);
 #endif
 
 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
 IEM_STATIC VBOXSTRICTRC     iemSvmVmexit(PVMCPU pVCpu, uint64_t uExitCode, uint64_t uExitInfo1, uint64_t uExitInfo2);
-IEM_STATIC VBOXSTRICTRC     iemHandleSvmEventIntercept(PVMCPU pVCpu, uint8_t u8Vector, uint32_t fFlags, uint32_t uErr,
-                                                       uint64_t uCr2);
+IEM_STATIC VBOXSTRICTRC     iemHandleSvmEventIntercept(PVMCPU pVCpu, uint8_t u8Vector, uint32_t fFlags, uint32_t uErr, uint64_t uCr2);
 #endif
 
@@ -8598,4 +8602,29 @@
         return rcStrict;
     GCPhysSecond &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
+
+#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+    /*
+     * Check if we need to cause an APIC-access VM-exit.
+     *
+     * The reason we do have to check whether the access is to be virtualized here is that
+     * we already know we're crossing a page-boundary. Any cross-page access (which is at
+     * most 4 bytes) involves accessing offsets prior to XAPIC_OFF_ID or extends well beyond
+     * XAPIC_OFF_END + 4 bytes of the APIC-access page and hence must cause a VM-exit.
+     */
+    if (   CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu))
+        && IEM_VMX_IS_PROCCTLS2_SET(pVCpu, VMX_PROC_CTLS2_VIRT_APIC_ACCESS))
+    {
+        RTGCPHYS const GCPhysMemFirst  = GCPhysFirst  & ~(RTGCPHYS)PAGE_OFFSET_MASK;
+        RTGCPHYS const GCPhysMemSecond = GCPhysSecond & ~(RTGCPHYS)PAGE_OFFSET_MASK;
+        RTGCPHYS const GCPhysApicAccessBase = CPUMGetGuestVmxApicAccessPageAddr(pVCpu, IEM_GET_CTX(pVCpu))
+                                            & ~(RTGCPHYS)PAGE_OFFSET_MASK;
+        if (   GCPhysMemFirst  == GCPhysApicAccessBase
+            || GCPhysMemSecond == GCPhysApicAccessBase)
+        {
+            uint16_t const offAccess = GCPhysFirst & (RTGCPHYS)PAGE_OFFSET_MASK;
+            IEM_VMX_VMEXIT_APIC_ACCESS_RET(pVCpu, offAccess, fAccess);
+        }
+    }
+#endif
 
     PVM pVM = pVCpu->CTX_SUFF(pVM);
@@ -8879,4 +8908,24 @@
     iemMemUpdateWrittenCounter(pVCpu, fAccess, cbMem);
     *ppvMem = pvMem;
+
+#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+    /*
+     * Check if this is an APIC-access and whether it needs to be virtualized.
+     */
+    if (   CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu))
+        && IEM_VMX_IS_PROCCTLS2_SET(pVCpu, VMX_PROC_CTLS2_VIRT_APIC_ACCESS))
+    {
+        RTGCPHYS const GCPhysMemAccessBase  = GCPhysFirst & ~(RTGCPHYS)PAGE_OFFSET_MASK;
+        RTGCPHYS const GCPhysApicAccessBase = CPUMGetGuestVmxApicAccessPageAddr(pVCpu, IEM_GET_CTX(pVCpu))
+                                            & ~(RTGCPHYS)PAGE_OFFSET_MASK;
+        if (GCPhysMemAccessBase == GCPhysApicAccessBase)
+        {
+            Assert(pvMem);
+            uint16_t const offAccess = GCPhysFirst & (RTGCPHYS)PAGE_OFFSET_MASK;
+            return iemVmxVirtApicAccessMem(pVCpu, offAccess, cbMem, pvMem, fAccess);
+        }
+    }
+#endif
+
     return VINF_SUCCESS;
 }
@@ -13894,4 +13943,5 @@
                       /* nested hw.virt codes: */
                       || rcStrict == VINF_VMX_VMEXIT
+                      || rcStrict == VINF_VMX_MODIFIES_BEHAVIOR
                       || rcStrict == VINF_SVM_VMEXIT
                       , ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
@@ -13899,5 +13949,6 @@
             int32_t const rcPassUp = pVCpu->iem.s.rcPassUp;
 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
-            if (   rcStrict == VINF_VMX_VMEXIT
+            if (   (   rcStrict == VINF_VMX_VMEXIT
+                    || rcStrict == VINF_VMX_MODIFIES_BEHAVIOR)
                 && rcPassUp == VINF_SUCCESS)
                 rcStrict = VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 75319)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 75320)
@@ -4000,5 +4000,5 @@
  *                      IEM_ACCESS_TYPE_WRITE).
  */
-IEM_STATIC bool iemVmxVirtApicIsAccessIntercepted(PVMCPU pVCpu, uint16_t offAccess, uint32_t cbAccess, uint32_t fAccess)
+IEM_STATIC bool iemVmxVirtApicIsAccessIntercepted(PVMCPU pVCpu, uint16_t offAccess, size_t cbAccess, uint32_t fAccess)
 {
     PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
@@ -4029,8 +4029,77 @@
 
     /*
-     * Check read accesses to the APIC-access page that cause VM-exits.
-     */
-    if (fAccess == IEM_ACCESS_TYPE_READ)
-    {
+     * Check write accesses to the APIC-access page that cause VM-exits.
+     */
+    if (fAccess & IEM_ACCESS_TYPE_WRITE)
+    {
+        if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_APIC_REG_VIRT)
+        {
+            /*
+             * With APIC-register virtualization, a write access to any of the
+             * following registers are virtualized. Accessing any other register
+             * causes a VM-exit.
+             */
+            uint16_t const offAlignedAccess = offAccess & 0xfffc;
+            switch (offAlignedAccess)
+            {
+                case XAPIC_OFF_ID:
+                case XAPIC_OFF_TPR:
+                case XAPIC_OFF_EOI:
+                case XAPIC_OFF_LDR:
+                case XAPIC_OFF_DFR:
+                case XAPIC_OFF_SVR:
+                case XAPIC_OFF_ESR:
+                case XAPIC_OFF_ICR_LO:
+                case XAPIC_OFF_ICR_HI:
+                case XAPIC_OFF_LVT_TIMER:
+                case XAPIC_OFF_LVT_THERMAL:
+                case XAPIC_OFF_LVT_PERF:
+                case XAPIC_OFF_LVT_LINT0:
+                case XAPIC_OFF_LVT_LINT1:
+                case XAPIC_OFF_LVT_ERROR:
+                case XAPIC_OFF_TIMER_ICR:
+                case XAPIC_OFF_TIMER_DCR:
+                    break;
+                default:
+                    return true;
+            }
+        }
+        else if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_INT_DELIVERY)
+        {
+            /*
+             * With virtual-interrupt delivery, a write access to any of the
+             * following registers are virtualized. Accessing any other register
+             * causes a VM-exit.
+             *
+             * Note! The specification does not allow writing to offsets in-between
+             * these registers (e.g. TPR + 1 byte) unlike read accesses.
+             */
+            switch (offAccess)
+            {
+                case XAPIC_OFF_TPR:
+                case XAPIC_OFF_EOI:
+                case XAPIC_OFF_ICR_LO:
+                    break;
+                default:
+                    return true;
+            }
+        }
+        else
+        {
+            /*
+             * Without APIC-register virtualization or virtual-interrupt delivery,
+             * only TPR accesses are virtualized.
+             */
+            if (offAccess == XAPIC_OFF_TPR)
+            { /* likely */ }
+            else
+                return true;
+        }
+    }
+    else
+    {
+        /*
+         * Check read accesses to the APIC-access page that cause VM-exits.
+         */
         if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_APIC_REG_VIRT)
         {
@@ -4082,73 +4151,4 @@
         }
     }
-    else
-    {
-        /*
-         * Check write accesses to the APIC-access page that cause VM-exits.
-         */
-        if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_APIC_REG_VIRT)
-        {
-            /*
-             * With APIC-register virtualization, a write access to any of the
-             * following registers are virtualized. Accessing any other register
-             * causes a VM-exit.
-             */
-            uint16_t const offAlignedAccess = offAccess & 0xfffc;
-            switch (offAlignedAccess)
-            {
-                case XAPIC_OFF_ID:
-                case XAPIC_OFF_TPR:
-                case XAPIC_OFF_EOI:
-                case XAPIC_OFF_LDR:
-                case XAPIC_OFF_DFR:
-                case XAPIC_OFF_SVR:
-                case XAPIC_OFF_ESR:
-                case XAPIC_OFF_ICR_LO:
-                case XAPIC_OFF_ICR_HI:
-                case XAPIC_OFF_LVT_TIMER:
-                case XAPIC_OFF_LVT_THERMAL:
-                case XAPIC_OFF_LVT_PERF:
-                case XAPIC_OFF_LVT_LINT0:
-                case XAPIC_OFF_LVT_LINT1:
-                case XAPIC_OFF_LVT_ERROR:
-                case XAPIC_OFF_TIMER_ICR:
-                case XAPIC_OFF_TIMER_DCR:
-                    break;
-                default:
-                    return true;
-            }
-        }
-        else if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_INT_DELIVERY)
-        {
-            /*
-             * With virtual-interrupt delivery, a write access to any of the
-             * following registers are virtualized. Accessing any other register
-             * causes a VM-exit.
-             *
-             * Note! The specification does not allow writing to offsets in-between
-             * these registers (e.g. TPR + 1 byte) unlike read accesses.
-             */
-            switch (offAccess)
-            {
-                case XAPIC_OFF_TPR:
-                case XAPIC_OFF_EOI:
-                case XAPIC_OFF_ICR_LO:
-                    break;
-                default:
-                    return true;
-            }
-        }
-        else
-        {
-            /*
-             * Without APIC-register virtualization or virtual-interrupt delivery,
-             * only TPR accesses are virtualized.
-             */
-            if (offAccess == XAPIC_OFF_TPR)
-            { /* likely */ }
-            else
-                return true;
-        }
-    }
 
     /* The APIC-access is virtualized, does not cause a VM-exit. */
@@ -4174,10 +4174,10 @@
  * @param   pVCpu       The cross context virtual CPU structure.
  * @param   offAccess   The offset of the register being accessed.
- * @param   fAccess     The type of access (must be IEM_ACCESS_TYPE_READ or
- *                      IEM_ACCESS_TYPE_WRITE).
+ * @param   fAccess     The type of access (must contain IEM_ACCESS_TYPE_READ or
+ *                      IEM_ACCESS_TYPE_WRITE or IEM_ACCESS_INSTRUCTION).
  */
 IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicAccess(PVMCPU pVCpu, uint16_t offAccess, uint32_t fAccess)
 {
-    Assert(fAccess == IEM_ACCESS_TYPE_READ || fAccess == IEM_ACCESS_TYPE_WRITE);
+    Assert((fAccess & IEM_ACCESS_TYPE_READ) || (fAccess & IEM_ACCESS_TYPE_WRITE) || (fAccess & IEM_ACCESS_INSTRUCTION));
 
     VMXAPICACCESS enmAccess;
@@ -4185,6 +4185,8 @@
     if (fInEventDelivery)
         enmAccess = VMXAPICACCESS_LINEAR_EVENT_DELIVERY;
-    else if (fAccess == IEM_ACCESS_TYPE_READ)
-        enmAccess = VMXAPICACCESS_LINEAR_READ;
+    else if (fAccess & IEM_ACCESS_INSTRUCTION)
+        enmAccess = VMXAPICACCESS_LINEAR_INSTR_FETCH;
+    else if (fAccess & IEM_ACCESS_TYPE_WRITE)
+        enmAccess = VMXAPICACCESS_LINEAR_WRITE;
     else
         enmAccess = VMXAPICACCESS_LINEAR_WRITE;
@@ -4198,13 +4200,17 @@
 
 /**
- * Virtualizes an APIC read access.
+ * Virtualizes a memory-based APIC-access.
  *
  * @returns VBox strict status code.
  * @param   pVCpu       The cross context virtual CPU structure.
- * @param   offAccess   The offset of the register being read.
- * @param   cbAccess    The size of the APIC access.
- * @param   pvData      Where to store the read data.
- */
-IEM_STATIC VBOXSTRICTRC iemVmxVirtApicRead(PVMCPU pVCpu, uint16_t offAccess, uint32_t cbAccess, void *pvData)
+ * @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 read or written.
+ * @param   fAccess     The type of access (must contain IEM_ACCESS_TYPE_READ or
+ *                      IEM_ACCESS_TYPE_WRITE or IEM_ACCESS_INSTRUCTION).
+ */
+IEM_STATIC VBOXSTRICTRC iemVmxVirtApicAccessMem(PVMCPU pVCpu, uint16_t offAccess, size_t cbAccess, void *pvData,
+                                                uint32_t fAccess)
 {
     PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
@@ -4212,75 +4218,59 @@
     Assert(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS);
     Assert(pvData);
-
-    /* Check if we need to cause a VM-exit for this APIC access. */
-    bool const fIntercept = iemVmxVirtApicIsAccessIntercepted(pVCpu, offAccess, cbAccess, IEM_ACCESS_TYPE_READ);
+    Assert(   (fAccess & IEM_ACCESS_TYPE_READ)
+           || (fAccess & IEM_ACCESS_TYPE_WRITE)
+           || (fAccess & IEM_ACCESS_INSTRUCTION));
+
+    bool const fIntercept = iemVmxVirtApicIsAccessIntercepted(pVCpu, offAccess, cbAccess, fAccess);
     if (fIntercept)
-        return iemVmxVmexitApicAccess(pVCpu, offAccess, IEM_ACCESS_TYPE_READ);
-
-    /*
-     * A read access from the APIC-access page that is virtualized (rather than
-     * causing a VM-exit) returns data from the virtual-APIC page.
-     *
-     * See Intel spec. 29.4.2 "Virtualizing Reads from the APIC-Access Page".
-     */
-    Assert(cbAccess <= 4);
-    Assert(offAccess < XAPIC_OFF_END + 4);
-    static uint32_t const s_auAccessSizeMasks[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
-
-    uint32_t u32Data = iemVmxVirtApicReadRaw32(pVCpu, offAccess);
-    u32Data &= s_auAccessSizeMasks[cbAccess];
-    *(uint32_t *)pvData = u32Data;
-    return VINF_VMX_INTERCEPT_NOT_ACTIVE;
-}
-
-
-/**
- * Virtualizes an APIC write access.
- *
- * @returns VBox strict status code.
- * @param   pVCpu       The cross context virtual CPU structure.
- * @param   offAccess   The offset of the register being written.
- * @param   cbAccess    The size of the APIC access.
- * @param   pvData      Pointer to the data being written.
- */
-IEM_STATIC VBOXSTRICTRC iemVmxVirtApicWrite(PVMCPU pVCpu, uint16_t offAccess, uint32_t cbAccess, void *pvData)
-{
-    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
-    Assert(pVmcs);
-    Assert(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS);
-    Assert(pvData);
-
-    /* Check if we need to cause a VM-exit for this APIC access. */
-    bool const fIntercept = iemVmxVirtApicIsAccessIntercepted(pVCpu, offAccess, cbAccess, IEM_ACCESS_TYPE_WRITE);
-    if (fIntercept)
-        return iemVmxVmexitApicAccess(pVCpu, offAccess, IEM_ACCESS_TYPE_WRITE);
-
-    /*
-     * A write access to the APIC-access page that is virtualized (rather than
-     * causing a VM-exit) writes data to the virtual-APIC page.
-     */
-    uint32_t const u32Data = *(uint32_t *)pvData;
-    iemVmxVirtApicWriteRaw32(pVCpu, offAccess, u32Data);
-
-    /*
-     * Record the currently updated APIC offset, as we need this later for figuring
-     * out what to do as well as the exit qualification when causing an APIC-write VM-exit.
-     */
-    pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = offAccess;
-
-    /*
-     * After completion of the current operation, we need to perform TPR virtualization,
-     * EOI virtualization or APIC-write VM-exit depending on which register was written.
-     *
-     * The current operation may be a REP-prefixed string instruction, execution of any
-     * other instruction, or delivery of an event through the IDT.
-     *
-     * Thus things like clearing bytes 3:1 of the VTPR, clearing VEOI are not to be
-     * performed now but later after completion of the current operation.
-     *
-     * See Intel spec. 29.4.3.2 "APIC-Write Emulation".
-     */
-    VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_UPDATE_VAPIC);
-    return VINF_VMX_INTERCEPT_NOT_ACTIVE;
+        return iemVmxVmexitApicAccess(pVCpu, offAccess, fAccess);
+
+    if (fAccess & IEM_ACCESS_TYPE_WRITE)
+    {
+        /*
+         * Record the currently updated APIC offset, as we need this later for figuring
+         * out what to do as well as the exit qualification when causing an APIC-write VM-exit.
+         */
+        pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = offAccess;
+
+        /*
+         * A write access to the APIC-access page that is virtualized (rather than
+         * causing a VM-exit) writes data to the virtual-APIC page.
+         */
+        uint32_t const u32Data = *(uint32_t *)pvData;
+        iemVmxVirtApicWriteRaw32(pVCpu, offAccess, u32Data);
+
+        /*
+         * After completion of the current operation, we need to perform TPR virtualization,
+         * EOI virtualization or APIC-write VM-exit depending on which register was written.
+         *
+         * The current operation may be a REP-prefixed string instruction, execution of any
+         * other instruction, or delivery of an event through the IDT.
+         *
+         * Thus things like clearing bytes 3:1 of the VTPR, clearing VEOI are not to be
+         * performed now but later after completion of the current operation.
+         *
+         * See Intel spec. 29.4.3.2 "APIC-Write Emulation".
+         */
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_UPDATE_VAPIC);
+    }
+    else
+    {
+        /*
+         * A read access from the APIC-access page that is virtualized (rather than
+         * causing a VM-exit) returns data from the virtual-APIC page.
+         *
+         * See Intel spec. 29.4.2 "Virtualizing Reads from the APIC-Access Page".
+         */
+        Assert(cbAccess <= 4);
+        Assert(offAccess < XAPIC_OFF_END + 4);
+        static uint32_t const s_auAccessSizeMasks[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
+
+        uint32_t u32Data = iemVmxVirtApicReadRaw32(pVCpu, offAccess);
+        u32Data &= s_auAccessSizeMasks[cbAccess];
+        *(uint32_t *)pvData = u32Data;
+    }
+
+    return VINF_VMX_MODIFIES_BEHAVIOR;
 }
 
