Index: trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
===================================================================
--- trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp	(revision 82859)
+++ trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp	(revision 82860)
@@ -48,4 +48,10 @@
 #include "internal/memobj.h"
 
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#define MY_PRINTF(...) do { printf(__VA_ARGS__); kprintf(__VA_ARGS__); } while (0)
+
 /*#define USE_VM_MAP_WIRE - may re-enable later when non-mapped allocations are added. */
 
@@ -241,10 +247,10 @@
         }
         else
-            printf("rtR0MemObjDarwinReadPhys: createMappingInTask failed; HCPhys=%llx\n", HCPhys);
+            MY_PRINTF("rtR0MemObjDarwinReadPhys: createMappingInTask failed; HCPhys=%llx\n", HCPhys);
 
         pMemDesc->release();
     }
     else
-        printf("rtR0MemObjDarwinReadPhys: withAddressRanges failed; HCPhys=%llx\n", HCPhys);
+        MY_PRINTF("rtR0MemObjDarwinReadPhys: withAddressRanges failed; HCPhys=%llx\n", HCPhys);
 }
 
@@ -281,5 +287,5 @@
         if (!(u64.u & X86_PML4E_P))
         {
-            printf("rtR0MemObjDarwinGetPTE: %p -> PML4E !p\n", pvPage);
+            MY_PRINTF("rtR0MemObjDarwinGetPTE: %p -> PML4E !p\n", pvPage);
             return 0;
         }
@@ -289,5 +295,5 @@
         if (!(u64.u & X86_PDPE_P))
         {
-            printf("rtR0MemObjDarwinGetPTE: %p -> PDPTE !p\n", pvPage);
+            MY_PRINTF("rtR0MemObjDarwinGetPTE: %p -> PDPTE !p\n", pvPage);
             return 0;
         }
@@ -299,5 +305,5 @@
         if (!(u64.u & X86_PDE_P))
         {
-            printf("rtR0MemObjDarwinGetPTE: %p -> PDE !p\n", pvPage);
+            MY_PRINTF("rtR0MemObjDarwinGetPTE: %p -> PDE !p\n", pvPage);
             return 0;
         }
@@ -309,5 +315,5 @@
         if (!(u64.u &  X86_PTE_P))
         {
-            printf("rtR0MemObjDarwinGetPTE: %p -> PTE !p\n", pvPage);
+            MY_PRINTF("rtR0MemObjDarwinGetPTE: %p -> PTE !p\n", pvPage);
             return 0;
         }
@@ -904,8 +910,20 @@
     if (pMemToMapDarwin->pMemDesc)
     {
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+        /* The kIOMapPrefault option was added in 10.10.0; causes PTEs to be populated with
+           INTEL_PTE_WIRED to be set, just like we desire (see further down). */
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
         IOMemoryMap *pMemMap = pMemToMapDarwin->pMemDesc->createMappingInTask(kernel_task,
                                                                               0,
-                                                                              kIOMapAnywhere | kIOMapDefaultCache,
+                                                                              kIOMapAnywhere | kIOMapDefaultCache | kIOMapPrefault,
+                                                                              offSub,
+                                                                              cbSub);
+#elif MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+        static uint32_t volatile s_fOptions = UINT32_MAX;
+        uint32_t fOptions = s_fOptions;
+        if (RT_UNLIKELY(fOptions == UINT32_MAX))
+            s_fOptions = fOptions = version_major >= 14 ? 0x10000000 /*kIOMapPrefault*/ : 0; /* Since 10.10.0. */
+        IOMemoryMap *pMemMap = pMemToMapDarwin->pMemDesc->createMappingInTask(kernel_task,
+                                                                              0,
+                                                                              kIOMapAnywhere | kIOMapDefaultCache | fOptions,
                                                                               offSub,
                                                                               cbSub);
@@ -921,8 +939,12 @@
             IOVirtualAddress VirtAddr = pMemMap->getVirtualAddress();
             void *pv = (void *)(uintptr_t)VirtAddr;
-            if ((uintptr_t)pv == VirtAddr)
+            if ((uintptr_t)pv == VirtAddr && pv != NULL)
             {
-                //addr64_t Addr = pMemToMapDarwin->pMemDesc->getPhysicalSegment64(offSub, NULL);
-                //printf("pv=%p: %8llx %8llx\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr);
+//#ifdef __LP64__
+//                addr64_t Addr = pMemToMapDarwin->pMemDesc->getPhysicalSegment(offSub, NULL, kIOMemoryMapperNone);
+//#else
+//                addr64_t Addr = pMemToMapDarwin->pMemDesc->getPhysicalSegment64(offSub, NULL);
+//#endif
+//                MY_PRINTF("pv=%p: %8llx %8llx\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr);
 
 //                /*
@@ -945,14 +967,21 @@
 //                    if (IORet == kIOReturnSuccess)
 //                    {
-                        /* HACK ALERT! */
-                        rtR0MemObjDarwinTouchPages(pv, cbSub);
+                        /* HACK ALERT! On kernels older than 10.10 (xnu version 14), we need to fault in
+                                       the pages here so they can safely be accessed from inside simple
+                                       locks and when preemption is disabled (no page-ins allowed).
+                           Note! This touching does not cause INTEL_PTE_WIRED (bit 10) to be set as we go
+                                 thru general #PF and vm_fault doesn't figure it should be wired or something.  */
+                        rtR0MemObjDarwinTouchPages(pv, cbSub ? cbSub : pMemToMap->cb);
                         /** @todo First, the memory should've been mapped by now, and second, it
-                         *        should have the wired attribute in the PTE (bit 9). Neither
-                         *        seems to be the case. The disabled locking code doesn't make any
-                         *        difference, which is extremely odd, and breaks
-                         *        rtR0MemObjNativeGetPagePhysAddr (getPhysicalSegment64 -> 64 for the
-                         *        lock descriptor. */
-                        //addr64_t Addr = pMemDesc->getPhysicalSegment64(0, NULL);
-                        //printf("pv=%p: %8llx %8llx (%d)\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr, 2);
+                         *        should have the wired attribute in the PTE (bit 10). Neither seems to
+                         *        be the case. The disabled locking code doesn't make any difference,
+                         *        which is extremely odd, and breaks rtR0MemObjNativeGetPagePhysAddr
+                         *        (getPhysicalSegment64 -> 64 for the lock descriptor. */
+//#ifdef __LP64__
+//                        addr64_t Addr2 = pMemToMapDarwin->pMemDesc->getPhysicalSegment(offSub, NULL, kIOMemoryMapperNone);
+//#else
+//                        addr64_t Addr2 = pMemToMapDarwin->pMemDesc->getPhysicalSegment64(offSub, NULL);
+//#endif
+//                        MY_PRINTF("pv=%p: %8llx %8llx (%d)\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr2, 2);
 
                         /*
@@ -982,6 +1011,8 @@
 //                    rc = VERR_MEMOBJ_INIT_FAILED;
             }
+            else if (pv)
+                rc = VERR_ADDRESS_TOO_BIG;
             else
-                rc = VERR_ADDRESS_TOO_BIG;
+                rc = VERR_MAP_FAILED;
             pMemMap->release();
         }
@@ -1034,5 +1065,5 @@
             IOVirtualAddress VirtAddr = pMemMap->getVirtualAddress();
             void *pv = (void *)(uintptr_t)VirtAddr;
-            if ((uintptr_t)pv == VirtAddr)
+            if ((uintptr_t)pv == VirtAddr && pv != NULL)
             {
                 /*
@@ -1053,6 +1084,8 @@
                 rc = VERR_NO_MEMORY;
             }
+            else if (pv)
+                rc = VERR_ADDRESS_TOO_BIG;
             else
-                rc = VERR_ADDRESS_TOO_BIG;
+                rc = VERR_MAP_FAILED;
             pMemMap->release();
         }
