Index: /trunk/include/VBox/vmm/gvm.h
===================================================================
--- /trunk/include/VBox/vmm/gvm.h	(revision 78437)
+++ /trunk/include/VBox/vmm/gvm.h	(revision 78438)
@@ -67,5 +67,5 @@
 
     /** Pointer to the global (ring-0) VM structure this CPU belongs to. */
-    PGVM            pGVM;
+    R0PTRTYPE(PGVM) pGVM;
 #ifndef VBOX_BUGREF_9217
     /** Pointer to the corresponding cross context CPU structure. */
@@ -95,5 +95,5 @@
     union
     {
-# ifdef VMM_INCLUDED_SRC_include_NEMInternal_h
+# if defined(VMM_INCLUDED_SRC_include_NEMInternal_h) && defined(IN_RING0)
         struct NEMR0PERVCPU s;
 # endif
@@ -206,5 +206,5 @@
     union
     {
-# ifdef VMM_INCLUDED_SRC_include_NEMInternal_h
+# if defined(VMM_INCLUDED_SRC_include_NEMInternal_h) && defined(IN_RING0)
         struct NEMR0PERVM   s;
 # endif
Index: /trunk/include/VBox/vmm/vm.h
===================================================================
--- /trunk/include/VBox/vmm/vm.h	(revision 78437)
+++ /trunk/include/VBox/vmm/vm.h	(revision 78438)
@@ -315,4 +315,5 @@
 
 #ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSizeAlignment(VMCPU, 4096);
 
 /** @name Operations on VMCPU::enmState
@@ -1633,4 +1634,10 @@
 extern DECLIMPORT(VM)   g_VM;
 
+/** The VMCPU structure for virtual CPU \#0.
+ * This is imported from the VMMRCBuiltin module, i.e. it's a one of those magic
+ * globals which we should avoid using.
+ */
+extern DECLIMPORT(VMCPU) g_VCpu0;
+
 RT_C_DECLS_END
 #endif
Index: /trunk/src/VBox/VMM/Config.kmk
===================================================================
--- /trunk/src/VBox/VMM/Config.kmk	(revision 78437)
+++ /trunk/src/VBox/VMM/Config.kmk	(revision 78438)
@@ -82,4 +82,9 @@
  VMM_COMMON_DEFS += VBOX_WITH_MORE_RING0_MEM_MAPPINGS
 endif
+ifdef VBOX_WITH_NATIVE_NEM
+ if1of ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH), win.amd64)
+  VMM_COMMON_DEFS += VBOX_WITH_NATIVE_NEM VBOX_WITH_NEM_R0
+ endif
+endif
 ifdef VBOX_BUGREF_9217
  VMM_COMMON_DEFS += VBOX_BUGREF_9217
Index: /trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/Makefile.kmk	(revision 78437)
+++ /trunk/src/VBox/VMM/Makefile.kmk	(revision 78438)
@@ -972,4 +972,5 @@
 			\
 			-e '/^g_VM\>/d'\
+			-e '/^g_VCpu0\>/d'\
 			-e '/^g_CPUM\>/d'\
 			-e '/^g_Logger\>/d'\
Index: /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp	(revision 78437)
+++ /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp	(revision 78438)
@@ -24,4 +24,7 @@
 #include "VMMInternal.h"
 #include <VBox/vmm/vm.h>
+#ifdef IN_RING0
+# include <VBox/vmm/gvm.h>
+#endif
 #include <VBox/vmm/hm.h>
 #include <VBox/vmm/vmcpuset.h>
@@ -203,4 +206,10 @@
     if (pVM->cCpus == 1)
         return 0;
+# ifdef VBOX_BUGREF_9217
+    PGVM          pGVM  = (PGVM)pVM;
+    VMCPUID const cCpus = pGVM->cCpusSafe;
+# else
+    VMCPUID const cCpus = pVM->cCpus;
+# endif
 
     /* Search first by host cpu id (most common case)
@@ -215,7 +224,11 @@
 
         /** @todo optimize for large number of VCPUs when that becomes more common. */
-        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        for (VMCPUID idCpu = 0; idCpu < cCpus; idCpu++)
         {
+# ifdef VBOX_BUGREF_9217
+            PVMCPU pVCpu = &pGVM->aCpus[idCpu];
+# else
             PVMCPU pVCpu = &pVM->aCpus[idCpu];
+# endif
 
             if (pVCpu->idHostCpu == idHostCpu)
@@ -228,7 +241,11 @@
 
     /** @todo optimize for large number of VCPUs when that becomes more common. */
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
+    for (VMCPUID idCpu = 0; idCpu < cCpus; idCpu++)
+    {
+# ifdef VBOX_BUGREF_9217
+        PVMCPU pVCpu = &pGVM->aCpus[idCpu];
+# else
         PVMCPU pVCpu = &pVM->aCpus[idCpu];
+# endif
 
         if (pVCpu->hNativeThreadR0 == hThread)
@@ -259,9 +276,23 @@
         return NULL;
     Assert(idCpu < pVM->cCpus);
+# ifdef VBOX_BUGREF_9217
+    return pVM->apCpus[idCpu];
+# else
     return &pVM->aCpus[idCpu];
+# endif
 
 #elif defined(IN_RING0)
+# ifdef VBOX_BUGREF_9217
+    PGVM          pGVM  = (PGVM)pVM;
+    VMCPUID const cCpus = pGVM->cCpusSafe;
+# else
+    VMCPUID const cCpus = pVM->cCpus;
+# endif
     if (pVM->cCpus == 1)
+# ifdef VBOX_BUGREF_9217
+        return &pGVM->aCpus[0];
+# else
         return &pVM->aCpus[0];
+# endif
 
     /*
@@ -277,8 +308,11 @@
 
         /** @todo optimize for large number of VCPUs when that becomes more common. */
-        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        for (VMCPUID idCpu = 0; idCpu < cCpus; idCpu++)
         {
+# ifdef VBOX_BUGREF_9217
+            PVMCPU pVCpu = &pGVM->aCpus[idCpu];
+# else
             PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
+# endif
             if (pVCpu->idHostCpu == idHostCpu)
                 return pVCpu;
@@ -291,8 +325,11 @@
     /** @todo optimize for large number of VCPUs when that becomes more common.
      * Use a map like GIP does that's indexed by the host CPU index.  */
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
+    for (VMCPUID idCpu = 0; idCpu < cCpus; idCpu++)
+    {
+# ifdef VBOX_BUGREF_9217
+        PVMCPU pVCpu = &pGVM->aCpus[idCpu];
+# else
         PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
+# endif
         if (pVCpu->hNativeThreadR0 == hThread)
             return pVCpu;
@@ -301,5 +338,6 @@
 
 #else /* RC: Always EMT(0) */
-    return &pVM->aCpus[0];
+    RT_NOREF(pVM);
+    return &g_VCpu0;
 #endif /* IN_RING0 */
 }
@@ -316,5 +354,16 @@
 {
     Assert(pVM->cCpus == 1);
+#ifdef VBOX_BUGREF_9217
+# ifdef IN_RING3
+    return pVM->apCpus[0];
+# elif defined(IN_RING0)
+    return &((PGVM)pVM)->aCpus[0];
+# else /* RC  */
+    RT_NOREF(pVM);
+    return &g_VCpu0;
+# endif
+#else
     return &pVM->aCpus[0];
+#endif
 }
 
@@ -332,5 +381,17 @@
 {
     AssertReturn(idCpu < pVM->cCpus, NULL);
+#ifdef VBOX_BUGREF_9217
+# ifdef IN_RING3
+    return pVM->apCpus[idCpu];
+# elif defined(IN_RING0)
+    return &((PGVM)pVM)->aCpus[0];
+# else /* RC  */
+    RT_NOREF(pVM, idCpu);
+    Assert(idCpu == 0);
+    return &g_VCpu0;
+# endif
+#else
     return &pVM->aCpus[idCpu];
+#endif
 }
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp	(revision 78437)
+++ /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp	(revision 78438)
@@ -362,4 +362,6 @@
         if (!strcmp(pszSymbol, "g_VM"))
             *pValue = pVM->pVMRC;
+        else if (!strcmp(pszSymbol, "g_VCpu0"))
+            *pValue = pVM->pVMRC + pVM->offVMCPU;
         else if (!strcmp(pszSymbol, "g_CPUM"))
             *pValue = VM_RC_ADDR(pVM, &pVM->cpum);
Index: /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp	(revision 78437)
+++ /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp	(revision 78438)
@@ -453,6 +453,10 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
+#ifdef VBOX_BUGREF_9217
+    PVMCPU pVCpu = &g_VCpu0;        /* for PIC we always deliver to CPU 0, MP use APIC */
+#else
     PVM pVM = pDevIns->Internal.s.pVMRC;
     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+#endif
     /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
     APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 1 /* u8Level */, VINF_SUCCESS /* rcRZ */);
@@ -464,6 +468,10 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
+#ifdef VBOX_BUGREF_9217
+    PVMCPU pVCpu = &g_VCpu0;        /* for PIC we always deliver to CPU 0, MP use APIC */
+#else
     PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+#endif
     /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
     APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 0 /* u8Level */, VINF_SUCCESS /* rcRZ */);
Index: /trunk/src/VBox/VMM/VMMRC/VMMRCBuiltin.def
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/VMMRCBuiltin.def	(revision 78437)
+++ /trunk/src/VBox/VMM/VMMRC/VMMRCBuiltin.def	(revision 78438)
@@ -20,4 +20,5 @@
     ; data
     g_VM                            DATA
+    g_VCpu0                         DATA
     g_CPUM                          DATA
     g_TRPM                          DATA
