VirtualBox

Changeset 82860 in vbox for trunk


Ignore:
Timestamp:
Jan 26, 2020 2:17:48 PM (5 years ago)
Author:
vboxsync
Message:

IPRT/memobj-r0drv-darwin.cpp: rtR0MemObjNativeMapKernel wasn't forcing the pages into the mapping when the whole object was being mapped, so we would panic when the first access happened in non-preemptive code (code is only when VBOX_WITH_RAM_IN_KERNEL is defined, which it isn't yet). Found new kIOMapPrefault flag (10.10.0?) that does this very efficiently. bugref:9627

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp

    r78120 r82860  
    4848#include "internal/memobj.h"
    4949
     50
     51/*********************************************************************************************************************************
     52*   Defined Constants And Macros                                                                                                 *
     53*********************************************************************************************************************************/
     54#define MY_PRINTF(...) do { printf(__VA_ARGS__); kprintf(__VA_ARGS__); } while (0)
     55
    5056/*#define USE_VM_MAP_WIRE - may re-enable later when non-mapped allocations are added. */
    5157
     
    241247        }
    242248        else
    243             printf("rtR0MemObjDarwinReadPhys: createMappingInTask failed; HCPhys=%llx\n", HCPhys);
     249            MY_PRINTF("rtR0MemObjDarwinReadPhys: createMappingInTask failed; HCPhys=%llx\n", HCPhys);
    244250
    245251        pMemDesc->release();
    246252    }
    247253    else
    248         printf("rtR0MemObjDarwinReadPhys: withAddressRanges failed; HCPhys=%llx\n", HCPhys);
     254        MY_PRINTF("rtR0MemObjDarwinReadPhys: withAddressRanges failed; HCPhys=%llx\n", HCPhys);
    249255}
    250256
     
    281287        if (!(u64.u & X86_PML4E_P))
    282288        {
    283             printf("rtR0MemObjDarwinGetPTE: %p -> PML4E !p\n", pvPage);
     289            MY_PRINTF("rtR0MemObjDarwinGetPTE: %p -> PML4E !p\n", pvPage);
    284290            return 0;
    285291        }
     
    289295        if (!(u64.u & X86_PDPE_P))
    290296        {
    291             printf("rtR0MemObjDarwinGetPTE: %p -> PDPTE !p\n", pvPage);
     297            MY_PRINTF("rtR0MemObjDarwinGetPTE: %p -> PDPTE !p\n", pvPage);
    292298            return 0;
    293299        }
     
    299305        if (!(u64.u & X86_PDE_P))
    300306        {
    301             printf("rtR0MemObjDarwinGetPTE: %p -> PDE !p\n", pvPage);
     307            MY_PRINTF("rtR0MemObjDarwinGetPTE: %p -> PDE !p\n", pvPage);
    302308            return 0;
    303309        }
     
    309315        if (!(u64.u &  X86_PTE_P))
    310316        {
    311             printf("rtR0MemObjDarwinGetPTE: %p -> PTE !p\n", pvPage);
     317            MY_PRINTF("rtR0MemObjDarwinGetPTE: %p -> PTE !p\n", pvPage);
    312318            return 0;
    313319        }
     
    904910    if (pMemToMapDarwin->pMemDesc)
    905911    {
    906 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
     912        /* The kIOMapPrefault option was added in 10.10.0; causes PTEs to be populated with
     913           INTEL_PTE_WIRED to be set, just like we desire (see further down). */
     914#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
    907915        IOMemoryMap *pMemMap = pMemToMapDarwin->pMemDesc->createMappingInTask(kernel_task,
    908916                                                                              0,
    909                                                                               kIOMapAnywhere | kIOMapDefaultCache,
     917                                                                              kIOMapAnywhere | kIOMapDefaultCache | kIOMapPrefault,
     918                                                                              offSub,
     919                                                                              cbSub);
     920#elif MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
     921        static uint32_t volatile s_fOptions = UINT32_MAX;
     922        uint32_t fOptions = s_fOptions;
     923        if (RT_UNLIKELY(fOptions == UINT32_MAX))
     924            s_fOptions = fOptions = version_major >= 14 ? 0x10000000 /*kIOMapPrefault*/ : 0; /* Since 10.10.0. */
     925        IOMemoryMap *pMemMap = pMemToMapDarwin->pMemDesc->createMappingInTask(kernel_task,
     926                                                                              0,
     927                                                                              kIOMapAnywhere | kIOMapDefaultCache | fOptions,
    910928                                                                              offSub,
    911929                                                                              cbSub);
     
    921939            IOVirtualAddress VirtAddr = pMemMap->getVirtualAddress();
    922940            void *pv = (void *)(uintptr_t)VirtAddr;
    923             if ((uintptr_t)pv == VirtAddr)
     941            if ((uintptr_t)pv == VirtAddr && pv != NULL)
    924942            {
    925                 //addr64_t Addr = pMemToMapDarwin->pMemDesc->getPhysicalSegment64(offSub, NULL);
    926                 //printf("pv=%p: %8llx %8llx\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr);
     943//#ifdef __LP64__
     944//                addr64_t Addr = pMemToMapDarwin->pMemDesc->getPhysicalSegment(offSub, NULL, kIOMemoryMapperNone);
     945//#else
     946//                addr64_t Addr = pMemToMapDarwin->pMemDesc->getPhysicalSegment64(offSub, NULL);
     947//#endif
     948//                MY_PRINTF("pv=%p: %8llx %8llx\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr);
    927949
    928950//                /*
     
    945967//                    if (IORet == kIOReturnSuccess)
    946968//                    {
    947                         /* HACK ALERT! */
    948                         rtR0MemObjDarwinTouchPages(pv, cbSub);
     969                        /* HACK ALERT! On kernels older than 10.10 (xnu version 14), we need to fault in
     970                                       the pages here so they can safely be accessed from inside simple
     971                                       locks and when preemption is disabled (no page-ins allowed).
     972                           Note! This touching does not cause INTEL_PTE_WIRED (bit 10) to be set as we go
     973                                 thru general #PF and vm_fault doesn't figure it should be wired or something.  */
     974                        rtR0MemObjDarwinTouchPages(pv, cbSub ? cbSub : pMemToMap->cb);
    949975                        /** @todo First, the memory should've been mapped by now, and second, it
    950                          *        should have the wired attribute in the PTE (bit 9). Neither
    951                          *        seems to be the case. The disabled locking code doesn't make any
    952                          *        difference, which is extremely odd, and breaks
    953                          *        rtR0MemObjNativeGetPagePhysAddr (getPhysicalSegment64 -> 64 for the
    954                          *        lock descriptor. */
    955                         //addr64_t Addr = pMemDesc->getPhysicalSegment64(0, NULL);
    956                         //printf("pv=%p: %8llx %8llx (%d)\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr, 2);
     976                         *        should have the wired attribute in the PTE (bit 10). Neither seems to
     977                         *        be the case. The disabled locking code doesn't make any difference,
     978                         *        which is extremely odd, and breaks rtR0MemObjNativeGetPagePhysAddr
     979                         *        (getPhysicalSegment64 -> 64 for the lock descriptor. */
     980//#ifdef __LP64__
     981//                        addr64_t Addr2 = pMemToMapDarwin->pMemDesc->getPhysicalSegment(offSub, NULL, kIOMemoryMapperNone);
     982//#else
     983//                        addr64_t Addr2 = pMemToMapDarwin->pMemDesc->getPhysicalSegment64(offSub, NULL);
     984//#endif
     985//                        MY_PRINTF("pv=%p: %8llx %8llx (%d)\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr2, 2);
    957986
    958987                        /*
     
    9821011//                    rc = VERR_MEMOBJ_INIT_FAILED;
    9831012            }
     1013            else if (pv)
     1014                rc = VERR_ADDRESS_TOO_BIG;
    9841015            else
    985                 rc = VERR_ADDRESS_TOO_BIG;
     1016                rc = VERR_MAP_FAILED;
    9861017            pMemMap->release();
    9871018        }
     
    10341065            IOVirtualAddress VirtAddr = pMemMap->getVirtualAddress();
    10351066            void *pv = (void *)(uintptr_t)VirtAddr;
    1036             if ((uintptr_t)pv == VirtAddr)
     1067            if ((uintptr_t)pv == VirtAddr && pv != NULL)
    10371068            {
    10381069                /*
     
    10531084                rc = VERR_NO_MEMORY;
    10541085            }
     1086            else if (pv)
     1087                rc = VERR_ADDRESS_TOO_BIG;
    10551088            else
    1056                 rc = VERR_ADDRESS_TOO_BIG;
     1089                rc = VERR_MAP_FAILED;
    10571090            pMemMap->release();
    10581091        }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette