Index: /trunk/include/VBox/vmm/cpum.h
===================================================================
--- /trunk/include/VBox/vmm/cpum.h	(revision 75610)
+++ /trunk/include/VBox/vmm/cpum.h	(revision 75611)
@@ -2071,22 +2071,4 @@
 VMMDECL(void)           CPUMRawSetEFlags(PVMCPU pVCpu, uint32_t fEfl);
 
-/** @name SVM helpers.
- * @{ */
-VMM_INT_DECL(int)       CPUMSvmGetMsrpmOffsetAndBit(uint32_t idMsr, uint16_t *pbOffMsrpm, uint8_t *puMsrpmBit);
-VMM_INT_DECL(bool)      CPUMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg,
-                                                   uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo,
-                                                   PSVMIOIOEXITINFO pIoExitInfo);
-/** @} */
-
-/** @name VMX helpers.
- * @{ */
-VMM_INT_DECL(int)       CPUMVmxGetMsrPermission(void const *pvMsrBitmap, uint32_t idMsr, PVMXMSREXITREAD penmRead,
-                                                PVMXMSREXITWRITE penmWrite);
-VMM_INT_DECL(bool)      CPUMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort,
-                                                     uint8_t cbAccess);
-VMM_INT_DECL(int)       CPUMVmxApicAccessPageRegister(PVMCPU pVCpu, RTGCPHYS GCPhysApicAccess);
-VMM_INT_DECL(int)       CPUMVmxApicAccessPageDeregister(PVMCPU pVCpu, RTGCPHYS GCPhysApicAccess);
-/** @} */
-
 /** @name Changed flags.
  * These flags are used to keep track of which important register that
Index: /trunk/include/VBox/vmm/hm_svm.h
===================================================================
--- /trunk/include/VBox/vmm/hm_svm.h	(revision 75610)
+++ /trunk/include/VBox/vmm/hm_svm.h	(revision 75611)
@@ -1134,7 +1134,25 @@
     } while (0)
 
-/*
+
+/** @defgroup grp_hm_svm_c    SVM C Helpers
+ *
+ * These are functions that strictly only implement SVM functionality that is in
+ * accordance to the SVM spec. and thus fit to use by IEM/REM/HM.
+ *
+ * These are not HM all-context API functions, those are to be placed in hm.h.
+ * @{
+ */
+VMM_INT_DECL(int)       HMSvmGetMsrpmOffsetAndBit(uint32_t idMsr, uint16_t *pbOffMsrpm, uint8_t *puMsrpmBit);
+VMM_INT_DECL(bool)      HMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg,
+                                                 uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo,
+                                                 PSVMIOIOEXITINFO pIoExitInfo);
+/** @} */
+
+
+/** @defgroup grp_hm_svm_hwexec    SVM Hardware-assisted execution Helpers
+ *
  * These functions are only here because the inline functions in cpum.h calls them.
  * Don't add any more functions here unless there is no other option.
+ * @{
  */
 VMM_INT_DECL(bool)     HMHasGuestSvmVmcbCached(PVMCPU pVCpu);
@@ -1148,7 +1166,9 @@
 VMM_INT_DECL(bool)     HMIsGuestSvmNestedPagingEnabled(PVMCPU pVCpu);
 VMM_INT_DECL(uint16_t) HMGetGuestSvmPauseFilterCount(PVMCPU pVCpu);
-
 /** @} */
 
+
+/** @} */
+
 #endif
 
Index: /trunk/include/VBox/vmm/hm_vmx.h
===================================================================
--- /trunk/include/VBox/vmm/hm_vmx.h	(revision 75610)
+++ /trunk/include/VBox/vmm/hm_vmx.h	(revision 75611)
@@ -4191,4 +4191,19 @@
 
 
+/** @defgroup grp_hm_vmx_c    VMX Assembly Helpers
+ *
+ * These are functions that strictly only implement VT-x functionality that is in
+ * accordance to the VT-X spec. and thus fit to use by IEM/REM/HM.
+ *
+ * These are not HM all-context API functions, those are to be placed in hm.h.
+ * @{
+ */
+VMM_INT_DECL(int)   HMVmxGetMsrPermission(void const *pvMsrBitmap, uint32_t idMsr, PVMXMSREXITREAD penmRead,
+                                          PVMXMSREXITWRITE penmWrite);
+VMM_INT_DECL(bool)  HMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort,
+                                               uint8_t cbAccess);
+/** @} */
+
+
 /** @defgroup grp_hm_vmx_asm    VMX Assembly Helpers
  * @{
Index: /trunk/include/VBox/vmm/iem.h
===================================================================
--- /trunk/include/VBox/vmm/iem.h	(revision 75610)
+++ /trunk/include/VBox/vmm/iem.h	(revision 75611)
@@ -329,6 +329,4 @@
 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
 VMM_INT_DECL(VBOXSTRICTRC)  IEMExecVmxVirtApicAccessMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t *pu64Val, bool fWrite);
-VMM_INT_DECL(VBOXSTRICTRC)  IEMExecVmxVirtApicAccessMem(PVMCPU pVCpu, uint16_t offAccess, size_t cbAccess, void *pvData,
-                                                        bool fWrite);
 VMM_INT_DECL(VBOXSTRICTRC)  IEMExecVmxVirtApicUpdate(PVMCPU pVCpu);
 VMM_INT_DECL(VBOXSTRICTRC)  IEMExecVmxVmexitPreemptTimer(PVMCPU pVCpu);
Index: /trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/Makefile.kmk	(revision 75610)
+++ /trunk/src/VBox/VMM/Makefile.kmk	(revision 75611)
@@ -171,6 +171,4 @@
 	VMMAll/CPUMAllRegs.cpp \
 	VMMAll/CPUMAllMsrs.cpp \
-	VMMAll/CPUMAllSvm.cpp \
-	VMMAll/CPUMAllVmx.cpp \
 	VMMAll/CPUMStack.cpp \
 	VMMAll/DBGFAll.cpp \
@@ -562,6 +560,4 @@
 	VMMAll/CPUMAllRegs.cpp \
 	VMMAll/CPUMAllMsrs.cpp \
-	VMMAll/CPUMAllSvm.cpp \
-	VMMAll/CPUMAllVmx.cpp \
 	VMMAll/DBGFAll.cpp \
 	VMMAll/IEMAll.cpp \
@@ -715,6 +711,4 @@
 	VMMAll/CPUMAllRegs.cpp \
 	VMMAll/CPUMAllMsrs.cpp \
-	VMMAll/CPUMAllSvm.cpp \
-	VMMAll/CPUMAllVmx.cpp \
 	VMMAll/CPUMStack.cpp \
 	VMMAll/DBGFAll.cpp \
Index: unk/src/VBox/VMM/VMMAll/CPUMAllSvm.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/CPUMAllSvm.cpp	(revision 75610)
+++ 	(revision )
@@ -1,156 +1,0 @@
-/* $Id$ */
-/** @file
- * CPUM - SVM.
- */
-
-/*
- * Copyright (C) 2018 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_CPUM
-#include <VBox/vmm/cpum.h>
-#include <VBox/log.h>
-
-
-/**
- * Gets the MSR permission bitmap byte and bit offset for the specified MSR.
- *
- * @returns VBox status code.
- * @param   idMsr       The MSR being requested.
- * @param   pbOffMsrpm  Where to store the byte offset in the MSR permission
- *                      bitmap for @a idMsr.
- * @param   puMsrpmBit  Where to store the bit offset starting at the byte
- *                      returned in @a pbOffMsrpm.
- */
-VMM_INT_DECL(int) CPUMSvmGetMsrpmOffsetAndBit(uint32_t idMsr, uint16_t *pbOffMsrpm, uint8_t *puMsrpmBit)
-{
-    Assert(pbOffMsrpm);
-    Assert(puMsrpmBit);
-
-    /*
-     * MSRPM Layout:
-     * Byte offset          MSR range
-     * 0x000  - 0x7ff       0x00000000 - 0x00001fff
-     * 0x800  - 0xfff       0xc0000000 - 0xc0001fff
-     * 0x1000 - 0x17ff      0xc0010000 - 0xc0011fff
-     * 0x1800 - 0x1fff              Reserved
-     *
-     * Each MSR is represented by 2 permission bits (read and write).
-     */
-    if (idMsr <= 0x00001fff)
-    {
-        /* Pentium-compatible MSRs. */
-        uint32_t const bitoffMsr = idMsr << 1;
-        *pbOffMsrpm = bitoffMsr >> 3;
-        *puMsrpmBit = bitoffMsr & 7;
-        return VINF_SUCCESS;
-    }
-
-    if (   idMsr >= 0xc0000000
-        && idMsr <= 0xc0001fff)
-    {
-        /* AMD Sixth Generation x86 Processor MSRs. */
-        uint32_t const bitoffMsr = (idMsr - 0xc0000000) << 1;
-        *pbOffMsrpm = 0x800 + (bitoffMsr >> 3);
-        *puMsrpmBit = bitoffMsr & 7;
-        return VINF_SUCCESS;
-    }
-
-    if (   idMsr >= 0xc0010000
-        && idMsr <= 0xc0011fff)
-    {
-        /* AMD Seventh and Eighth Generation Processor MSRs. */
-        uint32_t const bitoffMsr = (idMsr - 0xc0010000) << 1;
-        *pbOffMsrpm = 0x1000 + (bitoffMsr >> 3);
-        *puMsrpmBit = bitoffMsr & 7;
-        return VINF_SUCCESS;
-    }
-
-    *pbOffMsrpm = 0;
-    *puMsrpmBit = 0;
-    return VERR_OUT_OF_RANGE;
-}
-
-
-/**
- * Determines whether an IOIO intercept is active for the nested-guest or not.
- *
- * @param   pvIoBitmap      Pointer to the nested-guest IO bitmap.
- * @param   u16Port         The IO port being accessed.
- * @param   enmIoType       The type of IO access.
- * @param   cbReg           The IO operand size in bytes.
- * @param   cAddrSizeBits   The address size bits (for 16, 32 or 64).
- * @param   iEffSeg         The effective segment number.
- * @param   fRep            Whether this is a repeating IO instruction (REP prefix).
- * @param   fStrIo          Whether this is a string IO instruction.
- * @param   pIoExitInfo     Pointer to the SVMIOIOEXITINFO struct to be filled.
- *                          Optional, can be NULL.
- */
-VMM_INT_DECL(bool) CPUMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg,
-                                              uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo,
-                                              PSVMIOIOEXITINFO pIoExitInfo)
-{
-    Assert(cAddrSizeBits == 16 || cAddrSizeBits == 32 || cAddrSizeBits == 64);
-    Assert(cbReg == 1 || cbReg == 2 || cbReg == 4 || cbReg == 8);
-
-    /*
-     * The IOPM layout:
-     * Each bit represents one 8-bit port. That makes a total of 0..65535 bits or
-     * two 4K pages.
-     *
-     * For IO instructions that access more than a single byte, the permission bits
-     * for all bytes are checked; if any bit is set to 1, the IO access is intercepted.
-     *
-     * Since it's possible to do a 32-bit IO access at port 65534 (accessing 4 bytes),
-     * we need 3 extra bits beyond the second 4K page.
-     */
-    static const uint16_t s_auSizeMasks[] = { 0, 1, 3, 0, 0xf, 0, 0, 0 };
-
-    uint16_t const offIopm   = u16Port >> 3;
-    uint16_t const fSizeMask = s_auSizeMasks[(cAddrSizeBits >> SVM_IOIO_OP_SIZE_SHIFT) & 7];
-    uint8_t  const cShift    = u16Port - (offIopm << 3);
-    uint16_t const fIopmMask = (1 << cShift) | (fSizeMask << cShift);
-
-    uint8_t const *pbIopm = (uint8_t *)pvIoBitmap;
-    Assert(pbIopm);
-    pbIopm += offIopm;
-    uint16_t const u16Iopm = *(uint16_t *)pbIopm;
-    if (u16Iopm & fIopmMask)
-    {
-        if (pIoExitInfo)
-        {
-            static const uint32_t s_auIoOpSize[] =
-            { SVM_IOIO_32_BIT_OP, SVM_IOIO_8_BIT_OP, SVM_IOIO_16_BIT_OP, 0, SVM_IOIO_32_BIT_OP, 0, 0, 0 };
-
-            static const uint32_t s_auIoAddrSize[] =
-            { 0, SVM_IOIO_16_BIT_ADDR, SVM_IOIO_32_BIT_ADDR, 0, SVM_IOIO_64_BIT_ADDR, 0, 0, 0 };
-
-            pIoExitInfo->u         = s_auIoOpSize[cbReg & 7];
-            pIoExitInfo->u        |= s_auIoAddrSize[(cAddrSizeBits >> 4) & 7];
-            pIoExitInfo->n.u1Str   = fStrIo;
-            pIoExitInfo->n.u1Rep   = fRep;
-            pIoExitInfo->n.u3Seg   = iEffSeg & 7;
-            pIoExitInfo->n.u1Type  = enmIoType;
-            pIoExitInfo->n.u16Port = u16Port;
-        }
-        return true;
-    }
-
-    /** @todo remove later (for debugging as VirtualBox always traps all IO
-     *        intercepts). */
-    AssertMsgFailed(("CPUMSvmIsIOInterceptActive: We expect an IO intercept here!\n"));
-    return false;
-}
-
Index: unk/src/VBox/VMM/VMMAll/CPUMAllVmx.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/CPUMAllVmx.cpp	(revision 75610)
+++ 	(revision )
@@ -1,206 +1,0 @@
-/* $Id$ */
-/** @file
- * CPUM - SVM.
- */
-
-/*
- * Copyright (C) 2018 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_CPUM
-#include <VBox/log.h>
-#include <VBox/vmm/cpum.h>
-#include "CPUMInternal.h"
-#include <VBox/vmm/iem.h>
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/vm.h>
-
-
-/**
- * Gets the permission bits for the specified MSR in the specified MSR bitmap.
- *
- * @returns VBox status code.
- * @param   pvMsrBitmap     Pointer to the MSR bitmap.
- * @param   idMsr           The MSR.
- * @param   penmRead        Where to store the read permissions. Optional, can be
- *                          NULL.
- * @param   penmWrite       Where to store the write permissions. Optional, can be
- *                          NULL.
- */
-VMM_INT_DECL(int) CPUMVmxGetMsrPermission(void const *pvMsrBitmap, uint32_t idMsr, PVMXMSREXITREAD penmRead,
-                                          PVMXMSREXITWRITE penmWrite)
-{
-    AssertPtrReturn(pvMsrBitmap, VERR_INVALID_PARAMETER);
-
-    int32_t iBit;
-    uint8_t const *pbMsrBitmap = (uint8_t *)pvMsrBitmap;
-
-    /*
-     * MSR Layout:
-     *   Byte index            MSR range            Interpreted as
-     * 0x000 - 0x3ff    0x00000000 - 0x00001fff    Low MSR read bits.
-     * 0x400 - 0x7ff    0xc0000000 - 0xc0001fff    High MSR read bits.
-     * 0x800 - 0xbff    0x00000000 - 0x00001fff    Low MSR write bits.
-     * 0xc00 - 0xfff    0xc0000000 - 0xc0001fff    High MSR write bits.
-     *
-     * A bit corresponding to an MSR within the above range causes a VM-exit
-     * if the bit is 1 on executions of RDMSR/WRMSR.
-     *
-     * If an MSR falls out of the MSR range, it always cause a VM-exit.
-     *
-     * See Intel spec. 24.6.9 "MSR-Bitmap Address".
-     */
-    if (idMsr <= 0x00001fff)
-        iBit = idMsr;
-    else if (   idMsr >= 0xc0000000
-             && idMsr <= 0xc0001fff)
-    {
-        iBit = (idMsr - 0xc0000000);
-        pbMsrBitmap += 0x400;
-    }
-    else
-    {
-        if (penmRead)
-            *penmRead = VMXMSREXIT_INTERCEPT_READ;
-        if (penmWrite)
-            *penmWrite = VMXMSREXIT_INTERCEPT_WRITE;
-        Log(("CPUMVmxGetMsrPermission: Warning! Out of range MSR %#RX32\n", idMsr));
-        return VINF_SUCCESS;
-    }
-
-    /* Validate the MSR bit position. */
-    Assert(iBit <= 0x1fff);
-
-    /* Get the MSR read permissions. */
-    if (penmRead)
-    {
-        if (ASMBitTest(pbMsrBitmap, iBit))
-            *penmRead = VMXMSREXIT_INTERCEPT_READ;
-        else
-            *penmRead = VMXMSREXIT_PASSTHRU_READ;
-    }
-
-    /* Get the MSR write permissions. */
-    if (penmWrite)
-    {
-        if (ASMBitTest(pbMsrBitmap + 0x800, iBit))
-            *penmWrite = VMXMSREXIT_INTERCEPT_WRITE;
-        else
-            *penmWrite = VMXMSREXIT_PASSTHRU_WRITE;
-    }
-
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Gets the permission bits for the specified I/O port from the given I/O bitmaps.
- *
- * @returns @c true if the I/O port access must cause a VM-exit, @c false otherwise.
- * @param   pvIoBitmapA     Pointer to I/O bitmap A.
- * @param   pvIoBitmapB     Pointer to I/O bitmap B.
- * @param   uPort           The I/O port being accessed.
- * @param   cbAccess        The size of the I/O access in bytes (1, 2 or 4 bytes).
- */
-VMM_INT_DECL(bool) CPUMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort,
-                                                uint8_t cbAccess)
-{
-    Assert(cbAccess == 1 || cbAccess == 2 || cbAccess == 4);
-
-    /*
-     * If the I/O port access wraps around the 16-bit port I/O space,
-     * we must cause a VM-exit.
-     *
-     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
-     */
-    /** @todo r=ramshankar: Reading 1, 2, 4 bytes at ports 0xffff, 0xfffe and 0xfffc
-     *        respectively are valid and do not constitute a wrap around from what I
-     *        understand. Verify this later. */
-    uint32_t const uPortLast = uPort + cbAccess;
-    if (uPortLast > 0x10000)
-        return true;
-
-    /* Read the appropriate bit from the corresponding IO bitmap. */
-    void const *pvIoBitmap = uPort < 0x8000 ? pvIoBitmapA : pvIoBitmapB;
-    return ASMBitTest(pvIoBitmap, uPort);
-}
-
-#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
-/**
- * @callback_method_impl{FNPGMPHYSHANDLER, VMX APIC-access page accesses}
- *
- * @remarks The @a pvUser argument is currently unused.
- */
-PGM_ALL_CB2_DECL(VBOXSTRICTRC) cpumVmxApicAccessPageHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysFault, void *pvPhys,
-                                                            void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType,
-                                                            PGMACCESSORIGIN enmOrigin, void *pvUser)
-{
-    RT_NOREF4(pVM, pvPhys, enmOrigin, pvUser);
-
-    Assert(CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.s.Guest));
-    Assert(CPUMIsGuestVmxProcCtls2Set(pVCpu, &pVCpu->cpum.s.Guest, VMX_PROC_CTLS2_VIRT_APIC_ACCESS));
-
-#ifdef VBOX_STRICT
-    RTGCPHYS const GCPhysApicBase   = CPUMGetGuestVmxApicAccessPageAddr(pVCpu, &pVCpu->cpum.s.Guest);
-    RTGCPHYS const GCPhysAccessBase = GCPhysFault & ~(RTGCPHYS)PAGE_OFFSET_MASK;
-    Assert(GCPhysApicBase == GCPhysAccessBase);
-#endif
-
-    uint16_t const offAccess = GCPhysFault & PAGE_OFFSET_MASK;
-    bool const fWrite = RT_BOOL(enmAccessType == PGMACCESSTYPE_WRITE);
-    VBOXSTRICTRC rcStrict = IEMExecVmxVirtApicAccessMem(pVCpu, offAccess, cbBuf, pvBuf, fWrite);
-    if (RT_FAILURE(rcStrict))
-        return rcStrict;
-
-    /* Any access on this APIC-access page has been handled, caller should not carry out the access. */
-    return VINF_SUCCESS;
-}
-#endif
-
-
-/**
- * Registers the PGM physical page handelr for teh VMX APIC-access page.
- *
- * @returns VBox status code.
- * @param   pVCpu               The cross context virtual CPU structure.
- * @param   GCPhysApicAccess    The guest-physical address of the APIC-access page.
- */
-VMM_INT_DECL(int) CPUMVmxApicAccessPageRegister(PVMCPU pVCpu, RTGCPHYS GCPhysApicAccess)
-{
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    int rc = PGMHandlerPhysicalRegister(pVM, GCPhysApicAccess, GCPhysApicAccess, pVM->cpum.s.hVmxApicAccessPage,
-                                        NIL_RTR3PTR /* pvUserR3 */, NIL_RTR0PTR /* pvUserR0 */,  NIL_RTRCPTR /* pvUserRC */,
-                                        NULL /* pszDesc */);
-    return rc;
-}
-
-
-/**
- * Registers the PGM physical page handelr for teh VMX APIC-access page.
- *
- * @returns VBox status code.
- * @param   pVCpu               The cross context virtual CPU structure.
- * @param   GCPhysApicAccess    The guest-physical address of the APIC-access page.
- */
-VMM_INT_DECL(int) CPUMVmxApicAccessPageDeregister(PVMCPU pVCpu, RTGCPHYS GCPhysApicAccess)
-{
-    /** @todo NSTVMX: If there's anything else to do while APIC-access page is
-     *        de-registered, do it here. */
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    if (PGMHandlerPhysicalIsRegistered(pVM, GCPhysApicAccess))
-        return PGMHandlerPhysicalDeregister(pVM, GCPhysApicAccess);
-    return VINF_SUCCESS;
-}
-
Index: /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp	(revision 75611)
@@ -297,4 +297,134 @@
 #endif /* !IN_RC */
 
+/**
+ * Gets the MSR permission bitmap byte and bit offset for the specified MSR.
+ *
+ * @returns VBox status code.
+ * @param   idMsr       The MSR being requested.
+ * @param   pbOffMsrpm  Where to store the byte offset in the MSR permission
+ *                      bitmap for @a idMsr.
+ * @param   puMsrpmBit  Where to store the bit offset starting at the byte
+ *                      returned in @a pbOffMsrpm.
+ */
+VMM_INT_DECL(int) HMSvmGetMsrpmOffsetAndBit(uint32_t idMsr, uint16_t *pbOffMsrpm, uint8_t *puMsrpmBit)
+{
+    Assert(pbOffMsrpm);
+    Assert(puMsrpmBit);
+
+    /*
+     * MSRPM Layout:
+     * Byte offset          MSR range
+     * 0x000  - 0x7ff       0x00000000 - 0x00001fff
+     * 0x800  - 0xfff       0xc0000000 - 0xc0001fff
+     * 0x1000 - 0x17ff      0xc0010000 - 0xc0011fff
+     * 0x1800 - 0x1fff              Reserved
+     *
+     * Each MSR is represented by 2 permission bits (read and write).
+     */
+    if (idMsr <= 0x00001fff)
+    {
+        /* Pentium-compatible MSRs. */
+        uint32_t const bitoffMsr = idMsr << 1;
+        *pbOffMsrpm = bitoffMsr >> 3;
+        *puMsrpmBit = bitoffMsr & 7;
+        return VINF_SUCCESS;
+    }
+
+    if (   idMsr >= 0xc0000000
+        && idMsr <= 0xc0001fff)
+    {
+        /* AMD Sixth Generation x86 Processor MSRs. */
+        uint32_t const bitoffMsr = (idMsr - 0xc0000000) << 1;
+        *pbOffMsrpm = 0x800 + (bitoffMsr >> 3);
+        *puMsrpmBit = bitoffMsr & 7;
+        return VINF_SUCCESS;
+    }
+
+    if (   idMsr >= 0xc0010000
+        && idMsr <= 0xc0011fff)
+    {
+        /* AMD Seventh and Eighth Generation Processor MSRs. */
+        uint32_t const bitoffMsr = (idMsr - 0xc0010000) << 1;
+        *pbOffMsrpm = 0x1000 + (bitoffMsr >> 3);
+        *puMsrpmBit = bitoffMsr & 7;
+        return VINF_SUCCESS;
+    }
+
+    *pbOffMsrpm = 0;
+    *puMsrpmBit = 0;
+    return VERR_OUT_OF_RANGE;
+}
+
+
+/**
+ * Determines whether an IOIO intercept is active for the nested-guest or not.
+ *
+ * @param   pvIoBitmap      Pointer to the nested-guest IO bitmap.
+ * @param   u16Port         The IO port being accessed.
+ * @param   enmIoType       The type of IO access.
+ * @param   cbReg           The IO operand size in bytes.
+ * @param   cAddrSizeBits   The address size bits (for 16, 32 or 64).
+ * @param   iEffSeg         The effective segment number.
+ * @param   fRep            Whether this is a repeating IO instruction (REP prefix).
+ * @param   fStrIo          Whether this is a string IO instruction.
+ * @param   pIoExitInfo     Pointer to the SVMIOIOEXITINFO struct to be filled.
+ *                          Optional, can be NULL.
+ */
+VMM_INT_DECL(bool) HMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg,
+                                            uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo,
+                                            PSVMIOIOEXITINFO pIoExitInfo)
+{
+    Assert(cAddrSizeBits == 16 || cAddrSizeBits == 32 || cAddrSizeBits == 64);
+    Assert(cbReg == 1 || cbReg == 2 || cbReg == 4 || cbReg == 8);
+
+    /*
+     * The IOPM layout:
+     * Each bit represents one 8-bit port. That makes a total of 0..65535 bits or
+     * two 4K pages.
+     *
+     * For IO instructions that access more than a single byte, the permission bits
+     * for all bytes are checked; if any bit is set to 1, the IO access is intercepted.
+     *
+     * Since it's possible to do a 32-bit IO access at port 65534 (accessing 4 bytes),
+     * we need 3 extra bits beyond the second 4K page.
+     */
+    static const uint16_t s_auSizeMasks[] = { 0, 1, 3, 0, 0xf, 0, 0, 0 };
+
+    uint16_t const offIopm   = u16Port >> 3;
+    uint16_t const fSizeMask = s_auSizeMasks[(cAddrSizeBits >> SVM_IOIO_OP_SIZE_SHIFT) & 7];
+    uint8_t  const cShift    = u16Port - (offIopm << 3);
+    uint16_t const fIopmMask = (1 << cShift) | (fSizeMask << cShift);
+
+    uint8_t const *pbIopm = (uint8_t *)pvIoBitmap;
+    Assert(pbIopm);
+    pbIopm += offIopm;
+    uint16_t const u16Iopm = *(uint16_t *)pbIopm;
+    if (u16Iopm & fIopmMask)
+    {
+        if (pIoExitInfo)
+        {
+            static const uint32_t s_auIoOpSize[] =
+            { SVM_IOIO_32_BIT_OP, SVM_IOIO_8_BIT_OP, SVM_IOIO_16_BIT_OP, 0, SVM_IOIO_32_BIT_OP, 0, 0, 0 };
+
+            static const uint32_t s_auIoAddrSize[] =
+            { 0, SVM_IOIO_16_BIT_ADDR, SVM_IOIO_32_BIT_ADDR, 0, SVM_IOIO_64_BIT_ADDR, 0, 0, 0 };
+
+            pIoExitInfo->u         = s_auIoOpSize[cbReg & 7];
+            pIoExitInfo->u        |= s_auIoAddrSize[(cAddrSizeBits >> 4) & 7];
+            pIoExitInfo->n.u1Str   = fStrIo;
+            pIoExitInfo->n.u1Rep   = fRep;
+            pIoExitInfo->n.u3Seg   = iEffSeg & 7;
+            pIoExitInfo->n.u1Type  = enmIoType;
+            pIoExitInfo->n.u16Port = u16Port;
+        }
+        return true;
+    }
+
+    /** @todo remove later (for debugging as VirtualBox always traps all IO
+     *        intercepts). */
+    AssertMsgFailed(("CPUMSvmIsIOInterceptActive: We expect an IO intercept here!\n"));
+    return false;
+}
+
 
 /**
Index: /trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp	(revision 75611)
@@ -880,2 +880,112 @@
 }
 
+
+/**
+ * Gets the permission bits for the specified MSR in the specified MSR bitmap.
+ *
+ * @returns VBox status code.
+ * @param   pvMsrBitmap     Pointer to the MSR bitmap.
+ * @param   idMsr           The MSR.
+ * @param   penmRead        Where to store the read permissions. Optional, can be
+ *                          NULL.
+ * @param   penmWrite       Where to store the write permissions. Optional, can be
+ *                          NULL.
+ */
+VMM_INT_DECL(int) HMVmxGetMsrPermission(void const *pvMsrBitmap, uint32_t idMsr, PVMXMSREXITREAD penmRead,
+                                        PVMXMSREXITWRITE penmWrite)
+{
+    AssertPtrReturn(pvMsrBitmap, VERR_INVALID_PARAMETER);
+
+    int32_t iBit;
+    uint8_t const *pbMsrBitmap = (uint8_t *)pvMsrBitmap;
+
+    /*
+     * MSR Layout:
+     *   Byte index            MSR range            Interpreted as
+     * 0x000 - 0x3ff    0x00000000 - 0x00001fff    Low MSR read bits.
+     * 0x400 - 0x7ff    0xc0000000 - 0xc0001fff    High MSR read bits.
+     * 0x800 - 0xbff    0x00000000 - 0x00001fff    Low MSR write bits.
+     * 0xc00 - 0xfff    0xc0000000 - 0xc0001fff    High MSR write bits.
+     *
+     * A bit corresponding to an MSR within the above range causes a VM-exit
+     * if the bit is 1 on executions of RDMSR/WRMSR.
+     *
+     * If an MSR falls out of the MSR range, it always cause a VM-exit.
+     *
+     * See Intel spec. 24.6.9 "MSR-Bitmap Address".
+     */
+    if (idMsr <= 0x00001fff)
+        iBit = idMsr;
+    else if (   idMsr >= 0xc0000000
+             && idMsr <= 0xc0001fff)
+    {
+        iBit = (idMsr - 0xc0000000);
+        pbMsrBitmap += 0x400;
+    }
+    else
+    {
+        if (penmRead)
+            *penmRead = VMXMSREXIT_INTERCEPT_READ;
+        if (penmWrite)
+            *penmWrite = VMXMSREXIT_INTERCEPT_WRITE;
+        Log(("CPUMVmxGetMsrPermission: Warning! Out of range MSR %#RX32\n", idMsr));
+        return VINF_SUCCESS;
+    }
+
+    /* Validate the MSR bit position. */
+    Assert(iBit <= 0x1fff);
+
+    /* Get the MSR read permissions. */
+    if (penmRead)
+    {
+        if (ASMBitTest(pbMsrBitmap, iBit))
+            *penmRead = VMXMSREXIT_INTERCEPT_READ;
+        else
+            *penmRead = VMXMSREXIT_PASSTHRU_READ;
+    }
+
+    /* Get the MSR write permissions. */
+    if (penmWrite)
+    {
+        if (ASMBitTest(pbMsrBitmap + 0x800, iBit))
+            *penmWrite = VMXMSREXIT_INTERCEPT_WRITE;
+        else
+            *penmWrite = VMXMSREXIT_PASSTHRU_WRITE;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Gets the permission bits for the specified I/O port from the given I/O bitmaps.
+ *
+ * @returns @c true if the I/O port access must cause a VM-exit, @c false otherwise.
+ * @param   pvIoBitmapA     Pointer to I/O bitmap A.
+ * @param   pvIoBitmapB     Pointer to I/O bitmap B.
+ * @param   uPort           The I/O port being accessed.
+ * @param   cbAccess        The size of the I/O access in bytes (1, 2 or 4 bytes).
+ */
+VMM_INT_DECL(bool) HMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort,
+                                                uint8_t cbAccess)
+{
+    Assert(cbAccess == 1 || cbAccess == 2 || cbAccess == 4);
+
+    /*
+     * If the I/O port access wraps around the 16-bit port I/O space,
+     * we must cause a VM-exit.
+     *
+     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
+     */
+    /** @todo r=ramshankar: Reading 1, 2, 4 bytes at ports 0xffff, 0xfffe and 0xfffc
+     *        respectively are valid and do not constitute a wrap around from what I
+     *        understand. Verify this later. */
+    uint32_t const uPortLast = uPort + cbAccess;
+    if (uPortLast > 0x10000)
+        return true;
+
+    /* Read the appropriate bit from the corresponding IO bitmap. */
+    void const *pvIoBitmap = uPort < 0x8000 ? pvIoBitmapA : pvIoBitmapB;
+    return ASMBitTest(pvIoBitmap, uPort);
+}
+
Index: /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 75611)
@@ -16047,5 +16047,37 @@
 }
 
-#endif
+
+/**
+ * @callback_method_impl{FNPGMPHYSHANDLER, VMX APIC-access page accesses}
+ *
+ * @remarks The @a pvUser argument is currently unused.
+ */
+PGM_ALL_CB2_DECL(VBOXSTRICTRC) iemVmxApicAccessPageHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysFault, void *pvPhys,
+                                                           void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType,
+                                                           PGMACCESSORIGIN enmOrigin, void *pvUser)
+{
+    RT_NOREF4(pVM, pvPhys, enmOrigin, pvUser);
+
+    Assert(CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu)));
+    Assert(CPUMIsGuestVmxProcCtls2Set(pVCpu, IEM_GET_CTX(pVCpu), VMX_PROC_CTLS2_VIRT_APIC_ACCESS));
+
+#ifdef VBOX_STRICT
+    RTGCPHYS const GCPhysApicBase   = CPUMGetGuestVmxApicAccessPageAddr(pVCpu, IEM_GET_CTX(pVCpu));
+    RTGCPHYS const GCPhysAccessBase = GCPhysFault & ~(RTGCPHYS)PAGE_OFFSET_MASK;
+    Assert(GCPhysApicBase == GCPhysAccessBase);
+#endif
+
+    uint16_t const offAccess = GCPhysFault & PAGE_OFFSET_MASK;
+    uint32_t const fAccess   = enmAccessType == PGMACCESSTYPE_WRITE ? IEM_ACCESS_TYPE_WRITE : IEM_ACCESS_TYPE_READ;
+
+    VBOXSTRICTRC rcStrict = iemVmxVirtApicAccessMem(pVCpu, offAccess, cbBuf, pvBuf, fAccess);
+    if (RT_FAILURE(rcStrict))
+        return rcStrict;
+
+    /* Any access on this APIC-access page has been handled, caller should not carry out the access. */
+    return VINF_SUCCESS;
+}
+
+#endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
 
 #ifdef IN_RING3
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h	(revision 75611)
@@ -985,5 +985,5 @@
     SVMIOIOEXITINFO IoExitInfo;
     void *pvIoBitmap = pVCpu->cpum.GstCtx.hwvirt.svm.CTX_SUFF(pvIoBitmap);
-    bool const fIntercept = CPUMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep,
+    bool const fIntercept = HMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep,
                                                        fStrIo, &IoExitInfo);
     if (fIntercept)
@@ -1034,5 +1034,5 @@
     uint16_t offMsrpm;
     uint8_t  uMsrpmBit;
-    int rc = CPUMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);
+    int rc = HMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);
     if (RT_SUCCESS(rc))
     {
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h	(revision 75611)
@@ -2729,5 +2729,4 @@
     PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     bool const fHostInLongMode = RT_BOOL(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE);
-    bool const fVirtApicAccess = RT_BOOL(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS);
 
     /* We cannot return from a long-mode guest to a host that is not in long mode. */
@@ -2757,10 +2756,17 @@
 
     /* De-register the handler for the APIC-access page. */
-    if (fVirtApicAccess)
-    {
+    if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS)
+    {
+        PVM pVM = pVCpu->CTX_SUFF(pVM);
         RTGCPHYS const GCPhysApicAccess = pVmcs->u64AddrApicAccess.u;
-        int rc = CPUMVmxApicAccessPageDeregister(pVCpu, GCPhysApicAccess);
-        if (RT_FAILURE(rc))
-            return rc;
+        if (PGMHandlerPhysicalIsRegistered(pVM, GCPhysApicAccess))
+        {
+            /** @todo NSTVMX: This is broken! We cannot simply deregister the handler for the
+             *        physical address as other VCPUs executing other nested-VCPUs might have
+             *        it registered! */
+            int rc = PGMHandlerPhysicalDeregister(pVM, GCPhysApicAccess);
+            if (RT_FAILURE(rc))
+                return rc;
+        }
     }
 
@@ -3044,5 +3050,5 @@
         Assert(pbIoBitmapA);
         Assert(pbIoBitmapB);
-        return CPUMVmxGetIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u16Port, cbAccess);
+        return HMVmxGetIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u16Port, cbAccess);
     }
 
@@ -6334,5 +6340,7 @@
 
         /* Register the handler for the APIC-access page. */
-        int rc = CPUMVmxApicAccessPageRegister(pVCpu, GCPhysApicAccess);
+        int rc = PGMHandlerPhysicalRegister(pVCpu->CTX_SUFF(pVM), GCPhysApicAccess, GCPhysApicAccess,
+                                            pVCpu->iem.s.hVmxApicAccessPage, NIL_RTR3PTR /* pvUserR3 */,
+                                            NIL_RTR0PTR /* pvUserR0 */,  NIL_RTRCPTR /* pvUserRC */, NULL /* pszDesc */);
         if (RT_FAILURE(rc))
             IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_AddrApicAccessHandlerReg);
@@ -7057,5 +7065,5 @@
         {
             VMXMSREXITREAD enmRead;
-            int rc = CPUMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, &enmRead,
+            int rc = HMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, &enmRead,
                                              NULL /* penmWrite */);
             AssertRC(rc);
@@ -7066,5 +7074,5 @@
         {
             VMXMSREXITWRITE enmWrite;
-            int rc = CPUMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, NULL /* penmRead */,
+            int rc = HMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, NULL /* penmRead */,
                                              &enmWrite);
             AssertRC(rc);
Index: /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 75611)
@@ -872,5 +872,5 @@
     uint16_t    offMsrpm;
     uint8_t     uMsrpmBit;
-    int rc = CPUMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);
+    int rc = HMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);
     AssertRC(rc);
 
@@ -5156,5 +5156,5 @@
     const bool        fStrIo        = pIoExitInfo->n.u1Str;
 
-    return CPUMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep, fStrIo,
+    return HMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep, fStrIo,
                                       NULL /* pIoExitInfo */);
 }
@@ -5248,5 +5248,5 @@
                 uint16_t offMsrpm;
                 uint8_t  uMsrpmBit;
-                int rc = CPUMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);
+                int rc = HMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);
                 if (RT_SUCCESS(rc))
                 {
Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 75611)
@@ -1738,5 +1738,5 @@
             VMXMSREXITREAD  enmRead;
             VMXMSREXITWRITE enmWrite;
-            rc = CPUMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, pGuestMsr->u32Msr, &enmRead, &enmWrite);
+            rc = HMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, pGuestMsr->u32Msr, &enmRead, &enmWrite);
             AssertMsgReturnVoid(rc == VINF_SUCCESS, ("HMVmxGetMsrPermission! failed. rc=%Rrc\n", rc));
             if (pGuestMsr->u32Msr == MSR_K6_EFER)
@@ -11963,5 +11963,5 @@
             VMXMSREXITREAD  enmRead;
             VMXMSREXITWRITE enmWrite;
-            int rc2 = CPUMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, idMsr, &enmRead, &enmWrite);
+            int rc2 = HMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, idMsr, &enmRead, &enmWrite);
             AssertRCReturn(rc2, rc2);
             if (enmRead == VMXMSREXIT_PASSTHRU_READ)
@@ -12108,5 +12108,5 @@
                         VMXMSREXITREAD  enmRead;
                         VMXMSREXITWRITE enmWrite;
-                        int rc2 = CPUMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, idMsr, &enmRead, &enmWrite);
+                        int rc2 = HMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, idMsr, &enmRead, &enmWrite);
                         AssertRCReturn(rc2, rc2);
                         if (enmWrite == VMXMSREXIT_PASSTHRU_WRITE)
Index: /trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 75611)
@@ -3642,18 +3642,4 @@
             /* Register statistic counters for MSRs. */
             cpumR3MsrRegStats(pVM);
-
-#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
-            /* Register VMX APIC-access page handler type. */
-            if (pVM->cpum.s.GuestFeatures.fVmx)
-            {
-                int rc = PGMR3HandlerPhysicalTypeRegister(pVM, PGMPHYSHANDLERKIND_ALL, cpumVmxApicAccessPageHandler,
-                                                          NULL /* pszModR0 */,
-                                                          "cpumVmxApicAccessPageHandler", NULL /* pszPfHandlerR0 */,
-                                                          NULL /* pszModRC */,
-                                                          NULL /* pszHandlerRC */, NULL /* pszPfHandlerRC */,
-                                                          "VMX APIC-access page", &pVM->cpum.s.hVmxApicAccessPage);
-                AssertRCReturn(rc, rc);
-            }
-#endif
             break;
         }
Index: /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp	(revision 75610)
+++ /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp	(revision 75611)
@@ -169,4 +169,22 @@
             pVCpu->iem.s.aMemMappings[iMemMap].fAccess = IEM_ACCESS_INVALID;
     }
+
+#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+    /*
+     * Register the per-VM VMX APIC-access page handler type.
+     */
+    if (pVM->cpum.ro.GuestFeatures.fVmx)
+    {
+        PVMCPU pVCpu0 = &pVM->aCpus[0];
+        int rc = PGMR3HandlerPhysicalTypeRegister(pVM, PGMPHYSHANDLERKIND_ALL, iemVmxApicAccessPageHandler,
+                                                  NULL /* pszModR0 */,
+                                                  "iemVmxApicAccessPageHandler", NULL /* pszPfHandlerR0 */,
+                                                  NULL /* pszModRC */,
+                                                  NULL /* pszHandlerRC */, NULL /* pszPfHandlerRC */,
+                                                  "VMX APIC-access page", &pVCpu0->iem.s.hVmxApicAccessPage);
+        AssertLogRelRCReturn(rc, rc);
+    }
+#endif
+
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/VMM/include/CPUMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 75610)
+++ /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 75611)
@@ -410,8 +410,5 @@
     /** The host MXCSR mask (determined at init). */
     uint32_t                fHostMxCsrMask;
-
-    /** The VMX APIC-access page handler type. */
-    PGMPHYSHANDLERTYPE      hVmxApicAccessPage;
-    uint8_t                 abPadding1[16];
+    uint8_t                 abPadding1[20];
 
     /** Host CPU feature information.
@@ -423,5 +420,4 @@
     /** Guest CPU info. */
     CPUMINFO                GuestInfo;
-
 
     /** The standard set of CpuId leaves. */
@@ -531,7 +527,4 @@
 PCPUMCPUIDLEAF      cpumCpuIdGetLeaf(PVM pVM, uint32_t uLeaf);
 PCPUMCPUIDLEAF      cpumCpuIdGetLeafEx(PVM pVM, uint32_t uLeaf, uint32_t uSubLeaf, bool *pfExactSubLeafHit);
-# ifdef VBOX_WITH_NESTED_HWVIRT_VMX
-PGM_ALL_CB2_PROTO(FNPGMPHYSHANDLER) cpumVmxApicAccessPageHandler;
-# endif
 
 # ifdef IN_RING3
Index: /trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/IEMInternal.h	(revision 75610)
+++ /trunk/src/VBox/VMM/include/IEMInternal.h	(revision 75611)
@@ -21,4 +21,5 @@
 #include <VBox/vmm/cpum.h>
 #include <VBox/vmm/iem.h>
+#include <VBox/vmm/pgm.h>
 #include <VBox/vmm/stam.h>
 #include <VBox/param.h>
@@ -558,4 +559,6 @@
     /** The CR2 for the current exception / interrupt. */
     uint64_t                uCurXcptCr2;
+    /** The VMX APIC-access page handler type. */
+    PGMPHYSHANDLERTYPE      hVmxApicAccessPage;
 
     /** @name Statistics
@@ -582,5 +585,4 @@
     /** Number of long jumps. */
     uint32_t                cLongJumps;
-    uint32_t                uAlignment6; /**< Alignment padding. */
     /** @} */
 
@@ -928,4 +930,7 @@
 } IEMACCESSCRX;
 
+# ifdef VBOX_WITH_NESTED_HWVIRT_VMX
+PGM_ALL_CB2_PROTO(FNPGMPHYSHANDLER) iemVmxApicAccessPageHandler;
+# endif
 
 /**
