Index: trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp	(revision 107201)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp	(revision 107202)
@@ -280,41 +280,30 @@
            variable, so we can't OR it directly on x86.
 
-           Note! We take a tiny liberty here and ASSUME that the VM and associated
-                 VMCPU mappings are less than 2 GiB away from one another, so we
-                 can access VM::fGlobalForcedActions via a 32-bit signed displacement.
-
-                 This is _only_ a potential issue with VMs using the _support_ _driver_
-                 for manging the structure, as it maps the individual bits separately
-                 and the mapping order differs between host platforms.  Linux may
-                 map the VM structure higher than the VMCPU ones, whereas windows may
-                 do put the VM structure in the lowest address.  On all hosts there
-                 is a chance that virtual memory fragmentation could cause the bits to
-                 end up at a greater distance from one another, but it is rather
-                 doubtful and we just ASSUME it won't happen for now...
-
-                 When the VM structure is allocated in userland, there is one
-                 allocation for it and all the associated VMCPU components, thus no
-                 problems. */
+           We try avoid loading the pVM address here by seeing if we can access
+           VM::fGlobalForcedActions via 32-bit pVCpu displacement.  For
+           driverless configs, this should go without problems (negative
+           offset), but when using the driver the layout is randomized and we
+           need to be flexible. */
         AssertCompile(VM_FF_ALL_MASK == UINT32_MAX);
-        intptr_t const offGlobalForcedActions = (intptr_t)&pReNative->pVCpu->CTX_SUFF(pVM)->fGlobalForcedActions
-                                              - (intptr_t)pReNative->pVCpu;
+        uintptr_t const uAddrGlobalForcedActions = (uintptr_t)&pReNative->pVCpu->CTX_SUFF(pVM)->fGlobalForcedActions;
+        intptr_t const  offGlobalForcedActions   = (intptr_t)uAddrGlobalForcedActions - (intptr_t)pReNative->pVCpu;
+
+# ifdef RT_ARCH_AMD64
         if (RT_LIKELY((int32_t)offGlobalForcedActions == offGlobalForcedActions))
-        { /* likely */ }
+        {
+            if (idxTmpReg2 >= 8)
+                pCodeBuf[off++] = X86_OP_REX_R;
+            pCodeBuf[off++] = 0x8b; /* mov */
+            off = iemNativeEmitGprByVCpuSignedDisp(pCodeBuf, off, idxTmpReg2, (int32_t)offGlobalForcedActions);
+        }
         else
         {
-            LogRelMax(16, ("!!WARNING!! offGlobalForcedActions=%#zx pVM=%p pVCpu=%p - CheckTimersAndIrqsCommon\n",
-                           offGlobalForcedActions, pReNative->pVCpu->CTX_SUFF(pVM), pReNative->pVCpu));
-# ifdef IEM_WITH_THROW_CATCH
-            AssertFailedStmt(IEMNATIVE_DO_LONGJMP(NULL, VERR_IEM_IPE_9));
-# else
-            AssertReleaseFailed();
-# endif
+            off = iemNativeEmitLoadGprImmEx(pCodeBuf, off, idxTmpReg2, uAddrGlobalForcedActions);
+
+            if (idxTmpReg2 >= 8)
+                pCodeBuf[off++] = X86_OP_REX_R | X86_OP_REX_B;
+            pCodeBuf[off++] = 0x8b; /* mov */
+            iemNativeEmitGprByGprDisp(pCodeBuf, off, idxTmpReg2, idxTmpReg2, 0);
         }
-
-# ifdef RT_ARCH_AMD64
-        if (idxTmpReg2 >= 8)
-            pCodeBuf[off++] = X86_OP_REX_R;
-        pCodeBuf[off++] = 0x8b; /* mov */
-        off = iemNativeEmitGprByVCpuSignedDisp(pCodeBuf, off, idxTmpReg2, (int32_t)offGlobalForcedActions);
 
         /* or reg1, reg2 */
@@ -327,7 +316,19 @@
 
 # elif defined(RT_ARCH_ARM64)
-        Assert(offGlobalForcedActions < 0);
-        off = iemNativeEmitGprBySignedVCpuLdStEx(pCodeBuf, off, idxTmpReg2, (int32_t)offGlobalForcedActions,
-                                                 kArmv8A64InstrLdStType_Ld_Word, sizeof(uint32_t));
+        if (RT_LIKELY((int32_t)offGlobalForcedActions == offGlobalForcedActions))
+        {
+            if (offGlobalForcedActions < 0)
+                off = iemNativeEmitGprBySignedVCpuLdStEx(pCodeBuf, off, idxTmpReg2, (int32_t)offGlobalForcedActions,
+                                                         kArmv8A64InstrLdStType_Ld_Word, sizeof(uint32_t));
+            else
+                off = iemNativeEmitGprByVCpuLdStEx(pCodeBuf, off, idxTmpReg2, (uint32_t)offGlobalForcedActions,
+                                                   kArmv8A64InstrLdStType_Ld_Word, sizeof(uint32_t));
+        }
+        else
+        {
+            off = iemNativeEmitLoadGprImmEx(pCodeBuf, off, idxTmpReg2, uAddrGlobalForcedActions);
+            pCodeBuf[off++] = Armv8A64MkInstrStLdRUOff(kArmv8A64InstrLdStType_Ld_Word, idxTmpReg2, idxTmpReg2, 0);
+        }
+
         off = iemNativeEmitOrGprByGprEx(pCodeBuf, off, idxTmpReg1, idxTmpReg2);
 
