Index: trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp	(revision 85541)
+++ trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp	(revision 85542)
@@ -5255,4 +5255,11 @@
                                           pImage->paSegments[iSeg].fProt);
             }
+        if (iSeg >= pImage->cSegments)
+        {
+            supdrvLdrUnlock(pDevExt);
+            return supdrvLdrLoadError(VERR_INVALID_PARAMETER, pReq,
+                                      "Bad entry point %p given for %s: no matching segment found (RVA %#zx)!",
+                                      pv, pszSymbol, uRva);
+        }
 
         if (pImage->fNative)
@@ -5335,4 +5342,24 @@
     }
 
+    /*
+     * Copy the segments before we start using supdrvLdrValidatePointer for entrypoint validation.
+     */
+    pImage->cSegments = pReq->u.In.cSegments;
+    {
+        size_t  cbSegments = pImage->cSegments * sizeof(SUPLDRSEG);
+        pImage->paSegments = (PSUPLDRSEG)RTMemDup(&pReq->u.In.abImage[pReq->u.In.offSegments], cbSegments);
+        if (pImage->paSegments) /* Align the last segment size to avoid upsetting RTR0MemObjProtect. */ /** @todo relax RTR0MemObjProtect */
+            pImage->paSegments[pImage->cSegments - 1].cb = RT_ALIGN_32(pImage->paSegments[pImage->cSegments - 1].cb, PAGE_SIZE);
+        else
+        {
+            supdrvLdrUnlock(pDevExt);
+            return supdrvLdrLoadError(VERR_NO_MEMORY, pReq, "Out of memory for segment table: %#x", cbSegments);
+        }
+        SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
+    }
+
+    /*
+     * Validate entrypoints.
+     */
     switch (pReq->u.In.eEPType)
     {
@@ -5404,16 +5431,4 @@
             if (!pImage->paSymbols)
                 rc = supdrvLdrLoadError(VERR_NO_MEMORY, pReq, "Out of memory for symbol table: %#x", cbSymbols);
-            SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
-        }
-
-        pImage->cSegments = pReq->u.In.cSegments;
-        if (RT_SUCCESS(rc))
-        {
-            size_t  cbSegments = pImage->cSegments * sizeof(SUPLDRSEG);
-            pImage->paSegments = (PSUPLDRSEG)RTMemDup(&pReq->u.In.abImage[pReq->u.In.offSegments], cbSegments);
-            if (pImage->paSegments) /* Align the last segment size to avoid upsetting RTR0MemObjProtect. */ /** @todo relax RTR0MemObjProtect */
-                pImage->paSegments[pImage->cSegments - 1].cb = RT_ALIGN_32(pImage->paSegments[pImage->cSegments - 1].cb, PAGE_SIZE);
-            else
-                rc = supdrvLdrLoadError(VERR_NO_MEMORY, pReq, "Out of memory for segment table: %#x", cbSegments);
             SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
         }
Index: trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
===================================================================
--- trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 85541)
+++ trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 85542)
@@ -146,5 +146,5 @@
 #endif
 
-#if 0 /*defined(RT_OS_LINUX)*/ /** @todo make everyone do this */
+#if defined(RT_OS_LINUX) /** @todo make everyone do this */
 /** Use the RTR0MemObj API rather than the RTMemExecAlloc for the images.
  * This is a good idea in general, but a necessity for @bugref{9801}. */
Index: trunk/src/VBox/HostDrivers/Support/SUPLibLdr.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/SUPLibLdr.cpp	(revision 85541)
+++ trunk/src/VBox/HostDrivers/Support/SUPLibLdr.cpp	(revision 85542)
@@ -359,7 +359,13 @@
     RT_NOREF(hLdrMod);
 
+    Log2(("supLoadModuleCompileSegmentsCB: %RTptr/%RTptr LB %RTptr/%RTptr prot %#x %s\n",
+          pSeg->LinkAddress, pSeg->RVA, pSeg->cbMapped, pSeg->cb, pSeg->fProt, pSeg->pszName));
+
     /* Ignore segments not part of the loaded image. */
     if (pSeg->RVA == NIL_RTLDRADDR || pSeg->cbMapped == 0)
+    {
+        Log2(("supLoadModuleCompileSegmentsCB: -> skipped\n"));
         return VINF_SUCCESS;
+    }
 
     /* We currently ASSUME that all relevant segments are in ascending RVA order. */
@@ -374,6 +380,4 @@
     AssertReturn(pSeg->RVA      < _1G, VERR_INTERNAL_ERROR_3);
     uint32_t uRvaSeg  = (uint32_t)pSeg->RVA;
-    Log2(("supLoadModuleCompileSegmentsCB: %RTptr/%RTptr LB %RTptr/%RTptr prot %#x %s\n",
-          pSeg->LinkAddress, pSeg->RVA, pSeg->cbMapped, pSeg->cb, pSeg->fProt, pSeg->pszName));
 
     /*
Index: trunk/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c	(revision 85541)
+++ trunk/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c	(revision 85542)
@@ -383,9 +383,34 @@
 #ifdef CONFIG_SMP
     IPRT_LINUX_SAVE_EFL_AC();
-    int rc;
-    RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+    int                     rc;
+    RTTHREADPREEMPTSTATE    PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) /* 2.6.28 introduces CONFIG_CPUMASK_OFFSTACK */
+    cpumask_var_t           DstCpuMask;
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+    cpumask_t               DstCpuMask;
+# endif
 
     AssertReturn(idCpu1 != idCpu2, VERR_INVALID_PARAMETER);
     AssertReturn(!(fFlags & RTMPON_F_VALID_MASK), VERR_INVALID_FLAGS);
+
+    /*
+     * Prepare the CPU mask before we disable preemption.
+     */
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+    if (!zalloc_cpumask_var(&DstCpuMask, GFP_KERNEL))
+        return VERR_NO_MEMORY;
+    cpumask_set_cpu(idCpu1, DstCpuMask);
+    cpumask_set_cpu(idCpu2, DstCpuMask);
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+    if (!alloc_cpumask_var(&DstCpuMask, GFP_KERNEL))
+        return VERR_NO_MEMORY;
+    cpumask_clear(DstCpuMask);
+    cpumask_set_cpu(idCpu1, DstCpuMask);
+    cpumask_set_cpu(idCpu2, DstCpuMask);
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+    cpus_clear(DstCpuMask);
+    cpu_set(idCpu1, DstCpuMask);
+    cpu_set(idCpu2, DstCpuMask);
+# endif
 
     /*
@@ -402,10 +427,4 @@
          * call wait ourselves.
          */
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-        /* 2.6.28 introduces CONFIG_CPUMASK_OFFSTACK */
-        cpumask_var_t DstCpuMask;
-# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
-        cpumask_t   DstCpuMask;
-# endif
         RTCPUID     idCpuSelf = RTMpCpuId();
         bool const  fCallSelf = idCpuSelf == idCpu1 || idCpuSelf == idCpu2;
@@ -417,21 +436,4 @@
         Args.idCpu2  = idCpu2;
         Args.cHits   = 0;
-
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
-        if (!zalloc_cpumask_var(&DstCpuMask, GFP_KERNEL))
-            return VERR_NO_MEMORY;
-        cpumask_set_cpu(idCpu1, DstCpuMask);
-        cpumask_set_cpu(idCpu2, DstCpuMask);
-# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-        if (!alloc_cpumask_var(&DstCpuMask, GFP_KERNEL))
-            return VERR_NO_MEMORY;
-        cpumask_clear(DstCpuMask);
-        cpumask_set_cpu(idCpu1, DstCpuMask);
-        cpumask_set_cpu(idCpu2, DstCpuMask);
-# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
-        cpus_clear(DstCpuMask);
-        cpu_set(idCpu1, DstCpuMask);
-        cpu_set(idCpu2, DstCpuMask);
-# endif
 
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
@@ -468,8 +470,4 @@
         else
             rc = VERR_CPU_IPE_1;
-
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-        free_cpumask_var(DstCpuMask);
-# endif
     }
     /*
@@ -481,5 +479,9 @@
     else
         rc = VERR_CPU_NOT_FOUND;
+
     RTThreadPreemptRestore(&PreemptState);;
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+    free_cpumask_var(DstCpuMask);
+# endif
     IPRT_LINUX_RESTORE_EFL_AC();
     return rc;
